粘性帖子超过每页帖子限制

时间:2012-12-19 作者:helgatheviking

我正在使用pre_get_posts 调整我的主页上显示的帖子数量。

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( \'posts_per_page\', 12 );
        return;
    }
}
add_filter( \'pre_get_posts\', \'lifelounge_query_adjust\' );
但我遇到了一个粘帖的问题。基本上,如果我有任何粘性帖子,查询将显示比我指定的12篇帖子更多的帖子,因为它将显示12篇外加任何粘性帖子。当然,我可以忽略粘性帖子:

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( \'posts_per_page\', 1 );
        set_query_var( \'ignore_sticky_posts\', 1 );
        return;
    }
}
add_filter( \'pre_get_posts\', \'lifelounge_query_adjust\' );
但我认为这并不理想。我认为粘性帖子应该包含在12篇帖子的限制内,而不是添加到限制内。这对我来说是最有意义的。有没有办法做到这一点?我是否犯了一个值得我去做的错误?

几乎与以下内容重复:Sticky Posts & Posts Per Page 但这是一个奇怪的封闭,因为太本地化了。我不同意,显然是因为我在寻找答案,但也因为这是一个为什么WordPress似乎不尊重posts_per_page <如果您使用的是粘性贴子,则em>限制。如果你想要每页12篇文章,你应该得到12篇,而不是13篇,如果你只有一篇粘性文章,你就会得到13篇。

4 个回复
最合适的回答,由SO网友:Ahmad M 整理而成

下面是一种通过获取粘性帖子的数量(如果有)并将其包含在计算中来说明粘性帖子的方法posts_per_page 参数:

add_action(\'pre_get_posts\', \'ad_custom_query\');
function ad_custom_query($query) {

    if ($query->is_main_query() && is_home()) {

        // set the number of posts per page
        $posts_per_page = 12;
        // get sticky posts array
        $sticky_posts = get_option( \'sticky_posts\' );

        // if we have any sticky posts and we are at the first page
        if (is_array($sticky_posts) && !$query->is_paged()) {

            // counnt the number of sticky posts
            $sticky_count = count($sticky_posts);

            // and if the number of sticky posts is less than
            // the number we want to set:
            if ($sticky_count < $posts_per_page) {
                $query->set(\'posts_per_page\', $posts_per_page - $sticky_count);

            // if the number of sticky posts is greater than or equal
            // the number of pages we want to set:
            } else {
                $query->set(\'posts_per_page\', 1);
            }

        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set(\'posts_per_page\', $posts_per_page);
        }
    }
}
编辑如果我们希望设置的每页帖子数小于或等于粘性帖子数,我已经设置了posts_per_page 到一个,这将导致13个或更多的职位$sticky_count + 1 (在这种情况下)仅在第一页(后续页面将有12篇帖子)。也许这是可以的,因为这种情况很少见,而且第一页上的+1篇文章可能没有那么重要。

这是因为Wordpress将首先在一页(第一页)上显示所有粘性帖子,即使它们的数量大于posts_per_page 参数,因此我们设置posts_per_page 在这种情况下,尽可能减少1, 因为0 负值将禁用posts_per_page 参数,这将使Wordpress在第一页上显示所有帖子。

SO网友:csag

如果粘性帖子位于第一页,则会出现问题。

解决方案是减少作为第一页一部分的粘性帖子的粘性帖子数量。

function fix_posts_per_page_with_sticky_posts( $query ) {

    if ( $query->is_main_query() ) {

        // set the number of posts per page
        $posts_per_page = 12;

        // get sticky posts array
        $sticky_posts = get_option( \'sticky_posts\' );

        // get queried post ids array
        $ids = array();
        $args = array(
            \'post_type\' => \'post\',
            \'post_per_page\' => $posts_per_page,
            \'paged\' => 1
        );

        $posts = get_posts( $args );

        foreach ( $posts as $post ) {
            $ids[] = $post->ID;
        }

        // if we have any sticky posts and we are at the first page
        if ( is_array( $sticky_posts ) && ! $query->is_paged() ) {

            // count the number of sticky posts
            $sticky_count = count( $sticky_posts );

            foreach ( $sticky_posts as $sticky_post ) {
                if ( in_array( $sticky_post, $ids ) ) {
                    // decrement sticky posts count if the sticky post in on the page
                    $sticky_count--;
                }
            }

            // and if the number of sticky posts is less than
            // the number we want to set:
            if ( $sticky_count < $posts_per_page ) {
                $query->set( \'posts_per_page\', $posts_per_page - $sticky_count );

            // if the number of sticky posts is greater than or equal
            // the number of pages we want to set:
            } else {
                $query->set( \'posts_per_page\', 1 );
            }

        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set( \'posts_per_page\', $posts_per_page );
        }
    }
}
add_action( \'pre_get_posts\', \'fix_posts_per_page_with_sticky_posts\'  );
我希望这会有帮助

SO网友:Andrew Killen

我将上述两个答案整理成一个,这样它就不会加载不必要的WP\\U查询,修复了第一页上的粘性问题,减少了处理信息的时间,代码更简洁、速度更快。

function modify_main_query( $query ) {
   if ( ( $query->is_home() || is_front_page() ) && $query->is_main_query() ) {
         // set the number of posts per page
        $posts_per_page = 12;
        // get sticky posts array
        $sticky_posts = get_option( \'sticky_posts\' );
        // if we have any sticky posts and we are at the first page
        if (is_array($sticky_posts) && !$query->is_paged()) {
            // make a second query to make sure the sticky posts will still work 
            // correctly when on the first page
            // Only reply with the ID\'s as that is all that is needed
            $args = [
                \'post_type\' => \'post\',
                \'post_per_page\' => $posts_per_page,
                \'paged\' => 1,
                \'fields\' => \'ids\'
            ];
            // Array flip to reduce the time taken by 
            // using isset and not in_array
            $posts = array_flip( get_posts( $args ) );

            // count the number of sticky posts
            $sticky_count = count($sticky_posts);

            // loop the posts from the 2nd query to see if the ID\'s of the sticky posts
            // sit inside it.
            foreach ( $sticky_posts as $sticky_post ) {
                if(isset($posts[$sticky_post])){
                    $sticky_count--;
                }
            }
            // and if the number of sticky posts is less than
            // the number we want to set:
            if ($sticky_count < $posts_per_page) {
               $query->set(\'posts_per_page\', $posts_per_page - $sticky_count);
            } else {
                // if the number of sticky posts is greater than or equal
                // the number of pages we want to set:
                $query->set(\'posts_per_page\', 1);
            }
        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set(\'posts_per_page\', $posts_per_page);
        }
    } 
}

add_action( "pre_get_posts", \'modify_main_query\' );

SO网友:jg314

这里写的答案可以完成任务,但WordPress提供了一种更简单的方法。作为WP_Query 类,WordPress包括current_post 所有物调用时,每次通过循环处理新帖子时,此属性都会增加1$my_query->the_post(). 该属性最初设置为-1。

因此,为了确保始终显示正确数量的帖子,包括粘性帖子,可以这样设置。在下面的示例中,无论有多少粘性帖子,总会显示两篇博客帖子。

<?php
$posts_per_page = 2;
$args           = array(
    \'posts_per_page\' => $posts_per_page,
);

$my_query = new WP_Query( $args );

if ( $my_query->have_posts() ) :

    while ( $my_query->have_posts() && $my_query->current_post + 1 < $posts_per_page ) :

        $my_query->the_post();

        // Run code to output your posts...

    endwhile;

endif;
这种方法只在自定义查询上进行了测试,但也应该与默认的WordPress循环一起使用。

结束

相关推荐