Разметка WordPress-меню по БЭМ с помощью волкера
Я верстаю по методологии БЭМ и при разработке WordPress-шаблонов стараюсь там, где это возможно, привести к соответствующему виду встроенные в WordPress CSS-классы.
Стандартное меню WordPress выводится функцией wp_nav_menu()
, и есть возможность его модифицировать с помощью волкера, что я, собственно, и сделал.
Далее в примерах будет использоваться БЭМ-блок с именем nav
.
Особенности
- За основу взят волкер Walker_Nav_Menu, расположенный в файле /wp-includes/class-walker-nav-menu.php.
- CSS-классы, добавленные при редактировании меню в админке в поле “Классы CSS”, становятся модификаторами. Например, если вы указали через пробел два класса: “mod-1 mod-2”, будут добавлены модификаторы
nav__item--mod-1
иnav__item--mod-2
. - У ссылки текущей страницы удаляется атрибут href и добавляется класс
nav__item--active
. - Для пункта-родителя добавляется класс
.nav__item--active-parent
. - Для пункта, являющегося предком среди родительских пунктов, добавляется класс
.nav__item--active-ancestor
. - Для списков 2-го и далее уровней вложенности добавляется класс
nav__sub-menu
и модификатор видаnav__sub-menu--level-1
, показывающий уровень вложенности.
Как это выглядит в коде
PHP-код для вывода меню в шаблоне:
wp_nav_menu( [
'theme_location' => 'header-nav',
'depth' => 1,
'container' => false,
'fallback_cb' => false,
'echo' => true,
'walker' => new BEM_Walker_Nav_Menu(),
'bem_block' => 'nav',
'items_wrap' => '
<nav class="nav">
<ul class="nav__list">%3$s</ul>
</nav>
',
] );
Здесь важны два параметра:
- walker – подключает соответствующий волкер;
- bem_block – содержит имя блока.
В результате получится примерно следующая структура HTML-кода:
<nav class="nav">
<ul class="nav__list">
<li class="nav__item">
<a class="nav__link" href="#">Пункт 1</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#">Пункт 2</a>
<ul class="nav__sub-menu nav__sub-menu--level-1">
<li class="nav__item">
<a class="nav__link" href="#">Подпункт 1</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#">Подпункт 2</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#">Подпункт 3</a>
</li>
</ul>
</li>
<li class="nav__item">
<a class="nav__link" href="#">Пункт 3</a>
</li>
</ul>
</nav>
Скачать
BEM_Walker_Nav_Menu.zip
Загрузок: 631 | Размер: 2 Кб
Подключение
- Поместите файл BEM_Walker_Nav_Menu.php, находящийся в скачанном архиве, в папку с шаблоном, например, сюда: includes/BEM_Walker_Nav_Menu.php.
-
Подключите его в файле functions.php следующей строкой:
require_once 'includes/BEM_Walker_Nav_Menu.php';
- Используйте параметры
walker
иbem_block
в функцииwp_nav_menu()
, как указано выше.
Комментарии (7)
С возвращением!!!
Здравствуйте! Я воспользовался вашим walker`ом, но возникла проблема. Как сделать так , что бы класс __sub-menu на более глубоких уровнях менялся на другой, а то получается он на всех уровнях и на втором и на третьем и т.д? С уважением Кирилл.
Например, заменив эту строку:
кодом:
Пример показан для 1-го и 2-го уровня вложенности. По аналогии можно сделать для любого уровня.
Гратс. Спасибо. Немного подстроил под себя. Отличное решение!
А именно, пришлось добавить вывод отдельного класса для LI у которого есть дочерний элемент. Ну и свои классы прописал еще)
В debug.log ошибка спамится постоянно
Подскажите, плиз, как решить.
Сорри, забыл приложить ошибку, а сайт не дает второй коммент отправить ни текущий отредактировать :)
PHP Notice: Trying to get property ‘cat_ID’ of non-object in BEM_Walker_Nav_Menu.php on line 66
PHP Notice: Undefined offset: 0 in BEM_Walker_Nav_Menu.php on line 66
Попробуйте заменить эту часть кода:
на такую:
У меня проблема не воспроизводится, поэтому не могу протестировать.