Detect Current Page Template

On the back of my hooks article last week, here’s another potentially useful WordPress trick I’ve picked up: detecting the current page template.

No SQL required

The beauty of the WordPress API is that in most situations, you can pull the values you need from the database without writing lines of SQL code. For example,

global $post;
get_post_meta($post->ID,'_wp_page_template',true);

This returns the template being used by the current page—for example, running it on my archives page would return the value archives.php, while doing it on my about page would return default. The function get_post_meta is documented in the Codex, but basically, it grabs some data from the wp_postmeta table of the database, which is used to store custom fields, including the post template.

A trip through postmeta land

By using the WordPress-generated $post variable, we avoid having to talk to the database directly; $post->ID returns the ID value of the current post, which can then be checked against the records in wp_postmeta. Since we want to return the page’s template, our second argument calls the key _wp_page_template, so the function will only return values with that key.

By default, the function returns an array, but by setting the third argument to true we can make it return a single result (the first one, although it’s pretty unlikely that a page has two _wp_page_template values. Obviously this technique can be extended to return the values for other custom fields, but I’ll leave that as an exercise for the reader.

The why of it

This trick could be useful for any number of things—I’m using it in Tarski to check whether a given page is an archives page, and to include or exclude certain things based on the result.

Obviously if I were just doing the include directly in the archives template, this wouldn’t be a problem, but since I’m actually calling a hook that’s present in a number of other templates, there’s no way I can tell in advance whether a given page is an archives page or not. In effect, I’m putting the coding burden onto my actions and filters, so as to not impose an overly restrictive system on end-users who might want to do something entirely different.

Coda

As a non-programmer myself, I’m always trying to work out how to do fairly simple things in WordPress. If people are interested, I could carry on writing up these code tips, so let me know what you think in the comments.

Amendment, 5th November 2007

If you’re on the WordPress trunk, instead of bothering with all this malarky just use the is_page_template function which was added in revision 6228. It will be in the 2.4 release when that comes out, and it uses essentially the same technique as I’ve described here, albeit with—as you’d expect—much more complete error handling.

Last updated 13th Jan 2009

,

5 responses

Very interesting code tips e.g. WP hooks. Keep on, as it’s easy to understand via your write up.

~ milo

Excellent mini-tutorial Benedict. I’ve added you to my feed list and will definitely be looking forward to more :).

Still a bit new too PHP, I downloaded Tarski and was looking through your code for a working example of this technique and wasn’t able to find it. I’m getting a “missing argument 2″ error in my implementation and am sure it’s because of my current lack of experience.

Would you mind sharing a complete working example for those new to PHP syntax? From there I’ll dive right in.

Keep up the excellent work! :)

-Jonathan

~ Jonathan

Update:

After a few more tries, I got it working! Do you have any suggestions for improvement?

< ?php
if(get_post_meta($post->ID,'_wp_page_template',true) == 'landing-page.php') { ?>

Hello World

< ?php } ?>

~ Jonathan

Thanks for this tip, I needed to do exactly this and was a bit disappointed when the Codex docs don’t mention a conditional tag along the lines of “uses_template($template_name)” function. You saved me from a real bind, thanks!

~ Stewart Johnson

Glad to hear it, Stewart. When I wrote the article, it seemed like an obscure hack that no one might ever need but me, and it’s nice to discover that’s not the case, and that it was worth writing up.

Jonathan: that looks just fine to me. I forgot to make it clear in the article that the Tarski implementation was just in our development build, and hadn’t made it into a proper release yet. Sorry about that. However, Tarski 1.5 is now out and includes this trick.

The code can be found here in the constants-hooks.php file, and I’m including the relevant part below for completeness’ sake (and in case the file ever changes or disappears). I’ll add a small piece of commentary after each function to elucidate what it does a little.

// Output $sidebarTopInclude
function tarski_output_sidebartopinclude() {
global $sidebarTopInclude;
global $post;
if(get_tarski_option('sidebar_onlyhome')) { // Sidebar only on index pages
if(!(is_page() || is_single())) {
tarski_output_constant($sidebarTopInclude);
}
} else { // Sidebar everywhere
if(!(is_page() || is_single())) {
tarski_output_constant($sidebarTopInclude);
} elseif(get_post_meta($post->ID,'_wp_page_template',true) != 'archives.php') {
tarski_output_constant($sidebarTopInclude);
}
}
}

All of these functions are a bridge between our previous theme hooks system—a flat PHP file with some variable definitions to allow people to customise the theme–and the new, action- and filter-based system which I described here. If a particular variable has a value—i.e. if the definition isn’t empty—then the function will output it. In this case we have a more generic action that adds stuff to the sidebar, while previous implementation only added that variable’s content under more specific circumstances (in this case, only on index pages when the option to only show the sidebar on those is set, and not on the archives page at all).

// Output $noSideBarInclude
function tarski_output_nosidebarinclude() {
global $noSidebarInclude;
global $post;
if(get_tarski_option('sidebar_onlyhome') && (is_single() || is_page())) {
if(get_post_meta($post->ID,'_wp_page_template',true) != 'archives.php') {
tarski_output_constant($noSidebarInclude);
}
}
}

This variable was included to let people put stuff in the sidebar when they’d set the option “Only display the sidebar on index pages”, and should only show on single entries and pages, and again, not on pages using the archives template.

// Output $archivesPageInclude
function tarski_output_archivesinclude() {
global $archivesPageInclude;
global $post;
if(get_post_meta($post->ID,'_wp_page_template',true) == 'archives.php') {
tarski_output_constant($archivesPageInclude);
}
}

This variable, on the other hand, should only be shown on pages using the archives page. All of this, really, is pretty hackish stuff and not at all optimal or ideal. However, sometimes one has to deal with legacy systems which are in common usage—as in this case with the constants.php file—and a hack is needed to bridge the old and new architectures.

~ Benedict