WordPress Function: is_page_or_descendant()

Here’s a handy little function to check if the page you’re currently viewing is a specific page or a descendant of it (child, grandchild, etc). I’ve come across a few simliar functions: is_child(), is_subpage(), is_descendant(), etc; but none that met my needs exactly.

Example scenario:

You need a conditional tag to use in your theme template, which checks if a navigation item is “current” or not. If it’s current you want to highlight it somehow using CSS.

Working example:

On Melissa’s website, the top navigation is a list of pages.
Each tutorial on her site is a child page of the main Tutorials page.
When you are viewing the Pop Art Tutorial, the little triangle above the main nav indicates that you are in the Tutorials section of the site.

Example theme code

The main nav is an unordered list, here’s the list item for Tutorials:

<li <?php if (is_page_or_descendant('Tutorials')) echo 'class="current"'; ?>>
	<a href="/tutorials">Tutorials</a>
</li>

This code checks if the current page is ‘Tutorials’ or a descendant of it.
If so, then it adds the class=”current” attribute to the list item.
CSS and jQuery are then used to position the triangle above it.

Function Definition

bool is_page_or_descendant($page)

returns TRUE if the page you’re viewing is the specified page or a descendant of it

Function Parameters

$page
(mixed) (required) Page specified by ID (integer), title (string) or path (string)

Function Code

I hope this function is as useful for you as it is for me, enjoy 🙂

function is_page_or_descendant($page) {
	if (!is_page()) return false; 
 
	// retrieve page being currently viewed
	global $wp_query;
	$obj_current_page = $wp_query->get_queried_object();
	if (empty($obj_current_page->ID)) return false; 
 
	// retrieve specified page (ID, title or path)
	if (is_numeric($page)) $obj_specified_page = get_page($page);
	else $obj_specified_page = ($page_by_path = get_page_by_path($page)) ? $page_by_path : get_page_by_title($page);
	if (empty($obj_specified_page->ID)) return false;
 
	return ($obj_specified_page->ID == $obj_current_page->ID or $obj_specified_page->ID == $obj_current_page->post_parent or in_array($obj_specified_page->ID, get_post_ancestors($obj_current_page->ID)));
}

2 Responses to “WordPress Function: is_page_or_descendant()”

  1. Hi Charlie

    Regarding the is_page_or_descendant()

    WP3.1 offers a new function get_ancestors() to get an array of ancestor IDs for a given object, I was wondering if this would be any help in making your function work better ?

    • Hi Paul – thanks for your comment! The new get_ancestors() function differs from get_post_ancestors() by allowing you to specify the object type. So it doesn’t offer anything to is_page_or_descendant() which is only concerned with pages.