Is there a variable for a template parts name?

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

Read More

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.

Related posts

Leave a Reply

4 comments

  1. 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.

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

    $path_parts = pathinfo(__FILE__);
    //var_dump($path_parts); 
    echo $path_parts['filename'];
    
  3. 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.

  4. 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 ( get_object_vars( $wp_query ) as $is_key => $is_value ) 
        { 
                if ( $is_value && preg_match( "/is_/", $is_key ) ) 
                        $conditionals[] = $is_key; 
        } 
    
        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

    Update

    If you know me, then you know my love for iterators for their elegance, clearness and their ability to hold only a single item in memory instead of of copy of a whole array while looping. So here’s a quick custom class that extends a FilterIterator, therefore needing only a single method reworked.

    <?php
    
    namespace WPSE;
    
    class ConditionalsFilter extends FilterIterator
    {
        /**
         * Accepts properties that start with `is_` and have a positive boolean value
         * @return bool
         */
        public function accept()
        {
            return 0 === strncasecmp( $this->key(), 'is_', 3 )
                and filter_var(
                    $this->current(),
                    FILTER_VALIDATE_BOOLEAN,
                    FILTER_NULL_ON_FAILURE
                );
        }
    }
    

    It can be used quite easily. The $it->current() holds the value, while $it->key() returns the conditional/property name.

    $cond = new WPSEConditionalsFilter( new ArrayIterator(
        get_object_vars( $GLOBALS['wp_query'] )
    ) );
    foreach ( $cond as $c )
    {
        var_dump(
            $cond->key(),
            $cond->current()
        );
    }