Building side navigation with PHP
I’m working on a website which requires a left side (secondary) navigation which links to logically relevant pages within a section. As is usually the case, all the pages inside a section had the same side navigation menu. I was initially handcoding the navigation lists into the html pages, but I realized that this wasn’t a good practice and would result in poor scalability and high maintenance costs.
I then wrote a couple of PHP functions to build the navigation using an associative array; the common links would be stored in a helper file and included into all the relevant pages.
This is how I went about it –
Scenario
Consider an About us section of a website. The pages inside could be –
About us
– Overview
– Our services
– Portfolio
– Contact us
All the pages inside the this section (or directory) would have this list as a side-navigation.
The standard approach
Normally, to display a secondary or side navigation, you’d put this in your html -
<nav class=secondary> <ul> <li><a href="overview.php">Overview</a> <li><a href="services.php">Our services</a> <li><a href="portfolio.php">Portfolio</a> <li><a href="contact.php">Contact us</a> </ul> </nav>
If you follow this practice for a large website with numerous sections and pages, you will soon find yourself repeating a lot of code. More importantly, maintenance will be painful. Consider that, later, you wan’t to change the structure of your a element to include an image before the text, like so –
<li><a href=foo><img src="bullet.png" alt=bullet />foo</a>
You’ll have to make this change in all the 4 pages above, and that’s just one section. Clearly, this method does not scale well.
Building the navigation using PHP
Let’s list our navigation items in an array –
<?php $_sidenav = array( "Overview" => "overview.php", "Our services" => "services.php", "Portfolio" => "portfolio.php", "Contact us" => "contact.php" ); ?>
We store this in a helper file as _sidenav.php. So our directory structure looks like this -
/
/about
_sidenav.php
overview.php
services.php
portfolio.php
contact.php
Now comes the PHP function that will take this array and echo a simple list. It’s pretty straightforward -
<?php
function sidenav_show( $arr ) {
echo "<nav class=secondary>";
sidenav_loop( $arr );
echo "</nav>";
}
function sidenav_loop( $arr ) {
echo "<ul>";
// loop through array
while( $nav_item = current( $arr ) ) {
echo "<li><a href=\"". $nav_item . "\">"
. key( $arr ) . "</a>";
next( $arr );
}
echo "</ul>";
}
?>
The function sidenav_loop() iterates over the elements of our array and uses the key-value pairs to generate the links.
You can store this function in any top-level location that is easily accessible by all pages in your website. I stored it along with my other globally included files –
/
/lib
sidenav.php
/about
_sidenav.php
overview.php
services.php
portfolio.php
contact.php
Now for every page in which you want to display this nav, you just have to include the function and the corresponding helper file and call sidenav_show(). For example, our overview.php will have this –
<?php require_once( $_SERVER["DOCUMENT_ROOT"] . "/lib/sidenav.php" ); require_once( "_sidenav.php" ); ?> <!-- header, body, etc. --> <?php sidenav_show( $_sidenav ); ?>
Thats it! Extend this to all the sections of the site. Any changes to links within a section are made to _sidenav.php in the corresponding directory. Any changes to the list structure / navigation style can be made to /lib/sidenav.php and they will be applied globally.
Point of note – You might ask why I chose to pass the array variable through the page itself. This is to accommodate an exceptional page where you’d want to define your own menu items, or extend the common menu. This can be done easily –
<?php require_once( $_SERVER["DOCUMENT_ROOT"] . "/lib/sidenav.php" ); // require_once( "_sidenav.php" ); ?> <!-- header, body, etc. --> <?php // a different menu $_sn = array( "foo" => "foo.php", "bar" => "bar.php" ); sidenav_show( $_sn ); ?>
Other thoughts
This same method can be applied to showing breadcrumb trails as well. I’ll be writing a follow-up of this article in which I’ll talk about nested navigation and highlighting the current page in the list.