Obtener el nombre del archivo de plantilla actual
He encontrado esto para mostrar el nombre actual del archivo usado en la plantilla:
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 = '(predeterminado)' ; }
$template_file = array_pop(explode('/themes/', basename($template_file)));
return $template_file . ' > '. $template_name ;
}
Fuente: obtener el nombre de la plantilla de página en una página
Funciona bastante bien, excepto que en el backend, en el cuadro de selección de plantillas, obtengo esta entrada extra poco atractiva:
¿Alguien tiene alguna idea de cómo arreglarlo? Ni siquiera sé por qué esta función se llama en el backend. ¿Existe una función condicional como is_frontend()
- tal vez esto resolvería el problema?

Podrías establecer una variable global durante el filtro template_include
y luego verificar esa variable global para saber qué plantilla se ha incluido.
Naturalmente, no querrás la ruta completa junto con el archivo, así que recomiendo truncar hasta solo el nombre del archivo usando la función basename
de PHP.
Código de ejemplo:
Dos funciones, una para establecer la global, otra para llamarla.
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'];
}
Luego puedes llamar a get_current_template
donde lo necesites en los archivos del tema, teniendo en cuenta que esto debe ocurrir después de que se haya ejecutado la acción template_include
(no tendrás que preocuparte por esto si la llamada se hace dentro de un archivo de plantilla).
Para plantillas de página existe is_page_template()
, teniendo en cuenta que esto solo ayuda en el caso de plantillas de página (una función mucho menos general).
Información sobre las funciones usadas o referenciadas arriba:

Una función más para añadir a la parte superior de mi lista de funciones de depuración.

Las personas también pueden estar interesadas en las funciones integradas is_single
, is_attachment
, is_singular
, is_page
y otras is_...
funciones.

aparentemente esto es suficiente:
add_action('wp_head', 'show_template');
function show_template() {
global $template;
echo basename($template);
}
o simplemente usarlo directamente en la plantilla (suelo mostrarlo en footer.php dentro de un comentario HTML)
<?php global $template; echo basename($template); ?>

Eso no funcionará con get-template-part, solo muestra single.php (por ejemplo) y no el archivo en el que está.

Sí, es cierto. Para obtener el nombre del archivo incluido probablemente necesitarías usar algo como esto echo __FILE__;

esto está bien, por ejemplo en casos cuando modificas la plantilla predeterminada sin asignarla a una publicación en el backoffice. Por ejemplo usando rutas personalizadas y el filtro template_include. Gracias.

¿Cómo podría hacer esto dentro de un bucle? Estoy intentando mostrar la URL de una página por cada archivo de plantilla.

Entre las funciones nativas de WordPress como get_template_part() y los includes nativos de PHP, la forma más confiable de ver los archivos del tema utilizados es obtener una lista de todos los archivos incluidos y filtrar aquellos que no pertenecen al tema (o temas cuando se usa una combinación de tema padre e hijo):
$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 );

Un complemento (más código interesante) a otras respuestas aquí.
Nombre de la Plantilla
Para obtener solo el nombre de la plantilla de página actual, usa la siguiente línea.
is_page() AND print get_page_template_slug( get_queried_object_id() );
Nombre del Archivo
Cuando solo quieres mostrar el nombre del archivo de plantilla actual, usa lo siguiente:
Edición: Aquí está la nueva versión del plugin encapsulada en una clase. Muestra tanto el nombre del archivo de plantilla actual como el nombre del archivo en la jerarquía de plantillas en el hook shutdown al final de la página.
Lo que te dice este plugin:
- ¿La plantilla es del tema padre o del tema hijo/actual?
- ¿La plantilla se sirve desde un subdirectorio? Si es así: Te dice el nombre
- El nombre del archivo de plantilla.
Solo copia el siguiente código en un archivo y nómbralo wpse10537_template_info.php
, súbelo al directorio de plugins y actívalo.
<?php
/** Plugin Name: (#10537) »kaiser« Obtener nombre de archivo de plantilla */
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(
"Archivo de plantilla"
,basename( $file )
);
return $file;
}
// Retorna variable estática en llamada echo fuera del filtro
if (
current_user_can( 'manage_options' )
AND defined( 'WP_DEBUG' )
AND WP_DEBUG
)
return print implode( " – ", $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( "Plantilla", $slug );
$this->to_stack(
"Subdirectorio"
,strstr( $slug, "/", true )
);
$this->to_stack(
"Plantilla (en subdirectorio)"
,str_replace( "/", "", strstr( $slug, "/" ) )
);
}
public function is_parent_template()
{
if ( ! is_null( wp_get_theme()->parent ) )
return $this->to_stack( 'del tema padre' );
$this->to_stack( 'del tema actual/hijo' );
}
public function to_stack( $part, $item = '' )
{
$this->stack[] = "{$part}: {$item}";
}
} // FIN Clase wpse10537_template_name
} // endif;
Este plugin también puede ejecutarse como MU-Plugin.
Luego puedes simplemente llamar wpse10537_get_template_name()
en cualquier punto (por ejemplo en una plantilla de tema). Esto evita saturar el espacio de nombres global.

template_redirect
no está pasando nada, creo que lo estás confundiendo con template_include
. También verificaría si dentro del filtro en lugar de si la variable estática está llena. Si algún código decide ejecutar el hook adicionalmente puede arruinar las cosas.

Sí, lo sé, pero el problema es que solo funciona cuando una página tiene una plantilla establecida. Lo bueno del código que publiqué es que te dirá si la página actual está usando front-page.php
, index.php
, single.php
, page.php
o cualquier otro archivo. Tu código muestra el nombre de la plantilla solo para páginas con una plantilla personalizada.

Esto no responde completamente a la pregunta del OP, pero el código siguiente es ciertamente más elegante que usar expresiones regulares y analizar el archivo de plantilla directamente.
Si estás en una Página que utiliza una Plantilla de Página, y quieres obtener el Nombre de la plantilla de página (es decir, el nombre legible por humanos que definiste en los comentarios al inicio de tu archivo PHP de plantilla), puedes usar este pequeño fragmento:
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];
}
Quería obtener el nombre de la plantilla porque estaba realmente cansado de los nombres de clase ridículamente largos que la función incorporada de WordPress body_class
crea cuando usas una plantilla. Afortunadamente, hay un filtro al final de esa función que te permite añadir tus propios nombres de clase. Aquí está mi filtro. Espero que alguien lo encuentre útil:
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;
}
Este filtro tomará el nombre que le diste a tu plantilla de página, reemplazará los espacios con guiones y convertirá todo a minúsculas para que se vea como todas las demás clases de WordPress.

Gracias por la sugerencia, no resuelven el problema, pero me orientaron hacia soluciones. Resulta que WP, al generar la lista de plantillas, incluso busca en functions.php
encuentra el "/Template Name:(.*)\n/siU"
y por lo tanto trata el functions.php
como un archivo de plantilla. Creo que esto es un error de WP, no debería siquiera mirar este archivo. La solución: mover el archivo a un subdirectorio.

Básicamente, WP te prohíbe poner la cadena "Template Name:" (incluso en un comentario) en el archivo functions.php
. Para mí, personalmente, eso es un error (pequeño, pero al fin y al cabo), pero eso está abierto a discusión, supongo. No creo que puedas decir que la función en sí tiene un error.

WP no te prohíbe hacer nada. Pero WP tampoco te promete que puedas iterar sobre un debug_backtrace() para descubrir qué archivo de plantilla estás usando. Solo porque lo encontraste en un foro de soporte de WP no significa que sea código oficialmente soportado. Como podrás ver, tu función excluye explícitamente footer.php. Igualmente podrías añadir otra condición que excluya functions.php. Por cierto: tu función no busca Template Name
dentro de cada uno de los archivos, tu bucle terminó mucho antes de eso.

El problema no estaba con debug_backtrace()
- puedo eliminar todo el código y dejar solo preg_match_all("/Template Name...
, o incluso solo // Template Name:
y WP trata entonces a functions.php
como archivo de plantilla, pero gracias por los comentarios - este es un problema tan único que, como dices, no es justo decir que es un bug. La solución de t31os es limpia y resuelve todo el problema. Saludos.

Juega con:
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>';
Escrito en:
¿Cómo descubrir qué plantilla está sirviendo la página actual?
Si la ruta de admin-bar stuff
aparece en la parte superior, o cualquier otro archivo, cambia el nombre de archivo template-loader.php
en esta línea de código por: cualquier nombre de archivo desde el cual necesites partir.
Si necesitas esto en la barra de administración, usa la prioridad correcta (la más temprana) para asegurarte de que no se añadan archivos al final de esta lista. Por ejemplo:
add_action('admin_bar_menu', 'my_adminbar_template_monitor', -5);
La prioridad -5
asegura que se cargue primero. La clave es ejecutar esta línea en el momento adecuado.
No devuelve el archivo de plantilla "actual", sino todos los que están en uso para la carga de la página actual. Quizás se pueda "extraer" con algo de lógica a partir de esta idea.
La última clave de get_included_files()
es el último archivo incluido registrado, probablemente el último archivo/parte de plantilla utilizado en el pie de página por un widget de la barra lateral o algo similar. Probablemente, porque múltiples archivos incluidos no se vuelven a registrar/poblar en get_included_files().
De lo contrario, la intención debe ser clara para hackear este problema. No hay forma de que un archivo incluido se reporte a sí mismo como incluido, hasta que ha sido incluido. Entonces probablemente es demasiado tarde para usar este escenario.
La mayoría de las "veces" te gustaría algo como:
$template = get_current_loaded_template();
if($template == 'single-product.php') add_filter('the_title' ....
if($template == 'format-gallery.php') add_action('post_thumbnail' ....
Pero eso no es posible si la plantilla se carga fuera del método central de WordPress get_template_part
. ¡Replantea tus necesidades! Quizás loop_start()
, in_the_loop()
y add_action('the_post')
tengan la solución que buscas, para alterar datos dependiendo de la plantilla que se cargará para cada entrada dentro de un bucle.
