Is there a default template file for child pages / subpages?
-
15-04-2021 - |
Question
This seems like a very simple question. I'm looking for something like sub-page.php or page-child.php where I can do some different things on the child pages of my theme.
They are different enough in design and content that I'm having to use a lot of php or the CSS .page-child class to do all the dirty work. I'm looking for a simpler method.
One caveat - I would like this to happen automatically so I don't have to tell the client "make sure to always select the 'subpage' template when you create a subpage!" which is precarious..
La solution
There is no specifica template for child pages, but you can do this pretty easily with the get_template_part() function.
First create a file called "content-child.php".
Second create a file called "content.php".
Next, inside of page.php, place this:
if( $post->post_parent !== 0 ) {
get_template_part('content', 'child');
} else {
get_template_part('content');
}
Anything that you want displayed on a child page will be placed inside of content-child.php. Anything you want displayed on non-child pages will be placed in content.php.
Autres conseils
It's actually very easy, add follow code to your functions.php
add_filter(
'page_template',
function ($template) {
global $post;
if ($post->post_parent) {
// get top level parent page
$parent = get_post(
reset(array_reverse(get_post_ancestors($post->ID)))
);
// or ...
// when you need closest parent post instead
// $parent = get_post($post->post_parent);
$child_template = locate_template(
[
$parent->post_name . '/page-' . $post->post_name . '.php',
$parent->post_name . '/page-' . $post->ID . '.php',
$parent->post_name . '/page.php',
]
);
if ($child_template) return $child_template;
}
return $template;
}
);
Then you can prepare templates with following patterns:
[parent-page-slug]/page.php
[parent-page-slug]/page-[child-page-slug].php
[parent-page-slug]/page-[child-post-id].php
My modification of OzzyCzech's solution above. This function looks in the theme's root directory for files who's name contains the parent's slug or parent's ID.
/theme_root/child-PARENT_SLUG.php
/theme_root/child-PARENT_ID.php
function child_templates($template) {
global $post;
if ($post->post_parent) {
// get top level parent page
$parent = get_post(
reset(array_reverse(get_post_ancestors($post->ID)))
);
// find the child template based on parent's slug or ID
$child_template = locate_template(
[
'child-' . $parent->post_name . '.php',
'child-' . $parent->ID . '.php',
'child.php',
]
);
if ($child_template) return $child_template;
}
return $template;
}
add_filter( 'page_template', 'child_templates' );