There are a lot of classes used in wp_list_pages as well as wp_nav_menu and they aren’t consistent from one to the other. Here I’ve provided a couple of walker classes as well as a sample and some explanation to tighten things up and make them a little easier to style. They could also be used to customize the output to match classes used by frameworks like Twitter’s Bootstrap and Zurb’s Foundation.
Here’s what were trying to remedy:
<li id="menu-item-1637" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item menu-item-1637 current_page_item current_page_parent"> <a href="#">Link</a> </li>
There’s an ID and a lot of classes. Even a class to match the ID. Impressive. But I prefer something that looks like this:
<li class="active"> <a href="#">Link</a> </li>
It gets even worse if you have parent/child relationships:
<li id="menu-item-1639" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-1639"> <a href="#">Parent</a> <ul class="sub-menu"> <li id="menu-item-1697" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1697"> <a href="#">Child</a> </li> </ul> </li>
I don’t often need so many classes. So this will work for me:
<li class="parent"> <a href="#">Parent</a> <ul class="sub-menu"> <li> <a href="#">Child</a> </li> </ul> </li>
Much better. So, let’s make this happen.
The Solution The Walkers
Here are the walkers (Github Gist):
A sample implementation of these using wp_list_pages and wp_nav_menu respiectively:
wp_list_pages( array( 'walker' => new Rational_Walker_Page, ) ); wp_nav_menu( array( 'walker' => new Rational_Walker_Nav_Menu, ) );
Breaking Down the Changes
start_lvl method, on line 18, I’m changing the class of the list element to “sub-menu” to match the default of
wp_nav_menu. To me “sub-menu” just sounds more semantic than “children”.
Most of the changes take place in the
start_el method. Starting on line 38 I removed a few generated classes including the one that generates the “page-item” classes and the one that matches the ID of the page. On line 43 I changed “current_page_parent” to a more efficient “parent”. From line 47 through 59 I changed the wording of the inheritance classes. They are now “active”, “active-parent” and “active-ancestor”. On lines 87 and 88 I switched up the
sprintf function to only output the “class” attribute if there are classes to put in it.
In this one I’m only replacing the
start_el method. Beginning on line 134 I added some statements to see what classes are contained within the “classes” array and use them to populate a new, cleaner array (“new_classes”) that I later use to replace the giant “classes” array. On line 160 I just removed the “id” attribute since I removed the code to create it earlier on in the method.
I can understand how you might need some of the classes I remove by default if you were making some elaborate, custom theme. But, in most cases, that much differentiation is just going to lead to overly complicated interfaces. Maybe, being a developer, I’m a little more inclined than most to minimalism.