Специальные шаблоны отдельных страниц для сообщений по категориям и всей их дочерней категории

У меня есть блог в WordPress. У меня несколько категорий. Я хочу использовать конкретный макет для всех сообщений под категорией и всеми ее подкатегориями.

Пример. Мои категории организованы ниже.

  1. Руководство (родительская категория)

    1.1.

    1.1.1 ТВ

    1.1.2 Радио

    1.2 Сантехника

    1.3 Домашний ремонт

    1.3.1 Кухня

    1.3.2 Ванная комната

Вы можете сделать это с single_template фильтра 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; , что является правильным, но работает только в том случае, если вы назначили одну категорию для каждого сообщения. Если у вас 2 и более категорий, это решение всегда будет работать.

РЕДАКТИРОВАТЬ

ПРИМЕЧАНИЕ. Если вам нужны только родительские и младшие дочерние термины, ответ от @Roberthue должен отлично работать. Если вам нужны все уровни, то мое решение должно работать)

Я обновил свой код, чтобы быть более эффективным.

  • Запускать get_ancestors() только в том случае, если мы не можем найти родительский термин или его прямые дети

  • Остановите выполнение цикла foreach немедленно, когда мы найдем наш родительский термин из функции get_ancestor

  • Сломайте мои проверки на более мелкие куски и немедленно прекратите выполнение, когда мои проверки вернутся

ОРИГИНАЛЬНЫЙ ОТВЕТ

По умолчанию нет возможности установить конкретный шаблон для сообщений из определенной категории. Это говорит о том, что это не значит, что это невозможно. Чтобы добиться этого, вам нужно использовать фильтр single_template чтобы настроить вашу страницу отдельного шаблона на сообщения с определенным набором категорий.

Вы можете попробовать что-то вроде следующего: ( 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; }); 

EDIT 2

Вышеприведенный код теперь протестирован и работает. Исправлено несколько мелких ошибок 🙂