1

Every page on my website so far has the same navigation menu and it's working fine. (I copied it only for sceptical readers, but it's just a normal navigation menu that works fine.)

<ul class="navigation">
    <li><a href="SampleCard.html">
        <div>FREE Yarn<br>Sample Card</div>
    </a></li>
    <li><a href="index.html">
        <div>Home</div>
    </a></li>
    <li><a href="SpinningFibre.html" class="active">
        <div>Spinning<br>Fibre</div>
    </a></li>
    <li><a href="MillSpun.html">
        <div>Mill Spun<br>Yarn</div>
    </a></li>
    <li><a href="HandSpun.html">
        <div>Hand Spun<br>Yarn</div>
    </a></li>
    <li><a href="Books.html">
        <div>Books</div>
    </a></li>
    <li><a href="WhyBuy.html">
        <div>Why Buy<br>Rare Breeds?</div>
    </a></li>
    <li><a href="AboutUs.html">
        <div>About Us</div>
    </a></li>
    <li><a href="ContactUs.html">
        <div>Contact Us</div>
    </a></li>
    <li><a href="PostagePrice.html">
        <div>Postage<br>Prices</div>
    </a></li>
</ul>

Notice that this particular page is "Spinning Fibre" so "SpinningFibre.html" has the "active" class. (This becomes important later.)

The biggest down side with this technique is that every time I want to change the navigation menu, I need to copy and paste the same change into every... single... page... I... have... made.

I saw a technique that allows me to embed one html file into another. For example:

<div w3-include-html="navigation.html"></div> 

I'm eager to try it, as it will make future edits to my navigation so much easier. However, how can I make the CSS know which link is the active link, so it can format accordingly?

I have learned a lot of PHP, so any solutions that require PHP code are welcome.

Edit Below: (This was formally an answer, but I think this is the way I should have posted the results)

Adam's answer, although definitely on the money, would never run exactly as written. Still, I was able to see past the typos to the gold hidden beneath. However, any future reader looking over this may not be able to, so here is the fully working version of the navigation code posted in the question.

(I also used echo, but only because I'm more familiar with how to use echo, and the limitations of it, than I am with Adam's method.)

File name "navigation.php":

<ul class="navigation">
    <li><a href="SampleCard.html"<?php if($currentPage == 'SampleCard'){echo 'class="active"';}?>>
        <div>FREE Yarn<br>Sample Card</div>
    </a></li>
    <li><a href="index.html"<?php if($currentPage == 'index'){echo 'class="active"';}?>>
        <div>Home</div>
    </a></li>
    <li><a href="SpinningFibre.html"<?php if($currentPage == 'SpinningFibre'){echo 'class="active"';}?>>
        <div>Spinning<br>Fibre</div>
    </a></li>
    <li><a href="MillSpun.html"<?php if($currentPage == 'MillSpun'){echo 'class="active"';}?>>
        <div>Mill Spun<br>Yarn</div>
    </a></li>
    <li><a href="HandSpun.html"<?php if($currentPage == 'HandSpun'){echo 'class="active"';}?>>
        <div>Hand Spun<br>Yarn</div>
    </a></li>
    <li><a href="Books.html"<?php if($currentPage == 'Books'){echo 'class="active"';}?>>
        <div>Books</div>
    </a></li>
    <li><a href="WhyBuy.html"<?php if($currentPage == 'WhyBuy'){echo 'class="active"';}?>>
        <div>Why Buy<br>Rare Breeds?</div>
    </a></li>
    <li><a href="AboutUs.html"<?php if($currentPage == 'AboutUs'){echo 'class="active"';}?>>
        <div>About Us</div>
    </a></li>
    <li><a href="ContactUs.html"<?php if($currentPage == 'ContactUs'){echo 'class="active"';}?>>
        <div>Contact Us</div>
    </a></li>
    <li><a href="PostagePrice.html"<?php if($currentPage == 'PostagePrice'){echo 'class="active"';}?>>
        <div>Postage<br>Prices</div>
    </a></li>
</ul>

You don't need to see my header (still needs tidying), but as soon as the body tag opens it looks like this (this example is the Spinning Fibre page):

<body>
    <?php 
        $currentPage = 'SpinningFibre';
        include 'navigation.php';
    ?>

It really works a treat. Thanks Adam.

(Now I am using the same method for all the headers.)

  • 1
    If this is a relatively small/static site, you could add a class to the html or body element for each page, and have your menu inherit from that. Otherwise you would have to use either JavaScript or a server-side language like PHP to read the URL of the page and add an active class accordingly. – delinear Jan 10 '18 at 15:01
  • Are you using JS or jQuery? Maybe I have a solution if you are using those – Calvin Nunes Jan 10 '18 at 15:02
  • Although I'm not, if it's the only solution available, it should be worth learning. Definitely post it up as a solution, and I'll mark it as correct if it's the simplest one that actually works. – Jonathon Philip Chambers Jan 10 '18 at 15:04
  • delinear... that first thing you wrote... I am intrigued. I'm not sure what it means, but it could be the solution I'm looking for. – Jonathon Philip Chambers Jan 10 '18 at 15:05
  • Take a look here, at this question, I answered there, if you use it, please upvote there. https://stackoverflow.com/questions/47141828/how-to-manage-several-html-nav-bars-from-one-single-area-in-order-to-avoid-going/47142964#47142964 – Calvin Nunes Jan 10 '18 at 15:11
  • Does that solution apply correct CSS formatting to the active page? A simple text search couldn't even find the word "active" in that solution, but maybe I just don't understand JavaScript well enough to understand how you did it. – Jonathon Philip Chambers Jan 10 '18 at 15:22

2 Answers2

1

Since you mentioned you're using PHP, you could move your menu into a file, "menu.php"

Then, you're going to need to change the extension of your files from ".html" to ".php" (so that the server can execute the following code):

<?php require_once 'menu.php'; ?>

That bit of code goes into all the files you're wanting to have the menu within.

As per the 'active state', there are a few ways to achieve this, one of the basic and easiest is to create a variable at the top of each page (before the require_once):

<?php $currentPage = 'Sample Card'; ?>

Then in your menu, you could have a bit of logic which reads the variable and then assigns an 'active' class to the menu item.

<ul class="navigation">
    <li <?php if ($currentPage == 'Sample Card'){ ?> class="active" <?php } ?>><a href="SampleCard.html">
        <div>FREE Yarn<br>Sample Card</div>
    </a></li>
    <li><a href="index.html">
        <div>Home</div>
    </a></li>
    <li><a href="SpinningFibre.html" class="active">
        <div>Spinning<br>Fibre</div>
    </a></li>
    <li><a href="MillSpun.html">
        <div>Mill Spun<br>Yarn</div>
    </a></li>
    <li><a href="HandSpun.html">
        <div>Hand Spun<br>Yarn</div>
    </a></li>
    <li><a href="Books.html">
        <div>Books</div>
    </a></li>
    <li><a href="WhyBuy.html">
        <div>Why Buy<br>Rare Breeds?</div>
    </a></li>
    <li><a href="AboutUs.html">
        <div>About Us</div>
    </a></li>
    <li><a href="ContactUs.html">
        <div>Contact Us</div>
    </a></li>
    <li><a href="PostagePrice.html">
        <div>Postage<br>Prices</div>
    </a></li>
</ul>

This part:

<?php if ($currentPage == 'Sample Card'){ ?> class="active" <?php } ?>

Could be added to any menu item, and you'd simple change $currentPage == '' to match the variable you set at the top of the page.

Adam
  • 1,149
  • 2
  • 14
  • 21
  • I "think" I followed that. Is " class="active" " supposed to be added to every line (with 'Sample Card' replaced with whatever that page is)? – Jonathon Philip Chambers Jan 10 '18 at 15:15
  • Correct, that code chunk gets added inside every
  • element, and "Sample Card" changed accordingly to whatever $currentPage is set to at the top of the page. There may be a better solution, but this covers the basics.
  • – Adam Jan 10 '18 at 15:17
  • Well, I've accepted the answer for now, but I won't implement it until tomorrow. If someone comes in with a better answer by then, they may steal the green tick from you, but this is definitely upvote worthy no matter what. (My account makes my upvotes worthless until I earn more reputation, but I encourage everyone to upvote this answer.) – Jonathon Philip Chambers Jan 10 '18 at 15:25