Навигация по дочерним страницам: Предыдущая/Следующая для текущей страницы?

7 июн. 2012 г., 03:31:10
Просмотры: 15.5K
Голосов: 4

Как я могу реализовать навигацию Предыдущая/Следующая, которая будет работать только для дочерних страниц текущей страницы?

То есть для страниц вида url.com/page/child1, url.com/page/child2 и так далее..

Я долго искал решение, но пока не разобрался.

Похоже, что это невозможно сделать стандартными средствами согласно WordPress (они рекомендуют плагины..)

0
Все ответы на вопрос 7
0

Вот полностью рабочий код:

<?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>

Осталась одна небольшая косметическая правка - ссылки "Назад" и "Вперед" должны отображаться всегда, даже если нет следующих или предыдущих страниц...

7 июн. 2012 г. 17:08:20
0

Не тестировалось, но должно работать:

Сначала используйте 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();.

7 июн. 2012 г. 13:12:25
0

Отличный хак, он сделал именно то, что мне было нужно. Я подумал, что некоторым из вас может быть интересно, что я добавил: альтернативные ссылки

  • на первую дочернюю страницу, когда вы находитесь на родительской странице
  • на родительскую страницу, когда вы находитесь на первой дочерней странице

Навигация не отображается, когда это не нужно, стили соответствуют тем, которые применяются к навигации по записям в теме 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">&larr;</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">&larr;</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">&rarr;</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">&rarr;</span></a>

</div>

1 мар. 2014 г. 18:08:32
0

Решение 'wpse5422_the_page_siblings()' работает отлично, я не могу оставить комментарий, так как мой рейтинг слишком низкий, но моё единственное изменение — сделать эту строку:

'sort_column'=>'menu_order',

Вот такой:

'sort_column'=>'menu_order title',

Таким образом, если пользователь оставит порядок сортировки всех страниц как 0, по умолчанию будет использоваться алфавитная сортировка по заголовку страницы.

Спасибо!

12 мар. 2018 г. 06:13:10
0

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

7 июн. 2012 г. 05:38:27
0

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

7 июн. 2012 г. 05:41:54
2

Для отображения ссылок "Назад" и "Вперед" независимо от наличия дополнительных страниц, необходимо добать условные операторы: (отредактированы бессмысленные конструкции 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>
24 мая 2013 г. 14:38:54
Комментарии

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

Johannes Pille Johannes Pille
24 мая 2013 г. 15:12:24

Согласен - извините за это - я сам разбирался по ходу дела и пришел сюда в основном из-за предыдущего ответа на этой странице. Я учел ваше замечание - спасибо.

Chris Chris
28 мая 2013 г. 11:42:12