Добавление класса к определённой ссылке в пользовательском меню
Я знаю, что можно добавить класс в настройках пользовательского меню, но он добавляется к LI перед A. Я хочу применить класс непосредственно к этой конкретной A, а не ко всему LI.
То есть вместо такого вывода
<li id="menu-item-51" class="NEWCLASS menu-item menu-item-type-custom menu-item-51"><a href="#">Ссылка</a> </li>
Я хочу получить вот такой.
<li id="menu-item-51" class="menu-item menu-item-type-custom menu-item-51"><a href="#" class="NEWCLASS">Ссылка</a></li>
Есть идеи?

вы можете использовать фильтр nav_menu_css_class
add_filter('nav_menu_css_class' , 'my_nav_special_class' , 10 , 2);
function my_nav_special_class($classes, $item){
if(your condition){ //пример: вы можете проверить значение $item для принятия решения...
$classes[] = 'my_class';
}
return $classes;
}
Используя $item вы можете задать любое условие. Это добавит класс к конкретному li, и вы сможете стилизовать тег a на его основе следующим образом:
.my_class a{
background-color: #FFFFFF;
}

Я нашел решение на этом сайте через использование пользовательского walker.
Два шага: заменить стандартный код wp_nav_menu на измененный, а затем добавить код в functions.php темы.
Сначала замените стандартный wp_nav_code следующим (код скопирован с указанного выше сайта):
wp_nav_menu( array(
'menu' => 'Main Menu',
'container' => false,
'menu_class' => 'nav',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'depth' => 0,
'walker' => new description_walker())
);
Затем добавьте следующий код в 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 ) .'"' : '';
$prepend = '<strong>';
$append = '</strong>';
$description = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';
if($depth != 0)
{
$description = $append = $prepend = "";
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
$item_output .= $description.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
if ($item->menu_order == 1) {
$classes[] = 'first';
}
}
}
В конце кода есть несколько строк, начинающихся с $item_output. В частности, обратите внимание на этот фрагмент:
$item_output .= '<a'. $attributes .'>';
Поскольку эта строка определяет вывод HTML для начала ссылки. Если изменить её на что-то вроде этого:
$item_output .= '<a'. $attributes . 'class="abc"' .'>';
То ко всем ссылкам в меню будет добавлен class="abc".
Тем не менее, это не позволяет задать пользовательский класс для каждой ссылки (или, по крайней мере, я не знаю, как это закодировать). Это проблема для меня.
Для тех, кто спрашивает зачем это нужно? Я хочу, чтобы ссылки моего меню открывали лайтбоксы (точнее, colorbox), а для этого требуются классы на ссылках. Например:
<a class="lightbox1" href="#">Photo</a>
Есть ли возможность динамически генерировать классы, такие как "lightbox1" для первой ссылки, "lightbox2" для второй и так далее?

@Rainman ваш ответ мне немного помог, и вы задали хороший вопрос. Уверен, вы уже нашли лучшее решение, но для тех, кто еще не нашел, я использовал модифицированную версию решения, описанного здесь: http://www.wpbeginner.com/wp-themes/how-to-add-custom-items-to-specific-wordpress-menus/

РЕШЕНО!!!! Мне нужно было разобраться, как сделать пункт меню ссылкой на встроенный HTML в fancybox. Вставьте следующий код в файл function.php вашей темы:
function add_menuclass($ulclass) {
return preg_replace('/<a rel="fancybox"/', '<a class="fancybox"', $ulclass, -1);
}
add_filter('wp_nav_menu','add_menuclass');
Затем... в разделе "Меню" админ-панели WordPress создайте пользовательскую ссылку и добавьте её в меню. В верхней части, где написано "Настройки экрана", убедитесь, что у вас отмечен пункт "Связь ссылки (XFN)". Это добавит соответствующее поле к вашему пункту меню. Введите "fancybox" (без кавычек) в это поле и сохраните меню.
Функция ищет вызов навигационного меню, затем находит все места, где у вас есть rel="fancybox"
, и заменяет их на rel="fancybox" class="fancybox"
. Вы можете заменить fancybox на любой класс, который нужно добавить к пунктам меню. Готово!

Отличный пост!! Только одна деталь. Код не будет работать, если кто-то добавит заголовок. Я столкнулся с той же проблемой... Поэтому я просто убрал тег A из начала обоих значений замены. Оставив что-то вроде этого... return preg_replace('/rel="fancybox"/', 'class="fancybox"', $ulclass, -1); Код отлично работает!

Текущие ответы, похоже, не учитывают, что вопрос заключается в том, как добавить класс к элементу a
, а не к li
, или являются слишком сложными. Вот простой подход с использованием фильтра nav_menu_link_attributes
, который позволяет вам нацелиться на конкретное меню по его slug и конкретную ссылку в этом меню по её ID. Вы можете использовать var_dump для $args и $item, чтобы получить больше способов создания вашего условия.
add_filter('nav_menu_link_attributes', 'custom_nav_menu_link_attributes', 10, 4);
function custom_nav_menu_link_attributes($atts, $item, $args, $depth){
if ($args->menu->slug == 'your-menu-slug' && $item->ID == 1){
$class = "button";
// Убедитесь, что не перезаписываете существующие классы
$atts['class'] = (!empty($atts['class'])) ? $atts['class'].' '.$class : $class;
}
return $atts;
}

Недавно мне пришлось делать нечто подобное, и я нашел другой способ решения. Мне нужно было добавить аналогичный класс для плагина Nivo lightbox. Я добавил "nivo" в атрибут rel ("Link Relationship (XFN)") и затем использовал следующий фильтр nav_menu_link_attributes
.
function add_nivo_menuclass($atts, $item, $args) {
if( is_array($atts) && !empty($atts['rel']) && $atts['rel'] = 'nivo' ) {
$atts['class'] = 'lightbox';
$atts['data-lightbox-type'] = 'inline';
}
return $atts;
}
add_filter('nav_menu_link_attributes','add_nivo_menuclass', 0,3);
