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.

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: http://wordpress.org/support/topic/get-name-of-page-template-on-a-page

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

http://cl.ly/361q221Q0n0f1g473R3l

Anybody has idea how to fix it? I don't even know why this function is called in backend (is there a conditional function likie is_frontend() - maybe this would solve the problem).

share|improve this question
2  
@chodorowicz - While I will stop one step short of calling the selection of functions.php as a bug, I will agree completely with your premise. To make matters worse I scanned the WordPress core code and found about 5 places where there could have been a hook to allow you to handle this issue yet I found none. I'd suggest posting a ticket on core.trac.wordpress.org. –  MikeSchinkel Feb 26 '11 at 20:13
    
@MikeSchinkel - thanks for comment, but doesn't template_include hook, which t31os suggested, solve the issue? Or maybe I've misunderstood you. –  chodorowicz Feb 27 '11 at 15:29
    
@chodorowicz - You now have me very confused. The answer @t31os gave solves a problem that is very different from the one that I understood you were asking based on your question and your follow up comments to other's answers. But if @t31os' answer solved your actual need, then my confusion here is unimportant as your question has been answered. –  MikeSchinkel Feb 27 '11 at 16:21
1  
@MikeSchinkel - it already has a patch :) core.trac.wordpress.org/ticket/16689 –  chodorowicz Feb 28 '11 at 17:33
1  
I've made a new plugin in order to display the current template. Check it on wordpress.org/extend/plugins/display-template-name –  user16658 Jun 1 '12 at 11:32
show 3 more comments

9 Answers 9

up vote 5 down vote accepted

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 );
share|improve this answer
add comment

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:

share|improve this answer
    
This code is very clean and solves the whole issue. Many thanks! –  chodorowicz Feb 27 '11 at 11:57
    
You're welcome. :) –  t31os Feb 27 '11 at 12:00
    
Awesome! I knew there had to be a simpler way. –  racl101 Mar 8 '13 at 22:11
    
perfect. thank you! –  Luke Burns Jul 12 '13 at 15:28
    
One to add to the top of my debugging functions list. –  Jules Jul 16 '13 at 21:41
show 1 more comment

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.

share|improve this answer
1  
template_redirect is not passing anything, I think you are confusing with template_include. Also I'd check if inside the filter instead of if static var filled. If some code decides to run hook additional time it can wreck things. –  Rarst Sep 15 '12 at 17:42
    
@Rarst Done/Fixed. Thanks for the hint and pointing out the filter name. –  kaiser Sep 15 '12 at 19:18
add comment

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;
share|improve this answer
1  
Yes, I know about this, but the problem is that it works only when a page has a set template. The cool thing about the code I posted is that it will tell you if current page is using front-page.php, index.php, single.php, page.php or any other file. Your code displays template name only for pages with custom page template. –  chodorowicz Feb 26 '11 at 18:05
    
ah, sorry - my misunderstanding of your question. –  Simon Blackbourn Feb 26 '11 at 18:23
    
@SimonBlackbourn It's help for my requirement. Thanks. –  KarSho Oct 8 '13 at 7:04
add comment

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); ?>
share|improve this answer
1  
That won't work with get-template-part just so you know, it only shows single.php (for example) and not the file it is in. –  mattrepublic Sep 25 '12 at 15:11
    
Yes, it's true. To get the name of included file you'd probably need to use something like this echo __FILE__; –  chodorowicz Oct 5 '12 at 12:25
add comment

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.

share|improve this answer
    
Thanks for suggestion, they don't solve the problem, but they kinda directed me into solutions. It turns out that WP, while generating templates list, is looking even into functions.php finds the "/Template Name:(.*)\n/siU" and thus treats the functions.php as template file. I think this is WP bug, it shouldn't even look at this file. The solution: move the file into subdirectory. –  chodorowicz Feb 26 '11 at 17:33
    
@chodorowicz: That's not a bug in WP, it's a bug in your function. –  wyrfel Feb 26 '11 at 18:18
    
So basically WP forbids you to put string "Template Name:" (even in comment) in functions.php file. For me, personally, that's a bug, (small, but anyway) but that's the up to discussion, I suppose. I think you cannot say that the function itself is buggy. –  chodorowicz Feb 26 '11 at 19:14
    
WP doesn't forbid you to do anything. But WP also doesn't promise you that you can loop over a debug_backtrace() to find out what template file you're using. Just because you found it on a WP support forum doesn't mean it's officially supported code. As you may see, your function explicitly expludes footer.php. You may as well add another condition that excludes functions.php. BTW: your function doesn't look for Template Name within each of the files, your loop has ended long before that. –  wyrfel Feb 27 '11 at 6:00
    
The problem wasn't with debug_backtrace() - I can remove all the code and just leave preg_match_all("/Template Name..., or even just // Template Name: and WP treats then functions.php as template file, but thanks for comments - this is such a unique problem that, as you say, it's not fair to say it's a bug. t31os solution is clean and solves the whole issue. Greets. –  chodorowicz Feb 27 '11 at 11:56
add comment

WP, while generating templates list, is looking even into functions.php as a potential template file, finds there "/Template Name:(.*)\n/siU" and thus treats the functions.php as theme file with name: (.*)\n)siU",$template_contents,$template_name);

Temporary solution: move this function into some subdirectory and include this file from functions.php.

It seems that it's WP bug - it shouldn't treat functions.php as template file.

Update: it has a patch in WP trac, coming in 3.2 http://core.trac.wordpress.org/ticket/16689

share|improve this answer
add comment

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.

share|improve this answer
add comment

I had faced that problem and figured it out like that:

code for template page:

update_option('current_page_template','write the page template name here');

And get this name like that:

<body id="<?php echo get_option('current_page_template'); ?>">

Thanks.

share|improve this answer
    
Updating an option every time seems rather inefficient… especially when you will only need it in the current session –  bungeshea Feb 1 '13 at 22:41
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.