Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

One you have called a template with get_template_part() (or locate_template()) is there a way to know what template you are in.

For example if you call get_template_part('loop','archive'); from archive.php

and then are working in your loop-archive.php file. is there a way to define a variable that has the name of the current template part.... so $template = 'loop-archive'. better still, maybe in two parts so 'loop' and 'archive' but I can do that with some string splitting.

Question #10537 seems sort of related but doesn't seem to cover template parts.

share|improve this question
add comment

4 Answers

up vote 2 down vote accepted

There isn't a core global variable that returns the current context. However, you can construct your own, using contextual template conditional tags. You can step through the conditional tags in the same order as WordPress core, by following wp-includes/template-loader.php.

Simply wrap your output in a custom Theme function. Here's how I do it (note: I don't think I strictly follow template-loader.php):

function oenology_get_context() {

    $context = 'index';

    if ( is_home() ) {
        // Blog Posts Index
        $context = 'home';
        if ( is_front_page() ) {
            // Front Page
            $context = 'front-page';
        } 
    }else if ( is_date() ) {
        // Date Archive Index
        $context = 'date';
    } else if ( is_author() ) {
        // Author Archive Index
        $context = 'author';
    } else if ( is_category() ) {
        // Category Archive Index
        $context = 'category';
    } else if ( is_tag() ) {
        // Tag Archive Index
        $context = 'tag';
    } else if ( is_tax() ) {
        // Taxonomy Archive Index
        $context = 'taxonomy';
    } else if ( is_archive() ) {
        // Archive Index
        $context = 'archive';
    } else if ( is_search() ) {
        // Search Results Page
        $context = 'search';
    } else if ( is_404() ) {
        // Error 404 Page
        $context = '404';
    } else if ( is_attachment() ) {
        // Attachment Page
        $context = 'attachment';
    } else if ( is_single() ) {
        // Single Blog Post
        $context = 'single';
    } else if ( is_page() ) {
        // Static Page
        $context = 'page';
    }

    return $context;
}

Then, I just pass oenology_get_context() as a parameter, e.g.:

get_template_part( 'loop', oenology_get_context() );

I think something along these lines would be a good candidate for core, though I'm not sure the best way to implement. I'd love to submit a patch, though.

share|improve this answer
    
wow chip. that's very, very slick. and your use case is exactly what i was intending. as far as a patch, why wouldn't you just register this global right at the same time you are stepping through template loader? –  helgatheviking Aug 23 '12 at 3:16
1  
Because I'm not sure if adding another global would be the "blessed" approach for core. Probably a function that returns context as a string would be better - but then, that would probably require a bit of a rewrite to template-loader.php. –  Chip Bennett Aug 23 '12 at 11:09
    
Nice +1. Just one note: index would never match, as either is_front_page() or is_home() would trigger. –  kaiser Sep 17 '12 at 12:21
    
Another thing: is_home() should be first, as it gives back front-page even when the "latest post" setting is activated and no front-page is present. Just tested. –  kaiser Oct 2 '12 at 10:52
add comment

bit of a facepalm, because the answer is in pure PHP

$path_parts = pathinfo(__FILE__);
//var_dump($path_parts); 
echo $path_parts['filename'];
share|improve this answer
add comment

If you look at the source code of get_template_part function, you'll see:

function get_template_part( $slug, $name = null ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    locate_template($templates, true, false);
}

It creates an array of 2 template names: {$slug}-{$name}.php and {$slug}.php and use load_template to find the template file and include it (the 2nd parameter is true, which means include that file).

You can mimic this function to return the template file path instead of include it, like:

function my_get_template_part( $slug, $name = null, $include = false ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    return locate_template($templates, $include, false);
}

Usage:

// Don't load the template
$template = my_get_template_part( 'loop', 'archive', false );

// Or load the template
$template = my_get_template_part( 'loop', 'archive', true );

// Get the file name only
$template = basename( $template );

// Without .php extension
$template = substr( $template, 0, -4 );

You can play more with $template to get what you want.

share|improve this answer
    
that's pretty neat! +1 for sure, but i needed to know the $template info inside the loop-arhive.php template (to follow your example) –  helgatheviking Aug 22 '12 at 1:39
    
You can use a global variable which is set in archive.php, and reuse it in loop-archive.php –  Rilwis Aug 22 '12 at 16:36
add comment

List all conditionals that are true

As all is_*() functions have their equivalent in a query variable (the functions are just wrappers), you can access them also another way: Get simply all that are true.

I wrote a ticket on core/trac that adds a function to list them all.

In the meanwhile you can use both listed functions as helper plugins that show you on which request which conditional is available. It will print a var_dump() below the footer (both admin & public) at the shutdown hook.

<?php
/** Plugin Name: (#62232) »kaiser« List all conditionals that are true */
function get_conditionals()
{ 
        global $wp_query; 

        foreach ( array_keys( (array) $wp_query ) as $is_ ) 
        { 
                if ( $wp_query->$is_ && preg_match( "/is_/", $is_ ) ) 
                        $conditionals[] = $is_; 
        } 

        return var_dump( $conditionals );
} 
add_action( 'shutdown', 'get_conditionals' );

This way you can simply loop through them.

@scribu added his own function to the ticket (an interesting solution too).

   

<?php
/** Plugin Name: (#62232) »scribu« List all conditionals that are true */
function get_query_flags( $wp_query = null ) {
    if ( !$wp_query )
        $wp_query = $GLOBALS['wp_query'];

    $flags = array();

    foreach ( get_object_vars( $wp_query ) as $key => $val ) {
        if ( 'is_' == substr( $key, 0, 3 ) && $val )
            $flags[] = substr( $key, 3 );
    }

    return var_dump( $flags );
}
add_action( 'shutdown', 'get_query_flags' );

Performance

I ran a performance test on each function in the middle of a template using timer_start/*_stop();. TO be fair, I renamed all functions to a one character name a/b/c().

As you can see, Chips hard coded function is fastest, then goes mine and last is in this case scribus.

enter image description here

share|improve this answer
1  
Well that is very clever. Thanks! I'll have to re-visit this when I get done with some of the other things I am working. Also, it is really hard to remember to capitalize! Bad habits are tough to break. –  helgatheviking Sep 8 '12 at 1:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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