Keeping Navigation Current With PHP

Turning unordered lists into elegant navigational menus has become the new favorite pastime for many web developers. Adding a unique id or class attribute to indicate which menu item reflects a user’s current page, however, can become laborious. Even if you use body id attributes instead, as ALA does, some labor is involved and it is easy to make mistakes. But thanks to PHP, we can add these current-page indicators automatically.

Article Continues Below

Consider this tutorial a marriage of Christopher Robbins’s Manage Your Content With PHP and Mark Newhouse’s CSS Design: Taming Lists. The offspring of this marriage will be a single navigational document called navigation.php. Using PHP, we will include our one-size-fits-all navigational menu into every page of our site. Unlike other site-wide includes, however, this one will know which page the user is viewing and will adjust the current-page indicator appropriately.

Keeping current#section2

To visually indicate which page of your carefully crafted CSS navigational menu represents the current page, you typically add an id or class attribute with a currentpage value, and style accordingly. Your markup and CSS might look something like that shown next:

HTML#section3

<div id="navigation">
<ul>
<li><a href="#">Page One</a></li>
<li id="currentpage"><a href="#">Page Two</a>
</li>
<li><a href="#">Page Three</a></li>
<li><a href="#">Page Four</a></li>
</ul>
</div>

CSS#section4

#navigation ul {
list-style: none;
margin: 0;
padding: 0;
}

#navigation li {
background: #ccc;
border-left: 1px solid #999;
float: left;
margin: 0;
padding: 0;
}

#navigation a {
color: #666;
font-weight: bold;
padding: 5px 10px;
text-decoration: none;
}

#navigation a:hover {
color: #333;
}

#navigation #currentpage a {
background: #fff;
color: #333;
}

The result will look something like this:



The navigational menu indicates which page the user is on by displaying the Page Two link in a different color and background. The down side? As a developer, you must remember to manually remove id="currentpage" from one link to the next as you develop each page. Not so if you use PHP.

PHP is an open-source server-side language. In order to use PHP, you
will need the PHP module installed on your server. Most Linux servers
have this module installed, and the PHP module is also available for
Microsoft servers. If you are unsure about your server or modules, just
ask your web host.

What to include?#section5

We’ll start by removing the navigational menu from all pages and placing
it in a separate document called navigation.php. This document will contain
just the (X)HTML that makes up your navigational menu. In this case, it
will contain the above <div id="navigation"> and
all of its content.

As you remove the navigational menus from each page, you’ll add in a
pinch of PHP. All it takes is some basic PHP to include the content of navigation.php.

PHP’s include() function offers a handy way to call an external file from the server. Simply replace the navigational menu with this line of code, being sure to adjust for the location of the file on your server. I like to put all of my PHP includes in a folder named phpincludes. (How original.)

<?php include("phpincludes/navigation.php"); ?>

While you have your document open, you’ll also need to add a unique identifier at the very top of every page that PHP will understand, ideally appearing before the HTML tag. You’ll do this by creating a varible called $thisPage and assigning a value that is both descriptive and unique to the document.

Naming your document is easy. If you are working on the “About Us” page, assign the value About Us, like so:

<?php $thisPage="About Us"; ?>
<html><head>

Since PHP is a server-side language, the server will take care of the naming of the document and the inclusion of navigation.php well before the the file is sent to the browser. All that’s left is adding some PHP to your navigational file.

Putting it together#section6

If you haven’t figured it out, the current-page magic is determined
by the PHP value of $thisPage. Since we have assigned a unique
value to $thisPage for each XHTML file, we are able to craft
a navigational menu that will automatically add the id="currentpage" to
the appropriate link before the page is ever sent to the user. Here’s
how we do it:

HTML and PHP code for navigation.php#section7

<div id="navigation">
<ul>
<li<?php if ($thisPage=="Page One") 
echo " id=\"currentpage\""; ?>>
<a href="#">Page One</a></li>
<li<?php if ($thisPage=="Page Two") 
echo " id=\"currentpage\""; ?>>
<a href="#">Page Two</a></li>
<li<?php if ($thisPage=="Page Three") 
echo " id=\"currentpage\""; ?>>
<a href="#">Page Three</a></li>
<li<?php if ($thisPage=="Page Four") 
echo " id=\"currentpage\""; ?>>
<a href="#">Page Four</a></li>
</ul>
</div>

Pay attention to all of the PHP syntax. The dual equal signs and backslashes
next to the nested quotation marks are required. Your links should also
go to real pages on your site. I’m just using the pound symbol for simplicity,
but you knew that.

Upload your files to the server and give the menu a test run. This is important,
for unless you’ve configured PHP on your client or are using a tool like
Dreamweaver, the PHP includes will not run locally.

If all goes well, the server will receive your request, recognize and
run the PHP on your page, import your navigation.php file, and
return a custom-built (X)HTML document that — like your mother — seems
to always know where you’ve been.

Other uses for $thisPage#section8

Though the possibilities are endless, another favorite use I have for
$thisPage is focused toward search engine optimization. Since you’ve already given each document a useful name, why not go ahead and
update some document-specific tags with useful content? Here are a few
other uses you might find for $thisPage.

<?php $thisPage="About Us"; ?>
<head><html>
<title>Company Name<?php if ($thisPage!="")
echo " | $thisPage"; ?></title>
<meta name="title" content="Company Name<?php
if ($thisPage!="") echo " | $thisPage"; ?>" />
<meta name="keywords" 
content="<?php if ($thisPage!="")
echo "$thisPage, "; ?>
company name, keyword1, keyword2,
keyword3" />

When the file is processed and delivered, search engines will receive
a document that has page-specific title and keywords,
like so:

<head><html>
<title>Company Name | About Us</title>
<meta name="title" 
content="Company Name | About Us" />
<meta name="keywords" 
content="About Us, company name, 
keyword1, keyword2, keyword3" />

About the Author

Jason Pearce

Web designer Jason Pearce once had a great dream. Just before he awoke, a white cursor appeared, traveled to the top of his mind, and saved the dream to his Favorites menu. It was then that Jason realized he should avoid sleeping at his desk and get out more often.

66 Reader Comments

  1. Some have commented that, using CSS alone, there’s no way to change the link for the current page into unlinked text. Here’s a solution that comes close.

    For the current page, I use CSS not only to change the colors, but also to change the cursor {cursor: text;}. The current page doesn’t appear to be a link, even when you mouse over it. However, if the visitor clicks, it still functions as a link. (There’s probably an easy way to remove the link functionality via JavaScript, but I don’t know what it is. If someone does, please post it.)

    Let me back up and fully describe the way the whole thing, which has two parts:

    1. I use separate files to store my navigation menus (and more), and use SSI (server side includes) to pull them into the web pages. Of course, this can be done using any number of technologies (including PHP), so take your pick.

    The included file contains the menu:

    Notice the ids (use classes if you prefer. I use “link” here so that I can use the page name in the body tag. This way, the ids are different.) If the site navigation has only one level, the same menu can be used for the whole site; otherwise you can use several include files.

    2. In the of every web page, change the a style for the current page:

    And of course, you’ll want to define more link styles before that, preferably in a separate CSS file.

    Credit: I think it was either meyerweb.com or zeldman.com (or maybe both) where I got this method. I’m not sure, but I think I came up with the {cursor: text} bit on my own. Many web developers think it’s a bad idea to disguise links like this, but I like it.

    Demo: You can see it in action at a site I maintain: http://www.zimfest.org/ .

  2. I use a combination of css selectors and a simple php script. The script- navigation.php- generates a stylesheet based on it’s path info, and is included like this:

    navigation.php looks like this:

    #menu {
    /* style specific to current category */
    }

    /* more styles as necessary */

    All the php script does it strip the / off the front and the .css off the end, and use that text as part of the selector.

    This way, the XHTML can be changed to add whatever menu items are needed, and the PHP only needs to change when the actual style changes.

  3. This is a good article, i recommend you use this way, but it’s too much complicated for big sites or even medium sites, i recommend people use arrays instead of IF’s, this make the code more easy to mantain, can be slow? maybe, maybe not, but you don’t need to bother what section you are, you just need to define one array for the entire site, or maybe, make a script that construct this array based on your site files.

    Hope this idea helps. I can give examples here, but it’s take much time from me and other people, but is something like
    $array[‘home.php’] = “site-style”;
    $array[‘…samething above
    or even you can do bi-dimensional arrays like
    $array[‘home.php’] = array(‘site-style-1’, ‘site-style-2’, …);

    or if you are not familiary just make
    $array[‘home.php’][0] = “index-0-style”;
    $array[‘home.php’][1] = “index-1-style”;
    etc…
    Just imagine, arrays are powerfull.

    Hope this help.

  4. Great article, this one. I agree with many of the previous poster in that, if the example provided is not the most elegant from a coder’s point of view, it certainly is one of the easiest to understand to the designers’ crowd that make the biggest chunk of ALA’s visitors. If you’re into coding, then you can upgrade to more elegant, array-based options if you want.

    Now, as much as I’d love to work with PHP, unfortunately (?) our workgroup is heavily JSP-based, therefore I’d be very thankful if someone could point me to a JSP-based (Struts) approach to this issue. Thanks.

  5. I have AppServ installed locally and I get following error messages:

    Warning: main(/phpincludes/navigation.php): failed to open stream: No such file or directory in c:documents and settingssimemy documentsprojectsnetiquetteindex.php on line 19

    Warning: main(): Failed opening ‘/phpincludes/navigation.php’ for inclusion (include_path=’.;c:php4pear’) in c:documents and settingssimemy documentsprojectsnetiquetteindex.php on line 19

    Note: All other PHP scripts works well, I don’t know where I’m wrong, I followed instructions exactly.

  6. I use PHP for navigation on many sites that I’m developing, but instead of using an include() for each bit of (X)HTML to include I just include one PHP file at the top of each page. The PHP file includes functions for displaying headers, footers, and any other repeated elements. The upside with this is that the PHP interpreter will not be required to lookup multiple files on the server — it only needs one. Furthermore, instead of creating a variable at the top of each page, I just pass the page info into the function call, for example:

    Just another way about it.

  7. Hi,

    I code a Little PHP Script.

    rene@grassegger.at

    //Definition Function “footer”
    function footer($hl, $hl2) {

    //1. directoryname: e.g. home/
    //2. Title Tag: e.g. “Zurück zur Startseite”
    //3. Link name: e.g. Home
    //4. call name: this is the name you use in the website, to highlight the right link.
    $navidata = array(
    array (“directory/”, “Title”, “Steuerprofi”, “Steuerprofi”),
    array (“directory/”, “Title”, “Bestellen”, “Bestellen”, “U”),
    array (“directory/”, “Title”, “Download”, “Download”, “U”),
    array (“directory/”, “Title”, “Registrieren”, “U”),
    array (“directory/”, “Title”, “Lohnprofi”, “Lohnprofi”),
    array (“directory/”, “Title”, “Bestellen”, “Bestellen2”, “U”),
    array (“directory/”, “Title”, “Download”, “Download2”, “U”),
    array (“directory/”, “Title”, “Registrieren2”, “U”),
    array (“directory/”, “Title”, “Projekte”),
    array (“directory/”, “Title”, “AGB”, “AGB”),
    array (“directory/”, “Title”, “Kontakt”, “Kontakt”)
    );

    //Domain http://www.example.com
    $domain = “http://www.example.com”;

    ksort($navidata);

    reset($navidata);
    echo ‘

    ‘;

    }
    ?>

    ########## End Code

    This is the code I’m using to call the script and hightlight the right section.

    If you dont have an Sublink, just enter “foo” or “nothing”.

    You can use it, for what you want. Just let the litte copyright thing in the script.

    It is a simple script, but with some little modifactions it fits every “needs” you have.

    HTH

    Rene Grassegger

  8. Is there a way to make this work with the navigation as a separate include file too? I have tried to, but the “current page” code doesn’t seem to resolve in time to highlight the page you are on.

  9. What was the point of this again? Are we trying to change the style for the current link or trying to show people what page they are on? I just use php or asp to print out the current page somewhere, like in a header right above the pages content. Works fine for me.

    The style does not change or course, but the point is to show the visitor where they are correct? Save the arrays and just make it obvious. Between title pages, headings, etc it is pretty simple to figure out where you on a site, and changing the background color does nothing for those who cannot see. Printing the title of the current page does.

    Also, I certainly disagree with the current groupthink mandate of not linking to the current page. Why not? If a user clicks a link to get somewhere, why kill the link once the get there?

  10. The navigation bar on the right side of pages in alistapart.com removes a link pointing to the current page. This approach to navigation
    follows the advice of Jakob Nielsen for corporate websites (see http://www.useit.com/alertbox/20031110.html).

    If this concept of navigation menus is the standard, is there a way to use javascript instead of php to solve this dilemma of removing the link to the current page?

  11. Hi I am totally new to this but i did tried Corel Draw as a web page (1 page only) but I no idea on how you guys create the e-mail pop-up once a hand-pointer is clicked on a web page (design using Corel Draw).

    Any idea…?

  12. On my previous posting i forget something.

    I forget the css styles.
    If you look on http://www.info.at you see the thing working.

    The programm only puts the right css-class to the tags and the css does the rest.

    If you look on http://www.info.at if you click on a section the programm puts in the class and the link gets highlighted.

    Sorry for the forgotten infos.

    Greetings

    Rene

  13. IRT: Dominique PERETTI
    there is really no point in replacing PHP tags with smarty tags. especially in this simple example!

  14. Well this sure looks a useful technique, but I wanted to use an `ordered list` and generate numbers for my list items.

    So I started here, and it fell over in IE6 :

    Specifically, setting the width to 33% using CSS causes all those

  15. items to be numbered as ‘1’. Try it you’ll see the problem !

    Removing the width: 33% and the list numbering returns to sequential for all items. Add it back and the numbering is set to 1 for all li items with that style. Weird.

    1. Order Receipt
    2. Create Job Record Card
    3. Raise Datachecking Form
    4. Create Sub Job
    5. Enter Onto Schedule
  16. Hello. I dont know if Im posting this on the right place but anyway. Im making a page. And I also scripted the news script. Ok all works. When Iuse click on news it show news. But when user click on one news which one would be shown in cell where is include() function but the news is shown in all window not in one cell ? How I shguld do that the only one news would be shoen in the cell of my index page to ? Is there any chance or I must include header, footer left and right blocks in each script ? I hope you understand me 🙂

    Thanks

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

I am a creative.

A List Apart founder and web design OG Zeldman ponders the moments of inspiration, the hours of plodding, and the ultimate mystery at the heart of a creative career.
Career