Ask your WordPress questions! Pay money and get answers fast! (more info)

Removing generated ID & classes on wp_nav_menu WordPress

  • SOLVED

I'm looking for a wp_nav_menu walker that generates clean html output.

<strong>What I mean with clean html output is instead of this:</strong>

<ul id="menu-menu" class="menu">
<li id="menu-item-573" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-2 current_page_item menu-item-573"><a href="">Home</a></li>
<li id="menu-item-197" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-197"><a href="">About</a></li>
</ul>


<strong>I want this:</strong>

<ul>
<li class="current-menu-item"><a href="">Home</a></li>
<li><a href="">About</a></li>
</ul>


<em>Note that both the .current-menu-item and .current-menu-ancestor classes should work on any time!</em>

Answers (3)

2011-06-16

Ivaylo Draganov answers:

Hello,

There are filters provided for these attributes so you can get away without a separate walker. You could easily remove the id and all of the classes with this code snippet:

// filter the id and class attributes of nav menu items
add_filter( 'nav_menu_item_id', 'filter_nav_menu_attributes' );
add_filter( 'nav_menu_item_id', 'filter_nav_menu_attributes' );

// function that returns false
function filter_nav_menu_attributes($content) {

return false;

}


It is possible to filter the classes separately and leave the necessary ones, but it requires some more advanced PHP magic. I'll try to see if I can manage to hack it.


Melvin vd Ven comments:

Hi,

Sounds good! The filters are great, if you can manage to keep the current states in this filter it would be a perfect solution.


Ivaylo Draganov comments:

Well, this is where I got so far:

function filter_nav_menu_id( $id ) {

return false;

}

function filter_nav_menu_classes( $classes ) {

// create array for new classes
$new_classes = array();

// perform regex match for certain strings and merge the new arrays
$new_classes = preg_grep( '/current-menu-item/', $classes );
$new_classes = array_merge( $new_classes, preg_grep( '/current-menu-parent/', $classes ) );
$new_classes = array_merge( $new_classes, preg_grep( '/current-menu-ancestor/', $classes ) );

// return the new array with classes
return $new_classes;

}

add_filter( 'nav_menu_item_id', 'filter_nav_menu_id' );
add_filter( 'nav_menu_css_class', 'filter_nav_menu_classes' );


The only drawback here is that an empty class attribute remains on the menu items. Unfortunately there's no filter for that so the only way to remove it would be to use a custom walker that is just a slightly modified version(just a single line) of the default one. Something like that works:
http://pastebin.com/RGGLnPWs

Cheers!


Ivaylo Draganov comments:

An improved version of the walker + classes filter:
[[LINK href="http://pastebin.com/BVgnrjx5"]]http://pastebin.com/BVgnrjx5[[/LINK]]

This version uses a little less code. I've removed from the walker the part that builds the id attribute (and because of that the id filtering function is no longer necessary).


Melvin vd Ven comments:

This is exactly where I was looking for, I have tested it and worked like a charm! Thanks :-)


Melvin vd Ven comments:

Hmm, how can I hand over the cash? Do I have to wait till this question is ended? :-)


Ivaylo Draganov comments:

Vote me the prize money and after a while the question will be closed(by an admin maybe). It's a new thing on WP Questions.

2011-06-16

Jerson Baguio answers:

I think you use jquery to that just put this code in the footer


<script language='javascript'>
$('.menu li').removeAttr('id');
</script>


Melvin vd Ven comments:

Hi, I don't want a jQuery solution if it's possible to do this with a Walker. The problem isn't removing the ID's, but removing the classes + keeping the active's working.

2011-06-16

Marcel Bootsman answers:

Read this, that should get you started: http://www.kriesi.at/archives/improve-your-wordpress-navigation-menu-output/


Melvin vd Ven comments:

I have already read this article, but I didn't found a solution to keep the current states.