Existe uma variável para o nome de uma peça do modelo?

8

Com o qual você chamou um modelo get_template_part()(ou locate_template()), existe uma maneira de saber em qual modelo você está.

Por exemplo, se você ligar get_template_part('loop','archive');dearchive.php

e depois estão trabalhando no seu arquivo loop-archive.php. existe uma maneira de definir uma variável que tem o nome da parte do modelo atual .... assim $template = 'loop-archive'. melhor ainda, talvez em duas partes, para 'loop' e 'archive', mas eu posso fazer isso com uma divisão de cordas.

A pergunta nº 10537 parece um pouco relacionada, mas parece não cobrir partes do modelo .

helgatheviking
fonte

Respostas:

2

Não há uma variável global principal que retorne o contexto atual. No entanto, você pode criar seu próprio, usando tags condicionais de modelo contextual . Você pode percorrer as tags condicionais na mesma ordem que o núcleo do WordPress, seguindo wp-includes/template-loader.php.

Basta agrupar sua saída em uma função Tema personalizada. Aqui está como eu faço isso (nota: acho que não sigo estritamente o template-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;
}

Então, eu apenas passo oenology_get_context()como parâmetro, por exemplo:

get_template_part( 'loop', oenology_get_context() );

Penso que algo nesse sentido seria um bom candidato para o núcleo, embora não tenha certeza da melhor maneira de implementar. Eu adoraria enviar um patch, no entanto.

Chip Bennett
fonte
uau chip. isso é muito, muito liso. e seu caso de uso é exatamente o que eu pretendia. No que diz respeito a um patch, por que você não registraria esse direito global ao mesmo tempo em que está percorrendo o carregador de modelos?
precisa saber é o seguinte
1
Porque não tenho certeza se adicionar outra global seria a abordagem "abençoada" para o núcleo. Provavelmente, uma função que retorna o contexto como uma string seria melhor - mas, então, isso provavelmente exigiria um pouco de reescrita para template-loader.php.
Chip Bennett
Nice +1. Apenas uma nota: indexnunca corresponderia, como um is_front_page()ou is_home()provocaria.
Kaiser #
1
Outra coisa: is_home()deve ser a primeira, pois é devolvida front-pagemesmo quando a configuração "última postagem" está ativada e a primeira página não está presente. Apenas testado.
Kaiser #
Concorde com @kaiser. Você pode até usar is_home() && 'page', dependendo das necessidades. Para obter informações mais abrangentes sobre as postagens do blog e a página estática na primeira página, consulte minha própria resposta, aqui: wordpress.stackexchange.com/questions/208503/… . BTW, @Chip e @helgatheviking, seria melhor usar use um em switchvez de tantos elseif(é mais eficiente ;-). Saudações!
Gerard
4

um pouco de facepalm, porque a resposta está em PHP puro

$path_parts = pathinfo(__FILE__);
//var_dump($path_parts); 
echo $path_parts['filename'];
helgatheviking
fonte
2

Se você olhar o código fonte da get_template_partfunção, verá:

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

Ele cria uma matriz de 2 nomes de modelos: {$slug}-{$name}.phpe {$slug}.phpe uso load_templatepara encontrar o arquivo de modelo e incluí-lo (o segundo parâmetro é true, o que significa incluir esse arquivo).

Você pode imitar essa função para retornar o caminho do arquivo de modelo em vez de incluí-lo, como:

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

Uso:

// 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 );

Você pode jogar mais $templatepara conseguir o que deseja.

Anh Tran
fonte
isso é muito legal! +1 com certeza, mas eu precisava saber a informação $ template dentro do modelo loop-arhive.php (a seguir o seu exemplo)
helgatheviking
Você pode usar uma variável global que é definido em archive.php, e reutilizá-lo emloop-archive.php
Anh Tran
2

Listar todos os condicionais que são true

Como todas as is_*()funções têm seu equivalente em uma variável de consulta (as funções são apenas invólucros), você também pode acessá-las de outra maneira: obtenha simplesmente tudo o que é true.

Eu escrevi um ticket no core / trac que adiciona uma função para listar todos eles.

Enquanto isso, você pode usar as duas funções listadas como plug-ins auxiliares que mostram em qual solicitação qual condicional está disponível. Ele será impresso var_dump()abaixo do rodapé (admin e public) no shutdowngancho.

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

Dessa forma, você pode simplesmente passar por eles.

@scribu adicionou sua própria função ao ticket (uma solução interessante também).

   

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

atuação

Eu executei um teste de desempenho em cada função no meio de um modelo usando timer_start/*_stop();. Para ser justo, renomei todas as funções para um nome de um caractere a/b/c().

Como você pode ver, a função codificada Chips é mais rápida, depois a minha e a última é, neste caso, o scribus.

insira a descrição da imagem aqui

Atualizar

Se você me conhece, conhece o meu amor pelos iteradores por sua elegância, clareza e capacidade de armazenar apenas um único item na memória, em vez de copiar uma matriz inteira durante o loop. Então, aqui está uma classe personalizada rápida que estende a \FilterIterator, portanto, precisando apenas de um único método reformulado.

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

Pode ser usado facilmente. O $it->current()mantém o valor, enquanto $it->key()retorna o nome condicional / propriedade.

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}
kaiser
fonte
1
Bem, isso é muito inteligente. Obrigado! Vou ter que visitar novamente quando terminar algumas das outras coisas em que estou trabalhando. Além disso, é realmente difícil lembrar de capitalizar! Maus hábitos são difíceis de quebrar.
helgatheviking