Как получить pagination для работы в get_posts() в WordPress?
Я работаю над сайтом WordPress, и я создал шаблон страницы, который отображает сообщения в категории slug. Для этого я создаю поле для страницы WP_Catid и устанавливаю его равным категории slug, с которой я хочу отображать сообщения. Тем не менее, я хочу, чтобы на каждой странице отображалось пять сообщений с ссылками на страницы, расположенными внизу этих сообщений. Как правильно отображать ссылки для разбивки на страницы?
Мой код выглядит следующим образом:
<div id="container">
<div id="content" role="main">
<?php
$btpgid=get_queried_object_id();
$btmetanm=get_post_meta( $btpgid, 'WP_Catid','true' );
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array( 'posts_per_page' => 5,
'category_name' => $btmetanm,
'paged' => $paged,
'post_type' => 'post' );
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post );
echo "<div style='border:2px groove black; margin-bottom:5px;'><h3 class='btposth'>";
the_title();
echo "</h3><div class='btpostdiv'>";
the_content();
echo "</div></div>";
endforeach;
next_posts_link( 'Older Entries'); //not displaying
previous_posts_link('Newer Entries »'); //not displaying
wp_reset_postdata();
?>
</div><!-- #content -->
</div><!-- #container -->
Ответы
Ответ 1
Сладкий и недостаток этого, не используйте get_posts
, если вам нужны разбитые запросы. get_posts
отлично работает, если вы собираетесь использовать пользовательский запрос, который не нуждается в разбивке на страницы, но это действительно становится сложной проблемой, когда вам нужно вводить разбивку на страницы.
Я думаю, что самым простым и наиболее подходящим здесь является использование WP_Query
для создания пользовательского запроса, то есть если вы не можете использовать pre_get_posts
, чтобы изменить основной запрос, чтобы получить желаемый результат из основного запроса.
Я думаю, что next_posts_link()
и previous_posts_link()
лучше использовать с пользовательским запросом, т.е. с помощью WP_Query
. Однако вы должны просто запомнить параметр $max_pages
, когда вы используете пользовательский запрос, иначе постраничная разбивка страницы будет
С несколькими незначительными изменениями ваш запрос должен выглядеть так:
<div id="container">
<div id="content" role="main">
<?php
$btpgid=get_queried_object_id();
$btmetanm=get_post_meta( $btpgid, 'WP_Catid','true' );
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array( 'posts_per_page' => 5, 'category_name' => $btmetanm,
'paged' => $paged,'post_type' => 'post' );
$postslist = new WP_Query( $args );
if ( $postslist->have_posts() ) :
while ( $postslist->have_posts() ) : $postslist->the_post();
echo "<div style='border:2px groove black; margin-bottom:5px;'><h3 class='btposth'>";
the_title();
echo "</h3><div class='btpostdiv'>";
the_content();
echo "</div></div>";
endwhile;
next_posts_link( 'Older Entries', $postslist->max_num_pages );
previous_posts_link( 'Next Entries »' );
wp_reset_postdata();
endif;
?>
</div><!-- #content -->
</div><!-- #container -->
Ответ 2
Ответ Pieter Goosen полностью верен, и его предложение использовать WP_Query
вместо этого имеет наибольший смысл. Тем не менее, я наткнулся на этот вопрос, ища разбивку на страницы с помощью get_posts
вне цикла, поэтому я подумал, что это может быть полезной альтернативой для кого-либо еще:
get_posts
имеет прямое свойство offset
, которое достигает почти такой же величины, как paged
в WP_Query
; но где paged
относится к разбивке на страницы (например, 1, 2, 3), offset
- это фактическое количество сообщений, которые вы хотите компенсировать своим запросом (например, 5, 10, 15). С небольшой математикой - numberToShow * pageNumber
- вы можете легко получить правильное смещение:
$paged = (get_query_var('paged')) ? get_query_var('paged') : 0;
$postsPerPage = 5;
$postOffset = $paged * $postsPerPage;
$args = array(
'posts_per_page' => $postsPerPage,
'category_name' => $btmetanm,
'offset' => $postOffset,
'post_type' => 'post'
);
$myposts = get_posts($args);
Первоначальное значение paged
в этом примере - 0
, а не 1
, потому что при умножении posts_per_page
вы хотите, чтобы начальное смещение было 0
, а не 5
.
Это может быть наиболее удобно, если вы хотите немного более подробный контроль, а не простое разбиение на страницы, но должны работать так же хорошо в сочетании с циклом в принятом ответе.
Ответ 3
Попробуйте изменить $args:
$args = array(
'posts_per_page' => 5,
'category_name' => $btmetanm,
'post_type' => 'post',
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 )
);
И сразу после цикла поставьте это:
if (function_exists('wp_pagenavi')) {
wp_pagenavi();
}
Ответ 4
Я не скажу вам, что использование get_posts() - это правильная вещь... но вот какой-то базовый код разбивки на страницы, который я устанавливаю, используя get_posts().
EDIT: Как отметил Питер, это не предназначено для использования в производственном коде. Но только что-то я играл в любом случае, чтобы увидеть, могу ли я рисовать страницы с помощью get_posts(). Если вы находитесь в рабочей среде, вы не захотите использовать это.
$cpt_name = 'post-type'; //add your own post type
//what pagination page are we on?
if(! empty($_GET['pag']) && is_numeric($_GET['pag']) ){
$paged = $_GET['pag'];
}else{
$paged = 1;
}
//you could use this if you want, just make sure to use "/page/2" instead of "?pag=2" in the pagination links.
//$paged = (get_query_var('paged')) ? get_query_var('paged') : 0;
//how many posts should we display?
$posts_per_page = (get_option('posts_per_page')) ? get_option('posts_per_page') : 10;
//let first get ALL of the possible posts
$args = array(
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'fields' => 'ids',
'post_type' => $cpt_name
);
$all_posts = get_posts($args);
//how many total posts are there?
$post_count = count($all_posts);
//how many pages do we need to display all those posts?
$num_pages = ceil($post_count / $posts_per_page);
//let make sure we don't have a page number that is higher than we have posts for
if($paged > $num_pages || $paged < 1){
$paged = $num_pages;
}
//now we get the posts we want to display
$args = array(
'posts_per_page' => $posts_per_page,
'orderby' => 'title',
'order' => 'ASC',
'post_type' => $cpt_name,
'paged' => $paged
);
$my_posts = get_posts($args);
//did we find any?
if(! empty($my_posts)){
echo '<div id="my-posts-wrapper">';
//THE FAKE LOOP
foreach($my_posts as $key => $my_post){
//do stuff with your posts
echo '<div class="my-post">'.$my_post->post_title.'</div>';
}
echo '</div>';
//we need to display some pagination if there are more total posts than the posts displayed per page
if($post_count > $posts_per_page ){
echo '<div class="pagination">
<ul>';
if($paged > 1){
echo '<li><a class="first" href="?pag=1">«</a></li>';
}else{
echo '<li><span class="first">«</span></li>';
}
for($p = 1; $p <= $num_pages; $p++){
if ($paged == $p) {
echo '<li><span class="current">'.$p.'</span></li>';
}else{
echo '<li><a href="?pag='.$p.'">'.$p.'</a></li>';
}
}
if($paged < $num_pages){
echo '<li><a class="last" href="?pag='.$num_pages.'">»</a></li>';
}else{
echo '<li><span class="last">»</span></li>';
}
echo '</ul></div>';
}
}
Я надеюсь, что кто-то воспользуется этим:)
РЕДАКТОР: Что за черт! Идти делать что-то не так... может так же правильно! Здесь также немного МЕНЬШЕ (без каких-либо миксинов).
.pagination { margin: 30px 0px;
ul { display:block; list-style-type:none; margin:0 auto; padding: 0px;
li { display:inline-block; list-style-type:none; margin:0; padding:0;
a, span { display:inline-block; font-size: 14px; width:auto; min-width:26px; height:26px; line-height: 26px; border: 1px solid #dddddd; border-right: 0px; background:#FFFFFF; color:#FF0000; padding: 5px; text-align: center;
&:hover { cursor:pointer; text-decoration:none; }
&.first { border-top-left-radius: 3px; border-bottom-left-radius: 3px; }
&.last { border-top-right-radius: 3px; border-bottom-right-radius: 3px;}
}
span.last,
span.first { color: #FF0000;
&:hover { cursor: default; }
}
a.last,
a.first {
&:hover { }
}
a:hover,
&.active a,
.current { background:#FF0000; color:#ffffff; border-color: #b21712; }
&:last-child {
a, span { border-right: 1px solid #dddddd; }
a {
&:hover { border-color: #FF0000; }
}
}
}
}
}