Wordpress - 父类别和所有子类别的自定义模板页面

Wordpress - custom template page for a parent category and all child categories

在 WP 5.4.2 中,我想为一个类别及其所有子类别创建一个自定义存档页面。我知道模板文件层次结构:

1. category-slug.php
2. category-ID.php
3. category.php
4. archive.php
5. index.php

但如果我理解正确并且所有测试都正确,那么 category-slug.phpcategory-id.php 方案适用于单个类别,而不管类别层次结构如何。

假设我有以下类别:

colors (id 2)
- red  (id 10)
- green (id 11)
- blue  (id 12)

我需要一个用于所有这些的模板文件。简单地创建 category-colors.phpcategory-2.php 是行不通的。它仅适用于单一类别(颜色)。我希望它适用于所有当前的子类别,以及我将来添加的所有子类别。可能吗?如果是,请指教如何。

有多种方法可以做到这一点,但使用 category_template 过滤器让您使用自定义类别模板似乎是最常见的方法。

下面的函数可以让您动态地检查当前类别的父级别,直到它为最近的祖先找到一个名为“category-[parent slug]”的模板类别或达到最高级别 - 以先到者为准。

假设你有这样的东西:

 - products
    - hardware
    - food
      - dairy
      - vegetables
  1. 在奶制品页面上,它会首先检查您是否有一个名为 category-dairy.php 的鼻涕虫。
  2. 如果你这样做,它会 return 它。
  3. 如果您不这样做,它将查找 category-food.php
  4. 如果没有找到,它将寻找 category-products.php

将此添加到您的 functions.php - 这是未经测试的代码,注释很好,因此您可以理解它是如何工作的:

function get_template_for_category( $template ) {

    if ( basename( $template ) === 'category.php' ) { // No custom template for this specific term, let's find it's parent
        // get the current term, e.g. red
        $term = get_queried_object();

        // check for template file for the page category
        $slug_template = locate_template( "category-{$term->slug}.php" );
        if ( $slug_template ) return $slug_template;

        // if the page category doesn't have a template, then start checking back through the parent levels to find a template for a parent slug
        $term_to_check = $term;
        while ( $term_to_check ->parent ) {
            // get the parent of the this level's parent
            $term_to_check = get_category( $term_to_check->parent );

            if ( ! $term_to_check || is_wp_error( $term_to_check ) )
                break; // No valid parent found

            // Use locate_template to check if a template exists for this categories slug
            $slug_template = locate_template( "category-{$term_to_check->slug}.php" );
            // if we find a template then return it. Otherwise the loop will check for this level's parent
            if ( $slug_template ) return $slug_template;
        }
    }

    return $template;
}
add_filter( 'category_template', 'get_template_for_category' );

参考文献: