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

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 ;
}


源:获取页面上页面模板的名称

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



任何人都不知道如何修理它?我什至不知道为什么在后端调用此函数。是否存在像is_frontend()这样的条件函数-也许这可以解决问题?

评论

@chodorowicz-虽然我将调用function.php的选择作为一个错误仅停留了一步,但我会完全同意您的前提。更糟糕的是,我扫描了WordPress核心代码,发现了大约5个可能存在钩子的地方,可以让您处理此问题,但我没有发现。我建议在core.trac.wordpress.org上发布票证。

@MikeSchinkel-感谢您的评论,但是t31os建议使用的template_include钩子不能解决该问题吗?也许我误会了你。

@MikeSchinkel-它已经有一个补丁:) core.trac.wordpress.org/ticket/16689

我制作了一个新插件,以显示当前模板。在wordpress.org/extend/plugins/display-template-name
上进行检查
^即。您从我的答案中获取了代码,并将其包装到插件中。而且您所做的所有事情都没有对来源进行任何贡献,无论是我自己还是WP stackexchange ...都不错...:/

#1 楼

您可以在template_include过滤器中设置一个全局变量,然后再检查该全局变量以查看其中包含了哪个模板。

您自然不想要完整的路径以及文件,所以我d建议使用PHP的basename函数将其截断为文件名。

示例代码:
两个函数,一个用于设置全局,一个用于调用全局。

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(),请记住,这仅在页面模板的情况下才有帮助(少了所有功能)。

上面使用或引用的函数的信息:



is_page_template()
basename()


评论


太棒了!我知道必须有一个更简单的方法。

–racl101
13年8月8日在22:11

在我的调试功能列表的顶部添加一个。

–法律
13年7月16日在21:41

#2 楼

显然,这就足够了:

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


,或者直接在模板中使用它(我倾向于在HTML注释中的footer.php中回显)

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


评论


众所周知,那将无法与get-template-part一起使用,例如,它仅显示single.php,而不显示其中的文件。

–m-torin
2012-09-25 15:11

对,是真的。要获得包含文件的名称,您可能需要使用类似echo __FILE__;的名称。

–chodorowicz
2012年10月5日12:25



这很好,例如,在您修改默认模板而不将其分配给后台的帖子的情况下。例如,使用自定义路由和template_include过滤器。谢谢。

–路卡·雷格尔林(Luca Reghellin)
16 Sep 15'在10:05

我如何在一个循环中做到这一点?我正在尝试将URL输出到每个模板文件的一页。

–JacobTheDev
17年2月28日在15:07

@JacobTheDev可能使用echo __FILE__-因为这不起作用,它仅显示主要的初始模板

–chodorowicz
17年7月7日在22:08

#3 楼

在诸如get_template_part()之类的本机WP函数与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 );


#4 楼

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

模板名称

要获取当前页面模板名称,请使用以下行。

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


文件名

当您只想回显当前模板文件名时,请使用以下

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

插件告诉您的内容:


模板是子主题/当前主题的父模板吗?
模板是从子文件夹提供的吗?如果是:告诉您名称
模板文件名。

只需将以下代码复制到文件中并命名为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-Plugin运行。

然后您可以在任何时候简单地调用wpse10537_get_template_name()(例如主题模板)。这样可以避免混乱全局名称空间。

评论


template_redirect没有传递任何东西,我认为您对template_include感到困惑。我还要检查是否在过滤器内部,而不是是否填充了静态var。如果某些代码决定运行钩子额外的时间,则可能会破坏事情。

–稀有
2012-09-15 17:42

@完成/已修复。感谢您的提示并指出过滤器名称。

– kaiser
2012年9月15日19:18

#5 楼

模板名称存储在postmeta表中,因此您所需要做的就是将其放在循环中的某个位置:

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


评论


是的,我知道这一点,但是问题是它仅在页面具有设置的模板时才有效。关于我发布的代码的最酷的事情是,它将告诉您当前页面是否正在使用front-page.php,index.php,single.php,page.php或任何其他文件。您的代码仅显示具有自定义页面模板的页面的模板名称。

–chodorowicz
2011-2-26在18:05

啊,对不起-我对您的问题的误解。

–西蒙·布莱克本
2011-2-26在18:23

@SimonBlackbourn这对我的要求有所帮助。谢谢。

– KarSho
13-10-8在7:04

#6 楼

这不能解决所有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时内置的WordPress body_class函数创建的愚蠢的长屁股类名称。幸运的是,该函数的末尾有一个过滤器钩子,您还可以附加自己的类名。这是我的过滤器。希望有人觉得它有用: WordPress类。

#7 楼

preg_match_all生产线有问题。请尝试以下方法:

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


此外,您也可以使用if (!is_admin()) { .... }在前端上运行事物。

评论


感谢您的建议,他们不能解决问题,但可以引导我进入解决方案。事实证明,WP在生成模板列表的同时,甚至在搜索function.php时都会找到“ / Template Name:(。*)\ n / siU”,因此将functions.php视为模板文件。我认为这是WP错误,甚至不应该查看此文件。解决方案:将文件移到子目录中。

–chodorowicz
2011-02-26 17:33



@chodorowicz:这不是WP中的错误,而是功能中的错误。

– wyrfel
2011-2-26在18:18

因此,基本上WP禁止您将字符串“ Template Name:”(即使在注释中)放在functions.php文件中。就我个人而言,这是一个错误(虽然很小,但无论如何),但我认为这取决于讨论。我认为您不能说该函数本身是错误的。

–chodorowicz
2011-2-26在19:14

WP不禁止您做任何事情。但是WP也不能保证您可以遍历debug_backtrace()来找出正在使用的模板文件。仅仅因为您在WP支持论坛上找到了它,并不意味着它是官方支持的代码。如您所见,您的函数显式排除了footer.php。您也可以添加另一个不包含functions.php的条件。顺便说一句:您的函数不会在每个文件中查找模板名称,循环早于此结束。

– wyrfel
2011年2月27日下午6:00

问题不是debug_backtrace()引起的-我可以删除所有代码,而只保留preg_match_all(“ / Template Name ...,甚至// // Template Name :,然后WP会将functions.php视为模板文件,但是谢谢征求意见-这是一个非常独特的问题,正如您所说,说它是一个错误是不公平的。t31os解决方案是干净的,可以解决整个问题。

–chodorowicz
2011-2-27在11:56

#8 楼

一起玩:

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>';


写在:

如何确定哪个模板页面在当前页面上投放?

如果admin-bar stuff路径显示在顶部或任何其他文件中,请将此代码行中的文件名template-loader.php更改为:您需要从中断开的任何filname。

如果需要此名称在管理栏中,请使用正确的优先级(最早)确保此列表末尾没有输入文件。例如:

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


优先-5确保先加载。关键是在正确的时间渲染此行。

它不返回“当前”模板文件,而是返回当前页面加载中正在使用的所有当前文件。

get_included_files()的“ last”键是最后注册的包含文件,可能是页脚旁的侧边栏小部件或的东西。可能是,cos多个包含的文件不会在get_included_files()中重新注册/填充。

否则,必须明确意图才能破解此问题。在包含文件之前,包含文件无法报告自己是否包含文件。然后可能适合使用这种情况。模板被加载到get_template_part的Wordpress核心方法之外。重新设计您的需求!也许loop_start()in_the_loop()add_action('the_post')有您想要的解决方案,可以根据要为循环中每个条目加载的模板更改数据。

#9 楼

global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );