Turn static CSS3/HTML5 menu into dynamic with PHP/MYSQL



Hello everyone.

I build a static website (no CMS), DooMeHome, but would like to make the menu dynamic. I also set up a DB with the following structure:
I created a database with the following setup:

ID item link parent child
1 HOME root 0 NULL
2 Services building-services 0 NULL
3 Projects building-products 0 NULL
4 Info help-center 0 NULL
5 Blog home-improvement-blog 0 NULL
6 Painting professional-painters 2 1
7 Tiling professional-tilers 2 2
8 Carpentry professional-carpenters 2 3
9 Splashback splashback-options 2 4
10 Home Renovation home-renovation 2 5
11 Design / Decoration design-decoration 2 6
12 Cladding ALUCABOND cladding-alucabond 2 7
13 Services Overview building-services 2 8
14 Slap it on traditional-home-painting 6 1
15 Art feature wall art-feature-wall 6 2
16 Decorative painting decoratice-painting 6 3
17 Mural painting /external website/ 6 4
18 Floor to Ceiling floor-wall-tiling 7 1
19 Natural Sone travertine-natural-stone 7 2
20 Extensions home-extensions 8 1
21 Decking / Verandah deckings-verandahs 8 2
22 Stairs unusual-stairways 8 3
23 Repair Work repair-alterations 8 4
24 Carports / Other carports-other 8 5
25 Glass Splashback glass-splashback 9 1
26 Mirror Splashback mirror-splashback 9 2
27 Art Splashback art-splashback 9 3
28 Acrylic Splashback acrylic-splashback 9 4
29 Metaline Splashback metaline-splashback 9 5
30 Contact contact-doomehome 4 1
31 FAQ builders-faq 4 2
32 About about-doomehome 4 3

By making it dynamic, I mean:
1. I want to to 'include' the menu on every page with a simple 'include' call
2. Every page is unique, hence, it should display the menu item of this page as 'active' and in order to keep my CSS styling for the menu.

I am "Hopelessly" poor in PHP. Could anyone help me out, please? Much appreciated, thanks.

Oh, I forgot. In the DB I included the row 'child' because I want to be able to order the items the way they should appear on the menu.

I hope I make some kind sense.


Some more detail would be good. For example, are all of these individual pages, or only those where the "parent" is zero? Are you needing a hierarchical menu, or just a single level? By that I mean

Page 2, Services, for example, would you show only those menu entries where "parent" = 2, or would it also iterate to show those entries where parent=2, and then for each of those, show a sub-menu where parent=6, 7, 8, to 13, and then keep going for "x" levels?

I'd suggest the first thing to do is go for the simple single-level menu and get that working. Then expand on your PHP learning to get sub-levels working if you need to. Some would say that using Ajax to dynamically recover the second and subsequent menu levels would be a good choice, but that's for later.

Some pseudo-code

query = "SELECT menu, link FROM yourtable WHERE parent = pagevalue ORDER BY child"
execute query
for each row returned {
  display menu and link

That's pretty much it, if I've understood the question. Once you have that working, you can add deeper levels of nesting if you need to. The ORDER BY clause will sort the results in the order you specify.


For the PHP end of things, perhaps something like the following might do the trick:

<?php $pageName = basename($_SERVER['PHP_SELF']); ?>
    <li><a href="."<?php if ( $pageName == 'index.php' ) echo ' class="selected"'; ?>>Our services</a></li>
    <li><a href="about-us.php"<?php if ( $pageName == 'about-us.php' ) echo ' class="selected"'; ?>>About us</a></li>
    <li><a href="packages.php"<?php if ( $pageName == 'packages.php' ) echo ' class="selected"'; ?>>Packages</a></li>
    <li><a href="testimonials.php"<?php if ( $pageName == 'testimonials.php' ) echo ' class="selected"'; ?>>Testimonials</a></li>
    <li><a href="contact-us.php"<?php if ( $pageName == 'contact-us.php' ) echo ' class="selected"'; ?>>Contact us</a></li>

Set <select> option selected using PHP

I am in the process of creating a new menu system which includes a dynamic menu

I want to replace an old menu and add some SVG diagonals, triangles, etc.

Currently the menu under construction uses links instead of being driven from a database. Once complete I should be able to call one single "home.php" page and pass database variables.

Work in progress



Or perhaps something like this which is what I use in the menu under construction :slight_smile:

  <div id="mnuTop" class="pof POA w96 bg5">
    <div class="menu">
        foreach($aTopTabs as $url => $title):
          $current = '';
          if($title === ucfirst($wPage) ):
            $current = ' current'; 
          echo "\n\t" .'<a href="' .$url   .'" 
                  class="' .$title 
                 .$title .'</a>';
      <span class="dot">&nbsp;</span>

Set <select> option selected using PHP

This topic has some simple examples of menus from php. I gave an example using an array instead of a database to store item info.

Though I'm currently working on refactoring a site (from procedural to oop) where I have changed the menu to take item data from a database table of pages on the site. So the menu part of that uses a couple of classes, menu and menuitem and a couple of methods to build the menus and output them.
If you take that route, how that happens will depend on your intended menu structure.


Thank you for the hint, appreciated.
However, I can't just change the site layout because I am not good enough to create a hierarchical menu using PHP.
Then I keep it static and change every single page's header/menu with every change in pages (e.g. adding a new page).


Thank you.
Got that for adding classes.
Thank you very much for the lesson


Entire menu is actually here (as mentioned in my original post)


The most simple way to get around this if you are not a confident php programmer is to simply have a stand-alone, static html menu saved in a file which is an include in your pages/page-template. This won't be so "dynamic" but it's simple for a beginner and will save yo making multiple edits.

Taking it to the next step is using an array. This can be useful, because with a nested hierarchy of menus like you have, you can define that structure as a multi-dimensional array.
You will then use foreach loops, nested to render the html lists.
To edit the menu (add/remove/re-name pages) you only need edit the array.

Then the next level is using a database. Then it does get a bit more complex as you need a way of defining the hierarchy and then constructing the menu in that way.
I would say the array method may be easier and more efficient. So I would only use a database if I was going to also build/use some kind of admin interface to manage the entries via forms, like a mini CMS, rather than manually editing code. Otherwise I would see it as an over-complication.


Take a look at this dynamic menu which is the top part with the royal blue background. It is common to every page and accepts the $title, top $group links and sub $page links. Once modularized (spelling?) it will be populated from a database table.


I am busy with another version and hope to post the updates tonight.


This should be pretty close to what your are looking for.

$menu_array = array(); 

$sqlcatsmenu = "SELECT 
	  mc.item AS 'main_item'
	, mc.link AS 'main_link' 
	, p.item AS 'parent_item'
	, p.link AS 'parent_link' 
	, c.item AS 'child_item'
	, c.link AS 'child_link'
	FROM tbl_menu AS mc
		LEFT JOIN tbl_menu AS p 
			ON p.parent = mc.ID 
		LEFT JOIN tbl_menu AS c 
			ON c.parent = p.ID  
	WHERE mc.child IS NULL 
	ORDER BY mc.ID, p.child, c.child";
$resultcatsmenu = $conn->query($sqlcatsmenu);
while($row = $resultcatsmenu->fetch_assoc()){

		$menu_array[$row['main_link']]['name'] = $row['main_item'];
			$menu_array[$row['main_link']]['categories'][$row['parent_link']]['name'] = $row['parent_item'];
			$menu_array[$row['main_link']]['categories'][$row['parent_link']]['subcategories'][$row['child_link']] = $row['child_item'];
echo "<pre>";
echo "</pre>";

$menu = '';

	//Build menu
	$menu .= '<ul class="nav nav-pills" id="mainNav">'."\r";
	foreach($menu_array as $cat => $arr):
		$classparts = array();
		if(isset($pagename) && $pagename == $menu_array[$cat]['name']):
			$classparts[] = 'active'; 
			$classparts[] =  'dropdown';
		$dropclass = (!empty($classparts) ? ' class="'.implode(' ',$classparts).'"' : '');
		$catlink = ($cat !== "root" ? $cat : './');
		$caret = (!empty($menu_array[$cat]['categories']) ? '<i class="fa fa-caret-down"></i></a>' : '</a>');
		$dropsubclass = (!empty($menu_array[$cat]['categories']) ? ' class="dropdown-item dropdown-toggle"' : ' class="nav-link"');
		$menu .= '<!-- '.$menu_array[$cat]['name'].' -->'."\r";
		$menu .= '<li'.$dropclass.'><a href="'.$catlink.'"'.$dropsubclass.'>'.$menu_array[$cat]['name']."\r".$caret."\r";
			$menu .= '<ul class="dropdown-menu">'."\r";
			foreach($menu_array[$cat]['categories'] as $category => $arr2):				
				$category_name = $menu_array[$cat]['categories'][$category]['name'];	
				$dropdown_submenu = (!empty($menu_array[$cat]['categories'][$category]['subcategories']) ? ' class="dropdown-submenu"' : '');
				//Is linked icon. Based on `link` field being #
				$islinked = ($category == "#" ? '<img src="./img/icons/linked-no.png" alt="item is not linked" />' : '<img src="./img/icons/linked-yes.png" alt="item is linked" />');
				$sublink = (!empty($menu_array[$cat]['categories'][$category]['subcategories']) ? '<a class="dropdown-item" href="#"><span class="linkedicon">'.$islinked.'</span>'.$category_name.'<i class="fa fa-caret-down"></i></a>' : '<a class="dropdown-item" href="'.$category.'">'.$category_name.'</a>');
				$menu .= '<li'.$dropdown_submenu.'>'.$sublink.'</li>'."\r";	 
					$menu .= '<ul class="dropdown-menu">'."\r";	
					foreach($menu_array[$cat]['categories'][$category]['subcategories'] as $subcategory => $arr3):
						$subcategory_name = $menu_array[$cat]['categories'][$category]['subcategories'][$subcategory];	
						$menu .= '<li><a class="dropdown-item" href="'.$subcategory.'">'.$subcategory_name.'</a></li>'."\r";
					$menu .= '</ul>'."\r";
			$menu .= '</ul>'."\r";
		$menu .= '</li>'."\r";
	$menu .= '</ul>'."\r"; 

echo $menu;


Hope this will at least get you started.


This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.