スティッキーポストがページごとの制限を超える


21

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 制限を尊重していないように見える理由の質問でもあるためです。1ページあたり12件の投稿が必要な場合は、13件ではなく12件を取得する必要があります。

回答:


12

スティッキーポストの数(存在する場合)を取得し、それを計算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);
        }
    }
}

編集

設定するページあたりの投稿数がスティッキー投稿の数以下である場合、1に設定し、最初のposts_per_page投稿$sticky_count + 1のみで13以上の投稿(この場合)になりますページ(後続のページには12の投稿があります)。このケースはまれであり、最初のページへの+1投稿はそれほど重要ではない可能性があるため、おそらくそれで問題ありません。

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


すばらしいです!!ただし、変更$sticky_count + (12 - $sticky_count)する必要があると思います12- $sticky_count。たとえば、スティッキーが1つある場合、数学はまだ12になり、WPはスティッキーポストを追加して13 if ($sticky_count > $posts_per_page)にします。
helgatheviking

@helgatheviking:そのとおりです。私はいつもそのようなばかげた間違いを犯しますが、計算は決して面白くありませんでした。そして、はい、それは24の投稿になります。そのためにコードを更新し、ページ番号のチェックを追加しました。これは正常に機能しますが、$posts_per_pageに等しくなるケースが1つ$sticky_countあり、ここでposts_per_pageパラメーターを1に設定します。$sticky_count + 1)。
アフマドM

編集してくれてありがとう!これは、スティッキーポストを使用して得られる最善のソリューションだと思います。投稿が特集されているかどうかについて、最終的には単純なメタキーでソートできると思います。私の理解では、それはより正常に動作します。
ヘルガサビキング

スティッキーな投稿が本来必要なposts_per_pageの一部である場合、これは解決策として失敗します。投稿の総数は減少しますが、スティッキー投稿は通常の日付順序セットの一部であるため、その数を押し上げることはありません。
アンドリューキレン

3

固定投稿が最初のページにある場合、問題があります。

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

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

私はそれが役立つことを願っています


1
簡単で迅速な解決策はありませんか?ヒント:スティッキーポストやページごとの投稿の量を知っている...
カイザー

私はこれが私の意見でWPコアにする必要があります何かのためのより多くの修正..ですので、はるかに良い見つかりませんでした
CSAG

コアにある場合、他のシナリオは機能しません。
カイザー14

これは既知のバグであり、core.trac.wordpress.org / ticket / 27282
Will

@kaiser Ahmad Mのソリューションは、スティッキーの状態に関係なく、最初のページに表示されるスティッキーな投稿を考慮しません。最初のページに表示される投稿が少なすぎる可能性があります(WordPress v4.9.7)。それはそれを説明するので、この答えはより良いです。
ジェイコブバディン

0

上記の両方の回答をクリーンアップして、不要なWP_Queryをロードしないようにし、最初のページに粘着性がある場合は修正し、より高速なコードで情報を処理する時間を短縮します。

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' );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.