In this article I explain how you can setup your blog to automatically create main navigation links/tabs when new pages are published by using custom fields to mark those pages you want to appear in the navigation menu.
OK, I’ve had a number of inquiries about setting up navigation tabs to be automatically created when new pages are published (just pages, not posts). Specifically, these inquiries are about my WordPress theme, This Just In!, but this technique can be adapted to any theme to achieve the same effect.
Introduction
OK, so our problem we’re trying to solve here is how to automatically create main navigation tabs when we create new pages so that we don’t have to edit the code every time we want a link to a new page in our main navigation menu.
The main problem we’re going to run into here is that we don’t want to include every single page, otherwise, as you add pages that main navigation menu is going to grow wider than it’s container, which will cause it to wrap to a new line…and that’ll look terrible.
To solve this problem we need to have a way to limit the number of tabs that are automatically added to our navigation menu. Now, we could just limit the number of links to the most that will fit on one line, but that isn’t an ideal solution for two reasons.
First of all, the nav tabs on This Just In! stretch to accommodate the text inside them. So, a limit of 10 links may be OK for one blog if the anchor text is short, but for longer anchor text, those tabs will stretch to accommodate the anchor text within them and 10 tabs may be too much, causing the menu to wrap to a new line. Not good.
The second problem with setting a simple limit is that as we create new pages, we may want some to show up in the main nav menu, but not others. If we set a simple limit on the number of tabs in that menu, we won’t have the control we may need over exactly which pages are included in the navigation menu and which are excluded.
Create a New Category?
My first thought was to create a new category to house all of our pages that we want to appear in the main nav menu and simply throw links to all those pages in that category into the main nav menu. Unfortunately, WordPress doesn’t allow you to assign categories to pages, only to posts, so that idea’s out the window.
Using a Page Parent?
I also considered using a page parent to act like a category. Then we could set the page parent for all the pages we want to show up in the main nav menu, and use wp_list_pages() to list all pages that are children of that parent. This may be a viable, and easy, option for some, but if you’ve styled child page links different from their parents you’ll need to take that into account. For instance, This Just In! indents child pages under their parent page in the sidebar list of pages. That’s perfect for the sidebar, but not so much for the main nav… so we’ll have to go with something else.
Using Custom Fields
Luckily, WordPress does allow us to assign custom fields to any page. We’ll use a custom field to mark any page that we want to appear in the main nav menu, and later add any page with that custom field to the main nav menu.

The Custom Fields Area
Using a Custom Function
Once we’ve created our custom fields, we’re going to create a function in functions.php that calls on those custom fields to determine what pages are supposed to show up in the navigation menu.
Action Steps
Creating the Custom Field
First of all, we need to locate any pages we’ve already created that we want to appear in the main nav menu. Edit those pages and add a new custom field…set Key to “NavMenu”, and Value to “yes” (without the quotes).

Custom Field with "NavMenu" key added
Then select “Add Custom Field” button…once you’ve done that your Custom Fields area should look like Figure 3 here.

After Pressing "Add Custom Field" button
Just repeat this process for any pages you want to show up in the main navigation menu.
Adding the Function Call in Place of the Current Navigation Menu
For demonstration I’ll be using my This Just In! theme, but you should be able to follow along with any theme that uses a main navigation menu like This Just In!. Now you need to open up header.php in whatever you use to edit PHP files and find navigation menu code block…it looks like this in This Just In!:
<!--Main navigation menu-->
<ul>
<li><a <?php if(is_home()) echo 'class="current" '; ?>href="<?php bloginfo('url'); ?>" title="Home">Home</a></li>
<li><a <?php if(is_archive() || is_page('archives')) echo 'class="current" '; ?>href="<?php bloginfo('url'); ?>/archives/" title="Visit the archives">Archives</a></li>
<li><a <?php if(is_page('about')) echo 'class="current" '; ?>href="<?php bloginfo('url'); ?>/about/" title="About <?php bloginfo('name'); ?>">About</a></li>
<li><a href="<?php bloginfo('url'); ?>/feed/" title="RSS Feed">Feed</a></li>
<li><a href="<?php bloginfo('url'); ?>/sitemap/" title="Sitemap">Sitemap</a></li>
</ul>
Delete everything inside the <ul></ul> tags and replace it with <?php buildMenu(); ?>, so you end up with this:
<!--Main navigation menu--> <ul> <?php buildMenu(); ?> </ul>
Create a Function to Build the New Navigation Menu
If you don’t have a functions.php file in the root directory of your theme, create one now. Then open that file for editing and add the following function:
// Build navigation menu
function buildMenu() {
$pages = get_pages();
$key = 'NavMenu';
$pageIDs = array();
foreach($pages as $page) {
if(strtolower(get_post_meta($page->ID, $key, true)) == 'yes')
$pageIDs[] = $page->ID;
}
$pageIDList = implode(',', $pageIDs);
wp_list_pages('include=' . $pageIDList . '&title_li=');
}
Be sure your functions.php file has opening and closing tags. If you’re using the latest version of This Just In!, you should already have a functions.php file in your theme directory with something already in it. Just add the buildMenu() function above what’s already in the file so you end up with this:
// Build navigation menu
function buildMenu() {
$pages = get_pages();
$key = 'NavMenu';
$pageIDs = array();
foreach($pages as $page) {
if(strtolower(get_post_meta($page->ID, $key, true)) == 'yes')
$pageIDs[] = $page->ID;
}
$pageIDList = implode(',', $pageIDs);
wp_list_pages('include=' . $pageIDList . '&title_li=');
}
if(function_exists('register_sidebar'))
register_sidebar(array (
'before_widget' => '
<li>',
'after_widget' => '</li>
',
'before_title' => '<span class="sidetitle">',
'after_title' => '</span>',
));
?>
Highlighting the “Current” Page
In This Just In!, the current page’s navigation menu item is highlighted with a white background and dark text. Since we’ve removed our original code, which handled that for us, we’ll need to create a new style in our style.css in order to replace that feature.
In the above code, we used a built-in WordPress function called wp_list_pages() to display a list of pages that were marked with our custom “NavMenu” field. One nice feature about that function is that it returns those pages as list items (<li></li>) with the current_page_item class applied if that page is currently being viewed. So, all we need to do is add something like the following to styles.css:
#nav_menu li.current_page_item a {
background: #FFF;
color: #333;
}
That first #nav_menu part may not be necessary if you’re using a theme other than This Just In!.
And that’s it, you’ve successfully set up your blog to create your navigation menu links for you. Now all you need to do is when writing a new page that you want to be included in the menu, be sure to add the custom field to that page as we covered earlier.
If you’d like to understand the code in this tutorial a little better, read on for an explanation.
Code Explanation
Ok, let’s take another look at our code:
// Build navigation menu
function buildMenu() {
$pages = get_pages();
$key = 'NavMenu';
$pageIDs = array();
foreach($pages as $page) {
if(strtolower(get_post_meta($page->ID, $key, true)) == 'yes')
$pageIDs[] = $page->ID;
}
$pageIDList = implode(',', $pageIDs);
wp_list_pages('include=' . $pageIDList . '&title_li=');
}
Now let’s break it down line by line
// Build navigation menu
function buildMenu() {
Comment followed by function declaration.
$pages = get_pages();
get_pages() is a built-in WordPress function, that returns an array of objects for all of our blog’s pages.
$key = 'NavMenu';
Here we set the $key variable to “NavMenu” for use in the get_post_meta function below.
$pageIDs = array();
Next we initialize the $pageIDs array, which will hold the page IDs for the pages that have our custom field attached.
foreach($pages as $page) {
Simple for-each loop.
if(strtolower(get_post_meta($page->ID, $key, true)) == 'yes') $pageIDs[] = $page->ID;
The first line uses the get_post_meta() built-in WordPress function. This function takes as parameters 1) a page ID, and 2) a custom field Key, which in our case is “NavMenu”. The third parameter is true to tell the function to return a string of the first occurrence instead of an array of all occurrences of Key. Then we stick that function inside an if-statement to determine if a custom field we’re looking for exists, and we check to see that the custom field contains the value ‘yes’. strtolower() simply converts the string to lowercase just in case you enter something other than all lower case when setting the custom field for the page.
If that custom field exists, the second line adds the page ID to our $pageIDs array.
Then the foreach loop continues on to the next page.
$pageIDList = implode(',', $pageIDs);
This takes our $pageIDs array with all the page ID numbers of the pages marked with our custom field and strings them all together separated by commas using PHP’s implode() function.. This is so they’re in a format like 2,5,7,10,32 for the following line of code…
wp_list_pages('include=' . $pageIDList . '&title_li=');
wp_list_pages() is another built-in WordPress function, which, in this case, takes as parameters 1) a comma-separated list of page ID numbers, which we set up in the last step and 2) &title_li=, which tells WordPress not to return a title for the list of pages. The first parameter is a comma-separated list of page ID numbers that we set up in the previous step.
Conclusion
Now that wasn’t too tough was it? Now you know how to set up WordPress to automatically create a navigation menu from pages tagged with a specific custom field. We’ve also lightly touched on creating a new function and using the built-in WordPress functions, get_pages(), get_post_meta(), and wp_list_pages(), as well as the php implode() function.


thats awesome John, even I could follow and implement! Thanks!!
Thanks John! I am in the process of changing over to wordpress (and a noob!).
I LOVE wordpress and your theme is great, I admit I was a bit daunted by having to code the page headers but you must have explained it well because it works
I don’t regret learning basic html (before falling in love with wordpress) because it gave me the confidence to tackle this!
However, I have been studying: html, css, php, ftp, wordpress, e-commerce, internet marketing, seo, sem, linking strategies, writing copy etc etc and after a whole year I feel like I only have a broad overview!
How on earth do you guys manage to learn all this stuff (and have a life!) before you die is beyond me!
Learning the basics is a full time job for a 40 year old former builder!!
Hope to stick around though John,
Thanks again for the tutorial,
Stay well
Ian
That’s funny. For the first two years in this business I DIDN’T have a life! There’s definitely a lot to learn, but the good thing is there are a lot of great resources out there, especially when it comes to WordPress.
The one thing I’d suggest with regard to SEO is be careful who you take advice from, especially when it’s in a forum. In my experience a lot of people give advice on things they haven’t actually tried yet…they’re just regurgitating information they heard somewhere else. It’s hard to sift through what’s right and what’s wrong, but what I can say is learn as much as you can, try as much as you can to figure out what works, and remember who you’re taking advice from at all times.
Good luck!
Thanks John,
So agree with your SEO analysis; I posted a little seo enquiry on Elance and what those guys proposed scared me away forever! Their ‘techniques’ just adds mountains of ‘fluff’ to the already crowded web.
Starting up auto blogs pointing towards yours and harvesting links etc…sad. I’ll aim for good content and building relationships…sink or swim, I enjoy it, so I don’t much care which!
I so like your ‘this just in’ I’m bound to see you around John,
Stay well and thanks for making the time!
Ian
Hey John,
Thanks for the explanation and great theme.
But now i have what may be a very simple question.
I have the navigation tabs i need made for my pages, but now the “home” tab has dissappeared.
Since my home page is my blog, i cant figure a way to put the custom tag on it to make it a tab.
Any advice?
Hey Kyle, your best bet is to just hard code the homepage link in just before the code to pull in the rest of the nav.