php 如何让分页在 WordPress 中为 get_posts() 工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24838864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get pagination to work for get_posts() in WordPress?
提问by B_Troutman
I'm working on a WordPress site and I've created a page template that displays posts by a category slug. To do this, I create a field for the page, WP_Catid, and set it equal to the category slug I want to display posts from. However, I only want five posts to show up per page with pagination links at the bottom of those posts. How do I get the pagination links to display properly?
我在一个 WordPress 网站上工作,我创建了一个页面模板,该模板按类别 slug 显示帖子。为此,我为页面创建了一个字段 WP_Catid,并将其设置为等于我要从中显示帖子的类别 slug。但是,我只希望每页显示五个帖子,并在这些帖子底部显示分页链接。如何让分页链接正确显示?
My code is as follows:
我的代码如下:
<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 -->
回答by Pieter Goosen
The sweet and short of this, don't use get_posts
if you need paginated queries. get_posts
works perfectly if you are going to use a custom query that doesn't need pagination, but it really becomes a big complicated mess when you need to introduce pagination.
get_posts
如果您需要分页查询,请不要使用它。get_posts
如果您要使用不需要分页的自定义查询,则效果很好,但是当您需要引入分页时,它确实变得非常复杂。
I think the easiest and most appropriate here is to make use of WP_Query
to construct your custom query, that is, if you can't use pre_get_posts
to alter the main queryto get your desired output from the main query.
我认为这里最简单和最合适的方法是利用WP_Query
来构建您的自定义查询,也就是说,如果您不能使用pre_get_posts
来更改主查询以从主查询中获得所需的输出。
I do think that next_posts_link()
and previous_posts_link()
is better to use with a custom query, ie with WP_Query
. You must just remember however to set the $max_pages
parameter when you make use of a custom query, otherwise your pagination will break
我确实认为,next_posts_link()
并且previous_posts_link()
最好与自定义查询一起使用,即与WP_Query
. 但是,您必须记住$max_pages
在使用自定义查询时设置参数,否则您的分页会中断
With a few minor tweaks, your query should look like this
通过一些小的调整,您的查询应如下所示
<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 -->
回答by indextwo
Pieter Goosen's answeris completely correct, and his suggestion to use WP_Query
instead makes the most sense. However, I stumbled across this question whilst looking for pagination with get_posts
outside of the loop, so I thought this might also be a useful alternative for anyone else:
Pieter Goosen 的回答是完全正确的,他建议WP_Query
改用它是最有意义的。但是,我在寻找get_posts
循环外的分页时偶然发现了这个问题,所以我认为这对其他人来说也可能是一个有用的选择:
get_posts
has a direct property called offset
which achieves pretty much the same thing as paged
in WP_Query
; but where paged
refers to pagination (e.g. 1, 2, 3), offset
is the actual number of postsyou want to offset your query by (e.g. 5, 10, 15). With a little maths - numberToShow * pageNumber
- you can get the correct offset easily:
get_posts
有一个直接的属性叫做offset
,它实现了与paged
in几乎相同的事情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);
The initial paged
value in this example is 0
rather than 1
because, when multiplying the posts_per_page
, you want the initial offset to be 0
rather than 5
.
paged
此示例中的初始值是0
而不是1
因为,在乘以 时posts_per_page
,您希望初始偏移量是0
而不是5
。
This can be most handy if you want a little more granular control rather than straightforward pagination, but should work just as well in combination with the loop in the accepted answer.
如果您想要更精细的控制而不是直接的分页,这可能是最方便的,但与接受的答案中的循环结合使用时应该也能很好地工作。
回答by hamza
Try to change your $args:
尝试更改您的 $args:
$args = array(
'posts_per_page' => 5,
'category_name' => $btmetanm,
'post_type' => 'post',
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 )
);
And just after loop put this:
就在循环之后把这个:
if (function_exists('wp_pagenavi')) {
wp_pagenavi();
}
回答by Bullyen
I will not tell you that using get_posts() is the right thing to do...but here is some basic pagination code I setup using get_posts().
我不会告诉你使用 get_posts() 是正确的做法……但这里有一些我使用 get_posts() 设置的基本分页代码。
EDIT: As Pieter pointed out, this isn't meant to be used in production code. But just something I was playing around with anyway to see if I could get pagination working with get_posts(). If you are in a production environment you wouldn't want to use this.
编辑:正如 Pieter 指出的,这并不意味着在生产代码中使用。但无论如何我都在玩弄一些东西,看看我是否可以使用 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's 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's 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>';
}
}
I hope someone gets some use out of this :)
我希望有人能从中得到一些好处:)
EDIT: What the heck! Going to do something the wrong way...might as well do it right! Here is some LESS as well (without any mixins).
编辑:什么鬼!以错误的方式做某事......还不如做对!这里也有一些 LESS(没有任何混合)。
.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; }
}
}
}
}
}