1stwebdesigner

Posted by | Posted on 17:09

1stwebdesigner


WordPress Wp_Nav_Menu with Icons and Active Item Highlight

Posted: 29 May 2011 03:00 AM PDT

WordPress is a great tool, for sure, but as many other CMS’ it drives us into an “all standard” way of thinking, that is, you design things thinking that every element has to be identical to his brothers, same color, same style, same size.

How many WordPress sites with pretty menu icons do you know (with wp_nav_menu, not “static” menus)?  How many of them use a different color for some categories? Well, these little things make a big difference.

This time we will learn a simple way to customize our WordPress menu, without losing its wonderful admin options. We will be doing:

•   Home link in our wp_nav_menu that always gets current blog url
•   Customize each menu item as you want
•   Put pretty icons in our menu
•   Active item highlight

From now on, it is useful to have a little understanding about what wp_nav_menu is, and if you have a blank WordPress install, it is time to play with it ;)

So, let’s rock!

Our Final Result


This is how our demo menu will look, but you can customize yours as you need, of course. In this menu, I’ve used these great resources:

Home Link in Our Menu

Almost every site needs a home link on its menu. But if you want to put your home link in a wp_nav_menu you just can’t by default. But we have (at least) two ways to work around it. The first one is explained in WpBeginner. Just add this code in your functions.php:

 <!--?php function home_page_menu_args( $args ) { $args['show_home'] = true; return $args; } add_filter( 'wp_page_menu_args', 'home_page_menu_args' ); ?--> 

With this solution you enable Home as a page in your pages selection, so you can add it to your menu.

My solution is to edit the wp_nav_menu and force it to add the home menu item before the other menu items:

 <!--?php<br /-->add_filter('wp_nav_menu_items','homeMenu', 10, 2); function homeMenu($items, $args) { 	$home = ' 	<li><a class="home item-0" href="' . get_bloginfo('url') . '">Inicial</a></li> '; 	$items = $home.$items; 	return $items; } ?> 

As you can see, I’ve added a span around it and two classes. Both will be useful below.

Customizable Menu Items

When you need to customize each item of the wp_nav_menu the first thing you may notice is its standard generated HTML. Let’s see an example of wp_nav_menu output:

 <!--?php //php code that call menu wp_nav_menu( 	array( 		'link_before'        =--> '', 		'link_after'          => ' 'div', 		'container_id'      => 'topMenu', 		'theme_location' => 'primary-menu', 		'fallback_cb'       => 'primarymenu', 	) ); ?>  <!-- HTML Output --> <div id="topMenu" class="menu-topmenu-container"> <ul id="menu-topmenu" class="menu"> 	<li><a class="home item-0" href="#linktoHome">Home</a></li> 	<li id="menu-item-6" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-6"><a href="#">Features</a></li> 	<li id="menu-item-8" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-8"><a href="#">Awards</a></li> 	<li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-3"><a href="#">Pricing</a></li> 	<li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5"><a href="#">Blog</a></li> 	<li id="menu-item-10" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-10"><a href="#">About US</a></li> 	<li id="menu-item-12" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-12"><a href="#">Contact us</a></li> </ul> </div> 

As you can see, the only option to customize these items is to use the id or the unique class of it. But you may notice that they seems to be completely random. This is because they are the menu item ID. If you edit the menu, or delete something you can lose this unique reference. This is why I use the menu-order to customize them. So, add this snippet to your functions.php:

 <!--?php add_filter( 'nav_menu_css_class', 'additional_active_item_classes', 10, 2 ); function additional_active_item_classes($classes = array(), $menu_item = false){ 	//add current menu order to item classes 	$classes[] = "item-".$menu_item--->menu_order; 	return $classes; } ?> 

With this code, each menu item will have on this classes now:

 	<li id="menu-item-n" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-n item-1"><a href="#">Features</a></li> 

Yeah, that’s it. Now you can just add .item-1 and edit the first menu item!

Working a little bit on our demo, let’s make the pricing item different from others:

 #topMenu a { 	position: relative; 	float: left; 	padding: 18px 20px 14px; 	text-decoration: none; 	font-family: "arial"; 	text-transform: uppercase; 	color: #949494; 	font-weight: bold; 	font-size: 12px; 	border: 1px solid; 	border-style: none solid; 	border-color: transparent #9e9e9e transparent #d8d8d8; } /* pricing item style */ #topMenu .item-3 a { color: #879A51; } /* hover styles */ #topMenu a:hover { 	background: transparent url(MENU_hover.png) repeat-x; } 

Pretty easy and customizable, isn’t it? So let’s make it even better with pretty icons now.

Pretty Menu Icons

Do you remember that I’ve put a span around each element? So it will make more sense now. We will use each span to hide our text without affecting the link itself, when needed. For example, let’s say that instead of text and an icon I want just an icon for “home.” So we can use that span to hide our stuff.

Our CSS to create icons and text in all items and just an icon for “home” is this:

 /******** ICONS! **********/ #topMenu .item-1 a { background-image: url(promotion.png); padding-left: 38px; } #topMenu .item-2 a { background-image: url(prize_winner.png); padding-left: 38px; } #topMenu .item-3 a { background-image: url(dollar_currency_sign.png); padding-left: 38px; color: #879A51; } #topMenu .item-4 a { background-image: url(news.png); padding-left: 38px; } #topMenu .item-5 a { background-image: url(info.png); padding-left: 38px; } #topMenu .item-6 a { background-image: url(comment.png); padding-left: 38px; } #topMenu ul a.home span { 	display:block; 	margin: -10px 0 -8px; 	width: 32px; 	height: 32px; 	text-indent: 300px; 	overflow: hidden; 	background: url(home.png) no-repeat; } 

Now it is missing just one more thing to get it really good: the active item highlight.

Active Item Highlight

This is really good feedback for the user, so he knows where he is without scanning too much.

To get this working we need to know which page we are on. One easy way to get this it to put a simple id (or class) in our body tag, so it could be used for more than just this menu:

  //Output something like id="page-15" 

Now all our magic now is done via CSS (by the way, with LESS it would be MUCH easier). You just have to set which page will be the “parent” of each item, just like this:

 /* active styles */ #page-1 #topMenu .item-2, #page-2 #topMenu .item-5 { 	background: #fafafa url(60degree_gray.gif); } 

So we are saying here that the second menu item is active when we are on page 1, and the fifth item is active when the page is 2. For a better understanding I recommend to keep it in separated lines but pay attention that the last item can’t have a comma after it.

Are You Hungry Yet?

We certainly have more ways to create cool and unique things like this, what kind of unique menus have you created in WordPress? Do you think this way is better? What would you do instead?

I recommend  that you always read the WordPress Function Reference, so you can do a better job spending less time with WordPress pre-built functions!

Comments (0)

Post a Comment