Passer une variable à get_template_part

55

Le WP Codex dit de faire ceci:

// You wish to make $my_var available to the template part at `content-part.php`
set_query_var( 'my_var', $my_var );
get_template_part( 'content', 'part' );

Mais comment puis-je echo $my_vardans la partie du modèle? get_query_var($my_var)ne fonctionne pas pour moi.

J'ai vu des tonnes de recommandations pour utiliser à la locate_templateplace. Est-ce la meilleure façon de faire?

Florian
la source
Avait au sujet de la même question et il se mit au travail avec set_query_varet get_query_var, mais cela était pour utiliser les valeurs d'un $argstableau qui est passé à un WP_Query. Cela pourrait être utile pour les autres personnes qui commencent à apprendre cela.
lowtechsun

Réponses:

54

Lorsque les publications établissent leurs données via the_post()(respectivement via setup_postdata()) et sont donc accessibles via l'API ( get_the_ID()par exemple), supposons que nous parcourions un ensemble d'utilisateurs (car ils setup_userdata()remplissent les variables globales de l' utilisateur actuellement connecté et isn ' t utile pour cette tâche) et essayez d’afficher les métadonnées par utilisateur:

<?php
get_header();

// etc.

// In the main template file
$users = new \WP_User_Query( [ ... ] );

foreach ( $users as $user )
{
    set_query_var( 'user_id', absint( $user->ID ) );
    get_template_part( 'template-parts/user', 'contact_methods' );
}

Ensuite, dans notre wpse-theme/template-parts/user-contact_methods.phpfichier, nous devons accéder à l'ID utilisateur:

<?php
/** @var int $user_id */
$some_meta = get_the_author_meta( 'some_meta', $user_id );
var_dump( $some_meta );

C'est ça.

L'explication est en réalité exactement au-dessus de la partie que vous avez citée dans votre question:

Cependant, load_template()appelé indirectement par l' get_template_part()extraction de toutes les WP_Queryvariables de la requête, dans l'étendue du modèle chargé.

La extract()fonction PHP native "extrait" les variables (la global $wp_query->query_varspropriété) et place chaque partie dans sa propre variable qui porte exactement le même nom que la clé. En d'autres termes:

set_query_var( 'foo', 'bar' );

$GLOBALS['wp_query'] (object)
    -> query_vars (array)
        foo => bar (string 3)

extract( $wp_query->query_vars );

var_dump( $foo );
// Result:
(string 3) 'bar'
kaiser
la source
1
fonctionne toujours bien
huraji
23

La hm_get_template_partfonction créée par humanmade est extrêmement efficace et je l’utilise tout le temps.

Tu appelles

hm_get_template_part( 'template_path', [ 'option' => 'value' ] );

et à l'intérieur de votre modèle, vous utilisez

$template_args['option'];

pour renvoyer la valeur. Il fait la mise en cache et tout, même si vous pouvez le supprimer si vous le souhaitez.

Vous pouvez même renvoyer le modèle rendu sous forme de chaîne en le passant 'return' => truedans le tableau clé / valeur.

/**
 * Like get_template_part() put lets you pass args to the template file
 * Args are available in the tempalte as $template_args array
 * @param string filepart
 * @param mixed wp_args style argument list
 */
function hm_get_template_part( $file, $template_args = array(), $cache_args = array() ) {
    $template_args = wp_parse_args( $template_args );
    $cache_args = wp_parse_args( $cache_args );
    if ( $cache_args ) {
        foreach ( $template_args as $key => $value ) {
            if ( is_scalar( $value ) || is_array( $value ) ) {
                $cache_args[$key] = $value;
            } else if ( is_object( $value ) && method_exists( $value, 'get_id' ) ) {
                $cache_args[$key] = call_user_method( 'get_id', $value );
            }
        }
        if ( ( $cache = wp_cache_get( $file, serialize( $cache_args ) ) ) !== false ) {
            if ( ! empty( $template_args['return'] ) )
                return $cache;
            echo $cache;
            return;
        }
    }
    $file_handle = $file;
    do_action( 'start_operation', 'hm_template_part::' . $file_handle );
    if ( file_exists( get_stylesheet_directory() . '/' . $file . '.php' ) )
        $file = get_stylesheet_directory() . '/' . $file . '.php';
    elseif ( file_exists( get_template_directory() . '/' . $file . '.php' ) )
        $file = get_template_directory() . '/' . $file . '.php';
    ob_start();
    $return = require( $file );
    $data = ob_get_clean();
    do_action( 'end_operation', 'hm_template_part::' . $file_handle );
    if ( $cache_args ) {
        wp_cache_set( $file, $data, serialize( $cache_args ), 3600 );
    }
    if ( ! empty( $template_args['return'] ) )
        if ( $return === false )
            return false;
        else
            return $data;
    echo $data;
}
djb
la source
1
Inclure 1300 lignes de code (à partir de github HM) dans le projet pour passer un paramètre à un modèle? Je ne peux pas faire cela dans mon projet :(
Gediminas le
11

Je cherchais autour de moi et ai trouvé une variété de réponses. Cela semble au niveau natif, Wordpress permet d’accéder aux variables dans les parties modèles. J'ai constaté que l'utilisation de l'include associée à la méthode position_template permettait aux variables de rester accessibles dans le fichier.

include(locate_template('your-template-name.php'));
Murray Chapman
la source
L'utilisation includene passera pas la vérification .
lowtechsun
Avons-nous vraiment besoin de quelque chose qui ressemble au vérificateur W3C pour les thèmes WP?
Fredy31
5
// you can use any value including objects.

set_query_var( 'var_name_to_be_used_later', 'Value to be retrieved later' );
//Basically set_query_var uses PHP extract() function  to do the magic.


then later in the template.
var_dump($var_name_to_be_used_later);
//will print "Value to be retrieved later"

Je recommande de lire sur la fonction PHP Extract ().

Hugo R
la source
2

J'ai rencontré le même problème sur un projet sur lequel je travaille actuellement. J'ai décidé de créer mon propre petit plugin qui vous permet de transmettre plus explicitement des variables à get_template_part en utilisant une nouvelle fonction.

Au cas où cela vous serait utile, voici la page correspondante sur GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables

Et voici un exemple de la façon dont cela fonctionnerait:

$variables = [
    'name' => 'John',
    'class' => 'featuredAuthor',
];

jpr_get_template_part_with_vars('author', 'info', $variables);


// In author-info.php:
echo "
<div class='$class'>
    <span>$name</span>
</div>
";

// Would output:
<div class='featuredAuthor'>
    <span>John</span>
</div>
John O
la source
1

J'aime le plugin Pods et leur fonction pods_view . Cela fonctionne comme la hm_get_template_partfonction mentionnée dans la réponse de djb. J'utilise une fonction supplémentaire ( findTemplatedans le code ci-dessous) pour rechercher un fichier de modèle dans le thème actuel, et si non trouvé, il renvoie le modèle du même nom dans le /templatesdossier de mon plugin . Ceci est une idée approximative de la façon dont j'utilise pods_viewdans mon plugin:

/**
 * Helper function to find a template
 */
function findTemplate($filename) {
  // Look first in the theme folder
  $template = locate_template($filename);
  if (!$template) {
    // Otherwise, use the file in our plugin's /templates folder
    $template = dirname(__FILE__) . '/templates/' . $filename;
  }
  return $template;
}

// Output the template 'template-name.php' from either the theme
// folder *or* our plugin's '/template' folder, passing two local
// variables to be available in the template file
pods_view(
  findTemplate('template-name.php'),
  array(
    'passed_variable' => $variable_to_pass,
    'another_variable' => $another_variable,
  )
);

pods_viewprend également en charge la mise en cache, mais je n'en avais pas besoin pour mes besoins. Vous trouverez plus d'informations sur les arguments de la fonction dans les pages de documentation de Pods. Reportez-vous aux pages pods_view et Mise en cache partielle des pages et parties de modèle dynamique avec des modules .

troisième bailleur
la source
1

Basé sur la réponse de @djb en utilisant le code de humanmade.

Il s'agit d'une version allégée de get_template_part pouvant accepter les arguments. De cette façon, les variables sont localisées localement à ce modèle. Pas besoin d'avoir global, get_query_var, set_query_var.

/**
 * Like get_template_part() but lets you pass args to the template file
 * Args are available in the template as $args array.
 * Args can be passed in as url parameters, e.g 'key1=value1&key2=value2'.
 * Args can be passed in as an array, e.g. ['key1' => 'value1', 'key2' => 'value2']
 * Filepath is available in the template as $file string.
 * @param string      $slug The slug name for the generic template.
 * @param string|null $name The name of the specialized template.
 * @param array       $args The arguments passed to the template
 */

function _get_template_part( $slug, $name = null, $args = array() ) {
    if ( isset( $name ) && $name !== 'none' ) $slug = "{$slug}-{$name}.php";
    else $slug = "{$slug}.php";
    $dir = get_template_directory();
    $file = "{$dir}/{$slug}";

    ob_start();
    $args = wp_parse_args( $args );
    $slug = $dir = $name = null;
    require( $file );
    echo ob_get_clean();
}

Par exemple dans cart.php:

<? php _get_template_part( 'components/items/apple', null, ['color' => 'red']); ?>

Dans apple.php:

<p>The apple color is: <?php echo $args['color']; ?></p>
Veedka
la source
0

Que dis-tu de ça?

render( 'template-parts/header/header', 'desktop', 
    array( 'user_id' => 555, 'struct' => array( 'test' => array( 1,2 ) ) )
);
function render ( $slug, $name, $arguments ) {

    if ( $arguments ) {
        foreach ( $arguments as $key => $value ) {
                ${$key} = $value;
        }
    }

$name = (string) $name;
if ( '' !== $name ) {
    $templates = "{$slug}-{$name}.php";
    } else {
        $templates = "{$slug}.php";
    }

    $path = get_template_directory() . '/' . $templates;
    if ( file_exists( $path ) ) {
        ob_start();
        require( $path);
        ob_get_clean();
    }
}

En utilisant, ${$key}vous pouvez ajouter les variables dans la portée de la fonction actuelle. Fonctionne pour moi, rapide et facile, sans fuites ni stockage global.

Mattijs
la source
0

Pour ceux qui cherchent un moyen très facile de passer des variables, vous pouvez changer de fonction pour inclure:

include (Locate_template ('YourTemplate.php', false, false));

Et ensuite, vous pourrez utiliser toutes les variables définies avant d’inclure le modèle sans PASSING, ni chacune d’elles pour le modèle.

Les crédits vont à: https://mekshq.com/passing-variables-via-get_template_part-wordpress/

Gediminas
la source