Reputation: 761
In WP 5.4.2 I want to create a custom archive page for a category and all it's child categories. I am aware of the template file hierarchy:
1. category-slug.php
2. category-ID.php
3. category.php
4. archive.php
5. index.php
but if I understand correctly and if I did all the testing right, the category-slug.php
, or the category-id.php
scheme applies to a single category regardless of the category hierarchy.
Let's say I have following categories:
colors (id 2)
- red (id 10)
- green (id 11)
- blue (id 12)
I need a single template file for all of them. Simply creating category-colors.php
or category-2.php
doesn't work. It applies to the single category (colors) only. I want it to apply to all the current child categories, as well as all the child categories I add in the future. Is it possible? If so, please advice how.
Upvotes: 3
Views: 2416
Reputation: 14312
There are a couple of ways to do this, but using the category_template
filter to let you use a custom category template seems the most common.
The function below will let you dynamically check back through the parent levels of the current category until it finds a template called "category-[parent slug]" for the closest ancestor category or it reaches the top level - whichever is first.
Suppose you have something like:
- products
- hardware
- food
- dairy
- vegetables
category-dairy.php
.category-food.php
.category-products.php
.Add this to your functions.php - this is untested by the code is well commented so you can understand how it works:
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' );
References:
category_template
Referencelocate_template
ReferenceUpvotes: 4