Corey Worrell

  • Portfolio
  • Blog
  • Contact

PHP Menu Builder Class

  • What It Is
  • How It Works
  • Example
  • Other Options
  • Download

This class provides a way to easily build out a tree-like menu.

Normally, this task would require creating a huge and complex array of items to create the menu structure. This class simplifies that process and doesn't require you to use any arrays.

It also obviously supports multi-level lists, perfect for creating drop-down navigation menus.

			// Include necessary classes
			include 'menu.class.php';
			include 'tidy_menu.class.php';
			
			// Build out menu structure, the syntax makes it easy to see the levels
			$menu = menu::factory()
						->add('About Us', 'about-us.php', menu::factory()
							->add('Who We Are', 'who-we-are.php')
							->add('What We Do', 'what-we-do.php')
							->add('Other Things', 'other-things.php'))
						->add('Random', 'random.php', menu::factory()
							->add('Link One', 'link-one.php')
							->add('Link Two', 'link-two.php', menu::factory()
								->add('Level Three', 'level-three.php')));
			
			// (optional) Add some attributes to the main list
			$menu->attrs = array
			(
				'id'    => 'navigation',
				'class' => 'menu',
			);
			/*
			You can also do the following instead
			$menu->id = 'navigation';
			$menu->class = 'menu';
			*/
			
			// (optional) Tell it the current active item
			$menu->current = 'level-three.php';
			
			/*
			Echo the menu
			Normally, you could just do this:
			echo $menu;
			But for this example, we're using the tidy_menu class to output nice, readable HTML,
			whereas just echoing normally would render the HTML in a single line.
			*/
			echo new tidy_menu($menu);
		

The above generates the following HTML:

			<ul id="navigation" class="menu">
				<li class="parent"><a href="about-us.php">About Us</a>
					<ul>
						<li><a href="who-we-are.php">Who We Are</a></li>
						<li><a href="what-we-do.php">What We Do</a></li>
						<li><a href="other-things.php">Other Things</a></li>
					</ul>
				</li>
				<li class="parent active"><a href="random.php">Random</a>
					<ul>
						<li><a href="link-one.php">Link One</a></li>
						<li class="parent active"><a href="link-two.php">Link Two</a>
							<ul>
								<li class="active current"><a href="level-three.php">Level Three</a></li>
							</ul>
						</li>
					</ul>
				</li>
			</ul>
		

Here's a menu with some CSS applied.

  • About Us
    • Who We Are
    • What We Do
    • Other Things
  • Blog
    • Link One
    • Link Two
      • Dropdown
      • More Links
      • Level Three
      • Another Link
      • Last Anchor
    • Link Three
    • Link Four
  • Team
  • Portfolio
    • Web
    • Print
    • Logos
  • Contact Us

There are a few different ways to go about creating your menus. Here are a few examples.

			echo menu::factory()
					 ->add('Item One', 'item_one.php')
					 ->add('Item Two', 'item_two.php', menu::factory()
					      ->add('Item Three', 'item_three.php')
						  ->add('Item Four', 'item_four.php'));
		
			$attrs = array('class' => 'my_menu');
			$active = 'item_one.php';
			
			echo menu::factory()
					 ->add('Item One', 'item_one.php')
					 ->add('Item Two', 'item_two.php')
					 ->render($attrs, $active);
		

Or if you find it easier to create the array yourself, like if you were pulling values from a database, you can do that and just pass in the array to the class.

			$menu = array
			(
				array
				(
					'title' => 'Item One',
					'url' => 'item_one.php',
				),
				array
				(
					'title' => 'Item Two',
					'url' => 'item_two.php',
					'children' => array
					(
						array
						(
							'title' => 'Item Three',
							'url' => 'item_three.php',
						),
						array
						(
							'title' => 'Item Four',
							'url' => 'item_four.php',
						)
					)
				)
			);
			
			$attrs = array('id' => 'menu');
			$active = $_SERVER['REQUEST_URI'];
			
			echo menu::factory($menu)->render($attrs, $active);
		

Database Example

Below is an example of using this class with a database that holds your menu structure.

The table structure could look something like this:

			menu
			
			+--------+---------+
			| id     | int(11) |
			+--------+---------+
			| title  | varchar |
			+--------+---------+
			| url    | varchar |
			+--------+---------+
			| parent | int(11) |
			+--------+---------+
		

Then, in your model file you could have a function like this:

			public function build($level = NULL)
			{
				$level_id = empty($level) ? 0 : $level->id;
				
				$level = $this->where('parent', $level_id)->orderby('id', 'asc')->find_all();
				
				$menu = new menu;
				
				foreach ($level as $lvl)
				{
					$menu->add($lvl->title, $lvl->url, $this->build($lvl));
				}
				
				return $menu;
			}
		

And then in your controller or view, you could do this to render the menu:

			echo ORM::factory('menu')->build()->render();
		
Download