現在のテンプレートファイルの名前を取得する


57

テンプレートで使用されているファイルの現在の名前を表示するためにこれを見つけました:

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()ますか-これで問題が解決するでしょうか?


2
@chodorowicz-の選択をfunctions.phpバグと呼ぶ前に一歩停止しますが、あなたの前提に完全に同意します。さらに悪いことに、WordPressのコアコードをスキャンし、この問題を処理するためのフックが存在する可能性がある5つの場所を見つけましたが、どれも見つかりませんでした。core.trac.wordpress.orgにチケットを投稿することをお勧めします
-MikeSchinkel

@MikeSchinkel-コメントありがとうございます。しかし、template_includeフックしません。t31osが提案したこの問題は解決しましたか?または多分私はあなたを誤解しました。
-chodorowicz

1
@MikeSchinkel-すでにパッチがあります:) core.trac.wordpress.org/ticket/16689
chodorowicz

1
現在のテンプレートを表示するために、新しいプラグインを作成しました。wordpress.org/extend/plugins/display-template-nameで

4
^すなわち。あなたは私の答えからコードを取り出してプラグインにラップしました。そして、あなたはすべて、オリジンにクレジットを提供することなく、私自身もWPスタックエクスチェンジも...素晴らしい...:/
t31os 14年

回答:


68

template_includeフィルター中にグローバル変数を設定し、後でそのグローバル変数をチェックして、含まれているテンプレートを確認できます。

あなたは当然、ファイルとともに完全なパスを望んでいないので、PHPのbasename機能を使用してファイル名に切り捨てることをお勧めします。

サンプルコード:
2つの関数。1つはグローバルを設定し、もう1つはそれを呼び出します。

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()、これはページテンプレートの場合にのみ役立つことを念頭に置いてください(すべての機能をキャッチすることははるかに少ない)。

上記で使用または参照されている機能に関する情報:


驚くばかり!もっと簡単な方法が必要だと思いました。
racl101

デバッグ関数リストの一番上に追加するもの。
ジュール

23

どうやらこれで十分です:

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

または単にテンプレートで直接使用します(HTMLコメントのfooter.phpにエコーする傾向があります)

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

1
それはあなたが知っているだけのように、GET-テンプレート部分では動作しません、それはそれがであるファイル(例えば)single.phpを示していない。
M-トゥリン

はい、それは本当だ。含まれているファイルの名前を取得するには、おそらくこのようなものを使用する必要があるだろうecho __FILE__;
chodorowicz

これは、たとえば、デフォルトのテンプレートをバックオフィスの投稿に割り当てずに変更する場合に適しています。たとえば、カスタムルートとtemplate_includeフィルターを使用します。ありがとうございました。
ルカレゲリン16

ループ内でこれをどのように行うことができますか?各テンプレートファイルの1ページにURLを出力しようとしています。
JacobTheDev

@JacobTheDevを使用している可能性がありますecho __FILE__-これは機能しないため、メインの初期テンプレートのみが表示されます
-chodorowicz

17

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

9

ここでの他の回答への追加(より甘いコード)。

テンプレート名

現在のページテンプレート名を取得するには、次の行を使用します。

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()、任意の時点で(たとえば、テーマテンプレートで)簡単に呼び出すことができます。これにより、グローバル名前空間が乱雑になるのを防ぎます。


1
template_redirect何も渡していませんtemplate_include。あなたは混乱していると思います。また、静的変数が満たされているかどうかではなく、フィルター内かどうかを確認します。いくつかのコードがさらに時間をかけてフックを実行することに決めた場合、問題を引き起こす可能性があります。
ラースト

@Rarst完了/修正済み。ヒントとフィルター名の指摘に感謝します。
カイザー

5

テンプレート名はpostmetaテーブルに保存されるため、ループ内のどこかにこれを配置するだけです。

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

2
はい、これについては知っていますが、問題はページにテンプレートが設定されている場合にのみ機能することです。私は投稿のコードについてのクールなことは、現在のページが使用している場合、それはあなたを教えてくれるということですfront-page.phpindex.phpsingle.phppage.phpまたはその他のファイル。コードには、カスタムページテンプレートがあるページのテンプレート名のみが表示されます。
-chodorowicz

ああ、ごめんなさい-あなたの質問に対する私の誤解。
サイモンブラックボーン

@SimonBlackbournそれは私の要件の助けです。ありがとう。
KarSho

3

これは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];
}

body_classテンプレートを使用しているときに組み込みのWordPress 関数が作成する愚かな長いクラス名に本当にうんざりしていたので、テンプレート名を取得したかったのです。幸いなことに、その関数の最後にフィルターフックがあり、独自のクラス名も追加できます。これが私のフィルターです。誰かがそれを役に立つと思うことを望みます:

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クラスのようにすべてを小文字にします。


0

preg_match_allラインに問題があります。代わりにこれを試してください:

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

また、if (!is_admin()) { .... }フロントエンドでのみ実行するために使用できます。


提案をありがとう、彼らは問題を解決しませんが、彼らはちょっと解決策に私を導いた。WPは、テンプレートリストを生成してfunctions.phpいる間、検索を探し、テンプレートファイルとして"/Template Name:(.*)\n/siU"扱いfunctions.phpます。これはWPのバグだと思うので、このファイルを見てはいけません。解決策:ファイルをサブディレクトリに移動します。
chodorowicz

@chodorowicz:これはWPのバグではなく、関数のバグです。
ウィルフェル

したがって、基本的にWPでは、functions.phpファイルに文字列「テンプレート名:」(コメント内であっても)を含めることを禁止しています。個人的には、それはバグです(小さなですが、とにかく)が、それは議論の余地があると思います。関数自体がバグだと言うことはできないと思います。
chodorowicz

WPはあなたが何もすることを禁じていません。ただし、WPはdebug_backtrace()をループして使用しているテンプレートファイルを見つけることができるとは約束していません。WPサポートフォーラムで見つけたからといって、公式にサポートされているコードであるとは限りません。ご覧のとおり、関数はfooter.phpを明示的に除外します。functions.phpを除外する別の条件を追加することもできます。ところで:あなたの関数はTemplate Name各ファイル内で探していません、あなたのループはそのずっと前に終了しました。
ウィルフェル

問題はそうではありませんでしたdebug_backtrace()-私はすべてのコードを削除してそのまま残すことができますpreg_match_all("/Template Name...、または// Template Name:WPはfunctions.phpテンプレートファイルとして扱いますが、コメントをありがとうそれはバグです。t31osソリューションはクリーンであり、問​​題全体を解決します。あいさつ。
-chodorowicz

0

一緒に遊ぶ:

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、このコード行のファイル名を次のように変更します。

管理バーでこれが必要な場合は、正しい優先順位(最も早い)使用して、このリストの最後ファイルが入力されないようにします。例えば:

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

優先順位は-5、shureを最初にロードします。重要なのは、この行を適切なタイミングでレンダリングすることです。

「現在の」テンプレートファイルは返されませんが、現在のページロードで使用中のすべてのファイルが返されます。たぶん、そのアイデアからのいくつかのロジックで「カットアウト」

get_included_files()ファイル、サイドバーのウィジェットか何かでフッターに使用propably最後のテンプレートファイル/ -partを含め、「最後」のキーが最後に登録されます。おそらく、cosの複数のインクルードファイルは、get_included_files()で再登録/再挿入されません。

そうでなければ、この問題をハックする意図が明確でなければなりませんインクルードされるまで、インクルードされたファイルが自分自身をインクルード済みとして報告する方法はありません。その後、シナリオを使用するのが遅すぎることが適切です。

「時間」の大半は、あなたがなりたいと:

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

ただし、テンプレートがWordpressのコアメソッドの外部にロードされている場合、それは不可能ですget_template_part。代わりに、ニーズを再設計してください!たぶんloop_start()in_the_loop()そしてadd_action('the_post')あなたが望む解決策を持って、ループ内の各エントリにロードするテンプレートに応じてデータを変更します。


-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.