WEB170 » Creating a Navigation & Menu System for a WordPress Theme
So far, we have a good start on Creating a WordPress Theme From a Template. But, we are far from done.
Now, we need to make our Navigation & Menu system work for the pages that we created:
We will be making a Navigation for or Main Menu and our Sub-Page Menu.
Step One: Create the Main Menu from Our Menu System
Previously, we had created our Navigation & Menus in WordPress:
We now need to turn this into a working menu system. But, notice the error, “Your theme does not natively support menus…”
Here is where we will need to use the Functions (functions.php) file that we created earlier to register our navigational menus:
This function can register multiple custom navigation menus in the new custom menu editor of WordPress 3.0. This allows for the creation of custom menus in the dashboard for use in your theme.
1 2 3 4 5 6 7 8 9 |
<?php
// Register My Menus
register_nav_menus(array(
'main-menu' => __( 'Main' ),
));
//
?>
|
See Also: http://codex.wordpress.org/Function_Reference/register_nav_menus
Once we register our navigational menus, we can manage our locations:
Notice that I only have one to choose from because I only registered one.
Once we “Save Changes” we will be able to implement our Main Menu into our theme.
Step One: Implement the Main Menu from Our Menu System into Our Theme
Currently, we still have our main menu hand coded into our template:
Let’s replace it with the wp_nav_menu() function:
1 |
<?php wp_nav_menu( array( 'theme_location' => 'main-menu', 'container' => 'div','container_id' => 'navigation', ) ); ?>
|
See Also: http://codex.wordpress.org/Function_Reference/wp_nav_menu
Let’s break this down as it is a bit complex…
My hand coded menu in my template looked like this:
1 2 3 4 5 6 7 8 |
<div id="navigation">
<ul id="navigation-items">
<li><a href="main.html">About</a></li>
<li><a href="main.html">Portfolio</a></li>
<li><a href="main.html">Blog</a></li>
<li><a href="main.html">Contact</a></li>
</ul>
</div>
|
Therefore, I need to replace it using the wp_nav_menu() function where I need to set the parameters for the function via an array to:
- Create the menu for the theme location of “main-menu” as stated in my functions file
- State that I am going to use a “division” tag as my container element
- Name the container division tag “navigation”
- State that I am going to use an “unordered list” tag as my navigation items wrap
- Name that unordered list “navigation-items”
See Also: http://codex.wordpress.org/Function_Reference/wp_nav_menu#Parameters
If I have done this correctly, this will match up with the declarations in my CSS file:
I will then have a navigation system that looks like it is supposed to:
Well… almost like it is supposed to. Let’s take a look at what happened…
When we pulled this menu from WordPress, it gave us the following markup:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div id="navigation" class="menu-main-container">
<ul id="navigation-items" class="menu">
<li id="menu-item-26" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-26"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=14">About</a></li>
<li id="menu-item-27" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-27"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=8">Portfolio</a>
<ul class="sub-menu">
<li id="menu-item-30" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-30"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=11">Logos</a></li>
<li id="menu-item-29" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-29"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=16">Print</a></li>
<li id="menu-item-28" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-28"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=18">Websites</a></li>
</ul>
</li>
<li id="menu-item-25" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-25"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=20">Blog</a></li>
<li id="menu-item-24" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-24"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=22">Contact</a></li>
</ul>
</div>
|
This is exactly what I wanted! But, I didn’t have any sub-menu in my main-menu when I created my template.
I could make this a drop-down menu if I wanted to.
Or, I could just hide it for my desktop resolution:
1 2 3 |
#navigation ul li ul.sub-menu {
display: none;
}
|
… and show it for my mobile resolutions:
1 2 3 4 5 6 7 |
@media screen and (max-width: 600px) {
#navigation ul li ul.sub-menu {
display: block;
}
}
|
Done.
But what about the “You Are Here” states?
In my template I used:
1 2 3 |
#navigation ul li.current a {
color: #EBB700; /* and use bright gold */
}
|
… but, if I go to my about page, it’s not highlighted anymore:
Let’s take a look at what happened…
WordPress uses all kinds of classes and identifications when it publishes your site.
It gives each menu item a unique identification and a whole shitload of classes:
1 |
<li id="menu-item-26" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-14 current_page_item menu-item-26"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=14">About</a></li>
|
The class we are looking for is “current-menu-item.”
So, we need to change that in our theme:
1 2 3 |
#navigation ul li.current-menu-item a {
color: #EBB700; /* and use bright gold */
}
|
Now we should see our “You Are Here” state working again:
Fantastic! Now I can navigate through my site and know where I am!
But, what about the sub-navigation in the side bar?
Step Two: Implement the Sub-Menu for Pages Using a Function
Currently, I have a dummy sub-navigation system in my sidebar:
1 2 3 4 5 6 |
<h2>Header Level Two</h2>
<ul>
<li><a href="#">Lorem ipsum dolor</a></li>
<li><a href="#">Aliquam tincidunt</a></li>
<li><a href="#">Vestibulum auctor</a></li>
</ul>
|
I will need to replace this with some conditional functionality that will always list your sub-pages even when you are on a sub-page.
We will use the wp_list_pages() function to get the destination (child) pages and the get_the_title() function to get the gateway (parent) page title..
However, I am going to use the newer way of passing arguments thru the function:
1 2 3 4 5 6 |
<h2 class="sub-navigation-title"><?php echo get_the_title($post->post_parent); // ...get the gateway page title ?></h2>
<ul class="sub-navigation-items"><?php if ($post->post_parent) { // if the page has a parent...
wp_list_pages(array('child_of' => $post->post_parent, 'title_li' => __(''))); // ...list the sub-pages with no title
} else { // if the page does not have a parent...
wp_list_pages(array('child_of' => $post->ID, 'title_li' => __(''))); // ...list the sub-pages with no title
} ?></ul>
|
See Also:
- https://codex.wordpress.org/Function_Reference/get_the_title
- https://codex.wordpress.org/Function_Reference/wp_list_pages
Note: I have wrapped my sub-navigation in a division tag and used some extra identifications and classes. This will come in handy when I need to style some widgets in the sidebar that we will work on later.
For now, I should see my sub-navigation working when I am on a page that has sub-navigation:
But, if I go to one of the sub-pages, my “You Are Here” state doesn’t work!
Let’s investigate…
1 2 3 4 5 6 7 |
<li id="menu-item-27" class="menu-item menu-item-type-post_type menu-item-object-page current-page-ancestor current-menu-ancestor current-menu-parent current-page-parent current_page_parent current_page_ancestor menu-item-has-children menu-item-27"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=8">Portfolio</a>
<ul class="sub-menu">
<li id="menu-item-30" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-11 current_page_item menu-item-30"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=11">Logos</a></li>
<li id="menu-item-29" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-29"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=16">Print</a></li>
<li id="menu-item-28" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-28"><a href="http://www.web170.premiumdw.com/wordpress/?page_id=18">Websites</a></li>
</ul>
</li>
|
Aha… there’s another class of “current-menu-parent” in the list item!
Let’s put that in our CSS file:
1 2 3 |
#navigation ul li.current-menu-item a, #navigation ul li.current-menu-parent a {
color: #EBB700; /* and use bright gold */
}
|
Now my “You Are Here” state works for my parent pages:
Wow! Things are really starting to shape up!
Now, let’s break things apart by Creating the Template Files for a WordPress Theme.
Step Three: Implement the Sub-Menu for Blog Categories Using a Function
Unfortunately, the the wp_list_pages() function does not work to pull my blog categories as a sub-menu.
I will need to use the wp_list_categories() function instead:
1 2 3 |
<h2 class="sub-navigation-title">Blog</h2>
<ul class="sub-navigation-items"><?php wp_list_categories(array('title_li' => __(''))); // ...list the categories with no title ?></ul>
<?php endif; ?>
|
See Also: https://codex.wordpress.org/Template_Tags/wp_list_categories
Fabulous! But, now I want to make sure that these only show up in the correct places.
I will need to write some conditional tags and use the is_page() to do that:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php if (is_page()) : // if we are in "pages"... ?>
<h2 class="sub-navigation-title">
<?php echo get_the_title($post->post_parent); // ...get the gateway page title ?></h2>
<ul class="sub-navigation-items"><?php if ($post->post_parent) { // if the page has a parent...
wp_list_pages(array('child_of' => $post->post_parent, 'title_li' => __(''))); // ...list the sub-pages with no title
} else { // if the page does not have a parent...
wp_list_pages(array('child_of' => $post->ID, 'title_li' => __(''))); // ...list the sub-pages with no title
} ?></ul>
<?php endif; // end if we are in "pages" ?>
<?php if (!(is_page())) : // if we are not in "pages"... ?>
<h2 class="sub-navigation-title">Blog</h2>
<ul class="sub-navigation-items"><?php wp_list_categories(array('title_li' => __(''))); // ...list the categories with no title ?></ul>
<?php endif; ?>
|
See Also:
Note: We will be using more conditionals like this down the road. ;-)
This portion of the Premium Design Works website is written by Mike Sinkula for the Web Design & Development students at Seattle Central College and the Human Centered Design & Engineering students at the University of Washington.
Social