WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I found examples adding a class to top level itens, so we can display an arrow in menu itens with subitens, but is seems terrible to cope with the already builtin WordPress classes, can't display the arrow with current and css hover, it just ruins all states.

Is there someway to add a <span class="arrow"></span> within the parent li instead?!

Thanks a lot!

share|improve this question
up vote 1 down vote accepted

You can use the walker_nav_menu_start_el filter:

add_filter( 'walker_nav_menu_start_el', 'wpse_add_arrow',10,4);
function wpse_add_arrow( $item_output, $item, $depth, $args ){
    //Only add class to 'top level' items on the 'primary' menu.
    if('primary' == $args->theme_location && $depth ==0){
        $item_output .='<span class="arrow"></span>';
    return $item_output;

This assumes that you're using wp_nav_menu( array( 'theme_location' => 'primary') ); to display the menu.

Updated answer in response to comments. To add the span classes to only top-level elements which have children you need to use a custom walker:

class SH_Arrow_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl(&$output, $depth, $args) {
        $indent = str_repeat("\t", $depth);
        if('primary' == $args->theme_location && $depth ==0){
            $output .='<span class="arrow"></span>';
        $output .= "\n$indent<ul class=\"sub-menu\">\n";

To use this you'll need to set the walker argument in wp_nav_menu:

wp_nav_menu( array( 
     'theme_location' => 'primary', 
     'walker'=> new SH_Arrow_Walker_Nav_Menu()
 ) );
share|improve this answer
Oh! I found that the span show ups in all toplevel itens, I need it to show only the ones with nested items :( – Diana Jun 19 '12 at 15:52
See updated answer :) – Stephen Harris Jun 20 '12 at 10:34
Thanks Harris, that works! – Diana Jun 20 '12 at 17:26
Is there someway to insert things inside the menu item? Your code puts the content right after the link: <li id="menu-item-3344" class="etc"><a href="http://localhost/wp3/forums/">Fóruns</a><span class="arrow"></span> Is there someway to goes like this: <li id="menu-item-3344" class="etc"><a href="http://localhost/wp3/forums/">Fóruns New!</a> – Diana Jun 20 '12 at 18:08
You can edit the link text on the Appearance > Menu page. – Stephen Harris Jun 20 '12 at 18:32

To expand on the prev answer here is how to detect if an item is a parent menu item without using the Walker class

add_filter( 'walker_nav_menu_start_el', 'cfw_add_arrow',10,4);
function cfw_add_arrow( $output, $item, $depth, $args ){

//Only add class to 'top level' items on the 'primary' menu.
if('primary' == $args->theme_location && $depth === 0 ){
    if (in_array("menu-item-has-children", $item->classes)) {
        $output .='<span class="arrow">arrow</span>';
    return $output;

Please correct me if this PHP in_array check might fail in some situations, so far I have not had any issues with it.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.