web-dev-qa-db-ja.com

あるカテゴリとそのすべての子カテゴリの下にある投稿用の特別な単一ページテンプレート

WordPressにブログがあります。複数のカテゴリがあります。あるカテゴリーの下のすべての投稿とそのすべてのサブカテゴリーに特定のレイアウトを使用したい.

例: 私のカテゴリは以下のように整理されています。

  1. ガイド(親カテゴリー)

    1.1選り抜き

    1.1.1テレビ

    1.1.2ラジオ

    1.2配管

    1.3家の修理

    1.3.1キッチン

    1.3.2浴室

4
Bikram Pahi

あなたはsingle_templateフィルターでそれをすることができます。まず、投稿がトップレベルのカテゴリに属しているかどうかを確認する必要があります。だからここに関数です。

// custom single template for specific category
function wpse_custom_category_single_template( $single_template ) {

    global $post;

    // get all categories of current post
    $categories = get_the_category( $post->ID );
    $top_categories = array();

    // get top level categories
    foreach( $categories as $cat ) {
        if ( $cat->parent != 0 ) {
            $top_categories[] = $cat->parent;
        } else {
            $top_categories[] = $cat->term_id;
        }
    }

    // check if specific category exists in array
    if ( in_array( '8', $top_categories ) ) {
        if ( file_exists( get_template_directory() . '/single-custom.php' ) ) return get_template_directory() . '/single-custom.php';
    }

    return $single_template;

}

add_filter( 'single_template', 'wpse_custom_category_single_template' );

似たような状況では、通常、人々は$categories[0]->category_parent;で親カテゴリをチェックします。これは正しいですが、各投稿に1つのカテゴリを割り当てた場合にのみ機能します。あなたが2つ以上のカテゴリを持っているならば、この解決策は常にうまくいくでしょう。

3
Robert hue

編集

NOTE親と第1レベルの子用語のみが必要な場合は、@ Rooberthueからの回答が非常に役立ちます。動作するはずです

コードをより効果的に更新しました。

  • get_ancestors()を実行するのは、親用語またはその直接の子が見つからない場合だけにしてください。

  • get_ancestor関数から親用語を見つけたらすぐにforeachループの実行を停止します

  • 小切手を細かく分割して、小切手がtrueを返したらすぐに実行を停止する

もともとの答え

デフォルトでは、特定のカテゴリの投稿に対して特定のテンプレートを設定するオプションはありません。これは、できないという意味ではありません。これを実現するには、 single_template filter を使用して、カスタムの単一テンプレートページを特定のカテゴリセットを含む投稿に設定する必要があります。

次のようなことを試すことができます。(CAVEAT:コードはテストされていないため、少なくともPHP 5.3

add_filter( 'single_template', function ( $template ) 
{
    // Get the current queried post id
    $current_post = get_queried_object_id();

    // Get the post terms. Change category to the correct taxonomy name if your post terms is from a custom taxonomy
    $terms = wp_get_post_terms( $current_post, 'category' );

    // Check if we have terms and we don't have an error. If we do, return default single template
    if ( !$terms || is_wp_error( $terms ) )
        return $template;

    // Check if our custom template exists before going through all the trouble to find out terms
    $new_template = locate_template( 'single-custom.php' );
    if ( !$new_template ) 
        return $template;

    // Get al the term ids in an array and check if we can find our parent term
    $term_ids = wp_list_pluck( $terms, 'term_id' );
    if ( in_array( 10, $term_ids ) )
        return $template = $new_template;

    // Get all the parent ids in an array and look for our parent term if we could not find it using term ids
    $parent_ids = wp_list_pluck( $terms, 'parent' );
    if ( in_array( 10, $parent_ids ) )
        return $template = $new_template;

    // If we cannot find the parent or direct children, lets look for lower level children
    $bool = false;
    foreach ( $term_ids as $term ) {
        // Use get_ancestors and check if we can find our parent term id
        if ( in_array( 10, get_ancestors( $term, 'category' ) ) ) {
            $bool = true;
            // If we found our parent, stop execution of our foreach loop
            break;
        }
    }

    // If $bool is true, return our custom single template
    if ( $bool )
        return $template = $new_template;

    // If all our conditions failed, return the default single template
    return $template;
});

編集2

上記のコードは現在テスト済みで動作しています。いくつかの小さなバグを修正しました:-)

4
Pieter Goosen