If you didn’t have a chance to read my previous post about creating top horizontal menus with Pages – please, have a look at it.
Consider this post an update to it. The basic concept of creating horizontal top menu on WP blogs became widely known and many bloggers start modifying their existing theme to get it. It is all well and simple until the need to have one or more categories also included in that top level menu arises. From here things go wrong almost in every case.
For some unknown reason almost every user starts thinking about this in the wrong direction. Instead of modifying the menu to include there a category – they go the other way around and insist on forcing WordPress to display the posts in a Page. Now, Pages were “invented” and introduced in WP for a completely different reason: to show quasi-static content, i.e. entries that are not part of the chronological stream of the posts. Everybody seem to miss this basic definition of the Pages (notice, in WP documents they are mentioned with capital P). Especially, those already familiar with the concept of the Page Templates (which gives you a great flexibility in customization) – will instantly jump on this… asking endless questions in the forum about “how to display X category on a Page”?
When I respond simply stating this is the wrong approach – it is very difficult to convince them. However, I firmly believe, it is much easier to modify a little bit the code that displays the top menu than to go through all the hassle trying to come up with a custom Loop to get your posts in a Page.
So, let’s get back to our initial code, the template tag that is used to display the list of your static Pages – wp_list_pages. As you remember it displays the list of Pages as list items (sorrounded by li and /li items, so it needs an opening and closing ul and /ul:
<ul> <?php wp_list_pages('depth=1&sort_column=menu_order&title_li='); ?> </ul>
Keeping in mind this is a list with as many list items as many Pages we have – we can simply add some additonal items manually. For example, we can add a Home link to the beginning of the list:
<ul> <li><a href="<?php bloginfo('home'); ?>">Home</a></li> <?php wp_list_pages('depth=1&sort_column=menu_order&title_li='); ?> </ul>
The Demo site mentioned in the previous post also has this item included.
And now back to our categories. In any basic WordPress blog when you click a category name in the sidebar or in a post (the link that says “posted/filed in…”) – it will take you to a page (with lower case p – meaning a general web page) or view which displays only posts in those category in the usual chronological order: newest on the top.
The WordPress engine can use several different template files to do this. There is a very useful article in the Codex, titled Template Hierarchy, it is worth reading if you want to understand the logic of having different template files. In regards with the category listing or category archives here is the hierarchy of the templates:
[The -xx is the category's ID number]. When attempting to display your posts from XX category, the WordPress engine will look first for the #1, then for #2… and so on. The #2 template in the hierarchy will be used for all categories; and this applies to #3 and #4, too.
On the other hand, category-3.php, for example, is a perfect solution for the Page-obsessed users. It offers exactly the same level of customization as a Page template and you don’t have to touch anything in the Loop to make it work. Just save your index.php or archive.php as category-3.php – and you are done. If you need customization, you can call for a different header, for a different sidebar or footer; and, ultimately, you can have different div IDs and calsses in it to be able to style them differently than the rest of your template files.
And, finally, returning to the menu issue. As we added the Home link, we can also add a link to our preferred category:
<ul> <li><a href="<?php bloginfo('home'); ?>">Home</a></li> <?php wp_list_pages('depth=1&sort_column=menu_order&title_li='); ?> <li><a href="<?php bloginfo('url'); ?>/?cat=3">Preferred</a></li> </ul>
Note. If using the nice permalinks, replace the ?cat=3 with your category slug.
Go to the Demo blog and look for the “Hidden” item in the top level horizontal menu. It is the category among the Pages.
Update, July 31, 2008.
Otto suggested to add something about using the wp_list_categories template tag. Actually, he is right, because instead of adding manual links for each category you want to display – you could simply use the wp_list_categories tag with the proper parameters, to add a list of categories to your top nav menu. For example, if you take the code from above, it would look like this, if you add the categories:
<ul> <li><a href="<?php bloginfo('home'); ?>">Home</a></li> <?php wp_list_pages('depth=1&sort_column=menu_order&title_li='); ?> <li><a href="<?php bloginfo('url'); ?>/?cat=3">Preferred</a></li> <?php wp_list_categories('depth=1&exclude=3,7&title_li='); ?> </ul>
This would add only the parent cats (depth=1) and would exclude the categories with ID 3 and 7; the last parameter is preventing the code to add the usual “Categories” heading. Here you go!