Passare una variabile a get_template_part

2 feb 2015, 11:59:25
Visualizzazioni: 129K
Voti: 74

Il WP Codex dice di fare così:

// Vuoi rendere disponibile $my_var al template part in `content-part.php`
set_query_var( 'my_var', $my_var );
get_template_part( 'content', 'part' );

Ma come faccio ad eseguire echo $my_var all'interno del template part? get_query_var($my_var) non funziona nel mio caso.

Ho visto molte raccomandazioni sull'utilizzo di locate_template al suo posto. È questo il modo migliore di procedere?

2
Commenti

Avevo più o meno la stessa domanda e sono riuscito a farlo funzionare con set_query_var e get_query_var, tuttavia questo era per utilizzare i valori di un array $args che viene passato a una WP_Query. Potrebbe essere utile per altre persone che iniziano a imparare questo.

lowtechsun lowtechsun
15 giu 2017 02:59:28

@Florian per favore vedi https://wordpress.stackexchange.com/a/373230/54986 e segna come risposta se appropriato - ora è una funzionalità supportata ufficialmente

Selrond Selrond
18 ago 2020 14:24:47
Tutte le risposte alla domanda 13
2
73

Poiché i post ottengono i loro dati impostati tramite the_post() (rispettivamente tramite setup_postdata()) e sono quindi accessibili attraverso l'API (get_the_ID() ad esempio), supponiamo che stiamo ciclando attraverso un insieme di utenti (poiché setup_userdata() riempie le variabili globali dell'utente attualmente loggato e non è utile per questo compito) e proviamo a visualizzare i metadati per utente:

<?php
get_header();

// etc.

// Nel file template principale
$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' );
}

Poi, nel nostro file wpse-theme/template-parts/user-contact_methods.php, dobbiamo accedere all'ID dell'utente:

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

Ecco fatto.

Aggiornamento (WP >= v5.5)

Come sottolineato nei commenti, le versioni recenti di WP offrono un terzo parametro per get_template_part(): array $args. Quindi da questa versione in poi non è più necessario usare set_query_var( 'foo', 'bar' ). Esempio:

<?php
get_header();

// etc.

// Nel file template principale
$users = new \WP_User_Query( [ ... ] );

foreach ( $users as $user )
{
    $args = (array) $user;
    get_template_part( 'template-parts/user', 'contact_methods', $args );
}

Poi, nel nostro file wpse-theme/template-parts/user-contact_methods.php, dobbiamo accedere all'ID dell'utente:

<?php
/** @var array $args */
$some_meta = get_the_author_meta( 'some_meta', $args['ID'] );
var_dump( $some_meta );

La spiegazione è in realtà esattamente sopra la parte che hai citato nella tua domanda:

Tuttavia, load_template(), che viene chiamato indirettamente da get_template_part(), estrae tutte le variabili di query di WP_Query, nell'ambito del template caricato.

La funzione nativa di PHP extract() "estrae" le variabili (la proprietà global $wp_query->query_vars) e mette ogni parte nella sua variabile che ha esattamente lo stesso nome della chiave. In altre parole:

set_query_var( 'foo', 'bar' );

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

extract( $wp_query->query_vars );

var_dump( $foo );
// Risultato:
(string 3) 'bar'
2 feb 2015 12:14:01
Commenti

funziona ancora perfettamente

middlelady middlelady
11 giu 2019 16:43:05

Da WordPress 5.5 puoi passare argomenti alla funzione get_template_part. Qualcosa come get_template_part('somefile', null, ['arg1' => 'val1', 'arg2' => 'val2', ...].

norixxx norixxx
12 nov 2020 10:44:03
2
28

La funzione hm_get_template_part di humanmade è estremamente efficace per questo scopo e la uso continuamente.

La chiami con

hm_get_template_part( 'percorso_template', [ 'opzione' => 'valore' ] );

e poi all'interno del tuo template, usi

$template_args['opzione'];

per ottenere il valore. Gestisce anche la cache e tutto il resto, anche se puoi rimuoverlo se preferisci.

Puoi persino ottenere il template renderizzato come stringa passando 'return' => true nell'array di chiavi/valori.

/**
 * Simile a get_template_part() ma permette di passare argomenti al file template
 * Gli argomenti sono disponibili nel template come array $template_args
 * @param string filepart
 * @param mixed wp_args lista di argomenti in stile WP
 */
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;
}
4 feb 2015 21:25:57
Commenti

Includere 1300 righe di codice (da github HM) nel progetto solo per passare un parametro a un template? Non posso farlo nel mio progetto :(

Gediminas Gediminas
4 set 2019 11:31:06

Puoi semplicemente includere il codice che ha incollato sopra nel tuo functions.php...

DokiCRO DokiCRO
15 nov 2019 14:02:13
2
24

Stavo cercando in giro e ho trovato diverse risposte. Sembra che a livello nativo, WordPress non permetta di accedere alle variabili nelle parti dei template. Ho però scoperto che utilizzando l'include insieme a locate_template è possibile rendere accessibile l'ambito delle variabili nel file.

include(locate_template('your-template-name.php'));
4 giu 2016 08:52:20
Commenti

L'uso di include non supererà il controllo di themecheck.

lowtechsun lowtechsun
15 giu 2017 02:10:50

Abbiamo davvero bisogno di qualcosa che sia simile al validatore W3C ma per i temi di WordPress?

Fredy31 Fredy31
15 ago 2019 22:08:38
0
10
// puoi utilizzare qualsiasi valore compresi gli oggetti.

set_query_var( 'var_name_to_be_used_later', 'Valore da recuperare successivamente' );
// Fondamentalmente set_query_var utilizza la funzione PHP extract() per fare la magia.


poi più avanti nel template.
var_dump($var_name_to_be_used_later);
// stamperà "Valore da recuperare successivamente"

Consiglio di leggere riguardo alla funzione PHP Extract().

5 ago 2017 18:24:01
0

Aggiornamento

Come selrond ha correttamente risposto, a partire da WordPress 5.5 la funzione get_template_part() (vedi changelog) accetta ora un terzo parametro array $args = array(), che sarà disponibile nel tuo file template come $args.

Vedi questo esempio:

$bar = 'bar';

// ottieni helper-my-template.php
get_template_part(
    'template-parts/helper',
    'my-template',
    array(
        'foo' => $bar, // passare questo array è possibile da WP 5.5
    )
);

Nel tuo file template

Ad esempio in helper-my-template.php puoi ora accedere alla tua variabile così:

<?php

/**
 * @var array $args
 */

$foo = $args['foo'];

?>

<h1><?php echo $foo; ?></h1>

<?php // stamperà 'bar' ?>
2 set 2020 04:31:40
1

A partire dalla versione 5.5, sarà possibile passare dati ai template attraverso le varie funzioni core di caricamento dei template.

Tutte le funzioni di WordPress per il caricamento dei template supporteranno un parametro aggiuntivo $args, che permette agli autori di temi di passare un array associativo di dati al template caricato. Le funzioni che supportano questo nuovo parametro sono:

get_header()
get_footer()
get_sidebar()
get_template_part()
locate_template()
load_template()

Anche gli hook associati a queste funzioni riceveranno i dati passati.

Per maggiori informazioni: https://make.wordpress.org/core/2020/07/17/passing-arguments-to-template-files-in-wordpress-5-5/

4 ago 2020 00:13:53
Commenti

Sfortunatamente il parametro $args non viene processato attraverso extract() quindi dovrai fare echo $args['foo'] nel template. Vorrei che ci fosse un'opzione per estrarre anche gli args.

powerbuoy powerbuoy
17 ago 2020 12:27:19
0

Mi sono imbattuto nello stesso problema in un progetto su cui sto attualmente lavorando. Ho deciso di creare un mio piccolo plugin che permette di passare in modo più esplicito le variabili a get_template_part utilizzando una nuova funzione.

Nel caso possa esserti utile, ecco la pagina su GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables

Ed ecco un esempio di come funzionerebbe:

$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>
";

// Output generato:
<div class='featuredAuthor'>
    <span>John</span>
</div>
12 set 2016 01:02:05
0

Il parametro $args per le funzioni di caricamento dei template è stato introdotto in WordPress 5.5 "Eckstine":

Passaggio di dati ai file template

Le funzioni di caricamento dei template (get_header(), get_template_part(), ecc.) ora hanno un nuovo argomento $args. Questo permette di passare un intero array di dati a questi template.

18 ago 2020 14:23:25
0

Mi piace il plugin Pods e la sua funzione pods_view. Funziona in modo simile alla funzione hm_get_template_part menzionata nella risposta di djb. Utilizzo una funzione aggiuntiva (findTemplate nel codice qui sotto) per cercare prima un file template nel tema corrente e, se non trovato, restituisce il template con lo stesso nome nella cartella /templates del mio plugin. Ecco un'idea approssimativa di come utilizzo pods_view nel mio plugin:

/**
 * Funzione helper per trovare un template
 */
function findTemplate($filename) {
  // Cerca prima nella cartella del tema
  $template = locate_template($filename);
  if (!$template) {
    // Altrimenti, utilizza il file nella cartella /templates del plugin
    $template = dirname(__FILE__) . '/templates/' . $filename;
  }
  return $template;
}

// Mostra il template 'template-name.php' dalla cartella del tema
// *oppure* dalla cartella '/template' del plugin, passando due variabili
// locali che saranno disponibili nel file template
pods_view(
  findTemplate('template-name.php'),
  array(
    'passed_variable' => $variable_to_pass,
    'another_variable' => $another_variable,
  )
);

pods_view supporta anche la cache, ma non ne avevo bisogno per i miei scopi. Maggiori informazioni sugli argomenti della funzione possono essere trovate nella documentazione di Pods. Consulta le pagine per pods_view e Cache Parziale di Pagina e Template Part Intelligenti con Pods.

21 ago 2016 02:43:22
0

Basato sulla risposta di @djb utilizzando il codice di humanmade.

Questa è una versione leggera di get_template_part che può accettare argomenti. In questo modo le variabili sono limitate localmente a quel template. Non è necessario utilizzare global, get_query_var, set_query_var.

/**
 * Come get_template_part() ma permette di passare argomenti al file template
 * Gli argomenti sono disponibili nel template come array $args.
 * Gli argomenti possono essere passati come parametri URL, es. 'key1=value1&key2=value2'.
 * Gli argomenti possono essere passati come array, es. ['key1' => 'value1', 'key2' => 'value2']
 * Il percorso del file è disponibile nel template come stringa $file.
 * @param string      $slug Lo slug per il template generico.
 * @param string|null $name Il nome del template specializzato.
 * @param array       $args Gli argomenti passati al 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();
}

Ad esempio in cart.php :

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

In apple.php :

<p>Il colore della mela è: <?php echo $args['color']; ?></p>
18 dic 2018 21:02:53
0

Che ne pensi di questo?

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

Utilizzando ${$key} puoi aggiungere le variabili nell'ambito della funzione corrente. Funziona per me, è veloce e semplice e non fa trapelare né memorizza nell'ambito globale.

22 giu 2018 08:56:05
0

Per chi cerca un modo molto semplice per passare le variabili, puoi modificare la funzione per includere:

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

E così sarai in grado di utilizzare tutte le variabili definite prima di includere il template senza doverle PASSARE ulteriormente una per una al template.

Crediti a: https://mekshq.com/passing-variables-via-get_template_part-wordpress/

4 set 2019 11:35:58
1
-3

Questa è la soluzione esatta e ha funzionato perfettamente. https://developer.wordpress.org/reference/functions/set_query_var/

16 gen 2018 14:51:53
Commenti

Penso tu abbia frainteso

JDandChips JDandChips
22 ott 2020 12:49:55