Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add class to link in wp_nav_menu?

Tags:

php

wordpress

I am trying to out a wp menu without ul and li and have a class added to the element.

I have tried adding this in my function.php

function add_menuclass($ulclass) {
  return preg_replace('/<a /', '<a class="list-group-item"', $ulclass, 1);
}
add_filter('wp_nav_menu','add_menuclass');

And in my template I have:

<?php
 $menuParameters = array(
   'menu'  => 'Videos',
   'container'       => false,
   'echo'            => false,
   'items_wrap'      => '%3$s',
   'depth'           => 0,
);

  echo strip_tags(wp_nav_menu( $menuParameters ), '<a>' );
?>

But the output only applies the class to the first item and not all of the <a>s as expected.

<div class="list-group">
   <a class="list-group-item" href="#">First item</a>
   <a href="#">Second item</a>
</div>

I am trying to achieve this, basically to apply that class to ALL my item (not sure why it applies it to only one) - No jQuery please.

<div class="list-group">
   <a class="list-group-item" href="#">First item</a>
   <a class="list-group-item" href="#">Second item</a>
</div>
like image 591
rob.m Avatar asked Oct 03 '14 14:10

rob.m


People also ask

How do I add a class to a tag in wp nav menu?

Optionally, you may want to add the option to add classes to list items: function add_menu_list_item_class($classes, $item, $args) { if (property_exists($args, 'list_item_class')) { $classes[] = $args->list_item_class; } return $classes; } add_filter('nav_menu_css_class', 'add_menu_list_item_class', 1, 3);

How do I add a class to the menu anchor in WordPress?

Just add your classes into $menuClassMap values below. Show activity on this post. <? php // Show Menu here wp_nav_menu(array( 'theme_location' => 'my-menu', 'menu_class' => 'footer-top', 'add_a_class' => 'nav-link', )); ?>


4 Answers

Taking a hint from this answer which I found was the most concise about adding classes to the list items of the menus, I used nav_menu_link_attributes filter which does work well for adding classes.

In your functions.php, add:

function add_menu_link_class( $atts, $item, $args ) {
  if (property_exists($args, 'link_class')) {
    $atts['class'] = $args->link_class;
  }
  return $atts;
}
add_filter( 'nav_menu_link_attributes', 'add_menu_link_class', 1, 3 );

Optionally, you may want to add the option to add classes to list items:

function add_menu_list_item_class($classes, $item, $args) {
  if (property_exists($args, 'list_item_class')) {
      $classes[] = $args->list_item_class;
  }
  return $classes;
}
add_filter('nav_menu_css_class', 'add_menu_list_item_class', 1, 3);

Now, in your template, to build a menu you just add two new arguments, e.g.:

wp_nav_menu([
    'theme_location'=> 'primary_navigation',
    'menu_class'    => 'navbar-nav ml-auto flex-nowrap',
    'list_item_class'  => 'nav-item',
    'link_class'   => 'nav-link m-2 menu-item nav-active'
]);

Works well with themes with multiple menus which have different appearance.

like image 129
stol Avatar answered Oct 17 '22 16:10

stol


Thanks to Sergiu Paraschiv comment the issue was in regards of limiting to 1.

Therefore it should be in function.php:

function add_menuclass($ulclass) {
   return preg_replace('/<a /', '<a class="list-group-item"', $ulclass);
}
add_filter('wp_nav_menu','add_menuclass');

UPDATE

There is a better way actually which gives us much more control and the piece of code is provided by Jeff Starr on this post

NOTE: this isn't adding the current class tho

Create your menu on wp, then remember to click the location in the menu editor then in your function you'd do:

// custom menu example @ https://digwp.com/2011/11/html-formatting-custom-menus/
function clean_custom_menus() {
    $menu_name = 'nav-primary'; // specify custom menu name
    if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name])) {
        $menu = wp_get_nav_menu_object($locations[$menu_name]);
        $menu_items = wp_get_nav_menu_items($menu->term_id);

        $menu_list = '<nav>' ."\n";
        $menu_list .= "\t\t\t\t". '<ul>' ."\n";
        foreach ((array) $menu_items as $key => $menu_item) {
            $title = $menu_item->title;
            $url = $menu_item->url;
            $menu_list .= "\t\t\t\t\t". '<li><a href="'. $url .'">'. $title .'</a></li>' ."\n";
        }
        $menu_list .= "\t\t\t\t". '</ul>' ."\n";
        $menu_list .= "\t\t\t". '</nav>' ."\n";
    } else {
        // $menu_list = '<!-- no list defined -->';
    }
    echo $menu_list;
}

Finally we can call our menu:

<?php if (function_exists(clean_custom_menus())) clean_custom_menus(); ?>

The code above is taken from the post linked above, I thought to include this answer as it appears this question has many visits.

UPDATE 2

Another solution would be (maybe the best):

header.php:

    <?php
      wp_nav_menu( array(
        'theme_location'  => 'topnav',
        'menu'            =>'topnav',
        'container'       => 'div', 
        'container_class' => 'collapse navbar-collapse', 
        'container_id'    => 'navbarCollapse',
        'menu_class'      => 'menu', 
        'echo'            => true,
        'fallback_cb'     => 'wp_page_menu',
        'items_wrap'      => '<ul class="nav justify-content-end w-100 %2$s">%3$s</ul>',
        'depth'           => 0
      ) );
    ?>

function.php:

 // register the nav
 function register_my_menu() {
  register_nav_menu('topnav',__( 'topnav' ));
 }
 add_action( 'init', 'register_my_menu' );

// let's add "*active*" as a class to the li

add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class($classes, $item){
     if( in_array('current-menu-item', $classes) ){
             $classes[] = 'active ';
     }
     return $classes;
}

// let's add our custom class to the actual link tag    

function atg_menu_classes($classes, $item, $args) {
  if($args->theme_location == 'topnav') {
    $classes[] = 'nav-link';
  }
  return $classes;
}
add_filter('nav_menu_css_class', 'atg_menu_classes', 1, 3);

function add_menuclass($ulclass) {
   return preg_replace('/<a /', '<a class="nav-link"', $ulclass);
}
add_filter('wp_nav_menu','add_menuclass');
like image 42
rob.m Avatar answered Oct 17 '22 16:10

rob.m


I have solution to add class to anchor tag.

1: Step: add this in functions.php

function add_additional_class_on_a($classes, $item, $args)
{
    if (isset($args->add_a_class)) {
        $classes['class'] = $args->add_a_class;
    }
    return $classes;
}

add_filter('nav_menu_link_attributes', 'add_additional_class_on_a', 1, 3);

2: Then use it like this in your theme

<?php
        // Show Menu here
        wp_nav_menu(array(
            'theme_location' => 'my-footer-menu',
            'container_id'    => '',
            'menu_class'      => 'footer-top list-unstyled',
            'menu_id'         => '',
            'add_a_class'     => 'box-link text-dark',
        ));
?>
like image 4
Mohammad Ayoub Khan Avatar answered Oct 17 '22 18:10

Mohammad Ayoub Khan


I want add 'item' class to li should write this code:

add_filter('nav_menu_css_class' , 'nav_class' , 10 , 2);
function nav_class($classes, $item){
    $classes[] = 'item';
    return $classes;
}
like image 1
Omid Ahmadyani Avatar answered Oct 17 '22 18:10

Omid Ahmadyani