Отримати ім’я поточного файлу шаблону


57

Я знайшов це для відображення поточного імені файлу, що використовується в шаблоні:

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

Джерело: отримати назву шаблону сторінки на сторінці

Це працює досить добре, за винятком того, що в бекенді, у вікні вибору шаблонів, я отримую цей потворний додатковий запис:

скріншот

Хтось має ідею, як це виправити? Я навіть не знаю, чому ця функція викликається в бекенді. Чи є така умовна функція, як is_frontend()- можливо, це вирішило б проблему?


2
@chodorowicz - Хоча я не зупинюсь на тому, щоб називати вибір functions.phpпомилкою, я повністю погоджуся з вашою умовою. Що ще гірше, я просканував основний код WordPress і виявив близько 5 місць, де міг би бути гачок, щоб ви могли вирішити цю проблему, але я не знайшов жодного. Я б запропонував опублікувати квиток на core.trac.wordpress.org .
MikeSchinkel

@MikeSchinkel - дякую за коментар, але не template_includeгак, що пропонував t31, вирішити проблему? А може, я вас зрозумів неправильно.
chodorowicz

1
@MikeSchinkel - у нього вже є патч :) core.trac.wordpress.org/ticket/16689
chodorowicz

1
Я створив новий плагін, щоб відобразити поточний шаблон. Перевірте це на wordpress.org/extend/plugins/display-template-name

4
^ тобто. ти взяв код з моєї відповіді і загорнув його у плагін. І ви все це зробили, не надаючи жодного кредиту для походження, ні я, ні WP stackexchange ... приємно ...: /
t31os

Відповіді:


68

Ви можете встановити глобальну змінну під час template_includeфільтра, а потім пізніше перевірити, чи глобальний непридатний, щоб побачити, який шаблон був включений.

Ви, звичайно, не хотіли б повного шляху разом з файлом, тому я рекомендую обрізатися до імені файлу за допомогою basenameфункції PHP .

Приклад коду:
дві функції, одна для встановлення глобальної, одна для заклику до неї.

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

Потім ви можете зателефонувати, get_current_templateде вам це потрібно, у файлах тем, зазначаючи, що це, природно, має відбутися після template_includeзапуску дії (вам не потрібно буде турбуватися про це, якщо виклик буде зроблений у файлі шаблону).

Для шаблонів сторінок є is_page_template(), маючи на увазі, що це допоможе лише у випадку шаблонів сторінок (набагато менший показ усіх функцій).

Інформація про функції, які використовуються або посилаються вище:


Дивовижно! Я знав, що повинен бути простіший спосіб.
racl101

Один, який потрібно додати до початку мого списку функцій налагодження.
Jules

23

мабуть цього достатньо:

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

або просто використовувати його безпосередньо в шаблоні (я зазвичай перегукуюся у footer.php в коментарі HTML)

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

1
Це не буде працювати з get-template-частиною, щоб ви знали, він показує лише single.php (наприклад), а не файл, в якому він знаходиться.
m-torin

Так, це правда. Для отримання імені включеного файлу вам, мабуть, доведеться скористатися чимось подібнимecho __FILE__;
chodorowicz

це добре, наприклад, у випадках, коли ви змінюєте шаблон за замовчуванням, не призначаючи його публікації в backoffice. Наприклад, використовуючи власні маршрути та фільтр template_include. Дякую.
Лука Регеллін

Як я міг це зробити в циклі? Я намагаюся вивести URL-адресу на одну сторінку кожного файлу шаблону.
JacobTheDev

@JacobTheDev, можливо, використовує echo __FILE__- тому що це не працюватиме, він відображає лише основний, початковий шаблон
chodorowicz

17

Між нативними функціями WP, такими як get_template_part (), та нативним PHP, є найнадійнішим способом побачити використовувані файли теми, це отримати список усіх включених файлів та відфільтрувати все, що не належить до теми (або теми, коли використовується комбінація батьків та дітей) :

$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

Додаток (більш солодкий код) до інших відповідей тут.

Назва шаблону

Щоб просто отримати назву шаблону поточної сторінки , скористайтеся наступним рядком.

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

Ім'я файлу

Коли ви просто хочете відповісти поточному імені файлу шаблону , перейдіть до наступного

Редагувати: Ось нова версія плагіна, завернутого в клас. Він показує як поточне ім'я файлу шаблону, так і ім’я файлу ієрархії шаблонів у гачку закриття в самому нижній частині сторінки.

Що говорить вам плагін:

  • Чи шаблон від батьків дитини / поточна тема?
  • Чи шаблон подається з підпапки? Якщо так: повідомляє вам ім'я
  • Ім'я файлу шаблону.

Просто скопіюйте наступний код у файл та назвіть його wpse10537_template_info.php, завантажте його у свою довідку плагінів та активуйте його.

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

Цей плагін також може працювати як MU-плагін.

Потім можна просто зателефонувати wpse10537_get_template_name()в будь-яку точку (наприклад, шаблон теми). Це дозволяє уникнути захаращення глобального простору імен.


1
template_redirectнічого не передає, я думаю, що ви плутаєте template_include. Також я би перевірив, чи всередині фільтра замість того, чи заповнений статичний var. Якщо якийсь код вирішить запустити гачок додатковий час, він може зірвати речі.
Рарст

@ Rarst зроблено / виправлено. Дякуємо за підказку та вказали назву фільтра.
кайзер

5

Ім'я шаблону зберігається в таблиці постмета, тому все, що вам потрібно зробити, - це поставити його десь у циклі:

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

2
Так, я знаю про це, але проблема полягає в тому, що вона працює лише тоді, коли на сторінці є встановлений шаблон. Прохолодна річ про коді я вивісив, що він розповість вам , якщо поточна сторінка використовує front-page.php, index.php, single.php, page.phpабо будь-який інший файл. Ваш код відображає назву шаблону лише для сторінок із користувацьким шаблоном сторінки.
chodorowicz

ах, вибачте - моє нерозуміння вашого запитання.
Саймон Блекборн

@SimonBlackbourn Це допомога на мою вимогу. Дякую.
KarSho

3

Це не стосується всього питання щодо ОП, але код нижче, безумовно, більш елегантний, ніж регулярні вирази та аналіз самого файлу шаблону.

Якщо ви перебуваєте на сторінці, яка використовує шаблон сторінки, і ви хочете отримати ім'я шаблона сторінки (тобто: імя, читаемое людиною, визначене в коментарях у верхній частині шаблону PHP-файлу), ви можете використовувати цей маленький самородок:

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

Я хотів отримати назву шаблону, тому що мені дуже не до душі імена класів дурних довгих осел, які вбудована body_classфункція WordPress створює під час використання шаблону. На щастя, на самому кінці цієї функції є гачок фільтра, що дозволяє також додавати власні імена класів. Ось мій фільтр. Сподіваюся, хтось вважає це корисним:

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

Цей фільтр займе те, що ви назвали шаблоном своєї сторінки, замінить пробіли тире та зробить все в нижньому регістрі, щоб воно було схоже на всі інші класи WordPress.


0

Існує проблема з preg_match_allрядком. Спробуйте це замість цього:

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

Крім того, ви можете використовувати лише if (!is_admin()) { .... }для керування предметами на фронті.


Дякую за пропозицію, вони не вирішують проблему, але вони неначе направили мене на рішення. Виявляється, WP, створюючи список шаблонів, розглядає навіть functions.phpзнахідки "/Template Name:(.*)\n/siU"і, таким чином, розглядає functions.phpяк файл шаблону. Я думаю, що це помилка WP, вона навіть не повинна дивитися на цей файл. Рішення: перемістити файл у підкаталог.
chodorowicz

@chodorowicz: Це не помилка WP, це помилка у вашій функції.
wyrfel

Тому в основному WP забороняє вам вводити functions.phpфайл "Ім'я шаблону:" (навіть у коментарі) . Особисто для мене це помилка, (невелика, але все одно), але я думаю, що це обговорення. Я думаю, ви не можете сказати, що сама функція є помилковою.
chodorowicz

WP не забороняє вам нічого робити. Але WP також не обіцяє вам, що ви можете перейти через debug_backtrace (), щоб дізнатися, який файл шаблону ви використовуєте. Тільки те, що ви знайшли його на форумі підтримки WP, не означає, що це офіційно підтримуваний код. Як ви бачите, ваша функція явно виключає footer.php. Ви також можете додати ще одну умову, яка виключає function.php. BTW: ваша функція не шукається Template Nameв кожному з файлів, ваш цикл закінчився задовго до цього.
wyrfel

Проблема не полягала в тому, що debug_backtrace()я можу видалити весь код і просто залишити preg_match_all("/Template Name..., або навіть просто, // Template Name:і WP розглядає тоді functions.phpфайл файлу шаблону, але дякую за коментарі - це така унікальна проблема, що, як ви кажете, це нечесно сказати це помилка. Рішення t31os чисте і вирішує все питання. Вітаю.
chodorowicz

0

Грайте разом із:

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

Написано в:

Як дізнатися, яка сторінка шаблону обслуговує поточну сторінку?

якщо admin-bar stuffшлях відображається вгорі або будь-який інший файл, змініть ім'я файлу template-loader.phpв цьому рядку коду на: яке б ім’я фільму вам не потрібно було перервати.

якщо вам це потрібно на панелі адміністратора, використовуйте правий пріоритет (якнайшвидший), щоб зробити так, щоб у кінці цього списку не було введено жодних файлів . Наприклад:

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

першочергово -5змушуйте спочатку завантажувати. Ключовим моментом є надання цього рядка в потрібний момент.

Він не повертає "поточний" шаблон-файл шаблону, а весь поточний, який використовується для поточного завантаження сторінки. Можливо, "вирізали" якоюсь логікою з цієї ідеї .

get_included_files()«Останній» ключ останній зареєстрований включений файл, Propably останній шаблон-файл /-частина , що використовується в виносці по бічній панелі віджетів або що - то. Імовірно, що файли, включені cos mutiple, не перереєструються / заповнюються знову у get_included_files ().

Інакше, щоб зламати цю проблему, має бути зрозумілим . Немає способу включений файл звітувати про себе як включений, поки він не буде включений . Тоді можливо, щоб пізно використовувати сценарій.

Більшу частину часу, який ви хотіли б:

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

Але це неможливо, якщо шаблон завантажений поза основним методом Wordpress get_template_part. Натомість перепроектуйте свої потреби! Можливо loop_start(), in_the_loop()і add_action('the_post')є рішення, яке ви хочете, щоб змінити дані залежно від шаблону, який завантажуватимуться для кожного запису в циклі.


-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.