私はmeta_value変数に基づくカスタムWP_Query
ループを持っています。
$meta_cat = get_sub_field('category');
$posts = new WP_Query( array(
'cat' => $meta_cat,
'posts_per_page' => get_sub_field('recent_ppp'),
) );
しかし、どういうわけか私が投稿をスティッキーにすると、whileループの最初の項目として表示されません。
ignore_sticky_posts
はデフォルトでfalseに設定されているので、変更する必要はありません。また、de order_byのドキュメントを参照してみてください 何らかの値がスティッキポストに関連しているがそうではない場合。
order_by => 'post__in'
は近いかもしれませんが:
Post__in配列で与えられた投稿IDの順序を保持する
しかし、私がpost__in => get_options('sticky_posts')
- only と設定した場合、スティッキーポストが表示されます。
2つのカスタムループを作成しなくてもこれは可能ですか。1つはスティッキポストを扱い、もう1つは他のポスト用です。すべてのカテゴリにスティッキポストが含まれているわけではないので、これは本当に悪いことです。
スティッキーが含まれているソースコードを見た場合、WP_Query
がスティッキー投稿を含めるようになる前に、次の条件が見つかります。
if ( $this->is_home
&& $page <= 1
&& is_array($sticky_posts)
&& !empty($sticky_posts)
&& !$q['ignore_sticky_posts']
) {
大物はis_home
状態です。 WP_Query
内の条件は、渡された引数に従って設定され、クエリが行われるページではありません。 cat
を引数として渡すので、is_home
はfalseに設定され、is_category
はtrueに設定されます。 is_home
がfalseに設定されているため、上記の条件は失敗し、スティッキは含まれません。
できることは、is_home
を使って手動でpre_get_posts
をtrueに設定することです。必要なのは、'wpse_is_home' => true,
をカスタムのWP_Query
インスタンスに渡すことだけです。
それから、pre_get_posts
アクションを以下のように実行します。
add_action( 'pre_get_posts', function ( $q )
{
if ( true === $q->get( 'wpse_is_home' ) )
$q->is_home = true;
});
私たちはおそらく質問されたカテゴリに関連性があるスティッキーズを見せたいだけでしょう。その場合は、特定の照会カテゴリに属さないスティッキを削除する必要があります。
pre_get_posts
アクションの中で、次のことを試すことができます。
add_action( 'pre_get_posts', function ( $q )
{
remove_action( current_action(), __FUNCTION__ );
if ( true !== $q->get( 'wpse_is_home' ) )
return;
// Make sure get_sub_field exists, if not, bail
if ( !function_exists( 'get_sub_field' ) )
return;
// Lets query everything to keep code clean
$meta_cat = get_sub_field( 'category' ); // Copied from your code
$meta_cat = filter_var( $meta_cat, FILTER_VALIDATE_INT );
// Make sure we have a value, if not, bail
if ( !$meta_cat )
return;
$q->set( 'cat', $meta_cat );
// Set pagination if recent_ppp exists
$ppp = get_sub_field( 'recent_ppp');
$ppp = filter_var( $ppp, FILTER_VALIDATE_INT );
if ( $ppp )
$q->set( 'posts_per_page', $ppp );
// Set is_home to true
$q->is_home = true;
// Get all stickies
$stickies = get_option( 'sticky_posts' );
// Make sure we have stickies, if not, bail
if ( !$stickies )
return;
// Query the stickies according to category
$args = [
'post__in' => $stickies,
'posts_per_page' => -1,
'ignore_sticky_posts' => 1, // Ignore stickies
'cat' => $meta_cat,
'orderby' => 'post__in',
'order' => 'ASC',
'fields' => 'ids' // Get only post ID's
];
$valid_sticky_ids = get_posts( $args );
// Make sure we have valid ids
if ( !$valid_sticky_ids ) {
$q->set( 'post__not_in', $stickies );
return;
}
// Remove these ids from the sticky posts array
$invalid_ids = array_diff( $stickies, $valid_sticky_ids );
// Check if we still have ids left in $invalid_ids
if ( !$invalid_ids )
return;
// Lets remove these invalid ids from our query
$q->set( 'post__not_in', $invalid_ids );
});
カスタムクエリを実行する前に、get_sub_field
が存在すること、そして最も重要なことにget_sub_field( 'category' )
が設定され有効であることを確認する必要があります。これは、すべての投稿が返されることにつながる壊滅的な失敗を回避します。
WP_Query
を渡すだけでよいので、あなたの'wpse_is_home' => true
は次のようになります。
if ( function_exists( 'get_sub_field' )
&& filter_var( get_sub_field( 'category' ), FILTER_VALIDATE_INT )
) {
$args = [
'wpse_is_home' => true
];
$posts_array = new WP_Query( $args ); // DO NOT USE $posts
// Run your loop as normal
}
最後の編集
コードはテストされ、期待通りに動作しています