At some point when working with WordPress you’ll likely want to display your page links in a dropdown navigation bar. While there are many plugins that will do this for you, none are necessary as coding a dropdown menu in a WordPress theme is rather easy.
Below I’ll show two simple ways to have WordPress create the html for a flexible and dynamic drop down menu in your theme. I won’t be covering the css styling in the post. If you’re unfamiliar with how to develop drop down menus in general here are two posts that will show you how.
The second link above is an example of a css only drop-down. You’ll have to view the source code to see how it’s done. I’ve never used it myself, but the author, Stu Nicholls has tested it across many browsers and versions.
Typical HTML in a Drop Down
In general any time you want to create a menu or navigation bar think unordered lists in your html. For a typical dropdown menu your html might look something like the following:
The code above is a simple nested list. Two keys to note are first that the nested list comes before the closing </li> of the menu item that will contain the drop down. A common mistake is to forget to add the nested list inside the list item. The other key is we’ve given the outside <ul> an id so we can hook into it through our css.
Again I’ll point you to either of the two links above for styling a drop down menu. If you’d like me to write a post in the future showing the css and developing the full menu from scratch, leave a comment below.
Creating the HTML in WordPress
Editing the css file of a WordPress theme is straightforward. The hard part in creating the dropdown navigation is getting WordPress to display something close to the html above. Many people will hard code the html into their header.php file and while that works, it’s not particularly flexible. If you add a new menu item, you need to add another line of html in the appropriate place.
A better solution is to use a WordPress template tag to produce our html. There are two template tags that can produce the code we want. One has been around for years and one has only been with is since WordPress 2.7. Each has its advantages.
Dropdowns with wp_list_pages()
wp_list_pages() has been around for awhile. It outputs your pages as a series of links wrapped in list tags. Odds are your current theme uses this tag to produce your navigation. Not everyone knows how to use this tag to produce nested lists of pages, but it’s rather easy with the use of one parameter you include in the tag.
wp_list_pages() produces the list items, but not the <ul></ul> so I’ve hard coded those tags and added our id to hook into the list. The tag only lists your pages and since your home page often isn’t a WordPress page, but rather your index.php page, I’ve included a line of code to display the index.php page in the menu.
You’ll notice the added line also checks to see if the home page is the current page and if so it adds class=current_page_item. This class is used if you want to highlight the current page or style it in some unique way. wp_list_pages() will automatically add that class to the links if creates and so it’s a good idea to add it to the home page link as well.
Let’s look more closely at the one remaining line of code above
We’re passing three parameters to the wp_list_pages() tag. The first title_li is set to nothing, since we don’t want a title displayed. The second sort_column is set to menu order which will display our pages in the order we’ve specified through the admin side of WordPress. The last parameter depth is what actually creates our nested lists.
By default depth=1, which is why most menus in WordPress will only show our top level pages and not all your nested pages. By changing the depth to 2 WordPress will go one level deeper in producing our html and we’ll get a nested list, which we can style to be a drop-down. The code produced will look something like:
The actual source of the links would be included and, of course, the menu items would be called whatever you named the pages. wp_list_pages also gives you two additional classes to hook into, page_item, and page_item-#. The important thing to note is that we now have a nested list.
You’re not limited to a depth of 2 either. If your pages go 3 levels deep you could have depth=3. You could go even deeper, though if you need more than 3 levels you probably need to rethink how you’ve organized your content.
Dropdowns with wp_page_menu()
As of WordPress 2.7 we now have the wp_page_menu() template tag, which produces essentially what we did above in a single line of code.
wp_page_menu() is actually a wrapper around wp_list_pages() so you can pass the same parameters as well as a few extras. One of those extras is show_home. By setting show_home to 1, we’re telling WordPress to include our home page in the menu. Setting it to 0 would tell WordPress to ignore the home page.
Here’s the html that gets created by the above:
The code is similar to what we were able to produce with wp_list_pages(), though not quite the same. You can still use it to style your dropdown, but the differences will determine which tag you prefer to use.
First notice that our hook (class=menu) is added to a wrapper div instead of the list itself. You can set the class name via the menu_class parameter and the fact that we’re using a class instead of an id doesn’t really affect anything. The wrapper div isn’t necessary, though it’s often used in coding drop downs. You may or may not want to include it, which would determine your choice in tags.
Ian Stewart has written a nice post on how to add a class or id to the list through a WordPress filter.
The other major difference is that our home page doesn’t get the current_page_item class added. If you were hoping to use it to style the current page’s menu item then you may want to go with wp_list_pages() where you can add it as I did above.
You could also adapt Ian’s filter to add the current_page_item class. Justin Tadlock has also written a post on wp_page_menu, including his own filter, as well as a post on developing a widget for your page menu using the wp_page_menu() tag
While I’ve spent a lot of time showing you how these two WordPress template tags work and the code they produce, it won’t take you a long time to get comfortable using them.
Give both a try and familiarize yourself with the codex pages for each so you can see the parameters you can use with them. Remember that any parameter you can use with wp_list_pages() you can also use with wp_page_menu(). The latter then adds a few new parameters to the mix.
The next time you want a dropdown menu in your theme, don’t reach for a plugin or hard code your navigation. Just look to use either of these two template tags.
Download a free sample from my book, Design Fundamentals.