Стандартная навигация Bootstrap имеет замысловатую разметку, что не позволяет изпользовать ее при создании меню в WordPress с помощью функции wp_nav_menu()
, но эту проблему можно решить с помощью нестандартного Walker
и нескольких фильтров.
Задача
Главная задача – повторить стандартную разметку NavBar с помощью wp_nav_menu()
. Выглядит она вот так:
<nav class="navbar navbar-default" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li><a href="#">Separated link</a></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </nav>
Собственно, только элемент <ul class="nav navbar-nav">...</ul>
будет заменен функцией wp_nav_menu().
А значит получим такую конечную разметку:
<nav id="nav" class="navbar navbar-default" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header visible-xs"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Kawaii Walls</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse navbar-ex1-collapse"> <?php wp_nav_menu(array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'items_wrap' => '<ul id="%1$s" class="%2$s nav navbar-nav">%3$s</ul>', 'walker' => new Bootstrap_Walker_Nav_Menu, )); ?> </div><!-- /.navbar-collapse --> </nav>
Стоить заметить, что вам заранее нужно разрешить использование меню в WordPress теме и зарегистрировать новое меню, прикрепив его к позиции primary
.
Решение
Создаем свой нестандартный Walker. Это такой класс, который позволяет особым образом вывести стандартное меню в WordPress.
class Bootstrap_Walker_Nav_Menu extends Walker_Nav_Menu { /** * Display Element */ function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { $id_field = $this->db_fields['id']; if ( isset( $args[0] ) && is_object( $args[0] ) ) { $args[0]->has_children = ! empty( $children_elements[$element->$id_field] ); } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } /** * Start Element */ function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { if ( is_object($args) && !empty($args->has_children) ) { $link_after = $args->link_after; $args->link_after = ' <b class="caret"></b>'; } parent::start_el($output, $item, $depth, $args, $id); if ( is_object($args) && !empty($args->has_children) ) $args->link_after = $link_after; } /** * Start Level */ function start_lvl( &$output, $depth = 0, $args = array() ) { $indent = str_repeat("t", $depth); $output .= "\n$indent<ul class=\"dropdown-menu list-unstyled\">\n"; } }
Таким образом мы немного кастомизировали вывод меню, чтобы оно подходило для Bootstrap.
Последним шагом остается обеспечить возможность работы вложенных меню. Делается это с помощью следующего фильтра:
add_filter('nav_menu_link_attributes', function($atts, $item, $args) { if ( $args->has_children ) { $atts['data-toggle'] = 'dropdown'; $atts['class'] = 'dropdown-toggle'; } return $atts; }, 10, 3);
Обратите внимание, что тут используется анонимная функция. Это не будет работать на сервере со старой версией PHP.
Нашли ошибку или возник вопрос – пишите в комментариях.