9

How do I get something like below? My code is like this:

wp_nav_menu(
     array(
       'theme_location' => 'header_menu',
       'container_id' => 'menu',
       'link_before' => '<span data-hover="link-text-here">',
       'link_after' => '</span>',
     )
  );

I want to get the result below:

<nav class="main-nav">
    <li><a href="#"><span data-hover="Home">Home</span></a></li>
    <li><a href="#"><span data-hover="Proyects">Proyects</span></a></li>
</nav>

Please advise me.

4

Solution 1: Using customize walker

I got some idea from add span class inside wp_nav_menu link anchor tag and made some changes for your requirements.

1. Add this code below to your functions.php first.

class Nav_Walker_Nav_Menu extends Walker_Nav_Menu{
  function start_el(&$output, $item, $depth, $args){
       global $wp_query;
       $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
       $class_names = $value = '';
       $classes = empty( $item->classes ) ? array() : (array) $item->classes;
       $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
       $class_names = ' class="'. esc_attr( $class_names ) . '"';

       $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

       $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
       $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
       $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
      $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';


       $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';



        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'><span data-hover="'. $item->title .'">';
        $item_output .=$args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
        $item_output .= $description.$args->link_after;
        $item_output .= '</span></a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

2. Add code below to your header.php where your wp_nav_menu is installed. Explained below is the code so it installs the new custom menu in this case would be Nav_Walker_Nav_Menu.

<?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'walker' => new Nav_Walker_Nav_Menu() ) ); ?>

Hope this help you well!

Solution 2: Using wp_list_pages

Please check out this page . You can see their snippet. If you put the spans around the link tags you can use link_before and link_after

wp_list_pages("link_before=<span data-hover="link-text-here">&link_after=</span>");
4
  • its say Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/wp.dev/wp-content/themes/eta-theme/functions.php on line 98 – Mohamed Rihan Feb 1 '16 at 8:00
  • So, what is the code at line 98? – AddWeb Solution Pvt Ltd Feb 1 '16 at 8:02
  • $item_output = $args->before; $item_output .= '<a'. $attributes .'><span data-hover="'. $item->title .'">'; $item_output .=$args->link_before .apply_filters( 'the_title', $item->title, $item->ID ); $item_output .= $description.$args->link_after; $item_output .= '</span></a>'; $item_output .= $args->after; – Mohamed Rihan Feb 1 '16 at 8:08
  • seems ok now. its couse of i didnt add menu on dashbord.. thanks – Mohamed Rihan Feb 1 '16 at 8:08
9

Since version 4.4.0 the 'nav_menu_item_args' filter was added. This allows you to set 'link_before' and 'link_after' attributes for each item.

add_filter('nav_menu_item_args', function ($args, $item, $depth) {
    if ($args->theme_location == 'header_menu') {
        $title             = apply_filters('the_title', $item->title, $item->ID);
        $args->link_before = '<span data-hover="' . $title . '">';
        $args->link_after  = '</span>';
    }
    return $args;
}, 10, 3);
1
  • That is not correct.. below is output after using the filter... <li id="menu-item-44" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-24 current_page_item menu-item-44"> <a href="sandbox.test/about" aria-current="page"> <span data-hover="About">About</span> </a> </li> – Daren Zammit Apr 12 '19 at 7:07
2

Please try the following:

wp_nav_menu(
 array(
   'theme_location' => 'header_menu',
   'container_id' => 'menu',
   'walker' => new description_walker()
 )
);

And add this to functions.php:

class description_walker extends Walker_Nav_Menu{
  function start_el(&$output, $item, $depth, $args){
       global $wp_query;
       $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
       $class_names = $value = '';
       $classes = empty( $item->classes ) ? array() : (array) $item->classes;
       $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
       $class_names = ' class="'. esc_attr( $class_names ) . '"';

       $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

       $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
       $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
       $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
      $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';


       $description  = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';



        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'><span>';
        $item_output .=$args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
        $item_output .= $description.$args->link_after;
        $item_output .= '<span></a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
}

This way you can easily add a span tag...

1
  • but i want the data attr inside the span – Mohamed Rihan Feb 1 '16 at 7:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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