Wordpress menu walker - help to add custom class for each submenu

I am trying to apply to my already existing menu a walker in order to add custom classes to every sub menu anchor tag.

Here is my menu:

            wp_nav_menu(array(
            'theme_location' = 'menu-top',
            'container'      = 'ul',
            'menu_class'     = 'header_nav_ul',
            'menu_id'        = 'header_nav_id',
            'depth'          = 0,
        ))

I added the wolder and it became:

wp_nav_menu(array(
            'theme_location' = 'menu-top',
            'container'      = 'ul',
            'menu_class'     = 'header_nav_ul',
            'menu_id'        = 'header_nav_id',
            'depth'          = 0,
            'walker'        = new my_walker_nav_menu_start_el(),
        ))

The walker function is this one:

function my_walker_nav_menu_start_el($item_output, $item, $depth, $args) {
        // you can put your if statements in here (use item, depth and args in conditions)
        if ( $depth == 1 ) {
            $item_output = preg_replace('/a /', 'a class="level-1-menu" ', $item_output, 1);
        } else if ( $depth == 2 ){
            $item_output = preg_replace('/a /', 'a class="level-2-menu" ', $item_output, 1);
        }
        // .. and so on
        return $item_output;
    }
    add_filter('walker_nav_menu_start_el', 'my_walker_nav_menu_start_el', 10, 4);

However out of the box it doesn't work. I am new to php, but I see that it is a new walker which suggests me that I should write that function as a class.

Can anyone help me to edit my function so that it will work fine with my menu?

Thank you

Topic walker menus Wordpress

Category Web


You're right, it's the object-oriented parts that are throwing you off.

The nav menu call should be:

wp_nav_menu(array(
    'theme_location' => 'menu-top',
    'container'      => 'ul',
    'menu_class'     => 'header_nav_ul',
    'menu_id'        => 'header_nav_id',
    'depth'          => 0,
    'walker'         => new my_walker_nav_menu_start_el,
));
  • no parentheses () after the name of the walker.

The walker itself needs to extend Core's Walker_Nav_Menu, and there is no add_filter() call for it.

// Extend the existing Core class, to build on its functionality
class my_walker_nav_menu_start_el extends Walker_Nav_Menu {
    // Make the function public so it can be called elsewhere
    public function start_el($item_output, $item, $depth = 0, $args = array(), $id = 0) {
        if ( $depth == 1 ) {
            $item_output = preg_replace('/<a /', '<a class="level-1-menu" ', $item_output, 1);
        } else if ( $depth == 2 ) {
            $item_output = preg_replace('/<a /', '<a class="level-2-menu" ', $item_output, 1);
        }
        return $item_output;
    }
}
// Remove the add_filter() call as it's not used

Just make sure the links don't have any other class, or else you'll end up with links that have 2 "class" attributes.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.