Пагинация страницы с произвольным типом записей
Я создал страницу для своих произвольных типов записей. Код можно посмотреть на Snippi: http://snippi.com/s/e8852rx
Я пытаюсь добавить paginate_links, но по какой-то причине пагинация просто не отображается. Вот код paginate_links (этот код работает на обычных файлах archive.php):
<?php
global $wp_query;
$big = 999999999; // нужно маловероятное целое число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages
) );
?>

Следующий вариант работает у меня (я убрал все форматирование / произвольные метаданные записей).
Хочу добавить, что не совсем понятно, зачем использовать страницу с произвольным шаблоном, вместо того чтобы создать шаблон archive-portfolio.php
, который используется для архивных страниц произвольного типа записи (см. иерархию шаблонов).
<?php
/*
Template Name: Портфолио
*/
?>
<?php get_header(); ?>
<div id="container">
<div id="portfolio_content">
<div id="portfolio_wrap">
<?php $loop = new WP_Query(array('post_type' => 'portfolio', 'posts_per_page' => get_option('to_count_portfolio'), 'paged' => get_query_var('paged') ? get_query_var('paged') : 1 )
); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<span class="title"><?php the_title(); ?></span></br>
<?php endwhile; ?>
<?php
$big = 999999999; // маловероятное число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $loop->max_num_pages
) );
?>
</div>
</div>
</div>
</div>
<?php get_footer(); ?>

Вместо использования подхода "$loop->have_posts()", как отметил Стивен Харрис, вы также можете попробовать перебирать записи следующим образом:
<?php foreach ($loop->get_posts() as $post) { ?>
<span class="title"><?php echo $post->post_title; ?></span></br>
<?php } ?>

Пробовали ли вы использовать корневую архивную страницу для типа записи "портфолио"?
Если перенести большую часть вашего кода в файл archive-portfolio.php, то цикл должен быть настроен правильно, и пагинация будет работать "из коробки", без странных функций, хаков или костылей, точно так же, как это работает в архивах записей.
Это также означает, что вам не нужно использовать собственный пользовательский запрос — просто используйте основной цикл, что сделает загрузку страницы быстрее.

Абсолютно. И если пользовательский тип записи настроен правильно, страница архива будет использовать слаг типа записи без лишних телодвижений: например, www.mysite/portfolio

Когда я меняю на archive-portfolio.php, оригинальный код paginate_links перестает работать. Я что-то упускаю?

Вы ссылаетесь на основной запрос, поэтому, скорее всего, он пытается отображать только 'posts', а не ваш пользовательский тип записи.
Не уверен, какой именно у вас формат, но я бы переделал запрос следующим образом:
$args = Array( // Массив аргументов для query_posts()
'numberposts' => -1,
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'post_type' => array('ваш-слаг-типа-записи', 'еще-один-слаг-типа-записи-если-нужно')
);
query_posts($args);
Это означает, что ваш код будет выглядеть так:
<?php
global $wp_query; // Не нужно, если вы не в функции, поэтому можно удалить.
$args = Array( // Массив аргументов для query_posts()
'numberposts' => -1,
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'post_type' => array('ваш-слаг-типа-записи', 'еще-один-слаг-типа-записи-если-нужно')
);
query_posts($args);
$big = 999999999; // нужно маловероятное целое число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages )
);
?>

Эта проблема возникала у меня множество раз.
Вот что сработало для меня в данной ситуации (WP 3.1.1):
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array( 'post_type' => 'custom_post_type', 'posts_per_page' => 5, 'paged' => $paged);
$loop = new WP_Query( $args );
if($loop->have_posts()):
while ( $loop->have_posts() ) : $loop->the_post();
//любой необходимый вывод, например:
the_excerpt();
endwhile;
endif;
?>
Затем, для элементов пагинации:
<?php
echo custom_paginate_links(
array(
'format' => '?paged=%#%',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $loop->max_num_pages
) );
?>

Лучше создать функцию в вашем файле functions.php, которая будет обрабатывать пагинацию и может использоваться во всей вашей теме, как для стандартных, так и для пользовательских типов записей.
Следующая функция get_pagination()
, добавленная в вашу тему, предоставит навигацию везде, где это необходимо. Я написал об этом в блоге здесь: http://deadlyhifi.com/2011/06/non-bloated-pagination-for-your-wordpress-functions-php-file/ (код изначально основан на http://robertbasic.com/blog/wordpress-paging-navigation/)
/**
* Функция пагинации
* @param integer $range: Диапазон слайдера, лучше работает с четными числами
* Использованные функции WP:
* get_pagenum_link($i) - создает ссылку, например http://site.com/page/4
* previous_posts_link(' ‚ '); - возвращает ссылку на предыдущую страницу
* next_posts_link(' é '); - возвращает ссылку на следующую страницу
* http://robertbasic.com/blog/wordpress-paging-navigation/
* доработано tdB ...
*/
function get_pagination($range = 4) {
global $paged, $wp_query;
// Сколько всего страниц?
if ( !$max_page ) {
$max_page = $wp_query->max_num_pages;
}
// Пагинация нужна только если страниц больше одной
if ( $max_page > 1 ) {
if ( !$paged ) $paged = 1;
echo '<div class="postpagination">';
// Ссылка на предыдущую страницу
previous_posts_link('Пред.');
if ( $paged >= $range ) echo '<a href="' . get_pagenum_link(1) . '">1</a>';
if ( $paged >= ($range + 1) ) echo '<span class="page-numbers">…</span>';
// Скользящий эффект нужен только если страниц больше, чем диапазон
if ( $max_page > $range ) {
// Ближе к началу
if ( $paged < $range ) {
for ( $i = 1; $i <= ($range + 1); $i++ ) {
echo ( $i != $paged ) ? '<a href="' . get_pagenum_link($i) .'">'.$i.'</a>' : '<span class="this-page">'.$i.'</span>';
}
// Ближе к концу
} elseif ( $paged >= ($max_page - ceil(($range/2))) ) {
for ( $i = $max_page - $range; $i <= $max_page; $i++ ) {
echo ( $i != $paged ) ? '<a href="' . get_pagenum_link($i) .'">'.$i.'</a>' : '<span class="this-page">'.$i.'</span>';
}
// Где-то посередине
} elseif ( $paged >= $range && $paged < ($max_page - ceil(($range/2))) ) {
for ( $i = ($paged - ceil($range/2)); $i <= ($paged + ceil(($range/2))); $i++ ) {
echo ($i != $paged) ? '<a href="' . get_pagenum_link($i) .'">'.$i.'</a>' : '<span class="this-page">'.$i.'</span>';
}
}
// Меньше страниц, чем диапазон - скользящий эффект не нужен
} else {
for ( $i = 1; $i <= $max_page; $i++ ) {
echo ($i != $paged) ? '<a href="' . get_pagenum_link($i) .'">'.$i.'</a>' : '<span class="this-page">'.$i.'</span>';
}
}
// На последней странице не выводим ссылку на последнюю страницу
if ( $paged <= $max_page - ($range - 1) ) echo '<span class="page-numbers">…</span><a href="' . get_pagenum_link($max_page) . '">' . $max_page . '</a>';
// Следующая страница
next_posts_link('След.');
echo '</div><!-- postpagination -->';
}
}

У меня никогда не было проблем с использованием пагинации на кастомном архиве.
Вместо того, чтобы создавать страницу и писать собственный запрос, можно просто скопировать/вставить archive.php
и переименовать его в соответствии с вашим кастомным типом записи, например archive-videos.php
.
Если вам действительно нужно использовать шаблон кастомной страницы, добавьте это перед вашим запросом:
query_posts( array( 'post_type' => 'videos', 'paged' => get_query_var('page') ) )
Подробнее: http://scribu.net/wordpress/wp-pagenavi/right-way-to-use-query_posts.html
