Показ только одного уровня дочерних страниц, проблема с wp_list_pages
Я работаю над сайтом, который имеет довольно большую структуру страниц в несколько уровней глубины - в некоторых разделах много страниц.
Базовая структура выглядит примерно так...
Родитель Родитель Родитель -Ребенок -Ребенок --Внук --Внук --Внук ---Правнук -Ребенок -Ребенок --Внук --Внук --Внук ---Правнук -Ребенок Родитель -Ребенок Родитель Родитель -Ребенок -Ребенок --Внук ---Правнук --Внук
Вы понимаете картину - представьте еще больше страниц!
Мое обычное решение с подменю обычно работает нормально (взято прямо из Codex), потому что я работаю с гораздо меньшими сайтами. На этом сайте получается огромное длинное меню, которое слишком велико, чтобы быть полезным.
Я хотел бы показывать только уровень непосредственно под просматриваемой страницей. По сути, меню "В этом разделе...".
Какую бы комбинацию wp_list_pages я ни пробовал, я мог получить только все или ничего.
Также, поскольку есть разделы без дочерних элементов, нужно показывать ссылки верхнего уровня, когда дочерних элементов нет.
Надеюсь, это имеет смысл - я весь день ломаю голову над этим! Буду благодарен за любую помощь!
РЕДАКТИРОВАНИЕ
Хорошо, добавлю здесь. Извините за мою неопытность!
Огромное спасибо @chip-bennet за то, что довел меня до этого момента!
Теперь у меня есть код, который делает почти все, что мне нужно.
$output = wp_list_pages('echo=0&depth=1&title_li=Sections' );
if (is_page( )) {
$page = $post->ID;
if ($post->post_parent) {
$page = $post->post_parent;
}
$children=wp_list_pages( 'echo=0&child_of=' . $page . '&title_li=' );
if ($children) {
$output = wp_list_pages( array(
// Только страницы, которые являются дочерними для текущей страницы
'child_of' => $post->ID,
// Показывать только один уровень иерархии
'depth' => 1,
'title_li' => 'В этом разделе'
) );
}
}
echo $output;
Это работает именно так, как я хочу, пока не дойду до конца дерева, когда он ничего не выводит.
Chip дал мне код снова для показа соседних страниц вместо поиска дочерних элементов - однако из-за моего недостатка навыков PHP я испытываю трудности с добавлением его в этот код.

Это должно работать, используя только доступные параметры массива аргументов для wp_list_pages()
: конкретно, depth
и child_of
.
Для отображения одного уровня иерархии для дочерних страниц текущей страницы:
<?php
// Глобализируем переменную $post;
// скорее всего, она уже доступна в этом контексте, но на всякий случай...
global $post;
wp_list_pages( array(
// Только страницы, которые являются дочерними для текущей страницы
'child_of' => $post->ID,
// Показывать только один уровень иерархии
'depth' => 1
) );
?>
Нет необходимости прибегать к пользовательскому классу walker.
РЕДАКТИРОВАНИЕ
Чтобы также отображать ссылки верхнего уровня, просто измените пару параметров:
<?php
// Глобализируем переменную $post;
// скорее всего, она уже доступна в этом контексте, но на всякий случай...
global $post;
wp_list_pages( array(
// Только страницы, которые являются дочерними для родителя текущей страницы
'child_of' => $post->post_parent,
// Показывать два уровня иерархии
'depth' => 2
) );
?>
Обратите внимание на изменение 'child_of' => $post->ID
на 'child_of' => $post->post_parent
, что включит страницы родителя текущей страницы, и изменение 'depth' => 1
на 'depth' => 2
, что включит соседние страницы текущей страницы и их дочерние страницы.
РЕДАКТИРОВАНИЕ 2
Вот как бы я обработал добавленный вами код. Сначала я бы использовал правильный массив вместо строки массива. Затем я бы выполнил запрос для контекста/дочерних страниц перед созданием массива аргументов для wp_list_pages()
, а затем просто вызвал бы wp_list_pages()
один раз:
// Используем родительскую страницу, если она существует, иначе текущую страницу
$child_of_value = ( $post->post_parent ? $post->post_parent : $post->ID );
// Глубина 2, если есть родительская страница, иначе глубина 1
$depth_value = ( $post->post_parent ? 2 : 1 );
// Собираем массив аргументов
$wp_list_pages_args = array(
'child_of' => $child_of_value,
'depth' => $depth_value,
'title_li' => 'Разделы'
);
// Теперь выводим результат
wp_list_pages( $wp_list_pages_args );
Нам понадобится более сложный код, если вам действительно нужно выводить отдельные списки.

Отлично, это определенно направило меня в нужном направлении!
Комбинируя с другим фрагментом кода, я добился 90% от желаемого функционала...

Я сделал так, что когда нет дочерних страниц, выводятся страницы верхнего уровня. Это отлично работает, пока не доходишь до нижней части дерева — тогда сейчас ничего не выводится.
В идеале в таком случае должны выводиться страницы того же уровня (сёстры), или, если это невозможно, родительские страницы.

Я не могу легко опубликовать код здесь, верно?
По сути, я понимаю, как все это работает! К сожалению, я больше по фронтенду, и мое незнание PHP мешает мне все это собрать вместе!

Что это? Мне нужно добавить это к вашему исходному вопросу? Это рабочий/не рабочий код?

Я обновил пост, чтобы немного прояснить ситуацию — сайт находится в стадии разработки по адресу http://cheshirewestlscb-org-uk.temp.connectedcheshire.org.uk/?page_id=365 (это пример внизу иерархии).

Вы можете использовать аргумент depth для контроля количества отображаемых уровней вложенности. Я создал Walker для подменю, который отображает меню, начиная с прямых потомков текущей страницы. Код:
class My_Walker_Submenu extends Walker_Nav_Menu {
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
if (! $element)
return;
$itemId = null;
if ( $depth == 0) {
if (!isset($args[0]->child_of)){
return;
}
foreach ( $children_elements as $id => $children ) {
$data = get_post_meta ( $id, '_menu_item_object_id', true );
if ($data == $args [0]->child_of) {
$itemId = $id;
break;
}
}
if ($itemId == null) {
return;
}
unset($args [0]->child_of);
foreach ( $children_elements [$itemId] as $child ) {
parent::display_element ( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
}
return;
}
return parent::display_element ( $element, $children_elements, $max_depth, $depth, $args, $output );
}
И пример использования (я применяю его в сайдбаре):
echo wp_nav_menu( array(
'container' => '',
'theme_location' => 'header-menu',
'walker' => new My_Walker_Submenu(),
'child_of' => $page->ID,
'depth' => 2
) );

Это проблема, с которой я сталкиваюсь довольно часто. Я считаю, что решения с использованием WP_List_Pages, которые встречаются повсюду, уже немного устарели, учитывая, что WordPress имеет полноценный менеджер меню (Внешний вид → Меню).
Я пробовал множество решений, включая некоторые плагины/виджеты и walker'ы, подобные упомянутому выше. Ни одно из доступных решений меня не удовлетворило полностью. Поэтому я создал собственный плагин, который обрабатывает такие вторичные меню так, как мне удобно и привычно. При отображении меню можно установить start_depth, чтобы указать, сколько "уровней" выше текущей страницы следует игнорировать.
Таким образом, для ваших нужд вы установите start_depth равным 1, и меню автоматически будет игнорировать элементы навигации верхнего уровня при отображении.
Я назвал плагин WP Nav Plus, потому что он расширяет текущие возможности и параметры wp_nav_menu, добавляя аргумент start_depth для отображения дочерних меню.
Для тех, кто заинтересован, плагин доступен на моем сайте: https://mattkeys.me/products/wp-nav-plus/

Я создал функцию, которая использует wp_list_pages() для реализации этого. Настройте параметры, и всё готово.
