Поставил себе задачу сделать простейшее горизонтальное выпадающее меню исключительно с помощью css стилей, связываться с плагинами равно как и с jQuery не хотелось, чтобы не усложнять себе задачу и облегчить максимально мою тему Golden ratio.
Сразу как-то не заладилось у меня с css, разработчики WordPress добавили все мыслимые классы в меню, но самое главное естественно забыли: во первых отметить элемент li, который имеет потомков добавив ему класс parent, во вторых просто прописать уровень вложенности меню depth0, depth1, depth2 …
Но не тут то было. Нам оставили возможность подключить фильтр strong>nav_menu_css_class и добавить для каждого элемента свой нужный нам класс, но и тут полный облом – в этот фильтр передаются массив уже присвоенных классов и сам элемент однако толку от этого элемента = 0 . В отрыве от общей структуры меню ничего неизвестно ни о его потомках ни об уровне элемента. Рассчитывать все эти данные самостоятельно имея в наличии только id элемента – себе дороже будет. Кстати просматривая коды всех эти Walker_Nav_Menu, Walke создается впечатление что разработчики ну просто забыли добавить столь нужные классы ведь вот, вот они эти данные прямо тут, рукой достать можно и не надо ничего вычислять лишнего – глубина постоянно передается из одной функции в другую, но почему-то только не в фильтр nav_menu_css_class, примерно тоже самое и с массивом потомков. Эх ладно, быть может я вижу вообще все в неправильном CSS?
Далее описываю свой способ извращения.
Задача:
добавить для каждого элемента li из горизонтального меню классы –
parent – для тех ли у которых есть подменю
depthX – глубина, где X уровень вложения
Решение:
В function.php вашей темы добавляем:
class DD_Walker_Menu extends Walker_Nav_Menu { function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } class DD_Walker_Page extends Walker_Nav_Menu { var $db_fields = array (‘parent’ => ‘post_parent’, ‘id’ => ‘ID’); function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; $element->attr_title = $element->title = $element->post_title; $element->url = get_page_link($element->ID); parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } add_filter(‘nav_menu_css_class’,’add_parent_css’,10,2); function add_parent_css($classes, $item){ global $dd_depth, $dd_children; $classes[] = ‘depth’.$dd_depth; if($dd_children) $classes[] = ‘parent’; return $classes; }
123456789101112131415161718192021222324252627 | class DD_Walker_Menu extends Walker_Nav_Menu { function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); }} class DD_Walker_Page extends Walker_Nav_Menu { var $db_fields = array (‘parent’ => ‘post_parent’, ‘id’ => ‘ID’); function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){ $GLOBALS[‘dd_children’] = ( isset($children_elements[$element->ID]) )? 1:0; $GLOBALS[‘dd_depth’] = (int) $depth; $element->attr_title = $element->title = $element->post_title; $element->url = get_page_link($element->ID); parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); }}add_filter(‘nav_menu_css_class’,‘add_parent_css’,10,2);function add_parent_css($classes, $item){ global $dd_depth, $dd_children; $classes[] = ‘depth’.$dd_depth; if($dd_children) $classes[] = ‘parent’; return $classes;} |
Теперь печатем меню в header.php
<ul id=»headermenu»> <?php if(has_nav_menu( ‘header-menu’ )){ wp_nav_menu( array( ‘container_class’ => », ‘items_wrap’ => ‘%3$s’ , ‘container’ => », ‘menu’ => ‘header-menu’, ‘walker’=> new DD_Walker_Menu ) ); } else{ wp_list_pages(array(‘title_li’=>», ‘walker’=> new DD_Walker_Page )); } ?> </ul>
1234567891011 | <ul id=«headermenu»> <?php if(has_nav_menu( ‘header-menu’ )){ wp_nav_menu( array( ‘container_class’ => », ‘items_wrap’ => ‘%3$s’ , ‘container’ => », ‘menu’ => ‘header-menu’, ‘walker’=> new DD_Walker_Menu ) ); } else{ wp_list_pages(array(‘title_li’=>», ‘walker’=> new DD_Walker_Page )); } ?></ul> |
Проверяем если меню задано пользователем выводим его если нет выводим список страниц.
Обратите внимание подставляется новый обработчик Walker !
Примерный css код может быть такой
#headermenu{ /*background-color: #EEEEEE; */ text-align: right; padding:0 1.618em 0 0.618em; font-family: Tahoma; background-color: #F7F7F7; margin: 0 1.38em 0; padding: 0; } #headermenu> li{ display: inline; margin-left: 1.618em; } #headermenu li{ list-style: none; } #headermenu li a{ text-decoration: none; font-size: 1em; font-family: ‘Lato’,Helvetica,Arial,sans-serif ; letter-spacing: normal; white-space:nowrap; } #headermenu li.parent::after{ content:’»’; } #headermenu .sub-menu{ display: none; position: absolute; margin: 1.2em 0 0 -4em; padding: 0.6em; background-color: #fff; text-align: left; font-size: 0.9em; } #headermenu li.parent:hover::after{ content:’«’; } #headermenu li:hover>.sub-menu{ display: inline; border: solid 1px #BBBBBB; z-index: +1; }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | #headermenu{ /*background-color: #EEEEEE; */ text-align: right; padding:0 1.618em 0 0.618em; font-family: Tahoma; background-color: #F7F7F7; margin: 0 1.38em 0; padding: 0;}#headermenu> li{ display: inline; margin-left: 1.618em;}#headermenu li{ list-style: none;}#headermenu li a{ text-decoration: none; font-size: 1em; font-family: ‘Lato’,Helvetica,Arial,sans-serif ; letter-spacing: normal; white-space:nowrap;} #headermenu li.parent::after{ content:‘»’;} #headermenu .sub-menu{ display: none; position: absolute; margin: 1.2em 0 0 -4em; padding: 0.6em; background-color: #fff; text-align: left; font-size: 0.9em;}#headermenu li.parent:hover::after{ content:‘«’;} #headermenu li:hover>.sub-menu{ display: inline; border: solid 1px #BBBBBB; z-index: +1;} |
#menu-header-menu – корневой элемент ul вашего меню если что помень его на свой
Гребаный IE! есесено все покажет по своему – псевдо класс after эта гадина игнорирует и придется родительские пункты обозначить просто жирным шрифтом:
#headermenu li.parent>a{ font-weight: bold; }
123 | #headermenu li.parent>a{ font-weight: bold;} |