admin管理员组文章数量:1289565
I am trying to modify the number of posts_per_page in the loop. This way:
function posts_per_page($query) {
$query->query_vars['posts_per_page'] = 3;
}
add_filter('pre_get_posts', 'posts_per_page', 11);
The problem I have is that when I do so, then sticky posts appear twice in the loop: first one at the begining of the loop and second one in their original position. So in this case, the first page has 4 posts (3 of loop without sticky + the sticky post), and the sticky post will appear (again) later in its "page" with other 2 posts.
EDIT: SOLUTION
After doing quite much research I realised sticky posts appear always in the first page. If the original sticky post was already in the first page then only the sticky appears (this post only will appear one). I needed to know exacty how many posts will my query have, but $wp_query->found_posts was not counting the sticky posts. And if I did $wp_query->found_posts + get_option( 'sticky_posts' ) wouldnt be correct as it doesnt consider the 'sticky post from first page' I said before and also counts non-published sticky posts.
With $wp_query->posts I get the real number of posts in my first page, so:
$sticky = count($wp_query->posts) - get_option( 'posts_per_page' );
if ($sticky<0) {$sticky=0;}//In case there is only one page of results
Now $sticky will have the real number of sticky posts.
I am trying to modify the number of posts_per_page in the loop. This way:
function posts_per_page($query) {
$query->query_vars['posts_per_page'] = 3;
}
add_filter('pre_get_posts', 'posts_per_page', 11);
The problem I have is that when I do so, then sticky posts appear twice in the loop: first one at the begining of the loop and second one in their original position. So in this case, the first page has 4 posts (3 of loop without sticky + the sticky post), and the sticky post will appear (again) later in its "page" with other 2 posts.
EDIT: SOLUTION
After doing quite much research I realised sticky posts appear always in the first page. If the original sticky post was already in the first page then only the sticky appears (this post only will appear one). I needed to know exacty how many posts will my query have, but $wp_query->found_posts was not counting the sticky posts. And if I did $wp_query->found_posts + get_option( 'sticky_posts' ) wouldnt be correct as it doesnt consider the 'sticky post from first page' I said before and also counts non-published sticky posts.
With $wp_query->posts I get the real number of posts in my first page, so:
$sticky = count($wp_query->posts) - get_option( 'posts_per_page' );
if ($sticky<0) {$sticky=0;}//In case there is only one page of results
Now $sticky will have the real number of sticky posts.
Share Improve this question edited Oct 12, 2013 at 15:05 Alvaro asked Oct 6, 2013 at 20:11 AlvaroAlvaro 2,5932 gold badges28 silver badges29 bronze badges 1- Just a note, pre_get_posts is a action and not a filter – Buttered_Toast Commented Jul 2, 2021 at 15:44
3 Answers
Reset to default 1What you describe is not an issue but normal WordPress behaviour. When you mark a post as a sticky it will be at the top of the list and it will appear in it's original postition as well, unless the original position is on the first page. A sticky will appear at the top of the posts and in it's original position but it will not appear twice on the same page.
You might want to do something like this:
<?php
while (have_posts()) : the_post();
if ( !in_array( $post->ID, $do_not_duplicate ) ) { // check IDs
// display posts ...
the_title();
//store id in "do not duplicate
$do_not_duplicate = $post->ID;
}
endwhile;
?>
source with minor edit: http://wpengineer/1719/filter-duplicate-posts-in-the-loop/
More correct would be to use the set
method.
function posts_per_page($query) {
$query->set('posts_per_page',3);
}
add_filter('pre_get_posts', 'posts_per_page', 11);
Try that.
Note: I can't duplicate this multiple sticky issue. If that doesn't solve things edit your question with more detail. That may be theme specific or due to a plugin.
Consider a case where one needs the following:
- Keep sticky posts at the top.
- Not duplicate sticky posts in later pages
- Have each page be limited to a specific number of posts (even the first page).
It is very complex to do by setting parameters in the pre_get_posts
hook because there is no simple way to set the number of posts for the first page. WordPress naturally sends back all sticky posts + the posts on the first page. It is not a good idea to try to calculate a new value of posts_per_page
based on the number of sticky posts
of the following complications.
- There are many cases to consider. Sometimes
sticky posts
are less that theposts_per_page
, sometimes more, and sometimes equal. Each case will need to be dealt with separably. - There is no way to deal with the case where the number of
sticky posts
exceedsposts_per_page
as described in an answer to a similar question
Therefore the solution is to modify the code executes the loop
.
global $wp_query, $post;
// Setup manual paging scheme.
$page_requested = $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1;
$number_per_page = $wp_query->query_vars['posts_per_page'];
$first_post_to_display = ( $page_requested - 1 ) * $number_per_page + 1;
$last_post_to_display = $first_post_to_display + $number_per_page - 1;
$current_post = 1;
// Re query posts without paging so it won't duplicate the sticky posts.
$query = new WP_Query( array( 'nopaging' => true ) );
while ( $query->have_posts() ) :
$query->the_post();
$should_display_this_post = $current_post >= $first_post_to_display && $current_post <= $last_post_to_display;
if ( $should_display_this_post ) {
?>
<Template code to output post content here>
<?php }
++$current_post;
endwhile;
?>
Explanation:
- Re query all posts without paging in order to remove duplicates (while preserving the high priority of
sticky posts
. - Manually Calculate which posts should be displayed based on the requested page number and the desired
posts_per_page
.
本文标签: querySticky post appears twice
版权声明:本文标题:query - Sticky post appears twice 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741469879a2380536.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论