4

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..

13

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.

  • I was able to make this code work. As it turned out - I didn't need to separate it quite as much as I thought, so I just adjusted your code and used it in page.php in a couple specific instances. The CSS selector 'page-child' helped round out the edges. Thanks! – timshutes Jun 15 '12 at 5:29
  • Nice! Great solution. How to set a different template for Parent > Child > Child? Thanks! – Brightweb Jul 25 '12 at 21:23
9

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
  • 1
    This is a highly underrated reply, it's way more versatile than the accepted answer. +1 from me and another +1 for using an anonymous function. – gbinflames Nov 6 '18 at 23:07
0

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' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.