There are quite a few menu manging packages out there and I'm sure they all work brilliantly in their own way but they all just seemed to be a bit too... complex?

By complex I do not mean the coding is mind boggling or you need 7 qualifications in being able to read binary from the back of a fag packet to conquer how to use them.

I simply mean, you have to tell the script too much. Just throw it an item and it knows what to do with it!

So I wrote this little package where you simply pass a method some parameters and there you go, simples.

Menu::addItem( array(
	'text' 		=> 'I am a link!',
	'URL'  		=> '/clothes/jumpers/green/shirt.html',
	'reference' => "{$link->id}",
	'parent'	=> "{$link->parent_id}"

That's the main setup but there are currently a few other parameters you can use:

The weight parameter allows you to order the items:

Menu::addItem( array( 'weight' => 0 ) )

The icon parameter will add a font awesome icon to the beginning of the link (only if you are using the default renderer).

Menu::addItem( array( 'icon' => 'fa fa-envelope-square' ) )


For a little demonstration of how easy it is to build custom menu styles, I'll quickly run through creating a styles class with some of the main bootstrap styles.

This class can contain as many render methods as you wish. A render method is simply a method which the array of items walk through.

Menu::setMenuType( 'nav-tabs-dropdowns', 'main', 'LukeSnowden\Menu\Styles' );

Here, we are specifying firstly the name of the renderer, the menu to apply it to and thirdly the location of the class.

We then need to add the render method to our Styles.php class (note that the method name is camel case).

public static function renderNavTabsDropdowns( $structure = array(), $depth = 1 )
	if( $depth === 1 ) ob_start();
	foreach( $structure as $level ) {

	if( $depth === 1 ) return ob_get_clean();

This is an example of a very basic way of dealing with each level and returning the data. The data is returned and not printed out directly as you may want to store the menu as a variable and use elsewhere.

<?php namespace LukeSnowden\Menu\Styles;

class Styles
	public static function renderNavTabsDropdowns( $structure = array(), $depth = 1 )
		if( $depth === 1 ) ob_start();
		foreach( $structure as $level ) :
			$class = preg_replace( '/current/', 'active', $level['class'] );
			echo '<li class="' . $class . ' ' . ( empty( $level['children'] ) ? '' : 'dropdown' ) . '">';
				if( ! empty( $level['children'] ) ) :
					echo '<a href="#" class="dropdown-toggle" data-toggle="dropdown">' . $level['text'] . ' <span class="caret"></span></a>';
					echo '<ul class="dropdown-menu" role="menu">';
						echo self::renderNavTabsDropdowns( $level['children'], ($depth+1) );
					echo '</ul>';
				else :
					echo '<a href="' . $level['URL'] . '">' . $level['text'] . '</a>';
			echo '</li>';
		if( $depth === 1 ) return ob_get_clean();

Nav Tabs Dropdown Output:

Menu::addItem( array( 'text' => 'Home', 'URL' => '/menu-test-2/public/', 'reference' => '1', 'class' => 'home-icon', 'weight' => 0 ) )->toMenu( 'main' );
Menu::addItem( array( 'text' => 'Menu', 'URL' => '/menu', 'reference' => 'menu' ) )->toMenu( 'main' );
Menu::addItem( array( 'text' => 'Services', 'URL' => '/menu-test-2/public/services/', 'reference' => '2' ) )->toMenu( 'main' );
Menu::addItem( array( 'text' => 'Development', 'URL' => '/menu-test-2/public/services/development/', 'reference' => '3', 'parent' => '2' ) )->toMenu( 'main' );
Menu::addItem( array( 'text' => 'Design', 'URL' => '/menu-test-2/public/services/design/', 'reference' => '4', 'parent' => '2', 'weight' => 0 ) )->toMenu( 'main' );

Menu::setMenuType( 'nav-tabs-dropdowns', 'main', 'LukeSnowden\Menu\Styles' );
echo Menu::render( 'main', array( 'class' => 'nav nav-tabs', 'role' => 'tablist' ) );

If anyone would like to create some more render methods for bootstrap, please feel free to send them over and I'll make sure you are credited for your work.