Есть сайт на WordPress, где в тему хочу добавить bootstrap
меню с выпадающим списком при наведении. Регистрирую меню стандартным способом:
<?php
register_nav_menus(array(
'top' => 'Верхнее меню'
));
wp_nav_menu( array(
'container' => 'div',
'container_class' => 'collapse navbar-collapse navbar-ex1-collapse',
'menu_class'=>'nav navbar-nav navbar-right',
'theme_location'=>'top'
) );
?>
Затем хочу перенести в него функционал этого меню, но есть проблемы с добавлением в ссылку классов class="dropdown-toggle"
атрибутов data-toggle="dropdown"
и во внутренний список ul
класса dropdown-menu
. Как это можно сделать? фидл
.dropdown:hover > .dropdown-menu {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.css" rel="stylesheet">
<nav class="navbar navbar-default navbar-static">
<div class="container-fluid">
<div class="navbar-header">
<button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".js-navbar">
<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="#" style="padding:15px 15px;">Название проекта</a>
</div>
<div class="collapse navbar-collapse js-navbar">
<ul class="nav navbar-nav">
<li><a href="#">Главная</a>
</li>
<li class="dropdown">
<a id="drop1" href="#" class="dropdown-toggle" data-toggle="dropdown">
Меню
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">Текст подпункта</a>
</li>
<li><a href="#">Текст подпункта</a>
</li>
<li class="divider"></li>
<li><a href="#">Текст подпункта</a>
</li>
</ul>
</li>
<li class="dropdown">
<a id="drop1" href="#" class="dropdown-toggle" data-toggle="dropdown">
Меню
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">Текст подпункта</a>
</li>
<li><a href="#">Текст подпункта</a>
</li>
<li class="divider"></li>
<li><a href="#">Текст подпункта</a>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a id="drop1" href="#" class="dropdown-toggle" data-toggle="dropdown">
Меню
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#">Текст подпункта</a>
</li>
<li><a href="#">Текст подпункта</a>
</li>
<li class="divider"></li>
<li><a href="#">Текст подпункта</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
Нужно использовать класс Walker
, следующий код при добавлении в function.php
, добавляет нужные классы к пунктам меню и ссылкам внутри него, при этом стандартные классы меню wordpress не выводятся.
class mainMenuWalker extends Walker_Nav_Menu {
function start_el(&$output, $item, $depth, $args) {
// назначаем классы li-элементу и выводим его
$class_names = ' class="main-menu_item"';
$output.= '<li' .$class_names. '>';
// назначаем атрибуты a-элементу
$attributes.= !empty( $item->url ) ? ' href="' .esc_attr($item->url). '" class="main-menu_link" ' : '';
$item_output = $args->before;
// проверяем, на какой странице мы находимся
$current_url = (is_ssl()?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$item_url = esc_attr( $item->url );
$item_output.= '<a'. $attributes .'>'.$item->title.'</a>';
// заканчиваем вывод элемента
$item_output.= $args->after;
$output.= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
И в шаблоне где выводиться меню, выводим его следующим образом:
<?php $main_menu = new mainMenuWalker (); ?>
<?php wp_nav_menu(array(
'theme_location' => 'header_menu',
'container' => 'nav',
'container_class' => 'main-menu',
'menu_class' => 'main-menu_list',
'menu_id' => 'menu-header',
'walker' => $main_menu
)); ?>
В этом варианте конечно классы добавляются напрямую, без использования массива classes
и у вложенного меню у тега ul
генерируется дефолтный класс sub-menu
.
Если же необходим более тонкий контроль, то еще немного расширим класс Walker
:
class mainMenuWalker extends Walker_Nav_Menu {
//для начала зададим класс для вложенного пункта меню тегу ul
//функция start_lvl формирует превую строчку в шаблоне вывода списка, это нам и нужно.
function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<ul class=\"my-class\">\n";// указываем нужный нам класс, теперь все вложенные теги ul будут иметь указанный класс.
}
// если необходимо обозначить тег li, что он является родительским элементом вложенного списка модифицируем немного функцию display_element.
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
//получим id элемента пункта меню
$parent_elem = $this->db_fields['id'];
// проверим есть ли в нем вложенный список
if ( !empty( $children_elements[ $element->$parent_elem ] ) ) {
// запишем в массив classes необходимый нам класс и присвоим элементу списка
$element->classes['parent_class'] = 'parent-item';
}
Walker_Nav_Menu::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
//Ну а здесь уже приведем в нужный нам вид классы li элемента
function start_el(&$output, $item, $depth, $args) {
// назначаем классы li-элементу и выводим его
//для этого добавим наш класс в массив classes
$item->classes['my_class'] = 'main-menu_item';
// и напрямую укажем какие классы из массива мы хотим использовать.
$class_names = ' class="' .esc_attr( $item->classes['my_class'] .' '. $item->classes['parent_class'] ). '"';
$output.= '<li ' .$class_names. '>';
// назначаем атрибуты a-элементу
$attributes.= !empty( $item->url ) ? ' href="' .esc_attr($item->url). '" class="main-menu_link" ' : '';
$item_output = $args->before;
// проверяем, на какой странице мы находимся
$current_url = (is_ssl()?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$item_url = esc_attr( $item->url );
$item_output.= '<a'. $attributes .'>'.$item->title.'</a>';
// заканчиваем вывод элемента
$item_output.= $args->after;
$output.= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
PS
Eсли хотим использовать все классы и дефолтные, указываем просто массив $item->classes
тогда строка будет иметь вид:
$class_names = join( ' ', $item->classes );
$class_names = ' class="' .esc_attr( $class_names ). '"';
$output.= '<li id="menu-item-' . $item->ID . '"' .$class_names. '>';
Можно воспользоваться фильтрами и отсортировать классы так как нам нужно
Несколько ссылок по теме:
Может оказаться полезной
Кодекс (англ)
wp-кама
еще статья из wp-кама
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Стоит следующая задача, может кто направит на путь истинный :) Есть магазин, который работает в оффлайнеБудет разрабатываться интернет-магазин
Выдает: что "Регистрация не удалась" и на базу данных ничего не приходит, в чем мб ошибка?
Вообщем такое дело, решил потренироваться в traits и заодно избавится от одного расширения для сохранения картинок и в итоге написал такой код:
html_entity_decode возвращает строку в p, а мне нужно чтобы она не была обернута в тэг pКак можно это сделать? Потому как хочу на этот