Existe-t-il une variable pour le nom des pièces d'un modèle?

8

Celui avec lequel vous avez appelé un modèle get_template_part()(ou locate_template()) est un moyen de savoir dans quel modèle vous vous trouvez.

Par exemple, si vous appelez get_template_part('loop','archive');dearchive.php

puis travaillent dans votre fichier loop-archive.php. existe-t-il un moyen de définir une variable qui a le nom de la partie de modèle actuelle .... donc $template = 'loop-archive'. mieux encore, peut-être en deux parties, donc «boucle» et «archive», mais je peux le faire avec un fractionnement de chaîne.

La question # 10537 semble en quelque sorte liée, mais ne semble pas couvrir les parties du modèle .

helgatheviking
la source

Réponses:

2

Il n'y a pas de variable globale de base qui renvoie le contexte actuel. Cependant, vous pouvez créer le vôtre à l'aide de balises conditionnelles de modèle contextuel . Vous pouvez parcourir les balises conditionnelles dans le même ordre que le noyau WordPress, en suivant wp-includes/template-loader.php.

Enveloppez simplement votre sortie dans une fonction de thème personnalisée. Voici comment je le fais (note: je ne pense pas que je respecte strictement 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;
}

Ensuite, je passe simplement oenology_get_context()un paramètre, par exemple:

get_template_part( 'loop', oenology_get_context() );

Je pense que quelque chose dans ce sens serait un bon candidat pour le noyau, même si je ne suis pas sûr de la meilleure façon de le mettre en œuvre. J'adorerais cependant soumettre un patch.

Chip Bennett
la source
wow chip. c'est très, très lisse. et votre cas d'utilisation est exactement ce que je voulais. en ce qui concerne un patch, pourquoi ne pas simplement enregistrer ce droit global en même temps que vous passez par le chargeur de modèles?
helgatheviking
1
Parce que je ne sais pas si l'ajout d'un autre global serait l'approche "bénie" pour le noyau. Une fonction qui renvoie le contexte sous forme de chaîne serait probablement mieux - mais cela nécessiterait probablement un peu de réécriture dans template-loader.php.
Chip Bennett
Nice +1. Juste une note: indexne correspondrait jamais, comme l'un is_front_page()ou l' autre is_home()se déclencherait.
kaiser
1
Une autre chose: is_home()devrait être le premier, car il rend front-pagemême lorsque le paramètre "dernier message" est activé et qu'aucune page d'accueil n'est présente. Je viens de tester.
kaiser
D'accord avec @kaiser. Vous pouvez même utiliser is_home() && 'page', selon les besoins. Pour une information plus complète sur les articles de blog vs la page statique dans la première page, jetez un œil à ma propre réponse, ici: wordpress.stackexchange.com/questions/208503/… . BTW, @Chip et @helgatheviking, il vaudrait mieux utiliser use a switchau lieu de tant elseif(c'est plus efficace ;-). Cordialement!
Gerard
4

un peu de facepalm, parce que la réponse est en PHP pur

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

Si vous regardez le code source de la get_template_partfonction, vous verrez:

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

Il crée un tableau de 2 noms de modèle: {$slug}-{$name}.phpet {$slug}.phpet utilisez load_templatepour rechercher le fichier de modèle et l'inclure (le deuxième paramètre est true, ce qui signifie inclure ce fichier).

Vous pouvez imiter cette fonction pour renvoyer le chemin du fichier modèle au lieu de l'inclure, comme:

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

Usage:

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

Vous pouvez jouer plus avec $templatepour obtenir ce que vous voulez.

Anh Tran
la source
c'est assez soigné! +1 à coup sûr, mais j'avais besoin de connaître les informations $ template à l'intérieur du modèle loop-arhive.php (pour suivre votre exemple)
helgatheviking
Vous pouvez utiliser une variable globale qui est définie dans archive.php, et la réutiliser dansloop-archive.php
Anh Tran
2

Liste de toutes les conditions qui sont true

Comme toutes les is_*()fonctions ont leur équivalent dans une variable de requête (les fonctions ne sont que des wrappers), vous pouvez également y accéder d'une autre manière: obtenez simplement tout ce qui existe true.

J'ai écrit un ticket sur core / trac qui ajoute une fonction pour les lister tous.

En attendant, vous pouvez utiliser les deux fonctions répertoriées comme plugins d'assistance qui vous montrent à quelle demande le conditionnel est disponible. Il imprimera un var_dump()sous le pied de page (à la fois administrateur et public) au niveau du shutdowncrochet.

<?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 cette façon, vous pouvez simplement les parcourir.

@scribu a ajouté sa propre fonction au ticket (une solution intéressante aussi).

   

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

Performance

J'ai exécuté un test de performance sur chaque fonction au milieu d'un modèle en utilisant timer_start/*_stop();. Pour être juste, j'ai renommé toutes les fonctions en un nom à un caractère a/b/c().

Comme vous pouvez le voir, la fonction codée en dur des puces est la plus rapide, puis la mienne et la dernière est dans ce cas scribus.

entrez la description de l'image ici

Mise à jour

Si vous me connaissez, alors vous connaissez mon amour pour les itérateurs pour leur élégance, leur clarté et leur capacité à ne conserver qu'un seul élément en mémoire au lieu de copier un tableau entier lors de la boucle. Voici donc une classe personnalisée rapide qui étend a \FilterIterator, ne nécessitant donc qu'une seule méthode retravaillée.

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

Il peut être utilisé assez facilement. Le $it->current()contient la valeur, tandis que $it->key()renvoie le nom conditionnel / propriété.

$cond = new WPSE\ConditionalsFilter( new \ArrayIterator(
    get_object_vars( $GLOBALS['wp_query'] )
) );
foreach ( $cond as $c )
{
    var_dump(
        $cond->key(),
        $cond->current()
    );
}
kaiser
la source
1
Eh bien, c'est très intelligent. Merci! Je devrai revisiter cela quand j'aurai fini avec certaines des autres choses sur lesquelles je travaille. De plus, il est vraiment difficile de se rappeler de capitaliser! Les mauvaises habitudes sont difficiles à briser.
helgatheviking du