Get name of the current template file

I’ve found this to display the current name of the file used in template:

function get_template_name () {
    foreach ( debug_backtrace() as $called_file ) {
        foreach ( $called_file as $index ) {
            if ( !is_array($index[0]) AND strstr($index[0],'/themes/') AND !strstr($index[0],'footer.php') ) {
                $template_file = $index[0] ;
            }
        }
    }
    $template_contents = file_get_contents($template_file) ;
    preg_match_all("Template Name:(.*)n)siU",$template_contents,$template_name);
    $template_name = trim($template_name[1][0]);
    if ( !$template_name ) { $template_name = '(default)' ; }
    $template_file = array_pop(explode('/themes/', basename($template_file)));
    return $template_file . ' > '. $template_name ;
}

Source: get name of page template on a page

Read More

It works quite well, except that in the backend, in the template select box, I get this ugly extra entry:

screenshot

Does anybody have any idea how to fix it? I don’t even know why this function is called in the backend. Is there a conditional function like is_frontend() – maybe this would solve the problem?

Related posts

Leave a Reply

9 comments

  1. You could set a global variable during the template_include filter and then later check that global vairable to see which template has been included.

    You naturally wouldn’t want the complete path along with the file, so i’d recommend truncating down to the filename using PHP’s basename function.

    Example code:
    Two functions, one to set the global, one to call upon it.

    add_filter( 'template_include', 'var_template_include', 1000 );
    function var_template_include( $t ){
        $GLOBALS['current_theme_template'] = basename($t);
        return $t;
    }
    
    function get_current_template( $echo = false ) {
        if( !isset( $GLOBALS['current_theme_template'] ) )
            return false;
        if( $echo )
            echo $GLOBALS['current_theme_template'];
        else
            return $GLOBALS['current_theme_template'];
    }
    

    You can then call upon get_current_template wherever you need it in the theme files, noting this naturally needs to occur after the template_include action has fired(you won’t need to worry about this if the call is made inside a template file).

    For page templates there is is_page_template(), bearing in mind that will only help in the case of page templates(a far less catch all function).

    Information on functions used or referenced above:

  2. apparently this is enough:

    add_action('wp_head', 'show_template');
    function show_template() {
        global $template;
        echo basename($template);
    }
    

    or just use it directly in template (I tend to echo in footer.php in HTML comment)

    <?php global $template; echo basename($template); ?>
    
  3. Between native WP functions like get_template_part() and PHP’s native includes the most reliable way to see theme’s files used is to fetch list of all included files and filter out whatever doesn’t belong to theme (or themes when parent and child combination is used):

    $included_files = get_included_files();
    $stylesheet_dir = str_replace( '', '/', get_stylesheet_directory() );
    $template_dir   = str_replace( '', '/', get_template_directory() );
    
    foreach ( $included_files as $key => $path ) {
    
        $path   = str_replace( '', '/', $path );
    
        if ( false === strpos( $path, $stylesheet_dir ) && false === strpos( $path, $template_dir ) )
            unset( $included_files[$key] );
    }
    
    var_dump( $included_files );
    
  4. An addition (more sweet code) to other answers here.

    Template Name

    To just get the current page template name, use the following line.

    is_page() AND print get_page_template_slug( get_queried_object_id() );
    

    File Name

    When you just want to echo the current template file name, go with the following

    Edit: Here’s the new version of the plugin wrapped up in a class. It shows both the current template file name, as well as the template hierarchy file name in the shutdown hook at the most bottom of the page.

    What the plugin tells you:

    • Is the template from the parent of child/current theme?
    • Is the template served from a subfolder? If yes: Tells you the name
    • The template file name.

    Just copy the following code into a file and name it wpse10537_template_info.php, upload it to your plugins directory and activate it.

    <?php
    /** Plugin Name: (#10537) »kaiser« Get Template file name */
    
    if ( ! class_exists( 'wpse10537_template_name' ) )
    {
        add_action( 'plugins_loaded', array( 'wpse10537_template_name', 'init' ) );
    
    class wpse10537_template_name
    {
        protected static $instance;
    
        public $stack;
    
        public static function init()
        {
            is_null( self :: $instance ) AND self :: $instance = new self;
            return self :: $instance;
        }
    
        public function __construct()
        {
            if ( is_admin() )
                return;
    
            add_action( 'wp', array( $this, 'is_parent_template' ), 0 );
            add_action( 'wp', array( $this, 'get_template_file' ) );
            add_action( 'template_include', array( $this, 'get_template_name' ) );
            add_action( 'shutdown', array( $this, 'get_template_name' ) );
        }
    
        public function get_template_name( $file )
        {
            if ( 'template_include' === current_filter() )
            {
                $this->to_stack(
                     "Template file"
                    ,basename( $file )
                );
                return $file;
            }
    
            // Return static var on echo call outside of filter
            if (
                current_user_can( 'manage_options' )
                AND defined( 'WP_DEBUG' )
                AND WP_DEBUG 
            )
                return print implode( " &ndash; ", $this->stack );
        }
    
        public function get_template_file()
        {
            if ( ! is_post_type_hierarchical( get_post_type() ) )
                return;
    
            $slug = get_page_template_slug( get_queried_object_id() );
            if ( ! strstr( $slug, "/" ) )
                return $this->to_stack( "Template", $slug );
    
            $this->to_stack(
                 "Subdirectory"
                ,strstr( $slug, "/", true )
            );
    
            $this->to_stack(
                 "Template (in subdirectory)"
                ,str_replace( "/", "", strstr( $slug, "/" ) )
            );
        }
    
        public function is_parent_template()
        {
            if ( ! is_null( wp_get_theme()->parent ) )
                return $this->to_stack( 'from parent theme' );
    
            $this->to_stack( 'from current/child theme' );
        }
    
        public function to_stack( $part, $item = '' )
        {
            $this->stack[] = "{$part}: {$item}";
        }
    } // END Class wpse10537_template_name
    
    } // endif;
    

    This plugin can run as MU-Plugin too.

    You can then simply call wpse10537_get_template_name() at any point (in for example a theme template). This avoids cluttering the global namespace.

  5. The template name is stored in the postmeta table, so all you need to do is put this somewhere in your loop:

    $template = get_post_meta( $post->ID, '_wp_page_template', true );
    echo "Template: " . $template;
    
  6. This doesn’t address all of the OP’s question, but the code below is certainly more elegant than regular expressions and parsing the template file itself.

    If you’re on a Page that is using a Page Template, and you want to get the page template’s Name (ie: the human-readable name that you defined in the comments at the top of your template PHP file), you can use this little nugget:

    if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
        $templates = wp_get_theme()->get_page_templates();
        $template_name = $templates[$current_template];
    }
    

    I wanted to get the template name because I was really sick of the silly-long-ass class names that the built-in WordPress body_class function creates when you’re using a template. Luckily there’s a filter hook at the very end of that function to let you append your own class names as well. Here’s my filter. Hope someone finds it useful:

    add_filter( 'body_class', 'gs_body_classes', 10, 2 );
    function gs_body_classes( $classes, $class ){
        if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
            $templates = wp_get_theme()->get_page_templates();
            $template_name = str_replace( " ", "-", strtolower( $templates[$current_template] ) );
    
            $classes[] = $template_name;
        }
    
        return $classes;
    }
    

    This filter will take whatever you named your page template, replace spaces with dashes and make everything lower case so it looks like all the other WordPress classes.

  7. There’s an issue with the preg_match_all line. Try this instead:

    preg_match_all("/Template Name:(.*)n/siU",$template_contents,$template_name);
    

    Also, you can use if (!is_admin()) { .... } to run things on the frontend only.

  8. Play along with:

    echo '<ul><li>'.implode('</li><li>', str_replace(str_replace('', '/', ABSPATH).'wp-content/', '', array_slice(str_replace('', '/', get_included_files()), (array_search(str_replace('', '/', ABSPATH).'wp-includes/template-loader.php', str_replace('', '/', get_included_files())) + 1)))).'</li></ul>';
    

    Written at:

    How do you find out which template page is serving the current page?

    if admin-bar stuff path is showing at the top, or any other file, change the filename template-loader.php in this line of code to: whatever filname you need to break from.

    if you need this in the admin bar, use the right priotity (earliest) to make shure no files are entered at the end of this list. For example:

    add_action('admin_bar_menu', 'my_adminbar_template_monitor', -5);
    

    priority -5 make shure it loads first. The key is to render this line at the right moment.

    It does not returning the “current” template-file, but all the current in use for the current page-load. Maybe “cut out” with some logic from that idea.

    The get_included_files() “last” key is the last registered included file, propably the last template-file/ -part used in the footer by sidebar widget or something. Propably, cos mutiple included files does not re-register/ populates again in get_included_files().

    Otherwise, the intension must be clear to hack this problem. There is no way for a included file to report itself as included, until it has been included. Then its propably to late to use the scenario.

    Most of the “time” you would like:

    $template = get_current_loaded_template();
    if($template == 'single-product.php') add_filter('the_title' ....
    if($template == 'format-gallery.php') add_action('post_thumbnail' ....
    

    But thats not possible if the template is loaded outside WordPress core method of get_template_part. Re-design your needs instead! Maybe loop_start(), in_the_loop() and add_action('the_post') has the solution you want, to alter data depending of template thats gonna load for each entry within a loop.