WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Как добавить класс родительскому элементу который содержит субменю?

Как добавить класс родительскому элементу списка, который содержит вложенный список (субменю), например:

<ul class="main-menu">
	<li class="main-menu__item">
		<a class="main-menu__link" href="#">Ссылка</a>
	</li>
	<li class="main-menu__item main-menu__item--dropdown">
		<span>Меню с выпадашкой</span>
		<ul class="main-menu main-menu--nested">
			<li class="main-menu__item">
				<a class="main-menu_link" href="#">Элемент субменю</a>
			</li>
		</ul>
	</li>
</ul>

Нужная структура меню выводится через фильтры кроме класса для родительского элемента меню main-menu__item--dropdown.
И хотел бы еще спросить как решается проблема со ссылками, которые просто являются разделителями? по идее было бы правильно вместо

<a href="#">разделитель для субменю</a>

выводить

<span>разделитель для субменю</span>

Просьба помочь с кодом, перегуглил почти все адекватного решения кроме как вот этот код не нашел

add_filter( 'nav_menu_css_class', 'check_for_submenu', 10, 2);
function check_for_submenu($classes, $item) {
	global $wpdb;
	$has_children = $wpdb->get_var("SELECT COUNT(meta_id) FROM wp_postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value='".$item->ID."'");
	if ($has_children > 0) array_push($classes,'dropdown'); // add the class dropdown to the current list
	return $classes;
}

но у меня сайты работают в режиме мультисайт, все это чудо работает только на главном домене а на поддоменах классы не раздаются.

0
Merkif
1 месяц назад
  • 1
    Andrew475 america-xix.ru

    в массиве $class, отправляемом в вашу функцию, содержатся все классы, которые WordPress по умолчанию добавляет к элементу меню. В том числе там должен быть класс menu-item-has-children, который указывает на то, что элемент - родитель.

    В функцию можно также отправить третий параметр $args, который содержит всю информацию по меню. Эта информация может пригодится для чего-нибудь. Только не забудьте поменять 2 на 3 в add_filter.

    И хотел бы еще спросить как решается проблема со ссылками, которые просто являются разделителями?

    извините, я только спросить - а зачем использовать пустые теги a в качестве разделителя?

    Merkif 1 месяц назад

    Я не очень силен php, тем более в ЯП, первый раз делаю тему для вп)) по этому я не очень понимаю что вы написали, я нужную разметку сделал фильтрами, как раз на сайте было видео как это сделать, но я кажется перебил все классы, по этому кроме того что я вывожу больше ничего не выводится, и на счет вопроса, я наверное не совсем понял ваш вопрос, но есть такие пункты меню, которые содержат в себе подменю но при этом родительский пункт не является ссылкой, я делал это через произвольную ссылку а потом кидал необходимые ссылки в меню второго уровня этой произвольной ссылки, главная цель ссылки это вести куда то но в случае разделителя оно никуда не ведет, по этому было бы правильно если пункт меню не ссылка а просто текст выводить текст в span-е, ну это сугубо мое мнение, если еще раздать табиндексы спанам будет работать навигация с клавиатуры.

    Andrew 1 месяц назад

    я нужную разметку сделал фильтрами,

    я так понимаю, меню сделано по примеру Дмитрия (campusboy)

    вариант решения №1, при сохранении "БЭМ методологии" из примера: перед тем, как сбросить значение переменной $class узнать, есть ли в этом массиве элемент 'menu-item-has-children'. Если есть, то добавить класс с dropdown. Т.е. сделать что-то подобное:

    add_filter( 'nav_menu_css_class', 'filter_nav_menu_css_classes', 10, 4 );
    function filter_nav_menu_css_classes( $classes, $item, $args, $depth ) {
    	if (in_array('menu-item-has-children', $classes)) {
    		$dropdown = true;
    	}
    
    	if ( $args->theme_location === 'header-menu' ) {
    		$classes = [
    			'menu-node',
    			'menu-node--main_lvl_' . ( $depth + 1 )
    		];
    
    		if ( $item->current ) {
    			$classes[] = 'menu-node--active';
    		}
    	}
    
    if ($dropdown) {
    		$classes[] = 'main-menu__item--dropdown';
    }
    	return $classes;
    }

    вариант решения №2: выключить все фильтры и пользоваться теми классами, которые раздает элементам WP.

    вариант решения №3, если хочется совсем-совсем собственную разметку меню: использовать кастомный walker для меню (класс, расширяющий/изменяющий работу стандартного класса Walker_Nav_Menu{}). См. Пример #8 в описании функции wp_nav_menu().

    Пользуясь кастомным обходчиком создания меню, с элементами меню можно делать всё, что угодно - добавлять классы, менять разметку, пропускать элементы по условию и так далее.

    такие пункты меню, которые содержат в себе подменю но при этом родительский пункт не является ссылкой

    понятно.

    Решение №1: При использовании кастомного обходчика - поймать по условию нужный элемент и изменить его разметку.

    Решение №2: При использовании стандартного обходчика - не выводить меню на экран, а сохранять в переменную (в массиве параметров функции wp_nav_menu() передать параметр "echo" => false).

    Далее, при помощи регулярного выражения и функции preg_replace() заменить тег a на тег span.

    Получившееся меню вывести на экран.

    Merkif 1 месяц назад

    Спасибо большое за подробное разъяснениеsmile

    Комментировать
  • 1
    el-lable465 el-lable.ru

    Сделайте это на JS

    jQuery(function($){
    
    	$('.maim-menu > li:has(ul)').addClass('menu__item--dropdown');
    	$('ul[class*="menu"] a[href="#"]').each(function(){
    		$(this).replaceWith($('<span>').text($(this).text()));
    	});
    
    });
    Merkif 1 месяц назад

    Спасибо большое за код, на самом деле я так и поступил через js раздал классы, но хотелось бы рассмотреть еще и вариант когда у клиента будет отключён js, конечно можно и без этих классов все сделать, но все лежит на проде, переписывать стили и прочее было бы муторно.

    el-lable 1 месяц назад

    Сайты с отключенным джаваскриптом канули в летах. Такое перестали учитывать в 2015 году.

    Merkif 1 месяц назад

    Не спорю ситуации бывают разные, но например может быть такое что из-за слабого интернета не загрузится js, или где-нибудь в метро, без js можно хотя бы перейти на нужную страницу. На счет этого спорить можно бесконечно по правде, вам спасибо что откликнулись.

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Вход . Регистрация