Geçerli şablon dosyasının adını al


57

Bunu, şablonda kullanılan dosyanın geçerli adını görüntülemek için buldum:

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

Kaynak: bir sayfadaki sayfa şablonunun adını al

Arka uçta, şablon seçme kutusunda, bu çirkin ekstra girişi alıyorum dışında, oldukça iyi çalışıyor:

ekran görüntüsü

Bunu nasıl düzeltebileceği hakkında fikri olan var mı? Bu işlevin neden arka uçta çağrıldığını bile bilmiyorum. Gibi bir koşullu işlevi var mı is_frontend()- belki bu sorunu çözebilir?


2
@chodorowicz - Seçimini functions.phpbir hata olarak adlandırmaktan bir adım öteye giderken , öncülünüzle tamamen aynı fikirdeyim. Daha da kötüsünü yapmak için, WordPress çekirdek kodunu taradım ve bu sorunu çözmenize izin verecek bir çengelin olabileceği yaklaşık 5 yer buldum, ancak hiçbirini bulamadım. Core.trac.wordpress.org adresinden bir bilet göndermenizi öneririm .
MikeSchinkel

@MikeSchinkel - yorumunuz için teşekkürler, ancak template_includehangi t31os'un önerdiği kanca çözülmedi mi? Ya da belki seni yanlış anladım.
chodorowicz

1
@MikeSchinkel - zaten bir yaması var :) core.trac.wordpress.org/ticket/16689
chodorowicz

1
Mevcut şablonu görüntülemek için yeni bir eklenti yaptım. Wordpress.org/extend/plugins/display-template-name

4
^ yani. benim cevabımdaki kodu aldın ve bir eklentiye aldın. Bunların hepsini kökene, kendi kendime ya da WP
yığın değiş tokuşu olmadan

Yanıtlar:


68

template_includeFiltre sırasında bir genel değişken ayarlayabilir ve daha sonra hangi şablonun eklendiğini görmek için global değişkenin kontrol edilebileceğini kontrol edebilirsiniz.

Doğal olarak dosyayla birlikte tam yolu istemezsiniz, bu nedenle PHP'nin basenameişlevini kullanarak dosya adına kısma öneririm .

Örnek kod:
Biri global olanı diğeri çağırmak için iki fonksiyon.

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

Daha sonra get_current_template, tema dosyalarında ihtiyaç duyduğunuz her yerde çağrı yapabilirsiniz , template_includeeylemin başlamasından sonra bunun doğal olarak gerçekleşmesi gerektiğine dikkat çekebilirsiniz (çağrı bir şablon dosyasının içinde yapılırsa endişelenmenize gerek yoktur).

Sayfa şablonları için is_page_template(), sadece sayfa şablonları söz konusu olduğunda yardımcı olacağı akılda tutulmalıdır (çok az işlev tüm işlevler).

Yukarıda kullanılan veya başvurulan işlevler hakkında bilgi:


Korku veren! Daha basit bir yolu olması gerektiğini biliyordum.
racl101

Bir hata ayıklama fonksiyonları listemin üstüne eklemek için.
Jules

22

görünüşe göre bu yeterli:

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

veya sadece doğrudan şablonda kullanın (HTML yorumunda footer.php'de yankı oluşturma eğilimindeyim)

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

1
Yani bil ki get-şablon bölümü ile çalışmaz, sadece (örneğin) single.php değil dosyayı gösterir o içindedir.
m-torin

Evet bu doğru. Dahil edilen dosyanın adını almak için muhtemelen böyle bir şey kullanmanız gerekirecho __FILE__;
chodorowicz 5:12

Bu, örneğin varsayılan şablonu backoffice bir gönderiye atamadan değiştirdiğinizde durumlarda iyidir. Örneğin, özel yollar ve template_include filtresini kullanma. Teşekkür ederim.
Luca Reghellin

Bunu bir döngü içinde nasıl yapabilirim? URL’yi her şablon dosyasının bir sayfasına göndermeye çalışıyorum.
JacobTheDev,

@JacobTheDev belki kullanıyor echo __FILE__- çünkü bu işe yaramayacak, sadece ana, ilk şablonu görüntülüyor
chodorowicz

17

Yerli WP işlevleri arasında get_template_part () ve PHP'nin native özelliği, kullanılan dosyaları görmenin en güvenilir yolunu içerir; içerilen tüm dosyaların listesini almak ve temaya (veya ebeveyn ve çocuk kombinasyonu kullanıldığında kullanılan temalar) ne olursa olsun filtrelemektir. :

$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

Burada diğer cevaplara bir ek (daha tatlı kod).

şablon adı

Sadece geçerli sayfa şablonunun adını almak için aşağıdaki satırı kullanın.

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

Dosya adı

Yalnızca geçerli şablon dosya adını yankılamak istediğinizde , aşağıdakilere gidin

Düzenleme: İşte bir sınıfa sarılı eklentinin yeni sürümü. Hem geçerli şablon dosya adını hem de sayfanın en altındaki kapatma kancasında bulunan şablon hiyerarşi dosya adını gösterir.

Eklenti size ne söylüyor:

  • Şablon alt / ana temanın üstünden mi?
  • Şablon bir alt klasörden sunuluyor mu? Eğer evet ise: ismini söyler
  • Şablon dosyası adı.

Aşağıdaki kodu bir dosyaya kopyalayın ve adlandırın wpse10537_template_info.php, eklenti dizininize yükleyin ve etkinleştirin.

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

Bu eklenti de MU-Plugin olarak çalıştırabilir.

Daha sonra wpse10537_get_template_name()herhangi bir noktada (örneğin bir tema şablonunda) arayabilirsiniz . Bu, küresel ad alanının dağınıklığını önler.


1
template_redirecthiçbir şey geçmiyor, sanırım kafa karıştırıyorsun template_include. Ayrıca statik var doldurulmuş yerine filtrenin içinde olup olmadığını kontrol ediyorum. Bazı kodlar ek süre kancayı çalıştırmaya karar verirse, işleri mahvedebilir.
Rarst

@Rarst Bitti / Sabit. Tavsiyeniz ve filtre adını işaret ettiğiniz için teşekkür ederiz.
kaiser

5

Şablon adı postmeta tablosunda depolanır, bu nedenle tek yapmanız gereken bunu döngünüzde bir yere koymaktır:

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

2
Evet, bunu biliyorum, ancak sorun, yalnızca bir sayfada ayarlanmış bir şablon olduğunda işe yaraması. Ben yayınlanmıştır kodu hakkında serin şey mevcut sayfa kullanıyorsa o söyleyecektir olmasıdır front-page.php, index.php, single.php, page.phpya da başka herhangi bir dosya. Kodunuz, yalnızca özel sayfa şablonuna sahip sayfalar için şablon adını görüntüler.
chodorowicz

ah, üzgünüm - sorunuzu yanlış anladım.
Simon Blackbourn

@SimonBlackbourn Bu benim ihtiyacım için yardımcı olur. Teşekkürler.
KarSho

3

Bu, OP'nin tüm sorusunu ele almaz, ancak aşağıdaki kod kesinlikle normal ifadelerden ve şablon dosyasının kendisini ayrıştırmadan daha zarif.

Sayfa Şablonu kullanan bir Sayfa üzerindeyseniz ve sayfa şablonunun Adını almak istiyorsanız (yani: şablon PHP dosyanızın üst kısmındaki açıklamalarda tanımladığınız insan tarafından okunabilen ad), kullanabilirsiniz. bu küçük külçe:

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

Şablon adını almak istedim çünkü yerleşik WordPress body_classişlevinin bir şablon kullanırken yarattığı aptal-uzun eşek sınıf adlarından gerçekten bıktım . Neyse ki, kendi sınıf adlarınızı da eklemenize izin vermek için bu fonksiyonun sonunda bir filtre kancası var. İşte benim filtrem. Birisi onu yararlı bulur umarım:

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

Bu filtre, sayfa şablonunuz ne adlandırdıysanız alır, boşlukları tire ile değiştirir ve her şeyi küçük harf yapar, böylece diğer WordPress sınıflarına benzeyecektir.


0

Çizgide bir sorun var preg_match_all. Bunun yerine şunu deneyin:

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

Ayrıca, if (!is_admin()) { .... }yalnızca ön uçtaki şeyleri çalıştırmak için kullanabilirsiniz .


Öneriniz için teşekkürler, sorunu çözmüyorlar, ancak beni çözümlere yönlendirdiler. WP'nin şablon listesi oluştururken bile functions.phpbulduğu "/Template Name:(.*)\n/siU"ve bu yüzden functions.phpde şablon dosyasını ele aldığı anlaşılmaktadır . Bence bu WP hatası, bu dosyaya bile bakmamalı. Çözüm: dosyayı alt dizine taşıyın.
chodorowicz

@chodorowicz: Bu WP'de bir hata değil, fonksiyonunuzda bir hata.
wyrfel

Bu yüzden temelde WP, "Şablon Adı:" dizgesini (yorumda bile) functions.phpdosyaya koymanızı yasaklar . Benim için, kişisel olarak, bu bir hata, (küçük, ama yine de) ama sanırım tartışmanın nedeni budur. İşlevin kendisinin arabası olduğunu söyleyemezsin.
chodorowicz

WP hiçbir şey yapmanı yasaklamaz. Ancak WP, hangi şablon dosyasını kullandığınızı öğrenmek için debug_backtrace () üzerinde dönebileceğiniz konusunda size söz vermez. Sırf WP destek forumunda bulmuş olmanız resmen desteklendiği anlamına gelmez. Gördüğünüz gibi, işleviniz açıkça footer.php dosyasını dışlıyor. Functions.php dosyasını dışlayan başka bir koşul da ekleyebilirsiniz. BTW: fonksiyonunuz Template Nameher bir dosya için arama yapmıyor , döngünüz bundan çok önce sona ermişti.
wyrfel

Sorun şu değildi debug_backtrace()- tüm kodu kaldırabilir ve sadece bırakabilirim preg_match_all("/Template Name..., ya da sadece // Template Name:ve WP o zaman functions.phpşablon dosyası olarak kabul eder , ancak yorumlarınız için teşekkürler - bu sizin söylediğiniz gibi adil olmayan bir problemdir bu bir böcek. t31os çözümü temiz ve tüm sorunu çözüyor. Karşılıyor.
chodorowicz

0

Şununla birlikte oyna:

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

De yazılmıştır:

Hangi şablon sayfasının o anki sayfayı sunduğunu nasıl buluyorsunuz?

eğer admin-bar stuffyol üst, ya da başka bir dosyaya gösteriyor, dosya adını değiştirmek template-loader.phpsen kırmak için ne gerekiyorsa filname: Bu kod satırında.

Yönetici çubuğunda buna ihtiyacınız varsa, listenin sonunda hiçbir dosya girilmediğinden emin olmak için doğru önceliği kullanın (en eski) . Örneğin:

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

Öncelikle -5yükleri ilk önce yükleyiniz. Anahtar, bu çizgiyi doğru zamanda vermektir.

"Geçerli" şablon dosyasını döndürmez, ancak geçerli sayfa yükü için kullanılan tüm akımı döndürür. Belki de bu fikirden bir mantıkla "kes" .

get_included_files()"Son" anahtar dosyası, widgetlerdede oralarda da altbilgi kullanılan Propably son şablon dosya / -part dahil tescilli sonuncusu. Muhtemelen, çünkü mutiple içerilen dosyalar get_included_files () dizininde yeniden kaydedilmez / doldurmaz.

Aksi halde, bu sorunun üstesinden gelmek için niyet net olmalıdır . Dahil edilen bir dosyanın ekleninceye kadar kendisini dahil edildiği şekilde bildirmesi mümkün değildir . Sonra senaryoyu kullanmak için geç saatlere kadar.

"Zaman" çoğu, olur gibi:

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

Ancak şablon Wordpress'in çekirdek yönteminin dışına yüklendiyse bu mümkün değildirget_template_part . Bunun yerine ihtiyaçlarınızı yeniden tasarlayın! Belki loop_start(), in_the_loop()ve add_action('the_post')veri şablonun bağlı bir döngü içinde her giriş için olacak yükümüz değiştirmek istediğiniz çözümü vardır.


-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.