获取当前模板文件的名称

时间:2011-02-26 作者:chodorowicz

我发现这可以显示模板中使用的文件的当前名称:

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 ;
}
资料来源:get name of page template on a page

它工作得很好,除了在后端,在模板选择框中,我得到了一个丑陋的额外条目:

screenshot

有人知道怎么修吗?我甚至不知道为什么在后端调用这个函数。有这样的条件函数吗is_frontend() - 也许这能解决问题?

9 个回复
最合适的回答,由SO网友:chodorowicz 整理而成

显然,这就足够了:

add_action(\'wp_head\', \'show_template\');
function show_template() {
    global $template;
    echo basename($template);
}
或者直接在模板中使用它(我倾向于在HTML注释中的footer.php中进行回应)

<?php global $template; echo basename($template); ?>

SO网友:t31os

您可以在template_include 过滤,然后稍后检查全局变量,以查看包含了哪个模板。

您自然不希望文件包含完整的路径,因此我建议使用PHP的basename 作用

Example code:
两个功能,一个用于设置全局,一个用于调用全局。

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\'];
}
然后你可以拜访get_current_template 在主题文件中需要它的地方,请注意,这自然需要在template_include 操作已启动(如果调用是在模板文件中进行的,则无需担心此问题)。

对于页面模板,有is_page_template(), 请记住,这只会在页面模板的情况下有所帮助(一个远没有那么全面的功能)。

Information on functions used or referenced above:

SO网友:Rarst

在本机WP函数之间,如get_template_part() PHP本机包含查看所用主题文件最可靠的方法是获取所有包含文件的列表,并过滤掉不属于主题的内容(或使用父子组合时的主题):

$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 );

SO网友:kaiser

这里是对其他答案的补充(更甜美的代码)

仅获取当前page template 名称,请使用以下行。

is_page() AND print get_page_template_slug( get_queried_object_id() );
当您只想回显current template file name, 遵循以下步骤

Edit: 这是封装在类中的插件的新版本。它在页面最底部的关闭挂钩中显示当前模板文件名以及模板层次结构文件名。

插件告诉您:

模板是否来自子主题的父级/当前主题wpse10537_template_info.php, 将其上载到插件目录并激活。

<?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;
此插件也可以作为MU插件运行

你只需打电话wpse10537_get_template_name() 在任何时候(例如在主题模板中)。这样可以避免全局命名空间混乱。

SO网友:Simon Blackbourn

模板名称存储在Posteta表中,因此您只需将其放在循环中的某个位置:

$template = get_post_meta( $post->ID, \'_wp_page_template\', true );
echo "Template: " . $template;

SO网友:Tom Auger

这并没有解决OP的所有问题,但下面的代码肯定比正则表达式和解析模板文件本身更优雅。

如果您位于使用页面模板的页面上,并且希望获取页面模板的名称(即:在模板PHP文件顶部的注释中定义的人类可读名称),可以使用以下小金块:

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];
}
我想得到模板名称,因为我真的厌倦了内置WordPress的愚蠢的长屁股类名body_class 函数在使用模板时创建。幸运的是,在该函数的最末端有一个过滤器挂钩,允许您附加自己的类名。这是我的过滤器。希望有人觉得它有用:

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;
}
这个过滤器将接受您命名的页面模板,用破折号替换空格,并使所有内容都小写,使其看起来像所有其他WordPress类。

SO网友:wyrfel

有个问题preg_match_all 线请尝试以下操作:

preg_match_all("/Template Name:(.*)\\n/siU",$template_contents,$template_name);
此外,您可以使用if (!is_admin()) { .... } 只在前端运行。

SO网友:Jonas Lundman

配合使用:

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>\';
写于:

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

如果admin-bar stuff 路径显示在顶部,或任何其他文件,请更改文件名template-loader.php 在这一行代码中,输入:无论您需要从哪个filname中断。

如果你在管理栏中需要这个,use the right priotity (最早)to make shure no files are entered at the end 此列表的。例如:

add_action(\'admin_bar_menu\', \'my_adminbar_template_monitor\', -5);
优先级-5 先加载舒尔。关键是在正确的时刻渲染这条线。

它不会返回“当前”模板文件,而是返回当前页面加载使用的所有当前模板文件。Maybe "cut out" with some logic from that idea.

这个get_included_files() “last”键是最后注册的包含文件,可能是边栏小部件在页脚中使用的最后一个模板文件/部分。很可能,cos多个包含的文件不会在get\\u included\\u files()中重新注册/填充。

否则,必须明确意图才能解决这个问题。There is no way for a included file to report itself as included, until it has been included. 那么使用这个场景可能已经太晚了。

大多数“时间”你会喜欢:

$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 如果模板加载在Wordpress核心方法之外get_template_part. 重新设计您的需求!大概loop_start(), in_the_loop()add_action(\'the_post\') 有您想要的解决方案,根据循环中每个条目要加载的模板来更改数据。

SO网友:Shafi
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
结束

相关推荐