Ottieni il nome del file template corrente

26 feb 2011, 17:47:14
Visualizzazioni: 155K
Voti: 81

Ho trovato questo codice per visualizzare il nome corrente del file utilizzato nel 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 = '(predefinito)' ; }
    $template_file = array_pop(explode('/themes/', basename($template_file)));
    return $template_file . ' > '. $template_name ;
}

Fonte: ottieni il nome del template di pagina su una pagina

Funziona abbastanza bene, tranne che nel backend, nella casella di selezione del template, ottengo questa brutta voce extra:

Screenshot della casella di selezione del template nel backend di WordPress con voce extra non desiderata

Qualcuno ha un'idea su come risolvere? Non so nemmeno perché questa funzione viene chiamata nel backend. Esiste una funzione condizionale come is_frontend() - forse questo risolverebbe il problema?

9
Commenti

@chodorowicz - Anche se mi fermerò un passo prima di definire la selezione di functions.php come un bug, concordo completamente con la tua premessa. A peggiorare le cose, ho esaminato il codice core di WordPress e ho trovato circa 5 punti in cui avrebbe potuto esserci un hook per gestire questo problema, ma non ne ho trovato nessuno. Suggerirei di aprire un ticket su http://core.trac.wordpress.org.

MikeSchinkel MikeSchinkel
26 feb 2011 22:13:34

@MikeSchinkel - grazie per il commento, ma l'hook template_include, suggerito da t31os, non risolve il problema? O forse ho frainteso.

chodorowicz chodorowicz
27 feb 2011 17:29:35

@chodorowicz - Ora mi hai davvero confuso. La risposta di @t31os risolve un problema molto diverso da quello che avevo capito tu stessi chiedendo, basandomi sulla tua domanda e sui tuoi commenti alle risposte degli altri. Ma se la risposta di @t31os ha soddisfatto la tua effettiva esigenza, allora la mia confusione qui non ha importanza, visto che la tua domanda ha ricevuto risposta.

MikeSchinkel MikeSchinkel
27 feb 2011 18:21:23

Sì, l'esigenza effettiva era di visualizzare il nome del file del tema attualmente in uso, il codice che ho postato aveva un difetto (che può essere risolto spostando la funzione fuori dalla cartella principale del tema), ma la soluzione di @t31os è molto più pulita e soddisfa l'esigenza. Tuttavia, se ho capito correttamente, il problema reale (WP non dovrebbe tentare di leggere functions.php come file template di pagina) persiste ancora. Proverò a postarlo su trac, non l'ho ancora fatto. Saluti!

chodorowicz chodorowicz
27 feb 2011 18:44:34

@MikeSchinkel - ha già una patch :) http://core.trac.wordpress.org/ticket/16689

chodorowicz chodorowicz
28 feb 2011 19:33:19

@chodorowicz - Sì, il mio commento affrontava il problema reale, impedendo a WP di provare a leggere functions.php e/o permettendoti di scrivere un hook per cambiare ciò che viene restituito. Sono contento che tu abbia trovato una patch piuttosto che duplicarla; è così difficile trovare quei ticket esistenti.

MikeSchinkel MikeSchinkel
28 feb 2011 20:57:16

Ho creato un nuovo plugin per visualizzare il template corrente. Guardalo su http://wordpress.org/extend/plugins/display-template-name/

User User
1 giu 2012 14:32:12

^ cioè hai preso il codice dalla mia risposta e l'hai incapsulato in un plugin. E hai fatto tutto ciò senza fornire alcun credito alla fonte, né a me né a WP stackexchange... bello... :/

t31os t31os
31 mar 2014 00:08:14
Mostra i restanti 4 commenti
Tutte le risposte alla domanda 9
3
80

Potresti impostare una variabile globale durante il filtro template_include e successivamente controllare quella variabile globale per vedere quale template è stato incluso.

Naturalmente non vorrai il percorso completo insieme al file, quindi ti consiglio di ridurlo al solo nome del file utilizzando la funzione basename di PHP.

Codice di esempio:
Due funzioni, una per impostare la variabile globale, una per richiamarla.

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

Puoi poi richiamare get_current_template ovunque ne abbia bisogno nei file del tema, tenendo presente che questo naturalmente deve avvenire dopo che l'azione template_include è stata attivata (non dovrai preoccupartene se la chiamata viene fatta all'interno di un file template).

Per i page template esiste is_page_template(), tenendo presente che sarà utile solo nel caso di page template (una funzione molto meno universale).

Informazioni sulle funzioni utilizzate o menzionate sopra:

27 feb 2011 02:40:03
Commenti

Fantastico! Sapevo che doveva esserci un modo più semplice.

racl101 racl101
9 mar 2013 00:11:02

Da aggiungere in cima alla mia lista di funzioni per il debug.

Jules Jules
17 lug 2013 00:41:27

Le persone potrebbero essere interessate anche alle funzioni integrate is_single, is_attachment, is_singular, is_page e alle altre is_... functions.

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

apparentemente questo è sufficiente:

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

oppure puoi usarlo direttamente nel template (io solitamente lo inserisco in footer.php come commento HTML)

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

Sappi che non funzionerà con get-template-part, mostra solo single.php (ad esempio) e non il file in cui si trova.

MTT MTT
25 set 2012 18:11:09

Sì, è vero. Per ottenere il nome del file incluso probabilmente dovresti usare qualcosa come questo echo __FILE__;

chodorowicz chodorowicz
5 ott 2012 15:25:39

va bene, ad esempio nei casi in cui modifichi il template predefinito senza assegnarlo a un post nel backoffice. Ad esempio usando route personalizzate e il filtro template_include. Grazie.

Luca Reghellin Luca Reghellin
15 set 2016 13:05:23

Come potrei farlo all'interno di un ciclo? Sto cercando di visualizzare l'URL di una pagina per ogni file template.

JacobTheDev JacobTheDev
28 feb 2017 17:07:22

@JacobTheDev forse usando echo __FILE__ - perché questo non funzionerà, mostra solo il template principale iniziale

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

Tra le funzioni native di WP come get_template_part() e gli include nativi di PHP, il modo più affidabile per vedere i file del tema utilizzati è recuperare l'elenco di tutti i file inclusi e filtrare tutto ciò che non appartiene al tema (o ai temi quando viene utilizzata una combinazione di genitore e figlio):

$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

Un'aggiunta (più codice interessante) alle altre risposte qui presenti.

Nome del Template

Per ottenere semplicemente il nome del template della pagina corrente, usa la seguente riga.

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

Nome del File

Quando vuoi solo visualizzare il nome del file del template corrente, usa quanto segue

Modifica: Ecco la nuova versione del plugin racchiuso in una classe. Mostra sia il nome del file del template corrente, sia il nome del file della gerarchia dei template nell'hook di shutdown alla fine della pagina.

Cosa ti dice il plugin:

  • Il template proviene dal tema genitore o dal tema figlio/corrente?
  • Il template viene servito da una sottocartella? Se sì: Ti dice il nome
  • Il nome del file del template.

Basta copiare il seguente codice in un file e chiamarlo wpse10537_template_info.php, caricarlo nella directory dei plugin e attivarlo.

<?php
/** Plugin Name: (#10537) »kaiser« Ottieni nome del Template */

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(
                 "File del template"
                ,basename( $file )
            );
            return $file;
        }

        // Restituisce la variabile statica quando richiamato al di fuori del filtro
        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(
             "Sottocartella"
            ,strstr( $slug, "/", true )
        );

        $this->to_stack(
             "Template (in sottocartella)"
            ,str_replace( "/", "", strstr( $slug, "/" ) )
        );
    }

    public function is_parent_template()
    {
        if ( ! is_null( wp_get_theme()->parent ) )
            return $this->to_stack( 'dal tema genitore' );

        $this->to_stack( 'dal tema corrente/figlio' );
    }

    public function to_stack( $part, $item = '' )
    {
        $this->stack[] = "{$part}: {$item}";
    }
} // END Class wpse10537_template_name

} // endif;

Questo plugin può essere eseguito anche come MU-Plugin.

Puoi poi semplicemente chiamare wpse10537_get_template_name() in qualsiasi punto (ad esempio in un template del tema). Questo evita di ingombrare il namespace globale.

8 set 2012 05:16:18
Commenti

template_redirect non sta passando nulla, penso che tu stia confondendo con template_include. Inoltre, controllerei se all'interno del filtro invece che se la variabile statica è riempita. Se del codice decide di eseguire l'hook un'ulteriore volta può causare problemi.

Rarst Rarst
15 set 2012 20:42:16

@Rarst Fatto/Risolto. Grazie per il suggerimento e per aver indicato il nome del filtro.

kaiser kaiser
15 set 2012 22:18:02
3

Il nome del template è memorizzato nella tabella postmeta, quindi tutto ciò che devi fare è inserire questo codice all'interno del tuo loop:

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

Sì, lo so, ma il problema è che funziona solo quando una pagina ha un template impostato. La cosa interessante del codice che ho postato è che ti dirà se la pagina corrente sta utilizzando front-page.php, index.php, single.php, page.php o qualsiasi altro file. Il tuo codice mostra il nome del template solo per le pagine con un template personalizzato.

chodorowicz chodorowicz
26 feb 2011 20:05:17

ah, scusa - ho frainteso la tua domanda.

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

@SimonBlackbourn È stato utile per la mia esigenza. Grazie.

KarSho KarSho
8 ott 2013 10:04:02
0

Questo non risponde completamente alla domanda dell'OP, ma il codice qui sotto è certamente più elegante delle espressioni regolari e del parsing del file template stesso.

Se ti trovi su una Pagina che utilizza un Template di Pagina e vuoi ottenere il Nome del template (cioè il nome leggibile che hai definito nei commenti all'inizio del tuo file PHP template), puoi usare questo piccolo trucco:

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

Volevo ottenere il nome del template perché ero veramente stanco dei nomi di classe lunghissimi e ridicoli che la funzione integrata di WordPress body_class crea quando stai usando un template. Fortunatamente c'è un hook filter alla fine di quella funzione che ti permette di aggiungere i tuoi nomi di classe. Ecco il mio filter. Spero che qualcuno lo trovi utile:

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

Questo filter prenderà qualsiasi nome tu abbia dato al tuo template di pagina, sostituirà gli spazi con trattini e renderà tutto in minuscolo in modo che assomigli a tutte le altre classi di WordPress.

1 mag 2013 04:56:21
5

C'è un problema con la riga del preg_match_all. Prova invece questo:

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

Inoltre, puoi usare if (!is_admin()) { .... } per eseguire operazioni solo sul frontend.

26 feb 2011 18:43:26
Commenti

Grazie per il suggerimento, non risolvono il problema, ma mi hanno indirizzato verso delle soluzioni. Si scopre che WP, mentre genera la lista dei template, cerca persino nel functions.php trova il "/Template Name:(.*)\n/siU" e quindi tratta il functions.php come un file di template. Penso che questo sia un bug di WP, non dovrebbe nemmeno guardare questo file. La soluzione: spostare il file in una sottodirectory.

chodorowicz chodorowicz
26 feb 2011 19:33:30

@chodorowicz: Non è un bug in WP, è un bug nella tua funzione.

wyrfel wyrfel
26 feb 2011 20:18:54

Quindi, fondamentalmente, WP ti vieta di inserire la stringa "Template Name:" (anche in un commento) nel file functions.php. Per me, personalmente, è un bug (piccolo, ma comunque), ma questo è discutibile, suppongo. Penso che non si possa dire che la funzione stessa sia difettosa.

chodorowicz chodorowicz
26 feb 2011 21:14:01

WP non ti vieta di fare nulla. Ma WP non ti garantisce nemmeno che puoi eseguire un loop su un debug_backtrace() per scoprire quale file template stai utilizzando. Solo perché l'hai trovato su un forum di supporto WP non significa che sia codice ufficialmente supportato. Come puoi vedere, la tua funzione esclude esplicitamente footer.php. Potresti anche aggiungere un'altra condizione che esclude functions.php. BTW: la tua funzione non cerca Template Name all'interno di ciascuno dei file, il tuo loop è terminato molto prima di quello.

wyrfel wyrfel
27 feb 2011 08:00:12

Il problema non era con debug_backtrace() - posso rimuovere tutto il codice e lasciare solo preg_match_all("/Template Name..., o anche solo // Template Name: e WP tratta poi functions.php come file template, ma grazie per i commenti - questo è un problema così unico che, come dici tu, non è corretto definirlo un bug. La soluzione di t31os è pulita e risolve completamente il problema. Saluti.

chodorowicz chodorowicz
27 feb 2011 13:56:31
0

Gioca insieme a:

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

Scritto su:

Come scoprire quale template sta servendo la pagina corrente?

Se il percorso admin-bar stuff viene visualizzato in cima, o qualsiasi altro file, cambia il nome del file template-loader.php in questa riga di codice con: qualunque nome di file da cui vuoi interrompere.

Se hai bisogno di questo nella barra di amministrazione, usa la giusta priorità (la più precoce) per assicurarti che nessun file venga aggiunto alla fine di questa lista. Ad esempio:

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

La priorità -5 assicura che venga caricata per prima. La chiave è eseguire questa riga al momento giusto.

Non restituisce il file template "corrente", ma tutti quelli attualmente in uso per il caricamento della pagina. Forse "estrai" con un po' di logica da questa idea.

L'ultima chiave di get_included_files() è l'ultimo file incluso registrato, probabilmente l'ultimo file template/parte usata nel footer da un widget della sidebar. Probabilmente, perché più file inclusi non si ri-registrano/non popolano nuovamente get_included_files().

Altrimenti, l'intenzione deve essere chiara per risolvere questo problema. Non c'è modo per un file incluso di segnalare se stesso come incluso, finché non è stato incluso. A quel punto è probabilmente troppo tardi per usare lo scenario.

La maggior parte delle "volte" vorresti:

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

Ma questo non è possibile se il template viene caricato al di fuori del metodo core di WordPress get_template_part. Riprogetta le tue esigenze! Forse loop_start(), in_the_loop() e add_action('the_post') hanno la soluzione che desideri, per modificare i dati in base al template che verrà caricato per ogni voce all'interno di un loop.

15 set 2017 09:49:57
0
-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
17 feb 2016 10:54:16