Dapatkan nama file templat saat ini

58

Saya menemukan ini untuk menampilkan nama file saat ini yang digunakan dalam 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 ;
}

Sumber: dapatkan nama templat halaman pada suatu halaman

Ini bekerja dengan sangat baik, kecuali bahwa di backend, di kotak pilih template, saya mendapatkan entri ekstra jelek ini:

tangkapan layar

Adakah yang tahu cara memperbaikinya? Saya bahkan tidak tahu mengapa fungsi ini disebut di backend. Apakah ada fungsi kondisional seperti is_frontend()- mungkin ini akan menyelesaikan masalah?

chodorowicz
sumber
2
@chodorowicz - Meskipun saya akan berhenti satu langkah menyebut pemilihan functions.phpsebagai bug, saya akan setuju sepenuhnya dengan premis Anda. Lebih buruk lagi, saya memindai kode inti WordPress dan menemukan sekitar 5 tempat di mana mungkin ada kait untuk memungkinkan Anda menangani masalah ini, tetapi saya tidak menemukannya. Saya sarankan memposting tiket di core.trac.wordpress.org .
MikeSchinkel
@MikeSchinkel - terima kasih atas komentarnya, tetapi tidak template_includemengait, t31os mana yang disarankan, menyelesaikan masalah? Atau mungkin saya salah paham dengan Anda.
chodorowicz
1
@MikeSchinkel - sudah memiliki patch :) core.trac.wordpress.org/ticket/16689
chodorowicz
1
Saya telah membuat plugin baru untuk menampilkan template saat ini. Periksa di wordpress.org/extend/plugins/display-template-name
4
^ mis. Anda mengambil kode dari jawaban saya dan membungkusnya menjadi sebuah plugin. Dan Anda melakukan semua itu tanpa memberikan kredit ke asal, baik saya atau WP stackexchange ... bagus ...: /
t31os

Jawaban:

69

Anda bisa mengatur variabel global selama template_includefilter dan kemudian memeriksa apakah global bisa melihat templat mana yang sudah dimasukkan.

Anda tentu tidak ingin path lengkap bersama dengan file, jadi saya akan merekomendasikan memotong ke nama file menggunakan basenamefungsi PHP .

Kode contoh:
Dua fungsi, satu untuk mengatur global, satu untuk memanggilnya.

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

Anda kemudian dapat memanggil di get_current_templatemana pun Anda membutuhkannya di file tema, mencatat ini secara alami perlu terjadi setelah template_includetindakan telah dipecat (Anda tidak perlu khawatir tentang ini jika panggilan dilakukan di dalam file template).

Untuk halaman template ada is_page_template(), mengingat bahwa hanya akan membantu dalam hal halaman template (jauh kurang menangkap semua fungsi).

Informasi tentang fungsi yang digunakan atau direferensikan di atas:

t31os
sumber
Luar biasa! Saya tahu harus ada cara yang lebih sederhana.
racl101
Satu untuk ditambahkan ke bagian atas daftar fungsi debugging saya.
Jules
24

rupanya ini sudah cukup:

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

atau cukup gunakan langsung di templat (saya cenderung bergaung di footer.php dalam komentar HTML)

<?php global $template; echo basename($template); ?>
chodorowicz
sumber
1
Itu tidak akan berfungsi dengan get-templat-bagian supaya Anda tahu, itu hanya menampilkan single.php (misalnya) dan bukan file yang ada di dalamnya.
m-torin
Ya itu benar. Untuk mendapatkan nama file yang disertakan, Anda mungkin perlu menggunakan sesuatu seperti iniecho __FILE__;
chodorowicz
ini baik-baik saja, misalnya dalam kasus ketika Anda memodifikasi template default tanpa menetapkannya ke posting di backoffice. Misalnya menggunakan rute khusus dan filter template_include. Terima kasih.
Luca Reghellin
Bagaimana saya bisa melakukan ini dalam satu lingkaran? Saya mencoba untuk mengeluarkan URL ke satu halaman dari setiap file templat.
JacobTheDev
@JacobTheDev mungkin menggunakan echo __FILE__- karena ini tidak akan berfungsi, ini hanya menampilkan templat utama, awal
chodorowicz
17

Antara fungsi WP asli seperti get_template_part () dan PHP asli termasuk cara paling dapat diandalkan untuk melihat file tema yang digunakan adalah untuk mengambil daftar semua file yang disertakan dan memfilter apa pun yang bukan milik tema (atau tema saat kombinasi orangtua dan anak digunakan) :

$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 );
Jarang
sumber
9

Tambahan (lebih banyak kode manis) untuk jawaban lain di sini.

Nama Templat

Untuk mendapatkan nama templat halaman saat ini , gunakan baris berikut.

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

Nama file

Saat Anda hanya ingin menggema nama file templat saat ini , lanjutkan dengan yang berikut ini

Sunting: Ini versi baru plugin yang dibungkus dalam sebuah kelas. Ini menunjukkan nama file templat saat ini, serta nama file hierarki templat di hook shutdown di bagian paling bawah halaman.

Apa yang dikatakan plugin kepada Anda:

  • Apakah templat dari induk dari tema anak / saat ini?
  • Apakah template disajikan dari subfolder? Jika ya: Memberitahu Anda namanya
  • Nama file templat.

Cukup salin kode berikut ke dalam file dan beri nama wpse10537_template_info.php, unggah ke direktori plugins Anda dan aktifkan.

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

Plugin ini juga dapat dijalankan sebagai Plugin-MU.

Anda kemudian dapat menelepon wpse10537_get_template_name()di titik mana saja (misalnya, templat tema). Ini menghindari kekacauan namespace global.

kaisar
sumber
1
template_redirecttidak melewati apa pun, saya pikir Anda bingung template_include. Saya juga akan memeriksa apakah di dalam filter, bukan jika statis diisi. Jika beberapa kode memutuskan untuk menjalankan hook tambahan waktu, itu dapat merusak beberapa hal.
Jarang
@ Pertama Dilakukan / Diperbaiki. Terima kasih atas petunjuknya dan menunjukkan nama filternya.
kaiser
5

Nama templat disimpan di tabel postmeta, jadi yang perlu Anda lakukan adalah meletakkannya di suatu tempat di loop Anda:

$template = get_post_meta( $post->ID, '_wp_page_template', true );
echo "Template: " . $template;
Simon Blackbourn
sumber
2
Ya, saya tahu tentang ini, tetapi masalahnya adalah ia hanya berfungsi ketika halaman memiliki template yang ditetapkan. Dingin hal tentang kode saya diposting adalah bahwa ia akan memberitahu Anda jika halaman saat menggunakan front-page.php, index.php, single.php, page.phpatau file lainnya. Kode Anda hanya menampilkan nama templat untuk halaman dengan templat halaman khusus.
chodorowicz
ah, maaf - kesalahpahaman saya tentang pertanyaan Anda.
Simon Blackbourn
@SimonBlackbourn Ini membantu untuk kebutuhan saya. Terima kasih.
KarSho
3

Ini tidak membahas semua pertanyaan OP, tetapi kode di bawah ini tentu saja lebih elegan daripada ekspresi reguler dan mem-parsing file templat itu sendiri.

Jika Anda berada di Halaman yang menggunakan Templat Halaman, dan Anda ingin mendapatkan Nama templat halaman (yaitu: nama yang dapat dibaca manusia yang Anda tentukan dalam komentar di bagian atas file PHP templat Anda), Anda dapat menggunakan nugget kecil ini:

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

Saya ingin mendapatkan nama templat karena saya benar-benar muak dengan nama-nama kelas konyol yang dibuat oleh body_classfungsi WordPress bawaan saat Anda menggunakan templat. Untungnya ada kait filter di bagian paling akhir dari fungsi itu untuk memungkinkan Anda menambahkan nama kelas Anda sendiri juga. Ini filter saya. Semoga seseorang menemukan itu berguna:

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

Filter ini akan mengambil apa pun yang Anda beri nama templat halaman Anda, mengganti spasi dengan tanda hubung dan membuat semuanya huruf kecil sehingga terlihat seperti semua kelas WordPress lainnya.

Tom Auger
sumber
0

Ada masalah dengan preg_match_allsalurannya. Coba ini sebagai gantinya:

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

Juga, Anda dapat menggunakan if (!is_admin()) { .... }untuk menjalankan hal-hal di frontend saja.

wyrfel
sumber
Terima kasih atas saran, mereka tidak menyelesaikan masalah, tetapi mereka agak mengarahkan saya ke solusi. Ternyata WP, sambil membuat daftar templat, sedang mencari bahkan functions.phpmenemukan "/Template Name:(.*)\n/siU"dan dengan demikian memperlakukan functions.phpfile templat. Saya pikir ini adalah bug WP, seharusnya tidak melihat file ini. Solusinya: pindahkan file ke subdirektori.
chodorowicz
@chodorowicz: Itu bukan bug di WP, ini bug dalam fungsi Anda.
wyrfel
Jadi pada dasarnya WP melarang Anda untuk meletakkan string "Nama Templat:" (bahkan dalam komentar) dalam functions.phpfile. Bagi saya, secara pribadi, itu bug, (kecil, tapi toh) tapi itulah diskusi, saya kira. Saya pikir Anda tidak bisa mengatakan bahwa fungsinya sendiri bermasalah.
chodorowicz
WP tidak melarang Anda untuk melakukan apa pun. Tetapi WP juga tidak menjanjikan Anda bahwa Anda dapat mengulangi debug_backtrace () untuk mencari tahu file template apa yang Anda gunakan. Hanya karena Anda menemukannya di forum dukungan WP tidak berarti itu kode yang didukung secara resmi. Seperti yang Anda lihat, fungsi Anda secara eksplisit mengeksplor footer.php. Anda juga dapat menambahkan kondisi lain yang mengecualikan functions.php. BTW: fungsi Anda tidak mencari Template Namedalam setiap file, loop Anda telah berakhir jauh sebelum itu.
wyrfel
Masalahnya bukan dengan debug_backtrace()- Saya dapat menghapus semua kode dan hanya pergi preg_match_all("/Template Name..., atau bahkan hanya // Template Name:dan WP memperlakukannya functions.phpsebagai file templat, tetapi terima kasih atas komentar - ini adalah masalah unik yang, seperti yang Anda katakan, tidak adil untuk dikatakan itu adalah bug. solusi t31os bersih dan menyelesaikan seluruh masalah. Salam.
chodorowicz
0

Mainkan bersama dengan:

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

Ditulis di:

Bagaimana Anda mengetahui halaman templat mana yang melayani halaman saat ini?

jika admin-bar stuffpath ditampilkan di bagian atas, atau file lain, ubah nama file template-loader.phppada baris kode ini menjadi: apa pun nama file yang harus Anda hentikan.

jika Anda memerlukan ini di bilah admin, gunakan priotity yang tepat (paling awal) untuk membuat shure tidak ada file yang dimasukkan pada akhir daftar ini. Sebagai contoh:

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

prioritas -5membuat shure itu dimuat terlebih dahulu. Kuncinya adalah membuat garis ini pada saat yang tepat.

Itu tidak mengembalikan file template "saat ini", tetapi semua saat ini digunakan untuk memuat halaman saat ini. Mungkin "cocok" dengan beberapa logika dari ide itu .

The get_included_files()"terakhir" kunci adalah yang terakhir terdaftar file yang disertakan, propably terakhir Template-file / -bagian digunakan di footer oleh sidebar widget atau sesuatu. Mungkin, karena file yang disertakan bersama tidak mendaftar ulang / mengisi lagi di get_included_files ().

Kalau tidak, niat harus jelas untuk meretas masalah ini . Tidak ada cara bagi file yang disertakan untuk melaporkan dirinya seperti yang dimasukkan, sampai file tersebut dimasukkan . Maka mungkin terlambat untuk menggunakan skenario.

Sebagian besar "waktu" Anda akan menyukai:

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

Tapi itu tidak mungkin jika template dimuat di luar metode inti Wordpress get_template_part. Rancang kembali kebutuhan Anda! Mungkin loop_start(), in_the_loop()dan add_action('the_post')memiliki solusi yang Anda inginkan, untuk mengubah data tergantung dari template yang akan dimuat untuk setiap entri dalam satu lingkaran.

Jonas Lundman
sumber
-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
Syafi'i
sumber