¿Hay una variable para un nombre de partes de plantilla?

8

Una que haya llamado una plantilla con get_template_part()(o locate_template()) hay una manera de saber en qué plantilla se encuentra.

Por ejemplo si llamas get_template_part('loop','archive');desdearchive.php

y luego están trabajando en su archivo loop-archive.php. ¿hay alguna manera de definir una variable que tenga el nombre de la parte de la plantilla actual ... así $template = 'loop-archive'? mejor aún, tal vez en dos partes, así que 'bucle' y 'archivo', pero puedo hacerlo con un poco de división de cadenas.

La pregunta # 10537 parece estar relacionada, pero no parece cubrir partes de la plantilla .

helgatheviking
fuente

Respuestas:

2

No hay una variable global central que devuelva el contexto actual. Sin embargo, puede construir el suyo, utilizando etiquetas condicionales de plantilla contextual . Puede recorrer las etiquetas condicionales en el mismo orden que el núcleo de WordPress, siguiendo wp-includes/template-loader.php.

Simplemente envuelva su salida en una función de tema personalizada. Así es como lo hago (nota: no creo que siga estrictamente 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;
}

Luego, solo paso oenology_get_context()como parámetro, por ejemplo:

get_template_part( 'loop', oenology_get_context() );

Creo que algo en este sentido sería un buen candidato para el núcleo, aunque no estoy seguro de la mejor manera de implementarlo. Sin embargo, me encantaría enviar un parche.

Chip Bennett
fuente
wow chip Eso es muy, muy hábil. y su caso de uso es exactamente lo que pretendía. en cuanto a un parche, ¿por qué no registraría este derecho global al mismo tiempo que está pasando por el cargador de plantillas?
helgatheviking
1
Porque no estoy seguro si agregar otro global sería el enfoque "bendecido" para el núcleo. Probablemente, una función que devuelve el contexto como una cadena sería mejor, pero entonces, eso probablemente requeriría un poco de reescritura template-loader.php.
Chip Bennett el
Niza +1. Solo una nota: indexnunca coincidiría, ya sea is_front_page()o is_home()se dispararía.
kaiser
1
Otra cosa: is_home()debe ser lo primero, ya que devuelve front-pageincluso cuando la configuración de "última publicación" está activada y no hay portada. Acabo de probar.
kaiser
De acuerdo con @kaiser. Incluso puede usar is_home() && 'page', dependiendo de las necesidades. Para obtener más información sobre las publicaciones de blog y la página estática en la página principal, consulte mi propia respuesta, aquí: wordpress.stackexchange.com/questions/208503/… . Por cierto, @Chip y @helgatheviking, sería mejor usar un en switchlugar de tantos elseif(es más eficiente ;-). ¡Saludos!
Gerard
4

un poco de facepalm, porque la respuesta está en PHP puro

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

Si observa el código fuente de la get_template_partfunción, 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);
}

Crea una matriz de 2 nombres de plantilla: {$slug}-{$name}.phpy se {$slug}.phpusa load_templatepara buscar el archivo de plantilla e incluirlo (el segundo parámetro es true, lo que significa incluir ese archivo).

Puede imitar esta función para devolver la ruta del archivo de plantilla en lugar de incluirla, 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 );

Puedes jugar más $templatepara obtener lo que quieres.

Anh Tran
fuente
eso es bastante bueno! +1 seguro, pero necesitaba saber la información de $ template dentro de la plantilla loop-arhive.php (para seguir su ejemplo)
helgatheviking
Puede usar una variable global configurada archive.phpy reutilizarlaloop-archive.php
Anh Tran
2

Listar todos los condicionales que son true

Como todas las is_*()funciones tienen su equivalente en una variable de consulta (las funciones son solo envoltorios), también puede acceder a ellas de otra manera: Obtenga simplemente todo lo que hay true.

Escribí un ticket en core / trac que agrega una función para enumerarlos a todos.

Mientras tanto, puede usar ambas funciones enumeradas como complementos auxiliares que le muestran en qué solicitud qué condicional está disponible. Imprimirá un var_dump()debajo del pie de página (tanto admin como público) en el 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' );

De esta manera, simplemente puede recorrerlos.

@scribu agregó su propia función al ticket (una solución interesante también).

   

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

Actuación

Ejecuté una prueba de rendimiento en cada función en medio de una plantilla usando timer_start/*_stop();. Para ser justos, cambié el nombre de todas las funciones a un nombre de un personaje a/b/c().

Como puede ver, la función codificada de Chips es la más rápida, luego la mía y la última en este caso es scribus.

ingrese la descripción de la imagen aquí

Actualizar

Si me conoces, entonces conoces mi amor por los iteradores por su elegancia, claridad y su capacidad de mantener solo un elemento en la memoria en lugar de copiar una matriz completa durante el bucle. Entonces, aquí hay una clase personalizada rápida que se extiende a \FilterIterator, por lo tanto, solo necesita un método modificado.

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

Se puede usar con bastante facilidad. El $it->current()mantiene el valor, mientras que $it->key()devuelve el nombre condicional / propiedad.

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}
emperador
fuente
1
Bueno, eso es muy inteligente. ¡Gracias! Tendré que volver a visitar esto cuando termine con algunas de las otras cosas en las que estoy trabajando. Además, ¡es realmente difícil recordar capitalizar! Los malos hábitos son difíciles de romper.
helgatheviking