web-dev-qa-db-ja.com

スティッキー投稿がページあたりの投稿数を超えている

私は私のホームページに表示される投稿数を調整するために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 plus anyスティッキーポストが表示されるため、クエリは指定した12のポストよりも more を表示します。私はもちろん、付箋を無視することができます:

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ポストの制限内で included であるべきであり、 追加 までではないと思います。それが私にとって最も理にかなっていることです。それを達成する方法はありますか?私は顔にやさしいエラーをしましたか?

スティッキーポストとページあたりのポスト しかしそれはローカライズされているので奇妙に閉じられていました。私は答えを探しているのは明らかだが、それはあなたがスティッキーポストを使っているのならWordPressがposts_per_page limit を尊重していないように思われる理由の問題でもあるので、私は同意しない。 1ページに12の投稿が必要な場合は、13ではなく12を取得する必要があります。これは、スティッキー投稿が1つの場合に表示される結果です。

21
helgatheviking

スティッキーポスト(ある場合)の数を取得し、それを計算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を1に設定しました。これにより、13以上の投稿が$sticky_count + 1(この場合)のみになります。最初のページ(後続のページには12の投稿があります)。このケースはまれであり、最初のページへの+1投稿はそれほど重要ではない可能性があるため、おそらくそれで問題ありません。

これは、Wordpressがすべてのスティッキー投稿を最初に表示し、そのカウントがposts_per_pageパラメーターよりも大きい場合でも1ページ(最初のページ)に表示するためです。この場合、posts_per_pageを可能な限り最小1と負の値により0パラメーターが無効になり、Wordpressが最初のページにすべての投稿を表示するため、posts_per_pageです。

12
Ahmad M

付箋が最初のページにある場合は問題があります。

解決策は、最初のページの一部であるスティッキポストのスティッキポスト数を減らすことです。

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'  );

助けになれば幸いです

3
csag

不要なWP_Queryがロードされないように上記の両方の回答を1つに整理しました。最初のページに固定されている場合は修正し、情報を処理する時間をよりクリーンなコードで短縮します。

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' );
0
Andrew Killen