web-dev-qa-db-ja.com

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

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

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

ソース: ページ上のページテンプレートの名前を取得します

それはバックエンドで、テンプレート選択ボックスで、私がこの醜い余分なエントリを得ることを除いて、それはかなりうまくいきます:

screenshot 

誰かがそれを修正する方法について何か考えを持っていますか?私はなぜこの関数がバックエンドで呼ばれるのかさえ知りません。 is_frontend()のような条件付き関数はありますか - 多分これは問題を解決するでしょうか?

56
chodorowicz

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

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

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

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

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()がありますが、これはページテンプレートの場合にのみ役立つことを念頭に置いてください(はるかに少ないcatch all function)。

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

65
t31os

get_template_part() のようなネイティブWP関数と/の間で使用されているテーマのファイルを見る最も信頼できる方法は、すべてのインクルードファイルのリストを取得し、テーマに属さないものを除外することですまたは親と子の組み合わせが使用されている場合のテーマ)

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

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

テンプレート名

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

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プラグインとしても動作します。

そうすれば、いつでも(例えばテーマテンプレート内で)wpse10537_get_template_name()を呼び出すことができます。これにより、グローバルネームスペースが乱雑になるのを防ぎます。

9
kaiser

テンプレート名はpostmetaテーブルに格納されているので、あなたがする必要があるのはあなたのループのどこかにこれを置くことです:

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

これは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クラスのように見えます。

3
Tom Auger

一緒に遊ぶ:

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

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

「現在の」テンプレートファイルを返すのではなく、現在のページロードに現在使用されているすべてのテンプレートファイルを返します。 その考えからの論理で "切り抜く"かもしれない

get_included_files() "last"キーは最後に登録されたインクルードファイル、おそらくサイドバーウィジェットか何かによってフッターで使われた最後のtemplate-file/-partです。おそらく、複数のインクルードファイルがget_included_files()に再登録されることはありません。

さもなければ、この問題をハックするために意図は明白でなければならない インクルードファイルがインクルードされるまで、インクルードされたファイル自体をインクルードファイルとして報告する方法はありません 。それではシナリオを使うのを遅らせるのがたぶんそれです。

あなたが好きな「時間」のほとんどは、{would}:

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

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

0
Jonas Lundman

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

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

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

0
wyrfel