私は各カテゴリーに付箋を貼ることができる必要があります。これを行う最も簡単な方法は、ページ上に2つのループを作成することです。これは私が書いたものです:
<?php
//Custom "sticky" loop
$sticky_posts = new WP_Query(array(
'post__in' => get_option('sticky_posts')
));
if ($sticky_posts->have_posts()) :
while ($sticky_posts->have_posts()) : $sticky_posts->the_post();
get_template_part('post-formats/content', 'sticky');
endwhile; endif;
// CLEAR DATA
wp_reset_postdata();
if (have_posts()) :
// Normal loop
while (have_posts()) : the_post();
$format = get_post_format();
if (false === $format) {
$format = 'standard';
}
get_template_part('post-formats/content', $format);
endwhile;
残念ながらそれは期待通りに動作しません:
私は何をしましたか。私はスティッキーな投稿が2回表示されることを認識しています(1回は上部に、もう1回は通常の位置に表示されます)。 : - /
これをより完全にするために、手元の質問に答えて私がコメントで言ったことはここにあります
簡単に説明すると、
WP_Query
は空の配列がそのパラメータの一部に渡される場合に壊滅的に失敗します。予想どおりに空の配列も返すのではなく、WP_Query
はすべての投稿を返します。前述したように、正しいスティッキを取得するためには、現在のカテゴリIDを取得し、それを使用してスティッキ投稿をフィルタリングする必要があります。覚えておいて、あなたのアプローチでは、あなたがメインクエリからスティッキー投稿を削除する必要がありますそうでなければあなたは重複するでしょう
メインクエリでフックとフィルタを使用し、 類似の質問/回答 から作業する別の解決策として、これが私が思いついたものです:(コードはよくコメントされているので追うことができます)注意:これはまだテストされていないため、少なくともPHP 5.4+)が必要です。
function get_term_sticky_posts()
{
// First check if we are on a category page, if not, return false
if ( !is_category() )
return false;
// Secondly, check if we have stickies, return false on failure
$stickies = get_option( 'sticky_posts' );
if ( !$stickies )
return false;
// OK, we have stickies and we are on a category page, continue to execute. Get current object (category) ID
$current_object = get_queried_object_id();
// Create the query to get category specific stickies, just get post ID's though
$args = [
'nopaging' => true,
'post__in' => $stickies,
'cat' => $current_object,
'ignore_sticky_posts' => 1,
'fields' => 'ids'
];
$q = get_posts( $args );
return $q;
}
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // IMPORTANT, make sure to target front end only
&& $q->is_main_query() // IMPORTANT, make sure we only target the main query
&& $q->is_category() // Only target category archives
) {
// Check if our function to get term related stickies exists to avoid fatal errors
if ( function_exists( 'get_term_sticky_posts' ) ) {
// check if we have stickies
$stickies = get_term_sticky_posts();
if ( $stickies ) {
// Remove stickies from the main query to avoid duplicates
$q->set( 'post__not_in', $stickies );
// Check that we add stickies on the first page only, remove this check if you need stickies on all paged pages
if ( !$q->is_paged() ) {
// Add stickies via the the_posts filter
add_filter( 'the_posts', function ( $posts ) use ( $stickies )
{
$term_stickies = get_posts( ['post__in' => $stickies, 'nopaging' => true] );
$posts = array_merge( $term_stickies, $posts );
return $posts;
}, 10, 1 );
}
}
}
}
});
これはデフォルトのcategory
分類法でのみ機能します。分類法とその関連用語を使用するために、コードを簡単に変更することができます(それを実行してください。必要に応じて変更してください)。
これをfunctions.phpに追加するだけです。テンプレートファイルを変更したり、カスタムクエリを使用したりする必要はありません。必要なのは、デフォルトのループを持つメインクエリーだけです。
上記のコードは現在テストされており、Wordpress 4.2.1とPHP 5.4以降で動作しています。
評判のせいでPieter Goosenの回答をコメントすることはできません/ - :
現在のコードは現在のwordpress 4.8(2018年3月)に副作用があり、存在しないページにアクセスするとスティッキポストが表示され、代わりに404エラーが発生します。 "asd"が存在しない "www.example.com/asd"のように。同じ問題それ "WP - 管理者"。これは、その場合「asd」または「wp-admin」がカテゴリ名として$ qに保存されているためです。ただし、これは既存のカテゴリではありません。
修正:上記のコードにこのコードの最後の行を追加して、渡されたカテゴリが本当に存在するかどうかを確認します。
if ( !is_admin() // IMPORTANT, make sure to target front end only
&& $q->is_main_query() // IMPORTANT, make sure we only target the main query
&& $q->is_category() // Only target category archives
&& $q->is_tax(get_query_var ( 'category_name')) // Only target existing category names
両方の問題に対する答えは非常に簡単でした。
そのようです:
<?php
// Get sticky posts
$sticky_ids = get_option( 'sticky_posts' );
// BEGIN Custom "sticky" loop
// If sticky posts found...
if(!empty($sticky_ids)) {
$args = array(
'post_type' => 'post',
'category__in' => get_query_var('cat'), // Get current category only
'post__in' => get_option('sticky_posts') // Get stickied posts
);
$sticky_posts = new WP_Query($args);
if ($sticky_posts->have_posts()) :
while ($sticky_posts->have_posts()) : $sticky_posts->the_post();
get_template_part('post-formats/content', 'sticky');
endwhile; endif;
// END Custom "sticky" loop
// Reset post data ready for next loop
wp_reset_postdata();
}
if (have_posts()) :
/* Start the Loop */
while (have_posts()) : the_post();
$format = get_post_format();
if (false === $format) {
$format = 'standard';
}
get_template_part('post-formats/content', $format);
endwhile; endif; ?>