How To Call a menu file with PHP

This demo assumes the author is writing a multi-page web site and wishes to use the same menu on all of the pages. For the convenience of this demo, these files are at the same directory level. None are in sub-directories.

First, create and style the page, including the menu, in an .html version of the page.

For example:

home.html

<!DOCTYPE html>
<html lang="en-ca">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="./mycss.css" type="text/css">
    <title>HOME (page 1/5)</title>
<!--
This is an HTML page with four major subdivisions: header, nav, main, footer.
The navigation subdivision is the focus of this example.
The site, including the nav menu, would be styled using CSS in the external stylesheet.
-->
</head>
<body id="home">  <!-- id indicates page; is used by menu CSS to indicate active page.  No JS needed. -->

<div class="outer">
    <header>
        <figure>
            <img src="http://placehold.it/450x115/" alt="MyCompany Logo" width="450" height="115">
            <h1>My Home Maintenance Co.</h1>
            <figcaption>
                <p>No home repair job in the Valley area is too big for us.</p>
            </figcaption>
        </figure>
    </header>
    <nav>
        <ul>
            <li class="home"><a href="home.html">home</a></li>
            <li class="aboutus"><a href="aboutus.html">about us</a></li>
            <li class="services"><a href="services.html">services</a></li>
            <li class="projects"><a href="projects.html">projects</a></li>
            <li class="contact"><a href="contact.html">contact</a></li>
        </ul>
    </nav>
    <main>
        <div></div>  <!-- Use whatever tags are appropriate for content. -->
    </main>
    <footer>
        <div></div>  <!-- Use whatever tags are appropriate for content. -->
    </footer>
</div>

</body>
</html>

This sample CSS styles the menu only.

mycss.css

/* This demo stylesheet ONLY styles the nav menu. */
a {
    color:#33348e;
    text-decoration:none;
    text-transform:uppercase;
}
nav {
    background-color:#33348e;
    font-family:verdana,arial,times,serif;
    font-size:.875em;
    overflow:hidden;
    padding-left:4%;
}
nav ul {
    padding:0;
    margin:0;
}
nav ul li {
    list-style-type:none;
    float:left;
    position:relative;
    padding:0;
    margin:0;
}
nav ul li a {
    display:block;
    color:#fff;
    padding:.875em .625em;
    margin:0;
}
nav ul li a:hover,
nav ul li a:focus {
    background-color:#fff;
    color:#33348e;
    text-decoration:underline;
    font-weight:normal;
}
/* These selectors style the active page's menu */
#home .home a,
#aboutus .aboutus a,
#services .services a,
#projects .projects a,
#contact .contact a {
    color:#33348e;
    background-color:#fff;
    pointer-events:none;
}

If opened in one’s browser, the page should look approximately like this:

Second:
Make a copy of the .html file and give the copy a .php suffix.

Put comment marks around the HTML that is to go in a PHP include file. Like this:

Then cut the text from between the comment marks and paste it into a new file with a .php suffix. In this example the filename is mynav.php. IMPORTANT! Change the suffixes of the links in “mynav.php” from .html to .php.

Why the cut-and-paste routine? Because I am fussy about uniformly formatted code. If the original HTML code is nicely formatted, the code will appear just as properly formatted when imported from the .php file.

Third:

Now go back to the HTML page with the .php suffix and add a php call between the comment marks. As a helpful gesture, do not delete the comment marks. Leave them so anyone who “Views Source Only…” can tell that the code between those comment marks is being summoned from a PHP file.

    </header>
<!-- BEGIN mynav.php INCLUDE -->
<?php include "./mynav.php"; ?>
<!-- END mynav.php INCLUDE -->
    <main>

The complete HTML for the home.php and mynav.php files follows:

home.php

<!DOCTYPE html>
<html lang="en-ca">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="./mycss.css" type="text/css">
    <title>HOME (page 1/5)</title>
<!--
This is an HTML page with four major subdivisions: header, nav, main, footer.
The navigation subdivision is the focus of this example.
The site, including the nav menu, would be styled using CSS in the external stylesheet.
-->
</head>
<body id="home">  <!-- id indicates page; is used by menu CSS to indicate active page.  No JS needed. -->

<div class="outer">
    <header>
        <figure>
            <img src="http://placehold.it/450x115/" alt="MyCompany Logo" width="450" height="115">
            <h1>My Home Maintenance Co.</h1>
            <figcaption>
                <p>No home repair job in the Valley area is too big for us.</p>
            </figcaption>
        </figure>
    </header>
<!-- BEGIN mynav.php INCLUDE -->
<?php include "./mynav.php"; ?>
<!-- END mynav.php INCLUDE -->
    <main>
        <div></div>  <!-- Use whatever tags are appropriate for content. -->
    </main>
    <footer>
        <div></div>  <!-- Use whatever tags are appropriate for content. -->
    </footer>
</div>

</body>
</html>

mynav.php

    <nav>
        <ul>
            <li class="home"><a href="home.php">home</a></li>
            <li class="aboutus"><a href="aboutus.php">about us</a></li>
            <li class="services"><a href="services.php">services</a></li>
            <li class="projects"><a href="projects.php">projects</a></li>
            <li class="contact"><a href="contact.php">contacts</a></li>
        </ul>
    </nav>

Upload the two .php files to a server to test the menu. It should look and behave exactly like the .html version.

This menu css uses a technique popularly known as “matching classes” to target the menu item of the current/active page. It highlights the menu item whose ID appears in the <body> tag and matches the classname in the nav list item. (I’m using an ID in the <body> tag instead of a classname. ) NO JavaScript required.

And that, in a nutshell, is all there is to it.

10 Likes

This takes me back to my first foray into using PHP, for exactly this purpose, to beat the tedium of editing the same menu on multiple pages.

Taking this further into the realms of PHP, you can use php to do this by adding a current class to the menu item. The advantage being that when you edit the menu to add a new page for example, you only need edit the menu file, not the css too.

Here is a simple example of how that can be done.
First you must identify your page name.

<?php $pagename = basename($_SERVER['PHP_SELF']); ?>

This may need a little alteration if your site uses a rewrite or directories to remove extensions, but that’s not the case in this example.

Then we have the menu with a little bit of php in there.

    <nav>
        <ul>
            <li class="home"><a<?php if ($pagename == 'home.php') {echo ' class="current"';} ?> href="home.php">home</a></li>
            <li class="aboutus"><a<?php if ($pagename == 'aboutus.php') {echo ' class="current"';} ?> href="aboutus.php">about us</a></li>
            <li class="services"><a<?php if ($pagename == 'services.php') {echo ' class="current"';} ?> href="services.php">services</a></li>
            <li class="projects"><a<?php if ($pagename == 'projects.php') {echo ' class="current"';} ?> href="projects.php">projects</a></li>
            <li class="contact"><a<?php if ($pagename == 'contact.php') {echo ' class="current"';} ?> href="contact.php">contacts</a></li>
        </ul>
    </nav>

Again writing and editing such a list can be tedious, but it can be automated a bit.
The menu could be stored in an associative array that is quick and easy to edit.

<?php
    $menu = array(
        'home' => 'Home',
        'aboutus' => 'About Us',
        'services' => 'Services',
        'projects' => 'Projects',
        'contact' => 'Contact'
    );
?>

Here the key is the file name and the value is the link label. OK, in this case they are similar enough that you could maybe do away with having both, but in some cases it’s useful to have two differing strings stored.
The menu array could be a standalone include file referenced by all pages.

Because I am not putting the file extension in the name key, I now need to remove it from the pagename variable.

$pagename = str_replace('.php', '', $pagename);

Next you render out the menu using a foreach loop, either in your html template or in a menu include.

    <nav>
        <ul>
            <?php foreach( $menu as $menpage => $menlabel ) : ?>
            <li><a<?php if($menpage == $pagename){echo ' class="current"';} ?> href="<?php echo $menpage ; ?>.php"><?php echo $menlabel ; ?></a></li>
            <?php endforeach ?>
        </ul>
    </nav>

Now all you need to do to edit the menu list is edit the array.

9 Likes

I use a slightly different method. :mask:

A basic menu.txt file…

<ul id="menu">
 <li><a href="index.php">Home</a></li>
 <li><a href="one.php">Page One</a></li>
 <li><a href="two.php">Page Two</a></li>
 <li><a href="three.php">Page Three</a></li>
 <li><a href="four.php">Page Four</a></li>
 <li><a href="five.php">Page Five</a></li>
</ul>

.with this basic .php file…

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="css/screen.css" media="screen">

</head>
<body> 
<h1>Page Title</h1>
<?php
   $menu=file_get_contents("menu.txt");
   $base=basename($_SERVER['PHP_SELF']);
   $menu=preg_replace("|<li><a href=\"".$base."\">(.*)</a></li>|U", "<li id=\"current\">$1</li>", $menu);
   echo $menu;
?>

</body>
</html>

The attachment contains the files…

php-highlight-current-page.zip (4.0 KB)

coothead

5 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.