Accessibility, Usability & Compliance
How to make your Web site work for you. 2nd April - Liverpool.
In this article we will see how PHP can be used to generate a navigation menu which doesn't link to the current page, is up to date on every page and only shows section relevant links in the sub menu.
Author: Phil Smears
Date added: 3rd January 2007
As can be seen on the left hand side of this page 'Articles' is delinked and if you view the source 'Article' has been enclosed in a strong element with title 'You are here'. In addition a sub menu is open showing links within the articles section. A class of 'parent' has been applied to 'Article', the top level menu item, and a class of current has been applied to 'PHP navigation menus' in the sub menu. The same behaviour can be shown by visiting other sections of the site, such as the 'About Us' section.
Apart from displaying system state using classes and the <strong> element it can be difficult to keep a navigation menu up to date and displaying links to newly added pages. The same include file, with a little modification to ensure all the sub menus are displayed, can be used to generate a site map. Incidentally an error page for mistyped urls also uses the include to generate a site map. This means we'll never have to worry again whether the navigation menu is up to date on all sections of the site.
Obviously a link to an include file on every page can be used to generate a menu, but how can the same include file only show section relevant links and insert 'parent' and 'current' classes on the appropriate elements? Here's how:
We'll start by creating one array which holds every page, link URL and link text:
Here is the array for the navigation menu used by this site, possibly out of date by now, of course.
A mixture of index and associative arrays has been used basically for readability. Every time a page is added to the site it's inserted in the array in the correct place and that's it we don't need to worry about updating anything else.
The PHP script that acts on the array is a little more complicated.
It starts by looping through the first level of the array outputting each link in a list element. Whilst it is looping through each element of the array, it checks whether the 'url' element in the array corresponds to the page's current URL and if so adds a 'current' class. It also checks whether there is a sub menu and whether it should be displayed or not. For example we only want to display the 'Articles' sub menu containing 'PHP Navigation Menus' and 'Flexible images with CSS' if a visitor is in the 'Articles' section of the site. A similar include operates on the sub menu, again checking if it in turn has a sub menu, in which case a final include loops through third level navigation items. It ends there as we took a decision to limit depth to three levels otherwise, content would have just been buried too deep.
Section pages need a variable to let the script know which section the current page belongs to. This page has <? $section="Articles"; ?> near the top of the page in the code.
In the future I'll probably replace it with a script that builds a menu using the directory structure but I have to justify the time spent on it by using this menu for a bit, don't I? In the meantime, if you can suggest any improvements please let me know.