Множественные циклы WP_Query с пагинацией
Существует несколько других вопросов об этом (и пагинация WP_Query кажется большой проблемой для многих людей), поэтому я пытаюсь точно определить, как заставить это работать.
Я могу создать один пользовательский цикл с пагинацией, используя этот код:
// http://weblogtoolscollection.com/archives/2008/04/19/paging-and-custom-wordpress-loops/
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query();
$args = array(
'showposts' => 2,
'paged' => $paged
);
$wp_query->query($args);
while ($wp_query->have_posts()) : $wp_query->the_post();
// Запись
the_title();
echo '<br>';
the_category(' ');
the_excerpt();
echo '<hr>';
endwhile;
// http://codex.wordpress.org/Function_Reference/paginate_links#Examples
$big = 999999999;
$pag_args = array(
'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages
);
echo paginate_links($pag_args);
$wp_query = null;
$wp_query = $temp;
...но естественно, если я скопирую/вставлю этот цикл, он работает как точная копия, то есть когда вы нажимаете на "Страница 2", он переходит на Страницу 2 для ОБОИХ циклов.
Есть ли способ разделить их друг от друга, чтобы каждый имел отдельную пагинацию?
Вот полный код вместе с дублированным циклом, если кто-то заинтересован в настройке собственной локальной версии и экспериментах с ней: http://paste.pocoo.org/show/573108/
Да, это возможно сделать. Ключевой момент — использовать разные параметры format
для двух запросов:
<!-- Кошки -->
<div class="animals">
<?
$paged1 = isset( $_GET['paged1'] ) ? (int) $_GET['paged1'] : 1;
$paged2 = isset( $_GET['paged2'] ) ? (int) $_GET['paged2'] : 1;
// Пользовательский цикл с пагинацией 1
// http://codex.wordpress.org/Class_Reference/WP_Query#Usage
$args1 = array(
'paged' => $paged1,
'posts_per_page' => 2,
);
$query1 = new WP_Query( $args1 );
while ( $query1->have_posts() ) : $query1->the_post();
the_title();
echo '<br>';
the_category(' ');
the_excerpt();
echo '<hr>';
endwhile;
// http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters
$pag_args1 = array(
'format' => '?paged1=%#%',
'current' => $paged1,
'total' => $query1->max_num_pages,
'add_args' => array( 'paged2' => $paged2 )
);
echo paginate_links( $pag_args1 );
?>
</div>
<!-- Собаки -->
<div class="animals">
<?
// Пользовательский цикл с пагинацией 2
$args2 = array(
'paged' => $paged2,
'posts_per_page' => 2,
);
$query2 = new WP_Query( $args2 );
while ( $query2->have_posts() ) : $query2->the_post();
the_title();
echo '<br>';
the_category(' ');
the_excerpt();
echo '<hr>';
endwhile;
$pag_args2 = array(
'format' => '?paged2=%#%',
'current' => $paged2,
'total' => $query2->max_num_pages,
'add_args' => array( 'paged1' => $paged1 )
);
echo paginate_links( $pag_args2 );
?>
</div>

Большое спасибо за ответ, Бун. Я понял, о чем вы говорите, но каждый раз, когда я пытаюсь изменить get_query_var, возникает ошибка.
Вот обновленный код: http://paste.pocoo.org/show/573208/
Ошибка:
Call to a member function get() on a non-object in C:\wamp\www\wordpress_wp_query_pagination\wp-includes\query.php on line 27

Две проблемы: 1) Вы делаете странные вещи с глобальной переменной $wp_query
. 2) В самом WP_Query
есть некоторые особенности реализации, которые делают невозможным использование get_query_var()
и некоторых других функций с ним, поэтому я обычно обращаюсь напрямую к суперглобальному массиву $_GET
, обязательно санируя данные приведением к int
. Я обновил свой ответ полным рабочим примером.

Потрясающе, Бун! Огромное спасибо, работает отлично. Теперь нужно тщательно изучить ваш код.
Странные манипуляции с WP_Query были из этой статьи 2008 года: http://weblogtoolscollection.com/archives/2008/04/19/paging-and-custom-wordpress-loops/
Я думал, что get_query_var получает ту же переменную, но не догадался взять ее напрямую через $_GET.
Еще раз большое спасибо, чувак. Я бился с этой проблемой целую вечность.

Ох, черт. Хочешь продолжить бороться с этим вместе? :)
После тестирования твоей версии я заметил, что она не возвращается на страницу 1. Она застревает на странице 2.
Также, когда нажимаешь на другую страницу, это сбрасывает другой цикл. Можно ли объединить эти $_GET переменные, чтобы запоминалось http://foo.com/?paged_1=2&paged_2=3 ?

Не уверен, что ты имеешь в виду под "застревает". Что касается второго пункта - да, это то, что я имел в виду в последнем предложении своего ответа. Тебе нужно будет объединить параметры 'base'
или 'format'
, чтобы они учитывали другой аргумент пагинации.

Вот ошибка, с которой я столкнулся: http://www.screenr.com/tmS8 Вот мой код (та же ошибка с вашим дословным кодом): http://paste.pocoo.org/show/573351/

Кажется, работает идеально. Огромное спасибо, Бун! Ты просто гений уровня Лиги плюща. :D
Просто из любопытства, как именно работает параметр 'add_args'? Я посмотрел в Codex, но там не очень подробно.

add_args
позволяет добавить массив аргументов к URL. Это более понятно из встроенной документации и самой функции: https://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/general-template.php#L1876 https://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/general-template.php#L1985

можете взглянуть на этот вопрос http://stackoverflow.com/questions/23841520/pagination-error-wordpress
