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.
John M says
Hello Bill,I am looking forward to using the code you’ve offered here, but I am really new to all of this and don’t understand it fully.
Do I simply paste this code at the bottom of the functions.php area? Also I would like to simply add a search bar on my secondary nav, do you have the code to make that work?
Thanks in advance for your help!
John
Bill Erickson says
Yes, this code would go in functions.php.
To add the search bar to the secondary navigation, use this: https://gist.github.com/d0644aa57b5934263349
Jamie says
I’m so sorry, but even though I have been using Studio Press themes for over three years and modifying them mostly through CSS and slightly through modifying the functions.php file, I am not knowledgeable enough in PHP to understand your solution above. I want to add a Like Us on Facebook link to the right side of the primary navigation. Facebook provides the code. Is it possible to add this code the right side of the navigation bar?
Bill Erickson says
Yes, it is possible to add that, but writing the code for you is outside the scope of free support I provide through my blog.
Jeff says
Hey! This is awesome, thx!
2 Things:
1. I used the code, and changed the links and images. It’s putting my three images to the right of the primary nav bar, which I want, but they’re stacked vertically. If I put “display: inline” one each on the “a” tags, I can get them to line up horizontally. However, for some reason, it doesn’t seem to be paying any attention to the class on my “a” tags. When I use the debugger in Chrome, it’s not showing the class elements on the right, even though it’s showing it in the HTML on the left. Any ideas?
2. What’s the best way to insert an external URL into the “a” tag? (e.g. http://www.google.com)
Jeff says
Actually, I made it work.
I put each of the images/links as their own “li”, and that seemed to work 🙂
Allegra says
Hi, I’m currently working on developing a child theme for genesis. You’re code was VERY helpful in getting what I wanted faster, however I wanted to take it a step further and add many other social media icons. I would like to be able to input the specific page urls for various social media sites (not just twitter) in the wp genesis admin and have a function pull that content into the function you wrote here, so that I (or others) could interact with the admin (and not have to mess with the functions.php file) to turn on and off various social icons, and input their individual urls. I guess what’d I’d like to do is “genericize” it further – the way you can input the twitter handle… Is this possible? Where would I even start? Is an explanation outside the scope of this comment section? It would be really great to know how to do this.
Thanks in advance!
Efrem says
Hello,
I’m banging my head against my keyboard trying to figure out why I keep getting a T_STRING error when I try to include a search form in my functions.php using this method: https://gist.github.com/4656469
Any advice would be greatly appreciated.
Regards,
-Efrem
Bill Erickson says
I’m not sure what you’re trying to do there. To include a search form somewhere, use get_search_form( false ) ; the false returns it, leave that out to echo. See here for more information: http://codex.wordpress.org/Function_Reference/get_search_form
If you’re trying to customize the search form’s text or the button text, use the filters ‘genesis_search_text’, and ‘genesis_search_button_text’. For more information, look about halfway down this page: https://www.billerickson.net/genesis-quick-tips/
Efrem says
Hi, Bill.
Thanks for the quick reply. I was trying to include a custom search form in the nav bar of my theme using this code: http://wpmu.org/add-search-by-category-functionality-to-your-wordpress-site/ and using the method you described above.
I can get the search form with the category select menu to show up but it shows up above our header–not in the nav bar.
Bill Erickson says
It sounds like you’re using get_search_form() which echos it, rather than get_search_form( false ), which returns it.
Kearin says
I used this method to add a menu-toggle button (needed to make the navigation a toggle button for smaller devices) inside the and right before . It is required that the toggle button be directly above the ul.
Think this is the best approach or can I add an action that could place my toggle button Menu inside the add the custom nav action described above?
To sum it up my code has to look like this:
Menu
Thanks.
marianney says
Wow this is exactly what I was looking for, thanks Bill! And so simple too! I added it to my secondary nav and it works like a charm 🙂 Just wanted to show my appreciation!
Guido says
(new comment, botched the link in the last one)
Hi Bill,
Thanks for writing this blog post.
The first version of the code (that technically does nothing)… does nothing. So that’s good.
The second and third code samples break my Studiopress Outreach child theme.
After a bit of digging, I came across this post:
https://www.billerickson.net/customizing-wordpress-menus/#extra-code
Although that sample code did nothing either.
However, by merging the two (replacing filters and renaming the function within the new filters), I came up with this code that actually works for me: http://codebin.org/view/073ef4cc
I’ll try pasting it below, but I’m not sure if that will work. Either way, I hope this helps someone else!
David says
Hi Bill
It was a nice article. Actually I am developing a menu where I need to add div under sub menu.
Here is the code which I am using
add_filter( ‘genesis_nav_items’, ‘custom_sbmenu’, 10, 2 );
add_filter( ‘wp_nav_menu_items’, ‘custom_sbmenu’, 10, 2 );
function custom_sbmenu($menu, $args) {
$args = (array)$args;
if ( ‘primary’ !== $args[‘theme_location’] )
return $menu;
$follow = ‘Some Text and Images’;
return $menu . $follow;
}
The result is:
—————–
Menu Item 1
Menu Item 2
Menu Item 1
Menu Item 2
Menu Item 3
Some Text and Images
What I want to achieve is:
———————————-
Menu Item 1
Menu Item 2
Menu Item 1
Menu Item 2
Some Text and Images
Menu Item 3
Please let me know what changes I need to do in my code? Looking forward to hear from you soon.
Thanks.
Youssef says
Thank you very much the code is working perfectly