Need some help to make PHP better for NAVIGATION MENU

hey guys,

currently using the following php code (header-nav.php) on my page to mark which page has been selected and is active by calling the variable set on that page ($page)

I’m having difficulties setting this up for my sub links, rather than create 2 versions of every sublink with inline php, is there a better way of achieving this?

<!-- Navigation -->
	<div class="sixteen columns">

		<div id="navigation">
			<ul id="nav">
                <!-- If the button HOME is selected then make the HOME Button Active -->
                <?php if ($page == 'home') { ?><li><a href="index.php" a id="current">HOME</a></li>
				<?php } else { ?><li><a href="index.php">HOME</a><?php } ?>

				<!-- If the button ABOUT US is selected then make the ABOUT US Button Active -->
				<?php if ($page == 'about-us') { ?><li><a href="about-us.php" a id="current">ABOUT US</a>
				</li>
                <?php } else { ?><li><a href="about-us.php">ABOUT US</a>
				</li>
                <?php } ?>
				
                <!-- If the page projects is selected then make the Projects Button Active -->
				<?php if ($page == 'projects') { ?><li><a href="projects.php" a id="current">PROJECTS</a>
					<ul>
						<li><a href="project-01.php">Project 1</a></li>
						<li><a href="#">Project 2</a></li>
						<li><a href="#">Project 3</a></li>
                        <li><a href="#">Project 4</a></li>
					</ul>
				</li>
                <?php } else { ?><li><a href="projects.php">PROJECTS</a>
					<ul>
						<li><a href="project-01.php">Project 1</a></li>
						<li><a href="#">Project 2</a></li>
						<li><a href="#">Project 3</a></li>
                        <li><a href="#">Project 4</a></li>
					</ul>
				</li>
                <?php } ?>


                <!-- If the page Capabilities is selected then make the Capabilities Button Active -->
                <?php if ($page == 'capabilities') { ?><li><a href="capabilities.php" a id="current">CAPABILITIES</a>
					<ul>
						<li><a href="capabilities-construction.php">Construction &amp; Building Maintenance.</a></li>
                        <li><a href="capabilities-civil-works.php">Civil Works</a></li>
                        <li><a href="capabilities-controlled-waste-management.php">Controlled Waste Management</a></li>
                        <li><a href="capabilities-plant-hire.php">Plant Hire</a></li>
					</ul>
				</li>
				<?php } else { ?><li><a href="capabilities.php">CAPABILITIES</a>
					<ul>
						<li><a href="capabilities-construction.php">Construction &amp; Building Maintenance.</a></li>
                        <li><a href="capabilities-civil-works.php">Civil Works</a></li>
                        <li><a href="capabilities-controlled-waste-management.php">Controlled Waste Management</a></li>
                        <li><a href="capabilities-plant-hire.php">Plant Hire</a></li>
					</ul>
				</li>
				<?php } ?>


				<!-- If the page Careers is selected then make the Careers Button Active -->
                <?php if ($page == 'careers') { ?><li><a href="careers.php" a id="current">CAREERS</a></li>
				<?php } else { ?><li><a href="careers.php">CAREERS</a>
				</li>
				<?php } ?>

                <!-- If the page Contact Us is selected then make the Contact Us Button Active -->
                <?php if ($page == 'contactus') { ?><li><a href="contact-us.php" a id="current">CONTACT US</a></li>
				<?php } else { ?><li><a href="contact-us.php">CONTACT US</a>
				</li>
				<?php } ?>

			</ul>

			<!-- Search Form -->
			<div class="search-form">
				<form method="get" action="#">
					<input type="text" class="search-text-box" />
				</form>
			</div>

		</div>
		<div class="clear"></div>
		
	</div>
	<!-- Navigation / End -->

<!DOCTYPE html>
<html>
<head>

<?php $page = 'home'; ?>

</head>
<body>

<?php include 'header-nav.php'; ?>

<h1>My First Heading</h1>

<p>My first paragraph.</p>

</body>
</html>

You can use a css automate. :slight_smile:

  • Step 1

The header-nav.php gets the simple construction:

<ul id="nav">
	<li><a id="home" href="index.php">HOME</a></li>
	<li><a id="about" href="about-us.php">ABOUT US</a></li>
	<li><a id="projects" href="projects.php">PROJECTS</a>
		<ul>
			<li><a id="proj01" href="project-01.php">Project 1</a></li>
			<li><a id="proj02" href="project-02.php">Project 2</a></li>
			<li><a id="proj03" href="project-03.php">Project 3</a></li>
			<li><a id="proj04" href="project-04.php">Project 4</a></li>
		</ul>
	</li>
	... etc.
</ul>

=======

  • Step 2

In the <body> tag of a page you tell what item (or items, for a submenu) must get the actual style with a class name (or 2 class names).
Easy to do: the class name(s) is/are the same as the [B]ID/B of the corresponding menu-item(s).
Homepage:

<!DOCTYPE html>
<html>
<head>
...
</head>
<body class="home">

<?php include 'header-nav.php'; ?>
<h1>My First Heading</h1>
<p>My first paragraph.</p>

</body>
</html>

About Us page:

<body class="about">

Projects main page:

<body class="projects">

Projects subpages:

<body class="projects proj01">
or
<body class="projects proj02">
or
<body class="projects proj03">
or
<body class="projects proj04">

=======

  • Step 3

And in the stylesheet (1 for all) the magic is:

.home #home,
.about #about,
.projects #projects {
     /* actual styles for a main-menu item */
}
.proj01 #proj01,
.proj02 #proj02,
.proj03 #proj03,
.proj04 #proj04 {
     /* actual styles for a submenu item */
}

=======
That’s all. :wink:

What happens: the #home link can only get the actual state if there is a .home class in a parent element. And that is only the case in the homepage, which has the .home class in the <body> tag.
For the other main menu items: in the same way.

For the submenu-items, for instance in the page project-02.php:

  • The body-tag is: <body class=“projects proj02”>
  • The .projects class triggers that the #projects item in the main menu is highlighted.
  • The .proj02 class triggers that the #proj02 item in the submenu is highlighted.

If desired, you can omit the .projects class in the <body> of the submenu pages. Then only the corresponding submenu item is highlighted, and not the mainmenu item #projects in the meantime.

hi Francky,

First of all thank you for going to so much effort to try solve this problem I am having.

I made your modifications but this has not made a difference to the menu items being active. My trigger at the moment is a id=“current”

when I made modifications I lost my a id=“current” all together

Do I need to modify my css a little more? Navigation is using:

/* Main Navigation
====================================*/
.selectnav {
	display: none;
	cursor: pointer;
	width: 100%;
	padding: 8px;
	height: 37px;
	float: left;
	font-size: 14px;
	margin: 15px 0;
}

#navigation {
	background: #303030;
	display: block;
	width: 100%;
	float: left;
	max-height: 52px;
	margin: 0 0 10px 0;
}

#navigation ul,
#navigation li {
	list-style:none;
	padding:0;
	margin:0;
	display:inline;
}

#navigation ul li{
	float:left;
	position:relative;
}

#navigation ul li a { 
	display: inline-block;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	font-weight: bold;
	padding: 17px 25px;
	background: url(../images/navigation-divider.png) no-repeat right 50%;
}

#navigation ul li a:hover {
	background: #72b626;
	color: #fff;
	-webkit-transition: all 0.1s ease-in-out;
	-moz-transition: all 0.1s ease-in-out;
	-o-transition: all 0.1s ease-in-out;
	-ms-transition: all 0.1s ease-in-out;
	transition: all 0.1s ease-in-out;
}

#current {
	background: #72b626 !important;
	color: #fff !important;
}

#navigation ul ul {
	position: absolute;
	display: none;
	top: 51px;
	left: 0;
	background: #303030;
	z-index: 999;
}

#navigation ul ul li a {color: #aaa;}
#navigation ul ul li a:hover {
	color: #fff;
}

#navigation ul ul li a {
	display: block;
	width: 150px;
	margin: 0;
	padding: 9px 18px;
	font-family: Arial, sans-serif;
	font-weight: normal;
	font-size: 12px;
	border-bottom: 1px solid #404040;
	background: none;
}

#navigation ul ul ul { 
	position: absolute; 
	top:0px; 
	left:100%; 
	z-index: 999;
}

#navigation ul ul ul li a { 
	border-bottom: 1px solid #404040 !important;
	border-top: 1px solid transparent;
	background: none;
}

#navigation ul ul li:last-child a, #navigation ul ul li:last-child a:hover {border-bottom: 1px solid transparent}
#navigation ul ul ul li:last-child a {border-bottom: 1px solid transparent !important}
#navigation ul li:hover>ul {opacity: 1; position:absolute; top:99%; left:0;}
#navigation ul ul li:hover>ul {position:absolute; top:0; left:100%; opacity: 1; z-index:497;}
#navigation ul li:hover > a {background: #72b626;}
#navigation ul ul li:hover > a {color: #fff;}

Francky’s solution doesn’t add any identifyer to the links themselves, it adds it to the body. Then you use CSS to style the links depending on the body class.

To keep your CSS the same you can add the ‘id=“current”’ to all of your active links by doing this for each link:

    
<li><a<?php if($page === home):?> id="current" <?php endif; ?>href="index.php">Home</a></li>

The id=“current” will only be included if $page is equal to the current page. This way it’s much tidier you don’t need to duplicate the HTML for every link.

Yes and no. :wink:
There are identifiers in the body-tag of each page and the links themselves don’t have a php-motorized id=“current”.
But all individual links have got their own unique ID: <a id=“home” href=“index.php”>, <a id=“about” href=“about-us.php”>, etc.

=======

In my solution the CSS for all pages is the same. :smiley:
The problem with a php-solution is that the submenus have to be highlighted together with their main menu item. With only one id=“current” in a page this will not go. You could use a class=“current” to make an adapted php-construction which can serve them both, but that would make the code of the include rather complicated.

=======
@ motion2082:

Indeed! :slight_smile:
If you only change the html of the include menu, nothing can happen.
The css has to be enlarged a bit, and the main pages have to get a class in the <body> tag.

  • BTW, it’s giving faster responses on a question, if you give a link to an online test page. Now we have to rebuild the pages and their attachments before anything can be said or advised. For the next time!. :wink:

But here we go.

First I made the homepage with the php-include and the css you have posted above.

It appears there is an html-error according to the html-validator (always good to check that first).
And the css for the hover over the submenus is missing.

So to be able to see what is really going on, I corrected the html and css.

=======
Now we can apply the recipe of my post #2.

Step 1
Removing all php-instructions from the header-nav.php, and adding an ID to each link or submenu link.
That’s giving:

<!-- start of included header-nav-nw.php -->
<!-- Navigation -->
<div class="sixteen columns">
	<div id="navigation">
		<ul id="nav">
			<li><a id="home" href="index.php">HOME</a></li>
			<li><a id="about" href="about-us.php">ABOUT US</a></li>
			<li><a id="projects" href="projects.php">PROJECTS</a>
				<ul>
					<li><a id="proj01" href="project-01.php">Project 1</a></li>
					<li><a id="proj02" href="project-02.php">Project 2</a></li>
					<li><a id="proj03" href="project-03.php">Project 3</a></li>
					<li><a id="proj04" href="project-04.php">Project 4</a></li>
				</ul>
			</li>
			<li><a id="capabilities" href="capabilities.php">CAPABILITIES</a>
				<ul>
					<li><a id="construction" href="capabilities-construction.php">Construction &amp; Building Maintenance.</a></li>
					<li><a id="civilworks" href="capabilities-civil-works.php">Civil Works</a></li>
					<li><a id="wastemanagement" href="capabilities-controlled-waste-management.php">Controlled Waste Management</a></li>
					<li><a id="planthire" href="capabilities-plant-hire.php">Plant Hire</a></li>
				</ul>
			</li>
			<li><a id="careers" href="careers.php">CAREERS</a></li>
			<li><a id="contact" href="contact-us.php">CONTACT US</a></li>
		</ul>

		<!-- Search Form -->
		<div class="search-form">
			<form method="get" action="#">
				<input type="text" class="search-text-box" />
			</form>
		</div>
	</div> 
	<div class="clear"></div>
</div>
<!-- Navigation / End -->
<!-- end of included header-nav-nw.php -->

Step 2
Remove the <?php $page = ‘home’; ?> from the homepage, and make <body class=“home”> instead of <body>.
Code of the index.php will be:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>The HOME page (new)</title>
	<link rel="stylesheet" type="text/css" href="stylesheets/header-nav-nw.css">
</head>

<body class="home">

<?php include 'includes/header-nav-nw.php'; ?>

<h1>My Home Page</h1>
<p>My first paragraph.</p>

</body>
</html>

For the other pages: analogical, as described in step 2.

Step 3
Now we have to adapt the stylesheet. Using the class- and ID-names of the header-nav and the <body>-tag, that will be:

B[/B] Remove the #current styles, for nowhere is an id=“current” anymore.

/* ===== not needed anymore:
#current {
	background: #72b626 !important;
	color: #fff !important;
}
===== */

B[/B] Instead come the styles for the combination of the body-classes and the id’s in the menu:

/* ===== the new styles for the automatic highlighting of the actual page: ===== */
	
/* actual style for the main menu-items */
.home #home,
.about #about,
.projects #projects,
.capabilities #capabilities,
.careers #careers,
.contact #contact {
	background: #72b626 !important;
	color: #fff !important;
	cursor: default;
	}

/* if desired, the actual submenu-items can get a different color */
.proj01 #proj01,
.proj02 #proj02,
.proj03 #proj03, 
.proj04 #proj04,
.construction #construction,
.civilworks #civilworks,
.wastemanagement #wastemanagement,
.planthire #planthire {
	background: #72b626 !important;
	color: #fff !important;
	cursor: default;
	}

Ready.
Note: in the working flow you start with one page, you make the html of the menu-code, then you style them in the css. After that you isolate the menu in a php-include, and the css in a separate stylesheet.
Then for each page you’ve only to set the body-class.
Extending the menu with a new page is simple too: add the page in the menu with his own ID, add the new couple .newpage #newpage in the list of the stylesheet, and give the body of the new page his class.

Result:

Maybe it seems somewhat laborious, but if you’ve made 2 times such a “css actual menu” together with a php menu-include, you’ll want to do it in another way … nevermore!

Francky…can I just say you are amazing!

Not only did you explain that perfectly but your execution was perfect.

Made all the changes above step by step and I now have a perfect navigation menu http://tinyurl.com/kjxl3ab

No longer do I need to use IF or ELSE statements, just clean CSS.

BTW, it’s giving faster responses on a question, if you give a link to an online test page. Now we have to rebuild the pages and their attachments before anything can be said or advised. For the next time!.

Will definitely post a link next time, just in case your curious have included it above ^

Was so happy to ditch #current, caused me a lot of trouble.

I almost gave up on finding a better solution and I am so happy to have posted at the right time. If there is anything I can do for you please let me know.

Thanks again

Hi motion2082,
Glad to hear and see it’s good working. :slight_smile:

Looking at the site, I think I’ve another tip. Especially with architectural photo’s, there are often converging lines because the photographer was at floor level (buildings a lot smaller at the top, skewed lampposts, etc.). With a wide-angle lens, to get the whole building on the picture, this effect is increasing. In real life our brain is compensating this: you think you see vertical lines instead of converging lines. But if you see a photograph of the same, it’s rather striking.
The small program ShiftN can automatically correct this!

O, and if you give the jpg-images a compression of 15%, I don’t see a loss of quality, but the file-size & download time is about the half. :slight_smile:

Im very happy.

Thanks for the extra info about shiftn too, looks heaps better with half the file size.

Where abouts are you based francky, definitely buying you a beer if we ever cross paths

Ah, for you I’m living right Down Under (in the Netherlands). :slight_smile:
Maybe I should plan a holiday in AU: for some years I’ve already an other cold beer in Australia waiting for me (I think is was in Sidney), so now I have 2 of them anyway. Have to build a solar vehicle for a cross-country trip! :wink: