I have a little website with 5 nav sections.
For avoid change the code on every page when I have to add one more sections, I use a php include on the nav section of every page.
Now I need to add class "selected" to the list item (li) depending the page visited. ¿How to do this? Because now the nav is unique.
This is the code
<nav>
<ul>
<li class="selected"><a href="index.php">Home</a></li>
<li><a href="biography.php">Bio</a></li>
<li><a href="photo.php">Photo</a></li>
<li><a href="work.php">Work</a></li>
<li class="last"><a href="contact.php">Contact</a></li>
</ul>
<div class="clear"></div>
</nav>
Thanks!
Here's the easy way to do it, pure CSS no need for any programming: Add an ID to your body and your links:
<body id='home'>
<nav>
<ul>
<li id='home-link'><a href="index.php">Home</a></li>
<li id='bio-link'><a href="biography.php">Bio</a></li>
<li id='photo-link'><a href="photo.php">Photo</a></li>
<li id='work-link'><a href="work.php">Work</a></li>
<li id='contact-link'class="last"><a href="contact.php">Contact</a></li>
</ul>
<div class="clear"></div>
</nav>
Now, you just style like this:
#home #home-link, #bio #bio-link, #photo #photo-link, #work #work-link, #contact #contact-link{
//however you would have styled .active
}
In your URL structure, you can use $_SERVER['PHP_SELF']
to identify the current page.
$nav = array(
'Home' => 'index.php',
'Bio' => 'biography.php',
'Photo' => 'photo.php',
'Work' => 'work.php',
'Contact' => 'contact.php'
);
foreach($nav as $nav_title => $nav_link)
{
echo '<li '.($nav_link == basename($_SERVER['PHP_SELF']) ? 'class="selected"':'').'><a href="'.$nav_link.'">'.$nav_title.'</a></li>';
}
Heres a solution, add your new pages to the pages array:
<?php
$current_page = basename($_SERVER['REQUEST_URI']);
$pages = array('index','biography','photo','work','contact');
if(!in_array($current_page,$pages)){$current_page='index';}
$menu = "\n<nav>\n\t<ul>\n";
foreach($pages as $link){
$menu.="\t\t<li ".(($link==$current_page)?'class="selected"':'')."><a href=\"".$link.".php\">".(($link=='index')?'Home':ucfirst($link))."</a></li>\n";
}
$menu .= "\t</ul>\n\t<div class=\"clear\"></div>\n</nav>";
echo $menu;
?>
Outputs:
<nav>
<ul>
<li class="selected"><a href="index.php">Home</a></li>
<li ><a href="biography.php">Biography</a></li>
<li ><a href="photo.php">Photo</a></li>
<li ><a href="work.php">Work</a></li>
<li ><a href="contact.php">Contact</a></li>
</ul>
<div class="clear"></div>
</nav>
With JQuery, you could dynamically add a "current" class to the parent of the $('nav > ul > li > a') which its absolute href leads to the page you are currently viewing.
$(document).ready(function(){
$('nav > ul > li > a').each(function(){
if (window.location.indexOf($(this).prop('href'))!=-1) {
$(this).parent().addClass("current");
}
});
});
So, whenever the menu is loaded to the page, "current" class would be added to the right place in the nav.
I am still relatively new to php so I can not say whether this is along the lines of best practice or a hack, but it works.
I know this is an old topic, but I have a solution which addresses the problem brought up by Frederik in Chris Sobolewski's Post.
We will assume you have a header (which contains the links) and footer template, and don't wish to create new headers for each page.
Since each link takes us to a new page with a unique page name, we can use this to give an id to each of the links. Alternatively we could be using a parameter from $_GET depending how your navigation is set up.
In your example we could use something like:
<nav>
<ul>
<li class="selected"><a href="index.php" id="indexLink">Home</a></li>
<li ><a href="biography.php" id="biographyLink">Biography</a></li>
<li ><a href="photo.php" id="photoLink">Photo</a></li>
<li ><a href="work.php" id="workLink">Work</a></li>
<li ><a href="contact.php" id="contactLink">Contact</a></li>
</ul>
<div class="clear"></div>
</nav>
Now in our php file we can manipulate the DOM using whatever technique we prefer to add and remove the active class from the currently active link.
Remember I am new so forgive me if this is not best practice for manipulating DOM, but this is how I approached it:
?php
function curPageName() {
$pageName = substr($_SERVER["SCRIPT_NAME"],strrpos($_SERVER["SCRIPT_NAME"],"/")+1);
return trim($pageName, ".php");
}
//string to find the active class
$classString=' class="activeLink"';
//String to find the current page link
$pageString='id="'.curPageName().'Link"';
//String to set the current page link active
$activeString='id="'.curPageName().'Link" class="activeLink"';
//load the html from the header file
$fileContents=file_get_contents("header.html");
//Remove the old active class
$newHtmlContent=str_replace($classString, "", $fileContents);
//Set the new active class
$newHtmlContent=str_replace($pageString, $activeString, $newHtmlContent);
//Save the manipulated HTML
file_put_contents("header.html",$newHtmlContent);
?>
Then simply style activeLink in your css however you want.
I was tempted to simply search for the URL to modify the DOM of the header file, however if there are any other links to the same page somewhere else in the document, we don't want them styled as well. So I figured its best to add an id. This is also better if we are using some of the other methods of manipulating DOM in php.
Any feedback on whether the solution is good or bad practice is appreciated too!
$page = ""; ?>
<ul>
<?php
if ($page = "home")
echo "<li class='selected'><a href='home.html'>home</a></li>
<li><a href='bio.html'>bio</a></li>
<li><a href='contact.html'>contact</a></li>";
else if ($page = "bio")
echo "<li><a href='home.html'>home</a></li>
<li class='selected'><a href='bio.html'>bio</a></li><li><a href='contact.html'>contact</a></li>";
else if ($page = "content")
echo "<li><a href='home.html'>home</a></li>
<li><a href='bio.html'>bio</a></li>
<li class='selected'><a href='contact.html'>contact</a></li>";
this is really crude, and there are a million better ways to code this up, i'm sure, but here ya go.