Навигация по дочерним страницам: Предыдущая/Следующая для текущей страницы?
Как я могу реализовать навигацию Предыдущая/Следующая, которая будет работать только для дочерних страниц текущей страницы?
То есть для страниц вида url.com/page/child1, url.com/page/child2 и так далее..
Я долго искал решение, но пока не разобрался.
Похоже, что это невозможно сделать стандартными средствами согласно WordPress (они рекомендуют плагины..)

Вот полностью рабочий код:
<?php
// Получаем список страниц-потомков текущей родительской страницы, сортируем по порядку меню
$pagelist = get_pages("child_of=".$post->post_parent."&parent=".$post->post_parent."&sort_column=menu_order&sort_order=asc");
$pages = array();
foreach ($pagelist as $page) {
$pages[] += $page->ID;
}
// Находим текущую позицию страницы в массиве
$current = array_search($post->ID, $pages);
$prevID = $pages[$current-1];
$nextID = $pages[$current+1];
?>
<div class="navigation">
<?php if (!empty($prevID)) { ?>
<div class="previous">
<a href="<?php echo get_permalink($prevID); ?>" title="<?php echo get_the_title($prevID); ?>">Назад</a>
</div>
<?php }
if (!empty($nextID)) { ?>
<div class="Next">
<a href="<?php echo get_permalink($nextID); ?>" title="<?php echo get_the_title($nextID); ?>">Вперед</a>
</div>
<?php } ?>
</div>
Осталась одна небольшая косметическая правка - ссылки "Назад" и "Вперед" должны отображаться всегда, даже если нет следующих или предыдущих страниц...

Не тестировалось, но должно работать:
Сначала используйте get_pages
, чтобы найти все другие страницы (или пользовательские типы записей) с тем же родителем, что и текущая страница. Затем найдите "предыдущую" и "следующую" страницы.
function wpse5422_the_page_siblings(){
$post_id = get_the_ID();
$parent_id = wp_get_post_parent_id($post_id);
$post_type = get_post_type($post_id);
$sibling_list = get_pages(array(
'sort_column'=>'menu_order',
'sort_order' =>'asc',
'child_of' =>$parent_id,
'post_type'=> $post_type
));
if( !$sibling_list || is_wp_error($sibling_list) )
return false;
$pages = array();
foreach ($sibling_list as $sibling ) {
$pages[] = $sibling->ID;
}
$current = array_search($post_id, $pages);
$prevID = isset($pages[$current-1]) ? $pages[$current-1] : false;
$nextID = isset($pages[$current+1]) ? $pages[$current+1] : false;
echo wpse5422_display_prev_next($prevID, $nextID);
}
Приведенная выше функция должна использоваться внутри цикла - она берет текущую страницу (или любой иерархический тип записи) и находит предыдущую и следующую страницы-сестры (т.е. с тем же родителем, что и текущая страница) в соответствии с их порядком в меню (это можно изменить на дату или заголовок).
Затем она использует следующую функцию, которая принимает два ID в качестве аргумента и просто отвечает за вывод:
function wpse5422_display_prev_next($prevID=false, $nextID=false){
if( empty($prevID) && empty($nextID) )
return false;
$html = '<div class="navigation">';
if( !empty($prevID) ){
$html .= '<div class="alignleft">';
$html .= '<a href="'.get_permalink($prevID).'">Предыдущая</a>';
$html .= '</div>';
}
if( !empty($nextID) ){
$html .= '<div class="alignright">';
$html .= '<a href="'.get_permalink($nextID).'">Следующая</a>';
$html .= '</div>';
}
$html .= '</div><!-- .navigation -->';
return $html;
}
Где разместить этот код
В идеале вам следует создать из этого плагин. Код будет работать в functions.php — но на самом деле он не должен там находиться.
Использование
Внутри цикла, где вы хотите отобразить ссылки на страницы: wpse5422_the_page_siblings();
.

Отличный хак, он сделал именно то, что мне было нужно. Я подумал, что некоторым из вас может быть интересно, что я добавил: альтернативные ссылки
- на первую дочернюю страницу, когда вы находитесь на родительской странице
- на родительскую страницу, когда вы находитесь на первой дочерней странице
Навигация не отображается, когда это не нужно, стили соответствуют тем, которые применяются к навигации по записям в теме twenty-thirteen.
<?php // отображаем навигацию только если есть дочерние страницы
if ($post->post_parent) { // применяется только к дочерним страницам
$pagelist = get_pages("child_of=".$post->post_parent."&parent=".$post->post_parent."&sort_column=menu_order&sort_order=asc");
$pages = array();
foreach ($pagelist as $page) {
$pages[] += $page->ID;
}
$current = array_search($post->ID, $pages);
$prevID = $pages[$current-1];
$nextID = $pages[$current+1];
?>
<nav class="navigation post-navigation" role="navigation">
<div class="nav-links">
<?php if (!empty($prevID)) { /* если мы находимся на первой дочерней странице, то ссылаемся на родительскую страницу */ ?>
<a rel="prev" href="<?php echo get_permalink($prevID); ?>" title="<?php echo get_the_title($prevID); ?>"><span class="meta-nav">←</span> <?php echo get_the_title($prevID); ?></a>
<?php }
else { // иначе ссылаемся на предыдущую дочернюю страницу ?>
<a rel="prev" href="<?php echo get_permalink($post->post_parent); ?>"><span class="meta-nav">←</span> <?php echo get_the_title($post->post_parent); ?></a>
<?php }
if (!empty($nextID)) { ?>
<a rel="next" href="<?php echo get_permalink($nextID); ?>" title="<?php echo get_the_title($nextID); ?>"><?php echo get_the_title($nextID); ?> <span class="meta-nav">→</span></a>
<?php } ?>
</div>
</nav>
<?php }
else { // если мы находимся на родительской странице, то ссылаемся на первую дочернюю
$child_pages = get_pages("child_of=".$post->ID."&parent=".$post->ID."&sort_column=menu_order&sort_order=asc");
$first_child = $child_pages[0]; ?>
<?php if (!empty($first_child)) { ?>
<nav class="navigation post-navigation" role="navigation">
<div class="nav-links">
<a rel="next" href="<?php echo get_permalink($first_child->ID); ?>"><?php echo get_the_title($first_child->ID); ?> <span class="meta-nav">→</span></a>
</div>

Решение 'wpse5422_the_page_siblings()' работает отлично, я не могу оставить комментарий, так как мой рейтинг слишком низкий, но моё единственное изменение — сделать эту строку:
'sort_column'=>'menu_order',
Вот такой:
'sort_column'=>'menu_order title',
Таким образом, если пользователь оставит порядок сортировки всех страниц как 0, по умолчанию будет использоваться алфавитная сортировка по заголовку страницы.
Спасибо!

Вы можете найти родительскую страницу текущей записи, используя post->parent_page, затем передать её в get_page_children, получив все дочерние страницы родительской страницы, а затем найти следующий и предыдущий элементы в возвращаемом массиве.

Если вы не против использовать плагин (лично я в таких случаях за них), то плагин Ambrosite Next/Previous Page Link Plus просто великолепен. Он поддерживает нужную вам функциональность, а также многое другое.

Для отображения ссылок "Назад" и "Вперед" независимо от наличия дополнительных страниц, необходимо добать условные операторы: (отредактированы бессмысленные конструкции elseif)
<div class="navigation">
<?php if (!empty($prevID)) : ?>
<div class="previous">
<a href="<?php echo get_permalink($prevID); ?>"
title="<?php echo get_the_title($prevID); ?>">Назад</a>
</div>
<?php else : ?>
<div class="previous disabled">
<a href="#">Назад</a>
</div>
<?php endif; ?>
<?php if (!empty($nextID)) : ?>
<div class="next">
<a href="<?php echo get_permalink($nextID); ?>"
title="<?php echo get_the_title($nextID); ?>">Вперед</a>
</div>
<?php else : ?>
<div class="next disabled">
<a href="#">Вперед</a>
</div>
<?php endif; ?>
</div>

Зачем пустой else
? И зачем вообще elseif
, если второе условие является полной противоположностью первого? Здесь достаточно простой конструкции if / else
.
