Using the page hierarchy to customize different parts of a WordPress website.
In most complex websites that use WordPress as their Content Management System, custom development will require bringing changes to the code makeup of different sections of the website. This becomes more and more true as the amount of pages increases.
WordPress pages lack categories & tags:
Posts are entered into a database and need search-oriented categorization systems in order to be found and displayed in a WordPress theme. They are placed in hierarchical categories and associated with tags.
Pages on the other hand are expected to be more solid in their structure. Categories and tags are not available in WordPress pages: the only way to organize them is in hierarchy of each other. A page may both BE the child of another (its parent) and HAVE other pages as children. That is all.
Page templates are great…
It is possible to create and assign as many different page templates to WordPress pages as you wish. This way you can have different pages display their content quite differently. So you can have as many page templates as you want, and you can assign a template to as many pages as you want. NOT BAD.
…but what about the header?
The whole point of having the header.php, page.php and footer.php seperate is that it replaces the need for templates. With database technology, we have moved away from generating large amounts of static HTML pages with common ‘template’ code, to dynamically assembling different building blocs, THEN loading unique content into thus generated HTML pages.
So what if I want the header’s appearance to change depending on which section of the website I am?
Conditional Tags are awesome…
Let’s take a look at how to play with identifying which page we are on. This way we can use wordpress-specific php conditional tags to control the code that is included in the page sent to the end user.
// using the php if statement, we can test the values of WordPress specific tags:
// to test if you are on the index page of your domain
// remember you can set a static page as your front page in settings>reading
if ( is_front_page() ) { ... }
// to test if you are on the WordPress index.php template page of your theme
if ( is_home() ) { ... }
// to test which page you are on by ID number, page_title or post_name (slug)
// we will assume we are always interested in page with postID: 6
// the postID of a page is the number at the end of its 'edit' URL in the CMS UI
//
if ( is_page('6') ) { ... }
// to test if you are on a page that is a child of page 6
if ( $post->post_parent == '6' ) { ... }
// to test if you are on page 6 OR one of it's DIRECT children
if ( is_page('6') || $post->post_parent == '6' ) { ... }
// to test if a specific page template is being used
if ( is_page_template('page6template.php') ) { ... }
// to test if the sidebar is being displayed
if ( is_active_sidebar() ) { ... }
// to test if comments are enabled. useful to distinguish blog from pages
if ( comments_open() ) { ... }
… but $post->post_parent only works for direct children!
So what if we want to test whether we are on a level-4 descendant of page ’6′? Indeed, placing pages as children of children of children is the only way WordPress allows us to organize large amounts of pages.
The WordPress codex website suggests we create a is_tree() function and place it in the functions.php template file of our theme:
function is_tree($pid) { // $pid = The ID of the page we're looking for pages underneath
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
};
Then you can use that function to test if you are on a specific page or any of its descendants.
// to test if you are on page '6' or any level descendant of page '6'
if( is_tree('6')) { ... }
Creating a $grandpa variable:
It can be practical to create a $grandpa variable that is loaded with the postID of the first ancestor page of the current page (the great-grandpa!). This way you can test the value of that variable, or write it into HTML, CSS of JavaScript.
In his post on CSS Globe, Alen Glakalic gives a method to do precisely this. Paste this code in the <head> of your header.php template file:
if ($post->post_parent) {
$ancestors=get_post_ancestors($post->ID);
$root=count($ancestors)-1;
$grandpa = $ancestors[$root];
} else {
$grandpa = $post->ID;
}
Now $grandpa is the numeric postID of the first ancestor of the page you are on, or the ID of the page you are on if it has no parents.
Real life applications:
OK, so now you know how to test whether you are on the home page, the blog index page, a particular page or one of it’s descendants. You can test if the sidebar is being displayed on this page or if a particular template is being used… You can even create a $grandpa variable and test its value or echo it where convenient.
Example 1: Load a CSS and jQuery file in header only for descendants of page 6
Let’s say you want to use colorbox (or lightbox equilivalents) but only in the portfolio section of your website. You only want to load scripts when necessary to avoid waste of bandwidth.
- Create a “portfolio” page and set all children as ‘sub-pages’ in the WordPress CMS.
- Find out the postID number associated with the “portfolio” page. We will assume it is 6.
- Add the is_tree() function to your functions.php template page.
- Type this code in your header:
<?php if( is_tree('6') ) { ?>
<link rel="stylesheet" href="/path/to/your/script/styleSheet.css" type="text/css" />
<script type="text/javascript" src="/path/to/your/sript/colorbox.js"></script>
<?php } ?>
Example 2: Assign classes to menu elements with jQuery and $grandpa
Say you have a website divided into three sections: About us, Products and Portfolio. The menu navigation has three big links to the sections and drop downs for their sub-pages. You want the big link of the section being visited to change style when someone is viewing one of its sub-pages in order to make it obvious to the user where he is.
I. Create the links and assign id tags based on the postID of the top hierarchy page they link to:
<ul id="menuNav">
<li><a id="menu-item-2" href="/about-us">About us</a></li>
<li><a id="menu-item-4" href="/products">Products</a></li>
<li><a id="menu-item-6" href="/portfolio">Portfolio</a>
<ul><li><a>...sub-page...</a></li>
... sub-pages ...
</ul>
</li>
</ul>
II. Give them style on your CSS sheet:
ul#menuNav li {
float: left;
list-style: none;
}
ul#menuNav li a {
display: block;
width: 100px;
padding: 5px;
text-align: center;
color: white;
font-weight: bold;
text-decoration: none;
border: 5px solid blue;
background-color: green;
}
ul#menuNav li a:hover {
border: 5px solid black;
background-color: white;
color: black;
}
ul#menuNav li a.active {
border: 5px solid black;
background-color: #ddd;
color: black;
}
Note that the last rule refers to <a> with a class of “active” that we have not assigned yet. This is precisely when the $grandpa variable comes in handy.
III. Use javascript and php echo together to make magic!
Using php to echo the $grandpa variable into a line of Jscript, we will be able to achieve our effect with minimal scripting:
//in the <head>...
<?php
if ($post->post_parent) {
$ancestors=get_post_ancestors($post->ID);
$root=count($ancestors)-1;
$parent = $ancestors[$root];
} else {
$parent = $post->ID;
} ?>
<script type="text/javascript">$(document).ready(function(){
$('a#menu-item-<?php echo $parent; ?> > a ').addClass('active');
});</script>
IV. Sit back and enjoy the effect!
Now, not only will the main links react to hover, they will also change style to indicate which section of the website you are in, or in other words, which of the 3 master pages is the first ancestor of the page you are currently viewing.
And Voila!
I hope you found this article useful to understand various techniques for using WordPress page hierarchy and properties to customize content and appearance.
Tags: ancestors, coding, CSS, development, hierarchy, how to, HTML, javascript, jQuery, many pages, menu, page, php, UI, WordPress


[...] Using the page hierarchy to customize different parts of a WordPress website. | Adal Design [...]
[...] Using the page hierarchy to customize different parts of a WordPress website. | Adal Design [...]
If you have 10 sites in related niches, and it makes sense to send visitors from one to the other, then there’s little chance that you’re risking being penalized by the search engines. It’s the same with a company linking to its customer support forum. If it makes sense to do it for the visitors, do it.
Thx!! I am finaly able to give sub sub pages a different header with the is_tree function, this brings infinitive possibilities, thanks a lot!!
Hey no problem man, the pleasure’s in sharing. If you have tricks you want to learn about, suggest it and I might write an article.
Navigation within a website should be seamless. Users should be able to find their way around easily. While there is no standard for navigation within a website, especially now as more new web development technologies emerge, it is imperative to understand that navigation must be intuitive and consistent.
A critical element is that the content management system use search-engine friendly URL’s if your content is to be found and indexed by search engines such as Google and Bing. A few CMS programs cannot generate intuitive file names so you end up with names such as: