Отображение конкретного пункта меню из wp_nav_menu по ID
У меня есть меню wp_nav_menu "Main Menu" следующей структуры:
- Первый уровень (#menu-item-1)
- Подпункт
- Подпункт
- Первый уровень (#menu-item-2)
- Подпункт
- Первый уровень (#menu-item-3)
- Подпункт A
- Подпункт B
- Подпункт a.1
- Подпункт C
В моем шаблоне мне нужно выводить подпункты меню Main Menu для определенного пункта верхнего уровня, например, для пункта с id menu-item-3, где menu-item-3 является текущим верхним пунктом меню.
Что-то вроде такого: (но чтобы это реально работало)
wp_nav_menu( array('menu' => 'Main Menu', 'menu-item-id' => '3' ));
И это должно возвращать:
- Подпункт A
- Подпункт B
- Подпункт a.1
- Подпункт C
Если это важно - мне нужно показывать подпункты как внутреннее боковое меню в зависимости от того, в каком разделе основного меню находится пользователь.
Важно: это не дубликат вопроса "http://wordpress.stackexchange.com/questions/2802/display-a-portion-branch-of-the-menu-tree-using-wp-nav-menu". Хотя на той странице есть несколько похожих ответов, ни один из них не работает должным образом с текущей версией WordPress. Речь идет о показе конкретного подпункта меню и всех его дочерних элементов (с неограниченной вложенностью).

Если я правильно понимаю, что вам нужно, это можно сделать с помощью CSS. Вы вызовете wp_nav_menu как обычно, чтобы сгенерировать все ссылки, но затем скроете все, кроме подменю текущей страницы.
Ваш CSS будет выглядеть примерно так:
#sidebar ul.menu li
{
display: none;
}
#sidebar ul.menu li.current-page-parent,
#sidebar ul.menu li.current-page-parent ul,
#sidebar ul.menu li.current-page-parent ul.li
{
display: block;
}
Обновление: Вы можете посмотреть пример на http://thataboycreative.com, где я использовал этот подход. Вот соответствующий CSS из того примера:
ul.sub-menu
{
display: none;
}
#menu-main-navigation > li.current-menu-item ul.sub-menu,
#menu-main-navigation > li.current-menu-ancestor ul.sub-menu
{
display: block;
}

@Ian Это не работает. Я раньше не видел, чтобы использовался "current-page-parent". Насколько я знаю, WordPress генерирует "current-menu-item" и "current_page_item". Но даже используя их, это не срабатывает и просто скрывает всё меню. Вы успешно применяли такой подход на каком-то сайте, на который можно сослаться?

current-page-parent тоже существует, но, возможно, только в некоторых версиях. WordPress не был очень последовательным в именовании классов. Я отредактирую ответ, чтобы показать пример, где я это делал раньше.

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

На самом деле, я не думаю, что это так, потому что WordPress кэширует чтение из базы данных. Поэтому, если вы уже вызывали wp_nav_menu() один раз для вашего основного меню, повторный вызов для вторичной навигации не приведет ко второму запросу к базе данных.

@Ian, это хорошее замечание, если предположить, что так оно и работает.

Я создал плагин для этого - убедитесь, что передаете ID как СТРОКУ, а не как число. Пожалуйста, оцените мой плагин - это мой первый плагин! :)

Другой способ, который я использовал - это прямое получение записей вместо использования wp_nav_menu. Однако это основано на фактической структуре страниц, а не на меню.
functions.php:
function __construct()
{
$this->currentPageID = $this->getCurrentPageID();
$this->sectionChildren = $this->getSectionChildren();
}
// Получаем ID текущей страницы
function getCurrentPageID()
{
$currentPage = $_SERVER['REQUEST_URI'];
if($currentPage == '/')
$currentPage = '/home';
$currentPage = get_page_by_path($currentPage);
if($currentPage)
return $currentPage->ID;
else
return -1;
}
// Получаем ID раздела
function getSectionID()
{
global $wpdb;
$currentSectionID = $wpdb->get_var("
SELECT post_parent
FROM ". $wpdb->posts ."
WHERE ID = ". $this->currentPageID
);
if($currentSectionID == 0)
return $this->currentPageID;
else
return $currentSectionID;
}
// Получаем дочерние элементы раздела
function getSectionChildren()
{
global $wpdb;
$children = $wpdb->get_results("
SELECT ID, post_title
FROM ". $wpdb->posts ."
WHERE
post_parent = ". $this->getSectionID() ." AND
post_type = 'page' AND
post_status = 'publish'
", ARRAY_A);
return $children;
}
sidebar.php:
<ul id="sub-navigation">
<?php foreach($dc->sectionChildren as $c) : ?>
<li <?php if($dc->currentPageID == $c['ID']) echo 'class="active"'; ?>><a href="<?php echo get_permalink($c['ID']); ?>"><?php echo $c['post_title']; ?></a></li>
<?php endforeach; ?>
</ul>

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