Esiste una variabile per il nome di una parte del modello?


8

Uno che hai chiamato un modello con get_template_part()(o locate_template()) c'è un modo per sapere in quale modello ti trovi.

Ad esempio, se chiami get_template_part('loop','archive');daarchive.php

e quindi stanno lavorando nel tuo file loop-archive.php. c'è un modo per definire una variabile che ha il nome della parte del modello corrente .... così $template = 'loop-archive'. meglio ancora, forse in due parti, quindi "loop" e "archivio", ma posso farlo con una suddivisione delle stringhe.

La domanda n. 10537 sembra in qualche modo correlata ma non sembra coprire le parti del modello .

Risposte:


2

Non esiste una variabile globale di base che restituisce il contesto corrente. Tuttavia, puoi crearne uno tuo, usando i tag condizionali del modello contestuale . È possibile scorrere i tag condizionali nello stesso ordine del core di WordPress, seguendo wp-includes/template-loader.php.

Avvolgi semplicemente il tuo output in una funzione Tema personalizzata. Ecco come lo faccio (nota: non credo di seguire rigorosamente 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;
}

Quindi, passo solo oenology_get_context()come parametro, ad esempio:

get_template_part( 'loop', oenology_get_context() );

Penso che qualcosa del genere sarebbe un buon candidato per il core, anche se non sono sicuro del modo migliore per implementarlo. Mi piacerebbe inviare una patch, però.


wow chip. è molto, molto lucido. e il tuo caso d'uso è esattamente quello che volevo. per quanto riguarda una patch, perché non dovresti semplicemente registrare questo diritto globale mentre passi attraverso il template loader?
Helgatheviking

1
Perché non sono sicuro che l'aggiunta di un altro globale sarebbe l'approccio "benedetto" per core. Probabilmente una funzione che restituisce il contesto come stringa sarebbe meglio, ma che probabilmente richiederebbe un po 'di riscrittura template-loader.php.
Chip Bennett,

Bello +1. Solo una nota: indexnon corrisponderebbe mai, come uno dei due is_front_page()o is_home()si innescherebbe.
Kaiser,

1
Un'altra cosa: is_home()dovrebbe essere la prima, dato che restituisce front-pageanche quando l'impostazione "ultimo post" è attivata e non è presente la prima pagina. Appena testato.
Kaiser

Accetto con @kaiser. Puoi persino usarlo is_home() && 'page', a seconda delle esigenze. Per maggiori informazioni sui post di blog e sulla pagina statica nella prima pagina, dai un'occhiata alla mia risposta, qui: wordpress.stackexchange.com/questions/208503/… . A proposito, @Chip e @helgatheviking, sarebbe meglio usare un switchinvece di tanti elseif(è più efficiente ;-). Saluti!
Gerard,

4

un po 'di faccia, perché la risposta è in puro PHP

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

2

Se guardi il codice sorgente della get_template_partfunzione, vedrai:

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 un array di 2 nomi di template: {$slug}-{$name}.phpe {$slug}.phpusa load_templateper trovare il file template e includerlo (il secondo parametro è true, che significa includere quel file).

È possibile simulare questa funzione per restituire il percorso del file modello anziché includerlo, come:

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

Puoi giocare di più $templateper ottenere ciò che vuoi.


è abbastanza pulito! +1 di sicuro, ma dovevo conoscere le informazioni $ template all'interno del modello loop-arhive.php (per seguire il tuo esempio)
helgatheviking

Puoi usare una variabile globale che è impostata archive.phpe riutilizzarla inloop-archive.php
Anh Tran,

2

Elencare tutti i condizionali che sono true

Poiché tutte le is_*()funzioni hanno il loro equivalente in una variabile di query (le funzioni sono solo wrapper), puoi accedervi anche in un altro modo: ottieni semplicemente tutto ciò che è true.

Ho scritto un ticket su core / trac che aggiunge una funzione per elencarli tutti.

Nel frattempo è possibile utilizzare entrambe le funzioni elencate come plug-in di supporto che mostrano su quale richiesta è disponibile il condizionale. Verrà stampato un gancio var_dump()sotto il piè di pagina (sia admin che pubblico) 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' );

In questo modo puoi semplicemente collegarli.

@scribu ha aggiunto la propria funzione al ticket (anche una soluzione interessante).

   

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

Prestazione

Ho eseguito un test delle prestazioni su ciascuna funzione nel mezzo di un modello utilizzando timer_start/*_stop();. Per essere onesti, ho rinominato tutte le funzioni con un nome di un carattere a/b/c().

Come puoi vedere, la funzione hard coded di Chips è la più veloce, quindi diventa mia e l'ultima è in questo caso scribus.

inserisci qui la descrizione dell'immagine

Aggiornare

Se mi conosci, allora conosci il mio amore per gli iteratori per la loro eleganza, chiarezza e la loro capacità di tenere in memoria solo un singolo elemento anziché la copia di un intero array durante il looping. Quindi ecco una rapida classe personalizzata che estende a \FilterIterator, quindi necessita di un solo metodo rielaborato.

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

Può essere usato abbastanza facilmente. Il $it->current()detiene il valore, mentre $it->key()restituisce il nome condizionale / proprietà.

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}

1
Bene, è molto intelligente. Grazie! Dovrò visitare di nuovo questo quando avrò finito con alcune delle altre cose che sto lavorando. Inoltre, è davvero difficile ricordare di capitalizzare! Le cattive abitudini sono difficili da rompere.
helgatheviking
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.