Функция next_posts_link() работает только с оригинальным $wp_query

30 дек. 2012 г., 00:34:35
Просмотры: 19.6K
Голосов: 9

У меня есть пользовательский шаблон, в котором я хочу отображать постраничную навигацию для записей блога. Вот начало моего файла:

$wp_query = new WP_Query($args);
    if($wp_query->have_posts()){
        while($wp_query->have_posts()){ $wp_query->the_post();
            // какой-то код...
    <?php next_posts_link('Старые записи'); ?>
    <?php previous_posts_link('Новые записи'); ?>

Это работает нормально - отображаются ссылки "СТАРЫЕ" и "НОВЫЕ" записи, когда это необходимо. На первой странице отображается только ссылка на более старые записи. На второй странице - обе ссылки (на новые и еще более старые записи) и т.д.

Но я не хочу перезаписывать текущий $wp_query... Я хочу использовать, скажем, $wp_query2 для этого цикла. И в этом случае ссылки вообще не появляются.

Согласно документации: http://codex.wordpress.org/Function_Reference/next_posts_link эти функции выводят ссылки на предыдущий/следующий набор записей в текущем запросе. Я предполагаю, что $wp_query2 не является моим "ТЕКУЩИМ ЗАПРОСОМ", а $wp_query всегда им является. Можно ли это как-то изменить?

ОБНОВЛЕНИЕ: Если вручную добавить &paged=2 к ссылке, то она корректно переходит на следующий набор записей (следующую страницу), и на второй, третьей и т.д. страницах previous_posts_link() работает, даже если я использую $wp_query2. Таким образом, мне не хватает только функциональности next_posts_link() на каждой странице.

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

Функции next_posts_link и previous_posts_link используют глобальную переменную $wp_query.

function get_next_posts_link( $label = null, $max_page = 0 ) {
    global $paged, $wp_query;

http://core.trac.wordpress.org/browser/tags/3.5/wp-includes/link-template.php#L1523

Это означает, что для их корректной работы необходимо сделать следующее:

$orig_query = $wp_query; // Сохраняем оригинальный запрос
$wp_query = new WP_Query($args); // Устанавливаем новый запрос
// остальной код
$wp_query = $orig_query; // Восстанавливаем оригинальный запрос

Если вы больше не используете $wp_query в рамках этой загрузки страницы, нет необходимости сохранять его. Можно легко скопировать эти основные функции, модифицировать их для принятия параметра запроса и создать собственные функции пагинации.

30 дек. 2012 г. 02:16:50
Комментарии

Спасибо. Более тонкий подход, чем просто перезапись $wp_query. Функции *_post_link используют $wp_query только для вычисления значения параметра $max_pages, поэтому в обсуждении на Stack Overflow предлагают просто передавать это значение вместо перезаписи $wp_query. Что в каком-то смысле кажется проще, но вызывает у меня легкое беспокойство, так как предполагает, что будущие версии WP будут вести себя так же (нет гарантии: это не часть API/контракта, а скорее знание внутренней работы кода с переменными). http://stackoverflow.com/questions/14364488/wordpress-pagination-next-posts-link-on-custom-wp-query-not-showing

Andy Giesler Andy Giesler
16 мая 2013 г. 18:27:13

Это справедливое замечание, но вы же возвращаете переменную обратно, поэтому перезапись $wp_query не должна быть проблемой. Честно говоря, я редко сталкиваюсь с этой проблемой — pre_get_posts делает её решение довольно простым.

s_ha_dum s_ha_dum
16 мая 2013 г. 18:33:56

Извините, я был неясен. Я согласен, ваш метод безопасен. Моё замечание о рискованности относилось к решению на Stack Overflow. То решение выглядит проще на первый взгляд (просто добавить параметр), но оно основано на предположениях о внутренней работе кода WordPress... скорее всего безопасно, но внутренняя реализация может измениться. +1 вашему решению, так как оно кажется более устойчивым к изменениям в будущем.

Andy Giesler Andy Giesler
16 мая 2013 г. 22:54:44
0

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

Довольно хорошее решение для реализации пагинации в дополнительных циклах можно найти здесь: http://weblogtoolscollection.com/archives/2008/04/19/paging-and-custom-wordpress-loops/

Оно включает явное указание параметра запроса paged, например так:

<h3>Последние статьи</h3>
<ul>
<?php 
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query();
$wp_query->query('showposts=5'.'&paged='.$paged);
?>

Надеюсь, это поможет.

30 дек. 2012 г. 02:16:17
0

Я столкнулся с такой же проблемой. У меня есть вложенные циклы, поэтому во внутреннем цикле я использую $wp_query = new WP_Query($args); вместо глобального WP_Query. Решение, которое я применил, заключалось в явной передаче параметра max_num_pages в функцию next_posts_link. Это также упоминалось в комментариях Andy Giesler.

Решение:

<?php  
  //внешний цикл  
    //некоторый внешний код
    //начинается внутренний цикл
      $inner_query = new WP_Query( 
                array('posts_per_page' => '4', 'paged' => get_query_var('paged')) 
            ); 
        // ...код для отображения всех записей и т.д.  
      previous_posts_link( 'Старые записи' ); 
      next_posts_link( 'Новые записи', $inner_query->max_num_pages ); //Обратите внимание на это
    //заканчивается внутренний цикл
    //другой внешний код  
  //заканчивается внешний цикл
?>  

Причина, по которой мы должны это делать, заключается в том, что WordPress внутренне использует свойство $max_page глобального WP_query, которое, если не определено, по умолчанию будет равно $max_page = 0

17 мая 2022 г. 04:26:30