Genesis comes with a feature called Primary Navigation Extras, which let’s you stick the following at the end of the primary navigation: Date, RSS Feed, Search, or Twitter link. But for a project I’m working on now, I wanted something more custom.
This tutorial will show you how to customize the navigation area. I’ll be sticking a “Follow” section at the end of the navigation with links to an RSS feed and Twitter profile. You can use this technique to do almost anything to the navigation – stick something before it, after it, or modify the navigation’s output itself.
I’m going to walk you through the code, so skip to the end if you just want the functioning code.
Setting up the Filter
The best way to modify Genesis (and any other theme framework for that matter) is with functions attached to actions and filters. If you’d like a review, take a look at the Plugin API in the Codex.
I’m going to create a function called follow_icons() and attach it to two different filters, genesis_nav_items and wp_nav_menu_items. Which filter is actually used depends on what type of menu you select in the Genesis Options, so include them both for compatibility.
<?php
add_filter( 'genesis_nav_items', 'be_follow_icons', 10, 2 );add_filter( 'wp_nav_menu_items', 'be_follow_icons', 10, 2 );/** * Follow Icons in Menu * @author Bill Erickson * @link http://www.billerickson.net/genesis-wordpress-nav-menu-content/ * * @param string $menu * @param array $args * @return string */function be_follow_icons($menu, $args) { return $menu;}This code isn’t really doing anything yet. It’s pulling in the content of the nav menu and sending it right back out. The first condition of the add_filter specifies the filter you want to work with. The second is the function you want attached to that filter. The third is the priority (10 is default), and the fourth is the number of arguments used (I’m only using 1).
Add your Changes
Once you have the basic filter set up, you can jump in and add your modifications.
<?php
add_filter( 'genesis_nav_items', 'be_follow_icons', 10, 2 );add_filter( 'wp_nav_menu_items', 'be_follow_icons', 10, 2 );/** * Follow Icons in Menu * @author Bill Erickson * @link http://www.billerickson.net/genesis-wordpress-nav-menu-content/ * * @param string $menu * @param array $args * @return string */function be_follow_icons($menu, $args) { if ( 'primary' !== $args['theme_location'] ) return $menu; $follow = '<li id="follow">Follow: RSS and Twitter</li>'; return $menu . $follow;}In the first line I’ve created a variable called $follow which will contain the code I’m adding, and the second line sticks my new code to the end of the existing navigation content. This just contains static text right now, which I’ll be replacing next with some more code.
<?php
add_filter( 'genesis_nav_items', 'be_follow_icons', 10, 2 );add_filter( 'wp_nav_menu_items', 'be_follow_icons', 10, 2 );/** * Follow Icons in Menu * @author Bill Erickson * @link http://www.billerickson.net/genesis-wordpress-nav-menu-content/ * * @param string $menu * @param array $args * @return string */function be_follow_icons($menu, $args) { $args = (array)$args; if ( 'primary' !== $args['theme_location'] ) return $menu; $follow = '<li id="follow">Follow: <a rel="nofollow" class="rss" href="'.get_bloginfo('rss_url').'"><img src="'.get_bloginfo('stylesheet_directory').'/images/feed.png" /></a> <a rel="nofollow" class="twitter" href="'.esc_url( 'http://twitter.com/' .genesis_get_option('nav_extras_twitter_id') ).'"><img src="'.get_bloginfo('stylesheet_directory').'/images/twitter.png" /></a></li>'; return $menu . $follow;}I’ve turned the static RSS and Twitter text into links and images. Here’s what each one means:
get_bloginfo('rss_url');– This is the link to the RSS feed. The reason I didn’t hardcode an RSS feed link in is if you change your RSS feed using the Genesis Options, this will automatically be updated. This code also works on any site now, not just the one I built this for (always try and make your code easily reusable for future projects).get_bloginfo('stylesheet_directory');– This is the link to your child theme’s directory. I have an image for the RSS feed and Twitter uploaded in the images directory of the child theme.esc_url()– Any time you’re using data created by a person, you want to escape it. Escaping it ensures that untrusted text can’t do damage to your site (more info here). I have to thank Aaron Brazell for teaching me this.genesis_get_option('nav_extras_twitter_id')– In the Genesis Options panel, inside Primary Navigation Extras is a box to type your twitter username. This function pulls the content of that box.
From there, you can use CSS to style it how you want.
This technique can be used to do anything to the navigation. You could stick something to the beginning or modify the $output to change the navigation itself.


Hi Bill,
I would not really be exaggerating to say you have saved my life. Your tutorials and snippets are amazing and I can’t say enough how much I appreciate and benefit from them.
I have used but modified the code above and have achieved what I need plus an unusual twist. There is now a ’1′ in my navigation bar. I can’t figure it out for the life of me and would really appreciate it if you could have a look here – git://gist.github.com/1786595.git
Thanks a ton for everything
I believe the issue is that dynamic_sidebar() echos the sidebar and then returns “true” if it worked. When you echo a variable that is set to “true” it shows up as 1.
If you must use a sidebar, you’ll need to output buffer it. Try this: https://gist.github.com/1794879
Thank a lot Bill. The code you supplied almost did the trick. A little tweaking and it is now perfect. Code posted with yours…
Hi Bill,
Thanks for sharing this code. To me, as a novice it seems that in order to implement this code one would need to know how to make a plug in. I was wondering if making a plug in available so that it would be easy to implement would be difficult for this type of application. If it is not, I would greatly appreciate it.
Thanks
This code can be added directly to your theme files, but could also be done by a plugin. Unfortunately I don’t have the time to turn it into a plugin (or to support that plugin), but you could hire a developer to do it for you.
Hi Bill,
This was amazingly helpful. I’ve implemented the code you recommended for chad above on my site.
Quick question: is there a way to do the same thing chad did but also for the subnav? I’m pretty new at this and haven’t yet been able to figure it out. Any help is greatly appreciated!
Thanks!
Chris
Yep, just change ‘primary’ to ‘secondary’.
Just slapped my forehead. Awesome! Thx!
Thank you so much for this write up – it worked perfectly!!!!
Some might found this one helpful:
add_filter( ‘genesis_nav_items’, ‘sws_social_icons’, 10, 2 );
add_filter( ‘wp_nav_menu_items’, ‘sws_social_icons’, 10, 2 );
function sws_social_icons($menu, $args) {
$args = (array)$args;
if ( ‘primary’ !== $args['theme_location'] )
return $menu;
ob_start();
dynamic_sidebar(‘Social Menu’);
$social = ob_get_clean();
return $social . $menu;
}
It just makes an extra widget area in the primary navigation
Getting the following error:
Fatal error: Cannot use object of type stdClass as array in /home/clicktruemedia/peytonwilliamsforcongress.com/va/wp-content/themes/politica/functions.php on line 31
Referenced line is:
if ( ‘secondary’ !== $args['theme_location'] )
Have changed from ‘primary’ to ‘secondary’ b/c I need modification to appear in sub-nav.
Does ‘theme_location’ need to be specified? I pasted it into my functions.php exactly as shown, but is this a placeholder for the actual path to the theme?
Hmm, it looks like the error is that your $args is an object, not an array. Try doing print_r( $args ); exit; to see what’s in the args, and then find the theme location. You might need to use $args->theme_location.
I’ve never seen that issue before.
Thank you very much for sharing this Bill. As a Genesis newbie I was completely lost but thanks to your piece of code I was able to create a submenu drop down layer.