Comments on Keeping Navigation Current With PHP

66 Reader Comments

Back to the Article
  1. I have been waiting for a decent tutorial explaining how to get the current page nav change. Well done. But my site pages are generated through a Cold Fusion template. Placing $thisPage in the generating template would show the same current page in the nav throughout the site. So close…my search continues for an option for Cold Fusion.

    Copy & paste the code below to embed this comment.
  2. to the guy above me, try using a function like PHP_SELF (not sure what it would be called in cold fusion). then just use that to define your navigation…

    Copy & paste the code below to embed this comment.
  3. not too interesting for me, since I’m already using exactly this technique.

    Copy & paste the code below to embed this comment.
  4. Why not simply have all your links in an array, loop through them while checking to see if the current iteration of the loop equals the current page as determined from PHP_SELF?

    Copy & paste the code below to embed this comment.
  5. you could have easily taken things a step further and used a loop to create the list. I would suggest something like this:

    <?php
      $navvars = array(
        ‘home’ => array(“Home”, “./”, “My Homepage”),
        ‘blog’ => array(“Blog”, “./blog.html”, “My personal Weblog”),
        ‘VALUES ASSIGNED TO $thispage’ => array(“ENTER LABEL HERE”, “LINK GOES HERE”, “DECRIPTION FOR TITLE TAG GOES HERE”),
        ‘about’ => array(“About Us”, “./about.html”, “Who we are and how we can be contacted”),
        );
      foreach($navvars as $page => $values){
    print " <li";
    if ($page == $thispage){
    print ' class="active"';
    }
      print ‘>.’” title=”’.$values[2].’”]’.$values[0].”</li>\n”;
      }
    }
    ?>

    I actual use a slight variation of this.

    Copy & paste the code below to embed this comment.
  6. This is close to something I’ve just coded myself. My root pages now work by including a header, footer and menu. I use a variable to give the page name first (eg: “Index”) then use this to give a proper title tag. But that’s been covered above. Yet here’s my tip: use PHP to also generate a page-specific menu.

    I realise this too is close to the article, but here’s my version. Depending on the page you’re on, you get a menu with links to the other pages - but NOT the current page. (Since you’re already on it.)

    If you’re on the “Index” page, there’s no point displaying the “Home” link. Whilst if you’re on the “Articles” page, there’s no need to add a menu link to “Articles”.

    So I simply use the page title already defined at the top of my file, and output a menu using simple PHP like this:

    <?php
    if ($title <> “Index”) {echo "\n<li><a >HOME</a></li>";}
    if ($title <> “Articles”) {echo "\n<li><a >ARTICLES</a></li>";}
    if ($title <> “Artwork”) {echo "\n<li><a >ARTWORK</a></li>";}
    if ($title <> “Photography”) {echo "\n<li><a >PHOTOGRAPHY</a></li>";}
    if ($title <> “Links”) {echo "\n<li><a >LINKS</a></li>";}
    if ($title <> “Tips”) {echo "\n<li><a >TIPS & DEMOS</a></li>";}
    ?>

    Works a treat!

    Copy & paste the code below to embed this comment.
  7. I disagree, Chris. From a user interface point-of-view there is a very good reason to display a non-clickable “Home” menu item even while viewing the Index page, or a non-clickable “Articles” item while viewing the Articles page.

    The code you posted results in a very confusing menu—as soon as I click on “Articles”, it disappears and is replaced by “Artwork”.

    I use similar code to what you posted, but instead of not displaying the menu item at all for the current page, it displays it but without the A element so it is obvious which is the current page.

    Copy & paste the code below to embed this comment.
  8. This is the same technique we use at http://automaticlabs.com - very useful and handy, and the perfect step to make CSS navigation “complete.”

    Copy & paste the code below to embed this comment.
  9. I tend to use the reserved variable $REQUEST_URI for things like this.  That way I don’t have to fool with declaring a variable on every page.

    Copy & paste the code below to embed this comment.
  10. Another way that I think is simpler and can also be use for other thing is simply to declare an ID on the body and use it as descendant selector.

    This is a simplified example :

    <body id=“intro”>

    <ul id=‘mainmenu’>
    <li class=“menuintro”>Intro</li>
    <li class=“menucurriculum”>Curriculum</li>
    <li class=“menuportfolio”>Portfolio</li>
    <li class=“menuprojets”>Projets</li>
    <li class=“menucontact”>Contact</li>
    </ul>


    #intro .menuintro { background-color: #000 }

    It’s not with PHP but it works.

    Copy & paste the code below to embed this comment.
  11. I too prefer CSS selectors for this - why use a server side technology when there’s a reliable client side alternative that doesn’t rely on scripting?

    Copy & paste the code below to embed this comment.
  12. Dear god that’s some seriously ugly PHP.

    Copy & paste the code below to embed this comment.
  13. That looks close to what I did a several months ago, www.reames.org, magic menus. From the comments it seems to be a common practice. I would like to see other sites pick up on it.

    Copy & paste the code below to embed this comment.
  14. A nice article, and a good idea, but horrible code for non-programmers. Perhaps throw it all in one echo tag.  It’s not a purists route, but it’ll make it easier to read, and easier for the timid HTML’er to implement.

    Copy & paste the code below to embed this comment.
  15. While taking a UNI-course in LAMP and creating a totally bogus web-site, I modified the original a-list-apart technique to utilise the URL query-string to select between the ‘on’ and ‘off’ settings :
    <?php if (isset($_GET[‘vis’])) {$vis = $_GET['vis'];} else {$vis = '';} ?>

    <div id=“tabs”>
      <ul>
          <li class=”<?php if($vis == ‘kommende’) {echo('here');} else {echo('standard');} ?>”>
            kommende</li>
          <li class=”<?php if($vis == ‘afholdte’) {echo('here');} else {echo('standard');} ?>”>
            afholdte</li>
      </ul>
    </div>

    Copy & paste the code below to embed this comment.
  16. Right after you say that adding unique CLASSes IDs to list items can become cumbersome, you go and show us a MORE cumbersome way to do things.  I’ll stick with my plain old lists, thank you.

    Copy & paste the code below to embed this comment.
  17. This is something I run into on almost every site I do. In theory you can accomplish this *just* with CSS3 selectors, but I want something that’s going to work well for a useful majority of people who visit my sites.

    My approach is to have a normal list based menu like I always do in plain XHTML. Then read that menu into a variable (I use HEREDOC syntax) and iterate over the links to look if any of them match the REQUEST_URI. I match the first part of the link only because I want links deeper in the hierarchy to show the highlighted section. It’s not perfect code, but it works very well, is fast, and doesn’t require you manually building an array or some such. Just take your current menu code, wrap it in this, and maybe add a CSS rule.

    Since this forum provides no good method for posting and formatting advanced content, I have made the code available at my site here: http://photomatt.net/scripts/intellimenu . Suggestions are welcome and the code is free for anyone to use, modify, or steal.

    Copy & paste the code below to embed this comment.
  18. Forget about mixing php and html codes !! This is really bad.

    Use a template engine instead. The best of the best : Smarty.

    http://smarty.php.net

    Copy & paste the code below to embed this comment.
  19. Useful article, but one little suggestion: use single quotes on the echos (might as well on the $thispage=... checks as well) - saves you from having to escape out each of those double quotes, and is ever so slightly less processor-intensive.

    Of course, if you’re trying to echo a variable or PHP’s special characters (ie. \n \r etc.) in a string, you’ll have to use the double quotes. But in this example, it just sacrifices code readability.

    Copy & paste the code below to embed this comment.
  20. I prefer to id each list item and then append a “you are here” class if it’s the selected page.

    <?php
    if ($page) {
    echo "<style type=\"text/css\">
    #menu li#$page a {
    display: block;
    background-color: #ddd;
    font-weight: bold;
    }
    </style>”;
    } else {
    echo "<style type=\"text/css\">
    #menu li#home a {
    display: block;
    background-color: #ddd;
    font-weight: bold;
    }
    </style>”;
    }
    ?>

    <ul>
        <li id=“home”>home</li>
        <li id=“portfolio”>portfolio</li>
        <li id=“photos”>photos</li>
        <li id=“consulting”>consulting</li>
        <li id=“about”>about</li>
    </ul>

    Copy & paste the code below to embed this comment.
  21. I agree with some of the other comments regarding the unneeded complexity introduced by the PHP as used. My approach is to give each link in the navigation menu its own ID. I *do* use PHP to include it on each page of the site.

    Then, rather than use PHP to test if I’m on the current page, I add page-specific styles (knowing what page I’m on already…just like $thispage does), and add them (may be more than 1; for example a level 1 and a level 2 navigation highlight) to the header in the <style> section. Here again, I use PHP to include the styles so that I can change the type of styling for each “you are here” element by changing the included style.

    Here’s an example that I used on http://www.princetonacademy.org.

    <style type=“text/css”><!—

    a#the-school { <?php include("style-includes/level1-youarehere.inc"); ?> }

    a#allboys-why { <?php include("style-includes/level2-youarehere.inc"); ?> }

    —></style>

    So, my level1 and level2 “you are here” styles are easily managed sitewide.

    I know beforehand the ids of the nav menus (also included) and they never change, so this approach is simple. It does take a tad more bandwidth due to the ids for each link, as opposed to a little more processing power on the server side for your “if $thispage” approach.

    Copy & paste the code below to embed this comment.
  22. i’m using something similar to this with my personal site right now. my code actually has an array of all of the sections of the site with their corresponding filenames plus the navigation html in a php include file. the current page is not determined by manually setting a variable, rather, i use something like this:
    $current = basename($_SERVER[‘PHP_SELF’],”.php”);
    of course that only works if all of the filenames of the site are in the form sectionname.php.
    but it’s nice in the sense that *one* include file is used for every single page to generate the navigation, highlight the current section, etc, and i don’t have to change anything at all from page to page.

    Copy & paste the code below to embed this comment.
  23. I think that the all thing is in there, altough the code is very confuse for some people, i guess.

    Someting like:

    <?php
        $thispageAR[“menu1”] = ($thisPage==“Page One”): “id=\“currentpage\”” ? “”;
        $thispageAR[“menu2”] = ($thisPage==“Page Two”): “id=\“currentpage\”” ? “”;
    // for all links on menu and then
      <li <?=$thispageAR[“menu1”];?>>About Us</li>
      <li <?=$thispageAR[“menu2”];?>>Work</li>
    // ...
    ?>

    will do a major clean on your code

    Copy & paste the code below to embed this comment.
  24. One thing that doing it by the body id method doesn’t give you is removing the link to the current page (as is recommended)—you either have to have that link to the current page, or insert the menu code seperately on each and every page, making it a nightmare to change.

    I (already) use similar code on my site—not really intended for updating by a non-coder, though I don’t think it’s /too/ bad: (the spans are for the css)

      <ul id=“menu”>
    <?php
      $menu=array(
      array(‘url’ => ‘/’, ‘name’ => ‘Home’),
      array(‘url’ => ‘/fiction/’, ‘name’ => ‘Fiction’),
      array(‘url’ => ‘/museblog/’, ‘name’ => ‘Muse Blog’),
      array(‘url’ => ‘/maps/’, ‘name’ => ‘Maps’),
      array(‘url’ => ‘/art/’, ‘name’ => ‘Artwork’),
      array(‘url’ => ‘/links/’, ‘name’ => ‘Links’),
      array(‘url’ => ‘/search/’, ‘name’ => ‘Search’));

      while (list ($key, $item) = each ($menu))
        {
    echo ' <li> . ‘“id=“this"id=“open”]<span>’ . $item[‘name’] . “</span></li>\n”;
        }
    ?>
      </ul>

    and on the begining of a page
    I have something like:

    <?php
    $this=’/fiction/’;
    #$open=’/fiction/’;

    or

    <?php
    #$this=’/fiction/’;
    $open=’/fiction/’;

    depending if the page is the one linked to by   the navigation item or a page under it.

    Copy & paste the code below to embed this comment.
  25. While I am not a programmer of sorts, I can truly appreciate the creativity and inventiveness of this solution to an old problem.  Well done and Thank You!

    Copy & paste the code below to embed this comment.
  26. A Coldfusion version of this is simple.  Here it is (a copy of the article’s code in CF).

    set page variable at top of page:

    <cfset page=“About Us”>

    included navigation (<cfinclude template=“navigation.cfm”>):

    <div id=“navigation”>
      <ul>
      <li <cfif page IS ‘Home’>id=“currentpage”</cfif>>Page One</li>
      <li <cfif page IS ‘About Us’>id=“currentpage”</cfif>>Page Two</li>
      <li <cfif page IS ‘Products’>id=“currentpage”</cfif>>Page Three</li>
      <li <cfif page IS ‘Contact’>id=“currentpage”</cfif>>Page Four</li>
      </ul>
    </div>

    A more graceful way, assuming you’ve organized each section into its own folder, would be to parse out the URL.  If the folder name following the URL is /products/ then set the appropriate id, and so on.  This would save you from setting a variable on every page…which is just as much a pain in the backside as remembering to set the id on every page.  In addition, it would be a lot easier to manage assuming you’ve placed your navigation file as an include.

    Copy & paste the code below to embed this comment.
  27. The “CSS only” solution is more elegant, efficient, scalable and “cheaper” :)

    Copy & paste the code below to embed this comment.
  28. my understanding is that require() is faster than include().

    Copy & paste the code below to embed this comment.
  29. The purpose of this article seems to introduct a php tecnique to people that never used it. Hence i would suggest a couple of things that could get the newbye’s reading and understanding experience simpler. I agree though with this per-link or per-line use of the if() statement to leave it easy to understand (instead of above suggested hashes and arrays).
    In the “HTML and PHP code for navigation.php” you are echo’ing with double quotes, that are not actually needed. I think that
    <?php if ($thisPage==“Page Three”)
        echo ’ id=“currentpage”’; ?>
    could result more readable and understandable by a newbye.
    A newbye also wouldn’t know (s)he has to rename also the including page from “.html” to “.php” for apache to parse.
    Best regards.
    flevour

    Copy & paste the code below to embed this comment.
  30. I too prefer to use $_SERVER[‘REQUEST_URI’]; rather than hand coding the page title for each page (isn’t that the point of server-side coding?), however some of the comments here have given me some good ideas about better using CSS rather than relying on ‘echo’ing out each list item.

    While the majority of comments on this article may seem critical to some degree - it has brought forward rewarding discussion.

    Copy & paste the code below to embed this comment.
  31. As the web administrator for a college I try to add what I can to sites to assist maintenance and efficiency.  This article describes the technique I used in our English Department website for the subnavigation of each section.  The feedback on this article was the most helpful.  I used the technique described in the article as an experiment.  I’ve since learned more about the variables I can use such as $REQUEST_URI which I will try next.  Thanks!

    Copy & paste the code below to embed this comment.
  32. You can take advantage of the fact that echoing empty array members sends an empty string.  This makes the code (and the markup within the code) much cleaner:

    function nav($pagename) {
    $a[$pagename] = " id='currPage' ";
    echo <<<EOD
    <ul id="nav">
    <li {$a['home' ]}>...</li>
      <li {$a['projects']}>...</li>
      <li {$a['stuff' ]}>...</li>
    ...
    </ul>
    EOD;
    }

    Copy & paste the code below to embed this comment.
  33. I have a better way of doing this using $SCRIPT_FILENAME.  I have found that using $REQUEST_URI or $PHP_SELF does not work in some instances.  Here is my code for doing this:


    <ul>
    <li>Home</li>
    <li>Contact</li>
    </ul>

    This way you don’t have to define anything and it will be automatic as long as the filename matches.  This works really good in my situations.

    Copy & paste the code below to embed this comment.
  34. A lot of the comments are offereing “better” PHP solutions. They probably are, but only if you have a good level of understanding of PHP.

    The technique shown in the article is the solution I have used myself when starting out with PHP, because it is has a logical structure and it reads like plain language.

    Also you don’t need to code elaborate error trapping routines, to correct mistakes that can arise from bookmarks, e-mailed links with or without ‘id=’, people fumbling with ‘id=’ statements to try something out, cookies going weird and other scenario’s that could break the user experience of the website seriously because the user get loads of PHP error messages because the uri request is not completely correct.

    The code may be ‘ugly’ from a programmer’s point of vue, but from a webmaster or designer’s point of view this is a nifty little solution that makes maintenance of the website a little bit easier.

    Copy & paste the code below to embed this comment.
  35. I don’t mean to dismiss this article, I think it might be very useful to some. However, I think it’s time we started thinking about the X in XHTML.

    With the use of the appropriate programming tools (like the XML DOM) we can better separate presentation from programming logic.

    Say we have a navigation.xml, containing just the ul element (incluling all its descendants) which makes the navigation.

    A DOM script could grab all a elements and check their href values against the current url to find out which link is the current page, then it would grab its parent (the li element) and add the appropriate class attribute to it.

    Then this navigation file could be appended to the appropriate parent in the main template. (In fact we could just use one big template and select the menu by id, but I feel keeping things separate is better for organization)

    Seems a lot cleaner to me.

    I know processing a DOM tree is much costier than processing a handful of if blocks. But the little more you pay for more powerful hosting should easily pay in gained programmer time. (programmers allowed greater abstractions code faster)

    Copy & paste the code below to embed this comment.
  36. I complicated it probably (I’m new to php) a little bit to adjust my needs. I use Eric A. Meyer’s css tabbed menu (http://www.meyerweb.com/eric/talks/2003/commug/commug.html)  on my site http://hostinspace.com. It works fine and makes my pages even smaller.

    Here’s my code, if some want to take a look:

    <ul id=“navigation”>
    <li<?php if ($thisPage==“Home”) echo “><a ><a >Home</a></li>

    <li<?php if ($thisPage==“About”) echo “><a ><a >About</a></li>

    <li<?php if ($thisPage==“Galleries”) echo “><a ><a >Galleries</a></li>

    <li<?php if ($thisPage==“Webdesign”) echo “><a ><a >Webdesign</a></li>

    <li<?php if ($thisPage==“Contact”) echo “><a ><a >Contact</a></li>
    </ul>

    Thank you for this articles, that’s what I was looking for.

    Copy & paste the code below to embed this comment.
  37. I use a similar concept only keep the navigation in a master XML file that is then cached on the server each time it changes then called to a global header file as well as a side menu. I had to go this route as we have multiple servers some running ASP, others PHP and then my main server running CFMX. By storing the contents in one XML file I have components that can then spit out the appropriate navigation either by passing the variable within the page itself, or if I pass variables to it via a query string for those pages calling it via http (include_once etc). Kind of a home grown method, but it works pretty well so far and also allows me to then create a site map of the site in real time. Especially since we have a fairly large site with hundreds of pages, going this route gives me a bit more control of the structure of the site. The XML file I use can be seen here:
    http://www.pacificu.edu/xml/sitemap.xml

    Copy & paste the code below to embed this comment.
  38. After years of combining PHP with xHTML/CSS my preferred way of outputing code is like so:

    <?php

      print “\t\t\t” . ‘’ .$fileName. ’ . “\n”;

    ?>

    Due to the volume of double quotes in HTML, in my mind, it makes sense to enclose in singles.

    Don’t forget this output method too:

    <?= “\t\t\t” . ‘’ .$fileName. ’ . “\n”; ?>

    Copy & paste the code below to embed this comment.
  39. I’d agree with Chase- an array of link files and page titles makes your site more flexible- if you need to add, or change the order of links, you just edit the arrays. The code in the article needs a lot of nitty picky editing to change the menu.

    Another level of PHP I often use would involved a single index.php template file, and having all of the page content set as text files included in the main body, e.g. stored in content/c1, content.c2, etc.

    Passing the template file a variable tells it the current page to, e.g index.php?sect=4, means use content/c4 for the content.

    I set this up in the top by declaring arrays for the menu labels and the page titles:

    <?php
    // menu labels
    $labels = array(‘About’, ‘Register’,,‘Suggestion Box’‘);
    // page titles
    $titles = array(‘About The Festival’, ‘Register for XYX 2004’,  ‘Send Us Your Suggestions’‘);
    // bounds check
    if (!$sect or $sect>count($labels)) $sect = ‘0’;
    // strin to use for title displayed in header, title tag, footer
    $pretty_title = $titles[$sect];
    ?>

    The menu is built later:

    <div id=“navlist”>

    <ul>
    <?php
    for ($i=0; $i<count($labels); $i++) {
    // tag current page in view
    $uber = ($i==$sect) ? ' id="uberlink"' : '';

    if ($i==$sect) {
    echo '<li id="uberlink">’ . $labels[$i] . “</li>\n”;
      } else {
    echo '<li>’ . $labels[$i] . “</li>\n”;
      }
    }
    ?>
    </ul>
    </div>

    And later where the content needs to be inserted:

    <h1><?php echo $pretty_title?></h1>
    <?php include “./content/c$sect”?>

    I use this approach on a number of sites, easier when the design is a handful of content pages, but have managed to wrangle it on a more complex forms driven site.

    Copy & paste the code below to embed this comment.
  40. If the user were prompted to use PHP includes for the navigation, one can readily assume that some form of server side includes were also used for the main content of the site, rather than having a multitude of pages for different content.

    The problem arises when the main content holds the $page variable and is loaded after the navigation (main content after navigation seems logical).  The id tag will not be included in the navigation.

    Copy & paste the code below to embed this comment.
  41. This is a nice example but I consider it rather bloated.

    Adding a highlighted state to each page makes it not really flexible, a better way is to use the PHP_SELF variable and generate the whole list in PHP.

    I wrote a similar thing for the puredomnav script, that generates a nested list from a nested array, and highlights via strong rather than an own id, which also makes sense for screen readers and text browsers.

    Copy & paste the code below to embed this comment.
  42. Dynamic markup differs from XHTML in that, while there are only one or two best ways to mark up a static list, there are countless ways to build dynamic pages, each with advantages and disadvantages.

    Whenever ALA publishes an article on server-side technologies, we get comments that the code is too complex and other comments that the code is too simple or does not cover some contingency or another. This is especially true when we publish an article on PHP. Such comments make the article more useful in the same way that footnotes can add depth and amplification to an essay. So keep them coming.

    Copy & paste the code below to embed this comment.
  43. i agree w/ the author that while it may not be ‘excellent’ PHP code, it is easy to read/understand.

    but a small gripe, easy to fix…

    expressions get double quotes, and strings get single quotes.

    would you update the example in the article to offer syntactically correct code? this would also make the code more readable and quicker to process.

    you use proper syntax you won’t have to escape your double quotes. isn’t that good?! as people try to mess around with your example, it will make it alot easier for them.

    compare your example:

      <li<?php if ($thisPage==“Page One”)
        echo ” id=\“currentpage\”“; ?>>
        <a href=”#”>Page One</a></li>


    with this:

      <li<?if ($thisPage==‘Page One’)
        echo ’ id=“currentpage”’; ?>>
        <a href=”#”>Page One</a></li>

    Copy & paste the code below to embed this comment.
  44. (this is what it should read above)

    compare your example:

      <li<?php if ($thisPage==“Page One”)
        echo ” id=\“currentpage\”“; ?>>
        Page One</li>


    with this:

      <li<?if ($thisPage==‘Page One’)
        echo ’ id=“currentpage”’; ?>>
        Page One</li>


    (maybe someone could be bothered to fix the prev. entry with this code)

    Copy & paste the code below to embed this comment.
  45. Nice article. I use to use this type of method a while ago but my recent site redesign uses css selectors for the same task. Probably a better solution for people who don’t DO php.

    Copy & paste the code below to embed this comment.
  46. One issue that I haven’t seen anyone mention in all these discussions of navigation techniques is the fact that the nav item for the current page remains linked with these methods. It’s fairly important to not only visually indicate the current page by styling it differently, but to also turn off the link.

    On a practical level, if you’re already on a page, why would you ever need a nav link to it? On a usability/ accessibility level, to someone who’s browsing without visual css enabled (for whatever reason), there’s no obvious difference between the current page and the other pages in the nav bar—you can’t tell where you are in the site by quickly referring to the nav bar, since all items are linked and some, including the current page, may be appearing in the visited link color.

    I guess this is a problem with the Sliding Doors ( http://www.alistapart.com/articles/slidingdoors/ , http://www.alistapart.com/articles/slidingdoors2/ ) articles, as well. Obviously, you need to be able to select two elements for that method to work. You could substitute <span> for <a>, but of course, that introduces non-semantic muck into your code, but I’m not sure which is worse—an unneeded link that has a lot of unneeded markup (href=”...” class=”...”), or a span tag that, while of no semantic value, has less unnecessary markup.

    Copy & paste the code below to embed this comment.
  47. Those who have suggested using CSS Selectors might be a more elegant solution may be correct, but only when the navigation items are static and predefined. Where the server-side solution comes into its own is with content-managed sites where non-technical site editors require the ability to add menu items.

    In the CSS scenario this would require the rewriting of the style sheets. With a combination of PHP and a database this becomes unnecessary.

    I’m currently working on a site for a school where each department will have the opportunity to create and maintain its own area. Rather than revist the navigation every time a department gets around to adding content the navigation is built on the fly from the db.

    Copy & paste the code below to embed this comment.
  48. The technique introduced is useful for sites which are a bit more complex than the example given, but of course a simple example is needed to demonstrate the technique. If your site was as simple as the example, css selectors are a better choice.

    Regarding the PHP implementation - using arrays is a good idea, but I would suggest going a bit further and using an array of hashes:

    $contents = array(
    array(“url”  => “http://...”,
        “name” => “Index”),
    array(“url”  => “http://...”,
        “name” => “Links”),
    ...
    );

    Then, the printing stage is simpler because:
    1. the active page can be determined by examining the current URL and comparing.
    2. the link tag can be constructed in its entirety- href and name are there in the hashes.

    This technique can be combined with CSS selectors, if you are using them for page-identification already (e.g., ALA’s changing image), you either add a new hash entry for the selector name, or use the same selector name as page name (not suitable perhaps if the page name has spaces in it)

    This technique can also be extended to pull info from a database, which is great for large or changing index sites, and for sites with nested contents-structures (then you can do tree-walking and all sorts of fun compsci stuff). An example (in horrible HTML4, I apologise, revamp on the way) of a dynamic, nested contents system written this way using PHP is at http://www.dur.ac.uk/st-johns.jcr/ .

    However if you have alternative scripting languages available (e.g. python, asp, jsp, ruby, perl…) I’d consider looking into them too, as PHP has a few serious design issues.

    Copy & paste the code below to embed this comment.
  49. several people have brought this up and its a good point. however, there are cases where the designer wants the current section to remain linked. cases such as sub-pages that don’t have their own nav-level links (like individual articles in a section) in that scenario the linked current nav can be used to get back to the index of that section.

    Copy & paste the code below to embed this comment.
  50. If you are using dynamic pages (ie: using query strings to find your pages, like http://url.com/?page=about) you dont need to add the whole $thisPage = “About Us”; stuff into your html.  Rather than do this, you can accomplish it by simply having a page that sorts out your information. Example:

    switch ($_GET[‘page’]) {
    case 'about':
    include("about.php");
    default:
    include("index.php");
    }

    Just another way to accomplish the same thing, in what i think is a more organized manor.

    (note: i used the $_GET[’‘] array for people who dont have registered globals turned on)

    Copy & paste the code below to embed this comment.
  51. 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:
    <ul id=“menu”>
    <li>Home</li>
    <li>About</li>
    <li>Links</li>
    ...
    </ul>
    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 <head> of every web page, change the a style for the current page:
    <style type=“text/css”>
    a#link-home {color: #ff0009; background: white; text-decoration: none; cursor: text;}
    </style>

    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/ .

    Copy & paste the code below to embed this comment.
  52. my example http://www.alistapart.com/discuss/keepingcurrent/3/#c5448
    removes the href=”..” from the <a > for the current page (leaving an <a id=“this”> for the css to style - the default skin for my site, which that codes from, does indeed use ‘sliding doors’)—it could be modified to use a different tag completely or be nothing but the text if so desired.

    Copy & paste the code below to embed this comment.
  53. 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:

    <style type=“text/css” media=“screen”>
    @import url(”/c/navigation.php/home.css”);
    </style>

    navigation.php looks like this:
    <?php
          header(“Content-Type: text/css”);
          $section = ucfirst(substr($_SERVER[‘PATH_INFO’], 1, -4));
    ?>
    #menu<?= $section ?> {
    /* 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.

    Copy & paste the code below to embed this comment.
  54. 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.

    Copy & paste the code below to embed this comment.
  55. 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.

    Copy & paste the code below to embed this comment.
  56. 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 settings\sime\my documents\projects\netiquette\index.php on line 19

    Warning: main(): Failed opening ‘/phpincludes/navigation.php’ for inclusion (include_path=’.;c:\\php4\\pear’) in c:\documents and settings\sime\my documents\projects\netiquette\index.php on line 19

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

    Copy & paste the code below to embed this comment.
  57. 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:

    <? display_header(“company”); ?>

    Just another way about it.

    Copy & paste the code below to embed this comment.
  58. Hi,

    I code a Little PHP Script.

    <?php
        //Copyright by Rene Grassegger 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 '<ul id="navi">';

    while(list ($key, $wert) = each ($navidata)) {

    //If there Is a subsection "U"
    if ($wert[4]==U) {
    echo ("<li class=\"unterpunkt\">");
    } else {
    echo ("<li>");
    }
      echo (”<a >”);
      echo (”$wert[2]</a>”);
                echo (”</li>”);
      echo (”\n”);
          }
          echo ‘</ul>’;

        }
    ?>

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


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

    <?php include(”../inc/footer.php”);
    footer(“Link1”, “Sublink”);?>

    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

    Copy & paste the code below to embed this comment.
  59. 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.

    Copy & paste the code below to embed this comment.
  60. 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?

    Copy & paste the code below to embed this comment.
  61. 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?

     

    Copy & paste the code below to embed this comment.
  62. 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…?

    Copy & paste the code below to embed this comment.
  63. On my previous posting i forget something.

    I forget the css styles.
    If you look on 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 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

    Copy & paste the code below to embed this comment.
  64. IRT: Dominique PERETTI
    there is really no point in replacing PHP tags with smarty tags. especially in this simple example!

    Copy & paste the code below to embed this comment.
  65. 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 :

    <style type=“text/css”>
    li.process {
    background-color: #F4F4F4;
    font-size: 12px;
    vertical-align: top;
    width: 33%;
    }
    </style>

    Specifically, setting the width to 33% using CSS causes all those <li class=“process”> 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.

    <ol>
    <li>Order Receipt</li>
    <li>Create Job Record Card</li>
    <li class=“process”>Raise Datachecking Form</li>
    <li class=“process”>Create Sub Job</li>
    <li>Enter Onto Schedule</li>
    </ol>

    Copy & paste the code below to embed this comment.
  66. 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

    Copy & paste the code below to embed this comment.
  67. Sorry, commenting is closed on this article.