Obține numele fișierului șablon curent

26 feb. 2011, 17:47:14
Vizualizări: 155K
Voturi: 81

Am găsit această metodă pentru a afișa numele curent al fișierului folosit în șablon:

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 = '(implicit)' ; }
    $template_file = array_pop(explode('/themes/', basename($template_file)));
    return $template_file . ' > '. $template_name ;
}

Sursa: obține numele șablonului de pagină pe o pagină

Funcționează destul de bine, cu excepția faptului că în backend, în caseta de selectare a șablonului, primesc această intrare urâtă în plus:

captură de ecran a interfeței de administrare cu eroarea de afișare a șablonului

Are cineva vreo idee cum să rezolv asta? Nici măcar nu știu de ce această funcție este apelată în backend. Există o funcție condițională precum is_frontend() - poate aceasta ar rezolva problema?

9
Comentarii

@chodorowicz - Deși voi face un pas înapoi în a numi selecția functions.php ca o eroare, sunt complet de acord cu premisa ta. Pentru a înrăutăți lucrurile, am scanat codul WordPress core și am găsit aproximativ 5 locuri unde ar fi putut exista un hook care să îți permită să rezolvi această problemă, dar nu am găsit niciunul. Aș sugera să postezi un tichet pe http://core.trac.wordpress.org.

MikeSchinkel MikeSchinkel
26 feb. 2011 22:13:34

@MikeSchinkel - mulțumesc pentru comentariu, dar hook-ul template_include, sugerat de t31os, nu rezolvă problema? Sau poate nu te-am înțeles corect.

chodorowicz chodorowicz
27 feb. 2011 17:29:35

@chodorowicz - Acum m-ai dat peste cap. Răspunsul dat de @t31os rezolvă o problemă foarte diferită de cea pe care am înțeles-o eu că o întrebai, bazat pe întrebarea ta și pe comentariile ulterioare la răspunsurile altora. Dar dacă răspunsul lui @t31os ți-a rezolvat nevoia reală, atunci confuzia mea aici este lipsită de importanță, deoarece întrebarea ta a primit răspuns.

MikeSchinkel MikeSchinkel
27 feb. 2011 18:21:23

Da, nevoia reală era să afișez numele fișierului de temă utilizat în prezent, codul pe care l-am postat avea o eroare (care poate fi rezolvată prin mutarea funcției în afara folderului principal al temei), dar soluția lui @t31os este mult mai elegantă și îndeplinește nevoia. Dar, dacă te înțeleg corect, problema reală (WP nu ar trebui să încerce să citească functions.php ca fișier de șablon pentru pagină) încă persistă. Voi încerca să postez pe trac, nu am făcut-o încă. Salutări!

chodorowicz chodorowicz
27 feb. 2011 18:44:34

@MikeSchinkel - are deja un patch :) http://core.trac.wordpress.org/ticket/16689

chodorowicz chodorowicz
28 feb. 2011 19:33:19

@chodorowicz - Da, comentariul meu se referea la problema reală, împiedicând WP să încerce să citească functions.php și/sau permițându-ți să scrii un hook pentru a modifica ce este returnat. Mă bucur să văd că ai găsit un patch în loc să-l duplici; este atât de greu să găsești acele tichete existente.

MikeSchinkel MikeSchinkel
28 feb. 2011 20:57:16

Am creat un nou plugin pentru a afișa template-ul curent. Verifică-l pe http://wordpress.org/extend/plugins/display-template-name/

User User
1 iun. 2012 14:32:12

^ adică ai luat codul din răspunsul meu și l-ai împachetat într-un plugin. Și ai făcut toate astea fără să dai vreun credit sursei, nici mie, nici comunității WP stackexchange... frumos... :/

t31os t31os
31 mar. 2014 00:08:14
Arată celelalte 4 comentarii
Toate răspunsurile la întrebare 9
3
80

Puteți seta o variabilă globală în timpul filtrului template_include și apoi verificați acea variabilă globală pentru a vedea care șablon a fost inclus.

Bineînțeles, nu veți dori calea completă împreună cu fișierul, așa că recomand să trunchiați la numele fișierului folosind funcția PHP basename.

Exemplu de cod:
Două funcții, una pentru setarea variabilei globale, una pentru apelarea ei.

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

Apoi puteți apela get_current_template oriunde aveți nevoie în fișierele de șablon, ținând cont că acest lucru trebuie să se întâmple după ce acțiunea template_include a fost declanșată (nu va trebui să vă faceți griji pentru asta dacă apelul este făcut în interiorul unui fișier de șablon).

Pentru șabloanele de pagină există is_page_template(), reținând că aceasta va ajuta doar în cazul șabloanelor de pagină (o funcție mult mai puțin universală).

Informații despre funcțiile utilizate sau menționate mai sus:

27 feb. 2011 02:40:03
Comentarii

Super! Știam că trebuie să existe o cale mai simplă.

racl101 racl101
9 mar. 2013 00:11:02

Una de adăugat în vârful listei mele de funcții de depanare.

Jules Jules
17 iul. 2013 00:41:27

Oamenii ar putea fi interesați și de funcțiile încorporate is_single, is_attachment, is_singular, is_page și celelalte is_... funcții.

Fabien Snauwaert Fabien Snauwaert
7 apr. 2022 10:22:03
5
46

aparent, asta este suficient:

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

sau poți să folosești direct în template (eu prefer să afișez în footer.php într-un comentariu HTML)

<?php global $template; echo basename($template); ?>
9 apr. 2011 19:25:16
Comentarii

Asta nu va funcționa cu get-template-part, doar ca să știi, afișează doar single.php (de exemplu) și nu fișierul în care se află.

MTT MTT
25 sept. 2012 18:11:09

Da, este adevărat. Pentru a obține numele fișierului inclus, probabil ar trebui să folosești ceva de genul echo __FILE__;

chodorowicz chodorowicz
5 oct. 2012 15:25:39

acest lucru este în regulă, de exemplu în cazurile în care modifici șablonul implicit fără a-l atribui unui articol în backoffice. De exemplu, folosind rute personalizate și filtrul template_include. Mulțumesc.

Luca Reghellin Luca Reghellin
15 sept. 2016 13:05:23

Cum aș putea face acest lucru într-o buclă? Încerc să afișez URL-ul către o pagină din fiecare fișier șablon.

JacobTheDev JacobTheDev
28 feb. 2017 17:07:22

@JacobTheDev poate folosind echo __FILE__ - pentru că această metodă nu va funcționa, afișează doar șablonul principal, inițial

chodorowicz chodorowicz
8 mar. 2017 00:08:06
0
18

Între funcțiile native WordPress precum get_template_part() și include-urile native PHP, cea mai fiabilă metodă de a vedea fișierele temei utilizate este să obții lista tuturor fișierelor incluse și să filtrezi tot ce nu aparține temei (sau temelor atunci când se folosește combinația părinte-copil):

$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 );
1 mar. 2013 20:27:00
2
12

O completare (cod și mai interesant) la celelalte răspunsuri de aici.

Numele șablonului

Pentru a obține doar numele șablonului de pagină curent, folosiți următoarea linie.

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

Numele fișierului

Când doriți doar să afișați numele fișierului șablonului curent, utilizați următoarele

Editare: Iată noua versiune a pluginului încapsulată într-o clasă. Acesta afișează atât numele fișierului șablonului curent, cât și numele fișierului din ierarhia șabloanelor în hook-ul de shutdown, la partea de jos a paginii.

Ce vă spune pluginul:

  • Șablonul provine din tema părinte sau din tema copil/curentă?
  • Șablonul este servit dintr-un subfolder? Dacă da: Vă spune numele acestuia
  • Numele fișierului șablonului.

Doar copiați următorul cod într-un fișier și denumiți-l wpse10537_template_info.php, încărcați-l în directorul de pluginuri și activați-l.

<?php
/** Plugin Name: (#10537) »kaiser« Obține numele fișierului șablon */

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(
                 "Fișier șablon"
                ,basename( $file )
            );
            return $file;
        }

        // Returnează variabila statică la apelul echo în afara filtrului
        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( "Șablon", $slug );

        $this->to_stack(
             "Subdirector"
            ,strstr( $slug, "/", true )
        );

        $this->to_stack(
             "Șablon (în subdirector)"
            ,str_replace( "/", "", strstr( $slug, "/" ) )
        );
    }

    public function is_parent_template()
    {
        if ( ! is_null( wp_get_theme()->parent ) )
            return $this->to_stack( 'din tema părinte' );

        $this->to_stack( 'din tema curentă/copil' );
    }

    public function to_stack( $part, $item = '' )
    {
        $this->stack[] = "{$part}: {$item}";
    }
} // Sfârșitul clasei wpse10537_template_name

} // endif;

Acest plugin poate rula și ca MU-Plugin.

Puteți apela apoi simplu wpse10537_get_template_name() în orice moment (de exemplu, într-un șablon de temă). Acest lucru evită aglomerarea namespace-ului global.

8 sept. 2012 05:16:18
Comentarii

template_redirect nu transmit nimic, cred că confunzi cu template_include. De asemenea, aș verifica în interiorul filtrului în loc să verific dacă variabila statică este completată. Dacă un cod decide să ruleze hook-ul încă o dată, poate strica lucrurile.

Rarst Rarst
15 sept. 2012 20:42:16

@Rarst Finalizat/Rezolvat. Mulțumesc pentru indiciu și pentru precizarea numelui filtrului.

kaiser kaiser
15 sept. 2012 22:18:02
3

Numele șablonului este stocat în tabelul postmeta, așa că tot ce trebuie să faci este să plasezi acest cod undeva în bucla ta:

$template = get_post_meta( $post->ID, '_wp_page_template', true );
echo "Șablon: " . $template;
26 feb. 2011 19:51:28
Comentarii

Da, știu despre asta, dar problema este că funcționează doar când o pagină are un șablon setat. Partea bună despre codul pe care l-am postat este că îți va spune dacă pagina curentă folosește front-page.php, index.php, single.php, page.php sau orice alt fișier. Codul tău afișează numele șablonului doar pentru paginile cu șablon personalizat.

chodorowicz chodorowicz
26 feb. 2011 20:05:17

ah, scuze - am înțeles greșit întrebarea ta.

Simon Blackbourn Simon Blackbourn
26 feb. 2011 20:23:54

@SimonBlackbourn Ajută pentru cerința mea. Mulțumesc.

KarSho KarSho
8 oct. 2013 10:04:02
0

Acest lucru nu răspunde complet la întrebarea OP, dar codul de mai jos este cu siguranță mai elegant decât expresiile regulate și parsarea fișierului de șablon în sine.

Dacă te afli pe o Pagină care folosește un Șablon de Pagină și dorești să obții Numele șablonului de pagină (adică numele lizibil de om pe care l-ai definit în comentariile din partea de sus a fișierului PHP al șablonului), poți folosi acest mic truc:

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

Am vrut să obțin numele șablonului pentru că eram foarte sătul de numele lungi și stupide ale claselor pe care funcția încorporată WordPress body_class le creează atunci când folosești un șablon. Din fericire, există un filtru la sfârșitul acelei funcții care îți permite să adaugi propriile nume de clase. Iată filtrul meu. Sper că cineva îl va găsi util:

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

Acest filtru va lua orice nume ai dat șablonului tău de pagină, va înlocui spațiile cu liniuțe și va face totul cu litere mici, astfel încât să arate ca toate celelalte clase WordPress.

1 mai 2013 04:56:21
5

Există o problemă cu linia preg_match_all. Încearcă asta în schimb:

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

De asemenea, poți folosi if (!is_admin()) { .... } pentru a rula cod doar în partea publică a site-ului.

26 feb. 2011 18:43:26
Comentarii

Mulțumesc pentru sugestie, ele nu rezolvă problema, dar m-au îndrumat într-o oarecare măsură spre soluții. Se pare că WP, în timp ce generează lista de șabloane, caută chiar și în functions.php găsește "/Template Name:(.*)\n/siU" și astfel tratează functions.php ca fiind un fișier de șablon. Cred că aceasta este o eroare în WP, nu ar trebui să se uite deloc în acest fișier. Soluția: mutați fișierul într-un subdirector.

chodorowicz chodorowicz
26 feb. 2011 19:33:30

@chodorowicz: Aceasta nu este o eroare în WP, este o eroare în funcția ta.

wyrfel wyrfel
26 feb. 2011 20:18:54

Deci, practic WP te împiedică să pui șirul "Template Name:" (chiar și în comentariu) în fișierul functions.php. Pentru mine, personal, aceasta este o eroare (mică, dar totuși), dar asta e subiect de dezbatere, presupun. Nu cred că poți spune că funcția în sine este defectuoasă.

chodorowicz chodorowicz
26 feb. 2011 21:14:01

WP nu te împiedică să faci orice. Dar WP nu îți promite nici că poți parcurge un debug_backtrace() pentru a afla ce fișier de template folosești. Doar pentru că l-ai găsit pe un forum de suport WP nu înseamnă că este cod oficial suportat. După cum poți vedea, funcția ta exclude în mod explicit footer.php. La fel de bine ai putea adăuga o altă condiție care exclude functions.php. Apropo: funcția ta nu caută Template Name în interiorul fiecărui fișier, bucla ta s-a încheiat cu mult înainte de asta.

wyrfel wyrfel
27 feb. 2011 08:00:12

Problema nu a fost cu debug_backtrace() - pot elimina tot codul și să las doar preg_match_all("/Template Name..., sau chiar doar // Template Name: și WP tratează atunci functions.php ca fișier template, dar mulțumesc pentru comentarii - aceasta este o problemă atât de unică încât, după cum spui, nu este corect să spunem că este un bug. Soluția lui t31os este curată și rezolvă întreaga problemă. Salutări.

chodorowicz chodorowicz
27 feb. 2011 13:56:31
0

Joacă-te cu:

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

Scris la:

Cum afli care șablon servește pagina curentă?

Dacă calea admin-bar stuff apare în partea de sus sau orice alt fișier, schimbă numele fișierului template-loader.php în această linie de cod cu: orice nume de fișier de la care ai nevoie să te desprinzi.

Dacă ai nevoie de asta în bara de administrare, folosește prioritatea corectă (cea mai devreme) pentru a te asigura că niciun fișier nu este adăugat la sfârșitul acestei liste. De exemplu:

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

Prioritatea -5 asigură că se încarcă primul. Cheia este să rulezi această linie în momentul potrivit.

Nu returnează șablonul "curent", ci toate fișierele în uz pentru încărcarea curentă a paginii. Poate "elimina" cu o anumită logică din această idee.

Ultima cheie din get_included_files() este ultimul fișier inclus înregistrat, probabil ultimul fișier șablon/parte utilizat în subsol de către un widget de sidebar sau ceva similar. Probabil, deoarece fișierele multiple incluse nu se reînregistrează/nu populează din nou în get_included_files().

În caz contrar, intenția trebuie să fie clară pentru a rezolva această problemă. Nu există nicio modalitate ca un fișier inclus să se raporteze ca inclus, până nu a fost inclus. Atunci este probabil prea târziu să folosești acest scenariu.

De cele mai multe ori ai dori:

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

Dar acest lucru nu este posibil dacă șablonul este încărcat în afara metodei de bază a WordPress-ului get_template_part. Redesenează-ți nevoile în schimb! Poate loop_start(), in_the_loop() și add_action('the_post') au soluția pe care o dorești, pentru a modifica datele în funcție de șablonul care va fi încărcat pentru fiecare intrare dintr-o buclă.

15 sept. 2017 09:49:57
0
-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//afișează $templateName;
var_dump( $templateName );
17 feb. 2016 10:54:16