Freelance Web Design in Seattle, Wa

Figuring out if a WordPress page is descendant from another

In WordPress, there is no conditional tag for “is_child()” or “is_descendant()”, though I imagine there eventually will be, as this is a fairly common need for making logical demands within the WordPress templates. A reason I use this is to give different sections of a website, based on specific pages and their descendants, a different look (new background or header) than other sections. I’m sure there are many other reasons you’d want to do this.

For example, in a college website, you might need one header for the engineering department, and a separate one for the athletic department. Within WordPress, we are saying, if the current page is the descendant of the engineering department homepage, use header #1. If the current page is the descendant of the athletic department homepage, use header #2.

In WordPress, when creating a page, you have the option (in the righthand sidebar) to declare a parent page for your new page. This is WordPress’s way to create hierarchies similar to folder structures in static websites. There is no limit to how many descendants a page might have, allowing you to create child pages, child of child pages, etc.

A common way, in your template, to check if a page is descendant from another page, is to use this piece of code (which can be found in the WordPress codex), where ‘id’ is the numerical id of the page in WordPress:

if ( $post->post_parent == 'id' ) { then do some action }

However, the above code only works if the tested page is a direct parent of the current page. Well, what if you have a whole bunch of nested pages in the engineering department of your college?

There is another piece of code on that same WordPress codex page that will check if the current page is a descendant, now matter how deeply nested, of another page:

function is_tree($pid) {
// $pid = The ID of the ancestor page
global $post; // load details about this page
$anc = get_post_ancestors( $post->ID );
foreach($anc as $ancestor) {
if(is_page() && $ancestor == $pid) {
return true;
}
}
if(is_page()&&(is_page($pid)))
return true; // we're at the page or at a sub page
else
return false; // we're elsewhere
};

This function needs to be placed in the functions.php file of your theme. Then, you call this function when you need to test the ancestry of a page:

if ( is_tree( 'id' ) ) { then do some action }

This function essentially says, if this page is anywhere in the family tree of the tested page (including being the tested page itself), then do something.

There is one last detail that might come in handy, though. To check whether the current page is descended from another page, but is not that other page, you might do something like this:

if ( !is_page('id') && is_tree( 'id' ) ) { then do some action }

That’s clunky, though. If you’ll use this test somewhat regularly, just create another function in your functions.php file. You might call it “is_child()”. It’s exactly the same as “is_tree()” but without the last if statement:


function is_child($pid) {
// $pid = The ID of the ancestor page
global $post; // load details about this page
$anc = get_post_ancestors( $post->ID );
foreach($anc as $ancestor) {
if(is_page() && $ancestor == $pid) {
return true;
}
}
return false; // we're elsewhere
};

Now, if you need to determine if the current page is the child/descendant of another page, but is not that other page, you use this:

if ( is_child( 'id' ) ) { then do some action }

I seriously hope “is_child()” and “is_tree()” make it into the core functionality of WordPress one of these days, so I can stop having to add them to my functions.php file.

If you've found this article useful, found an error, or have a suggestion, please leave a comment below. Thanks a lot!


Tagged as: , , , , ,

5 Responses »

  1. Thanks, that code worked a treat. Absolutely agree that WordPress needs conditional tags such as is_child and is_descendant. In the meantime, it’s good to know we can create our own functions to do the task.

  2. Amazing, exactly what I needed! Hope they add the tag on the next releases.

    Thanks!!!

  3. Great advice, i’m currently using the second option. I’m using it because i’m converting my original website into a wordpress theme so that i can use it as a CMS :) it’s been tough but i’ve nearly finished it.

    This post has helped a lot and thank you :D

  4. Hey Ryan,

    Glad this was helpful. If you’re looking to use WordPress as a CMS, I can’t speak highly enough of Justin Tadlock’s articles ranging all over WordPress. Of particular interest to me was this article about custom post types. Custom post types really allow you to structure a site like a CMS, and it’s simpler than it looks at first blush to use them.

    Net Tuts+ has a great tutorial that has an even more concrete example than Justin’s site.

  5. Thanks, just what I needed! Funnily enough for almost the exact same purpose as you, except my ancestors are all the same homepage but in different languages. So I only want to show the child items that are in the correct language.

Leave a Response