Есть ли переменная для имени части шаблона?

8

Если вы назвали шаблон с get_template_part()(или locate_template()), есть ли способ узнать, в каком шаблоне вы находитесь.

Например, если вы звоните get_template_part('loop','archive');изarchive.php

и затем работаете в вашем файле loop-archive.php. Есть ли способ определить переменную, которая имеет имя текущей части шаблона .... так $template = 'loop-archive'. еще лучше, может быть, в двух частях, так что «цикл» и «архив», но я могу сделать это с некоторым разделением строк.

Вопрос № 10537 кажется похожим , но не охватывает части шаблона .

helgatheviking
источник

Ответы:

2

Не существует основной глобальной переменной, которая возвращает текущий контекст. Однако вы можете создать свой собственный, используя контекстные шаблоны условных тегов . Вы можете пройтись по условным тегам в том же порядке, что и ядро ​​WordPress, выполнив следующие действия wp-includes/template-loader.php.

Просто оберните ваш вывод в пользовательскую функцию Theme. Вот как я это делаю (примечание: я не думаю, что строго следую шаблону loader.php):

function oenology_get_context() {

    $context = 'index';

    if ( is_home() ) {
        // Blog Posts Index
        $context = 'home';
        if ( is_front_page() ) {
            // Front Page
            $context = 'front-page';
        } 
    }else if ( is_date() ) {
        // Date Archive Index
        $context = 'date';
    } else if ( is_author() ) {
        // Author Archive Index
        $context = 'author';
    } else if ( is_category() ) {
        // Category Archive Index
        $context = 'category';
    } else if ( is_tag() ) {
        // Tag Archive Index
        $context = 'tag';
    } else if ( is_tax() ) {
        // Taxonomy Archive Index
        $context = 'taxonomy';
    } else if ( is_archive() ) {
        // Archive Index
        $context = 'archive';
    } else if ( is_search() ) {
        // Search Results Page
        $context = 'search';
    } else if ( is_404() ) {
        // Error 404 Page
        $context = '404';
    } else if ( is_attachment() ) {
        // Attachment Page
        $context = 'attachment';
    } else if ( is_single() ) {
        // Single Blog Post
        $context = 'single';
    } else if ( is_page() ) {
        // Static Page
        $context = 'page';
    }

    return $context;
}

Затем я просто передаю oenology_get_context()в качестве параметра, например:

get_template_part( 'loop', oenology_get_context() );

Я думаю, что что-то в этом роде было бы хорошим кандидатом на ядро, хотя я не уверен, что лучший способ реализовать. Я хотел бы представить патч, хотя.

Чип Беннетт
источник
вау чип. это очень, очень гладко. и ваш вариант использования именно то, что я намеревался. Что касается патча, почему бы вам просто не зарегистрировать это глобальное право одновременно с переходом через загрузчик шаблонов?
helgatheviking
1
Потому что я не уверен, что добавление еще одного глобала будет «благословенным» подходом для ядра. Вероятно, функция, которая возвращает контекст в виде строки, будет лучше, но тогда, вероятно, потребуется немного переписать ее template-loader.php.
Чип Беннетт
Ницца +1. Только одно примечание: indexникогда не совпадет, как is_front_page()или is_home()будет срабатывать.
Кайзер
1
Другое дело: is_home()должно быть первым, так как оно возвращает, front-pageдаже когда активирована настройка «последнее сообщение» и нет главной страницы. Только что протестировано.
Кайзер
Согласитесь с @kaiser. Вы даже можете использовать is_home() && 'page', в зависимости от потребностей. Более подробную информацию о сообщениях блога и статической странице на главной странице можно найти в моем собственном ответе здесь: wordpress.stackexchange.com/questions/208503/… . Кстати, @Chip и @helgatheviking, было бы лучше использовать использовать switchвместо многих elseif(это более эффективно ;-). С уважением!
Джерард
4

немного лицевой стороны, потому что ответ на чистом PHP

$path_parts = pathinfo(__FILE__);
//var_dump($path_parts); 
echo $path_parts['filename'];
helgatheviking
источник
2

Если вы посмотрите на исходный код get_template_partфункции, вы увидите:

function get_template_part( $slug, $name = null ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    locate_template($templates, true, false);
}

Он создает массив из 2 имен шаблонов: {$slug}-{$name}.phpи {$slug}.phpиспользуется load_templateдля поиска файла шаблона и включения его (2-й параметр true, что означает включение этого файла).

Вы можете имитировать эту функцию, чтобы возвращать путь к файлу шаблона, а не включать его, например:

function my_get_template_part( $slug, $name = null, $include = false ) {
    do_action( "get_template_part_{$slug}", $slug, $name );

    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    return locate_template($templates, $include, false);
}

Применение:

// Don't load the template
$template = my_get_template_part( 'loop', 'archive', false );

// Or load the template
$template = my_get_template_part( 'loop', 'archive', true );

// Get the file name only
$template = basename( $template );

// Without .php extension
$template = substr( $template, 0, -4 );

Вы можете играть больше, $templateчтобы получить то, что вы хотите.

Ань Чан
источник
это довольно опрятно! +1, конечно, но мне нужно было знать информацию $ template внутри шаблона loop-arhive.php (чтобы следовать вашему примеру)
helgatheviking
Вы можете использовать глобальную переменную, которая установлена archive.php, и повторно использовать ееloop-archive.php
Anh Tran
2

Перечислите все условия, которые true

Поскольку все is_*()функции имеют свои эквиваленты в переменной запроса (функции являются просто обертками), вы можете получить к ним доступ и другим способом: просто получить все, что есть true.

Я написал тикет на core / trac, который добавляет функцию для перечисления их всех.

В то же время вы можете использовать обе перечисленные функции в качестве вспомогательных плагинов, которые показывают, по какому запросу доступно какое условие. Он выведет var_dump()нижний колонтитул (как администратора, так и общественности) на shutdownкрючок.

<?php
/** Plugin Name: (#62232) »kaiser« List all conditionals that are true */
function get_conditionals()
{ 
    global $wp_query; 

    foreach ( get_object_vars( $wp_query ) as $is_key => $is_value ) 
    { 
            if ( $is_value && preg_match( "/is_/", $is_key ) ) 
                    $conditionals[] = $is_key; 
    } 

    return var_dump( $conditionals );
} 
add_action( 'shutdown', 'get_conditionals' );

Таким образом, вы можете просто просмотреть их.

@scribu добавил свою собственную функцию в заявку (тоже интересное решение).

   

<?php
/** Plugin Name: (#62232) »scribu« List all conditionals that are true */
function get_query_flags( $wp_query = null ) {
    if ( !$wp_query )
        $wp_query = $GLOBALS['wp_query'];

    $flags = array();

    foreach ( get_object_vars( $wp_query ) as $key => $val ) {
        if ( 'is_' == substr( $key, 0, 3 ) && $val )
            $flags[] = substr( $key, 3 );
    }

    return var_dump( $flags );
}
add_action( 'shutdown', 'get_query_flags' );

Представление

Я выполнил тест производительности для каждой функции в середине шаблона, используя timer_start/*_stop();. Честно говоря, я переименовал все функции в одноименное имя a/b/c().

Как вы можете видеть, жестко закодированная функция Chips является самой быстрой, затем идет моей, а последней в данном случае является scribus.

введите описание изображения здесь

Обновить

Если вы знаете меня, то вы знаете мою любовь к итераторам за их элегантность, ясность и их способность хранить в памяти только один элемент вместо копии целого массива во время цикла. Итак, вот быстрый пользовательский класс, который расширяет класс \FilterIterator, поэтому требуется только один переработанный метод.

<?php

namespace WPSE;

class ConditionalsFilter extends \FilterIterator
{
    /**
     * Accepts properties that start with `is_` and have a positive boolean value
     * @return bool
     */
    public function accept()
    {
        return 0 === strncasecmp( $this->key(), 'is_', 3 )
            and filter_var(
                $this->current(),
                FILTER_VALIDATE_BOOLEAN,
                FILTER_NULL_ON_FAILURE
            );
    }
}

Это может быть использовано довольно легко. $it->current()Имеет значение, в то время как $it->key()возвращает имя условного / свойства.

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}
кайзер
источник
1
Ну, это очень умно. Спасибо! Я должен буду повторно посетить это, когда я закончу с некоторыми другими вещами, над которыми я работаю. Кроме того, это действительно трудно запомнить, чтобы заработать! От вредных привычек трудно избавиться.
Helgatheviking