980px

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:

My WordPress Pages

My WordPress Pages

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:

Our Menus Seem to Be Broken

Our Menus Seem to Be Broken

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:

Register Your Menus in Your Functions File

Register Your Menus in Your Functions File

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.

Select Code
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:

Manage My Menu Location

Manage My Menu Location

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:

My Hand Coded Navigation Looks So Pretty

My Hand Coded Navigation Looks So Pretty

Let’s replace it with the wp_nav_menu() function:

Implement My Main Menu Function

Implement My Main Menu Function

Select Code
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:

Select Code
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:

  1. Create the menu for the theme location of “main-menu” as stated in my functions file
  2. State that I am going to use a “division” tag as my container element
  3. Name the container division tag “navigation”
  4. State that I am going to use an “unordered list” tag as my navigation items wrap
  5. 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:

Navigation Declarations in My CSS FIle

Navigation Declarations in My CSS FIle

I will then have a navigation system that looks like it is supposed to:

My Menu System Preview

My Menu System Preview

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:

Select Code
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:

Select Code
1
2
3
#navigation ul li ul.sub-menu {
display: none;
}

… and show it for my mobile resolutions:

Select Code
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:

Select Code
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:

My "You Are Here" State is Broken :-(

My “You Are Here” State is Broken :-(

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:

Select Code
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:

Select Code
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:

My "You Are Here" State is Working Again :-)

My “You Are Here” State is 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:

Select Code
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:

The Get The Title & List Pages Functions

The Get The Title & List Pages Functions

Select Code
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:

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:

My Sub-Navigation in Action

My Sub-Navigation in Action

But, if I go to one of the sub-pages, my “You Are Here” state doesn’t work!

Let’s investigate…

Select Code
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:

Select Code
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:

My "You Are Here" State Works on my Parent Pages

My “You Are Here” State Works on 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:

The List Categories Function

The List Categories Function

Select Code
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:

Using The Is Page Function

Using The Is Page Function

Select Code
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.

Leave a Comment:

Don't forget to get your Globally Recognized Avatar.

css.php