Showing current page

The nav bar in this page tells you that you're on this page. How's that done? I remember when I started learning, I thought (as I think many beginners do) that the ':active' pseudo class did this. If only it were that easy...

You can do this with just HTML and CSS, but I prefer to use PHP too. Here's one way to do this which uses PHP... (another way has been posted by maskd in the comments at the bottom of this page).

Here's a page which I've saved as 'one.php'

PHP
<?php
$page='one';
$title="Page One";
include 'head.php';
?>
<body>
<?php include 'menu.php'; ?>
</body>
</html>

This says that the file is 'one', and the title is 'Page One'. It then includes the head of the page, which looks like this (saved as 'head.php'):

PHP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title><?php echo $title; ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
<!--
body {
background-color:white;
}
a {
color:navy;
}
.current a {
color:red;
}
-->
</style>
</head>

You can see the title will then be inserted into the title tag. The '.current a' part of the CSS is for what we want to do here - keep the page we're on highlighted.

Next, the menu is included ('menu.php'). The menu looks like this :

PHP
<?php
$link=array('one','two','three','four','five','six','seven','eight','nine','ten');
$text=array('first page','number two','third','page four','five','sixsixsix','SEVEN','eighth page','NiNe','TEN!');
echo '<ul>
';
$i=0;
while($i < count($link)) {
echo '<li'. (($page==$link[$i]) ? ' class="current"' : '') . '><a href="'.$link[$i].'.php">'.$text[$i].'</a></li>
';
$i++;
}
echo '</ul>
';
?>

The first array is the names of the files we want to link to, the second array is the text we want to display for the corresponding links. The 'while' loop builds the menu.

Here's the important part : When it's looping through the file names it checks to see if the file name we're linking to is the same as the page we're on. If it is the same, it adds 'class="current"' to the li tag, which gives us the style for the currently active page.

And that's about it.

You can download the files used in this demo here

Comments

#1
2005-09-10 James says :

Good stuff Bon, although I've tidied the PHP up a little for you

echo '<li'. ($page==$link[$i]) ? ' class="current"' : '' . '><a href="'.$link[$i].'.php">'.$text[$i].'</a></li>
';


It works using the ternary operator (`?`) coupled with a colon.

if ($page==$link[$i]) it returns the class="current" text and if not it returns the blank quotes.

HTH, thanks again for the excellent resource.
--James (LinuxPenguin)

#2
2005-09-10 BonRouge says :

James,
Thanks for the input. I appreciate the help - I'm really no expert - but I'm afraid there seems to be something wrong with your code. I implemented it (in a duplicate of this demo) and I got this.

#3
2005-09-10 James says :

I forgot the brackets to surround the conditional statement so it just parsed over them...

echo '<li'. (($page==$link[$i]) ? ' class="current"' : '') . '><a href="'.$link[$i].'.php">'.$text[$i].'</a></li>
';


I should pick up on these things but when i tested it the first time, i just tested the statement, not a full page like you...

Well I've tested the full page now...

The source
The preview

That'll teach me to not test things properly eh?

HTH, sorry about the mixup
--James

#4
2005-09-10 BonRouge says :

Thanks again, James.
I've made the changes... It saved about one character. ;)

#5
2005-09-11 James says :

Always the way ;)

It's a good way of teaching people about PHP's other conditional statements, that one is particularly timesaving, I've found (then again I use it a lot more often programming in C).

Anyway, you said you're learning PHP as you go along, something else to add to your repertoire of skills ;) Not to mention its cleaner to look at (IMO)

I like how this tip is short and sweet, too smile No 6 pages of code to wade through, good article, Bon

Sidenote: given your stunning response times, I presume you've written this to send you a mail when I post a comment?

Take Care and keep with the good work smile
--James

#6
2005-09-11 BonRouge says :

Yeah, I usually use that kind of conditional statement in javascript. You're right - it does look cleaner. I don't know why I hadn't been using the same thing for PHP.
About the size... I think what I'm trying to do here (on the site) is just that - I want to get to the point. Short and sweet is best.
...and yes, I've written it to send me an email when someone posts a comment. I don't get many comments, as you can see, so it doesn't exactly fill my inbox.

#7
2006-02-15 maskd says :

Just thought I'd just give a different approach to it, this will make it easier. This method allows for one array, which I believe is cleaner, also you don't have to say what page the file is, the PAGE_NAME definition I use in many of my scripts and find it dead useful.

<?php

define("PAGE_NAME", basename(__FILE__));

$links = array( array('one.php', 'page one'),
array('two.php', 'page two'),
array('three.php', 'page three'),
array('links.php', 'links'));

$html = '<ul>
';

for ($i = 0; $i < count($links); $i++) {
if ($links[$i][0] == PAGE_NAME) {
// $html .= '<!-- current page: '.$links[$i][0].' -->';
$html .= '<li class="current">';
} else {
$html .= '<li>';
}
$html .= '<a href="'.$links[$i][0].'">'.$links[$i][1].'</a></li>
';
}

$html .= '</ul>
';

echo $html;

?>

#8
2006-02-16 Ming says :

Is there a way to use pure CSS (or JavaScript) to do this (and the clickdrop menu)?

Thanks

#9
2006-02-16 BonRouge says :

maskd, thanks for the input. I think it is better to have just one array like you have there. Thanks for pointing that out.

Ming,
Yes, you can do this without PHP or javascript.
Just for you.
The clickdrop menu would be more difficult without PHP.

#10
2006-03-10 marion says :

I love using arrays, but in this application it's a bit more work than I want to go through. I also don't like the idea of the adding ?page=current in all my URLs (SEO issue).

On the page each page I have the following code above the HTML DOCTYPE (I'll show you menu.php later):
<?php
$file_name = basename($_SERVER['PHP_SELF']);
include_once("menu.php");
?>

In the page, I echo the menu back where I want it to appear on the page:
<?php echo $menu; ?>

I then have my menu.html page, which contains my navigation in pure HTML format (this way I can edit the file in Dreamweaver still):
<a href="index.php">Home</a>
<a href="about.php">About</a>
<a href="contact.php">Contact</a>


Then I use the menu.php file included on all the content pages. I pull in the contents of menu.html and change the link for $file_name using regex and convert it to a regular span tag with the active class, disabling the link and reducing the code even further and not using an array.

<?php
$menu = file_get_contents("menu.html");
$menu = preg_replace("|<a href=\"" . $file_name . "\">(.*)</[^>]+>|U", "<span class=\"active\">$1</span>", $menu);
?>


Maintenance on this is adding the code to the content page, and managing the menu.html file.

#11
2006-03-10 BonRouge says :

Marion,
Thanks for your input - that looks like a good way of doing it. I wish I'd thought of that. In fact, do you mind if I just steal that idea and replace this page with that? (I'm not joking by the way).

(One small thing though - there is no need to have '?page=current' in your urls. That's just how this site works. If you look at my demo, you'll see the pages have 'normal' names ('one.php', etc.).)

#12
2006-03-10 marion says :

Please do change the page. When I need this code again, I'll probably forget which site I used it on and I'll come back here to get it again.(I'm not joking either.)
smile

#13
2007-08-23 Daniel says :

Thanks alot people! I'm just starting to look at php and this helped me out alot with my current project :].

#14
2008-05-01 stardust says :

is there any way to do this on a page where the menu is always there and the content is switched out via PHP?

Comment form

Please type the word 'wife' here:

BB code available :

  • [b]...[/b] : bold
  • [it]...[/it] : italic
  • [q]...[/q] : quote
  • [c]...[/c] : code
  • [url=...]...[/url] : url