Transmiterea unei variabile către get_template_part
Documentația WP Codex spune să faci așa:
// Dorești să faci $my_var disponibilă în partea de șablon din `content-part.php`
set_query_var( 'my_var', $my_var );
get_template_part( 'content', 'part' );
Dar cum pot să folosesc echo $my_var
în interiorul părții de șablon? get_query_var($my_var)
nu funcționează în cazul meu.
Am văzut multe recomandări pentru folosirea locate_template
în schimb. Este aceasta cea mai bună abordare?

Deoarece postările își configurează datele prin the_post()
(respectiv prin setup_postdata()
) și sunt prin urmare accesibile prin API (get_the_ID()
de exemplu), să presupunem că iterăm printr-un set de utilizatori (deoarece setup_userdata()
completează variabilele globale ale utilizatorului autentificat curent și nu este utilă pentru această sarcină) și încercăm să afișăm metadate pe utilizator:
<?php
get_header();
// etc.
// În fișierul șablon principal
$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' );
}
Apoi, în fișierul nostru wpse-theme/template-parts/user-contact_methods.php
, trebuie să accesăm ID-ul utilizatorilor:
<?php
/** @var int $user_id */
$some_meta = get_the_author_meta( 'some_meta', $user_id );
var_dump( $some_meta );
Asta e tot.
Actualizare (WP >= v5.5)
După cum s-a menționat în comentarii, versiunile actuale de WP oferă un al treilea parametru pentru get_template_part()
: array $args
. Deci din această versiune, nu mai este nevoie să folosiți set_query_var( 'foo', 'bar' )
. Exemplu:
<?php
get_header();
// etc.
// În fișierul șablon principal
$users = new \WP_User_Query( [ ... ] );
foreach ( $users as $user )
{
$args = (array) $user;
get_template_part( 'template-parts/user', 'contact_methods', $args );
}
Apoi, în fișierul nostru wpse-theme/template-parts/user-contact_methods.php
, trebuie să accesăm ID-ul utilizatorilor:
<?php
/** @var array $args */
$some_meta = get_the_author_meta( 'some_meta', $args['ID'] );
var_dump( $some_meta );
Explicația este de fapt exact deasupra părții pe care ai citat-o în întrebarea ta:
Totuși,
load_template()
, care este apelat indirect deget_template_part()
, extrage toate variabilele de interogare dinWP_Query
, în domeniul de aplicare al șablonului încărcat.
Funcția nativă PHP extract()
"extrage" variabilele (proprietatea global $wp_query->query_vars
) și pune fiecare parte în propria variabilă care are exact același nume ca și cheia. Cu alte cuvinte:
set_query_var( 'foo', 'bar' );
$GLOBALS['wp_query'] (object)
-> query_vars (array)
foo => bar (string 3)
extract( $wp_query->query_vars );
var_dump( $foo );
// Rezultat:
(string 3) 'bar'

Funcția hm_get_template_part
creată de humanmade este extrem de utilă și o folosesc mereu.
O apelezi astfel:
hm_get_template_part( 'calea_template-ului', [ 'optiune' => 'valoare' ] );
iar apoi în interiorul template-ului, folosești
$template_args['optiune'];
pentru a returna valoarea. Funcția are inclusiv sistem de caching, dar poți să îl elimini dacă dorești.
Poți chiar să returnezi template-ul randat ca șir de caractere, trecând 'return' => true
în array-ul de chei/valori.
/**
* Similar cu get_template_part() dar permite transmiterea de argumente către fișierul template
* Argumentele sunt disponibile în template sub forma array-ului $template_args
* @param string filepart
* @param mixed wp_args listă de argumente în stil 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;
}

Să includ 1300 de linii de cod (de pe GitHub HM) în proiect doar pentru a transmite un singur parametru către un șablon? Nu pot face asta în proiectul meu :(

Cautând prin diverse surse, am găsit o varietate de răspunsuri. Se pare că, la nivel nativ, WordPress nu permite accesarea variabilelor în părțile de template. Totuși, am descoperit că folosirea funcției include
împreună cu locate_template
permite accesul la scope-ul variabilelor în fișierul respectiv.
include(locate_template('numele-template-ului.php'));

Folosirea include
nu va trece de verificarea temei.

// poți folosi orice valoare, inclusiv obiecte.
set_query_var( 'numele_variabilei_de_folosit_ulterior', 'Valoarea de preluat ulterior' );
//Practic, set_query_var utilizează funcția PHP extract() pentru a face magia.
apoi mai târziu în șablon.
var_dump($numele_variabilei_de_folosit_ulterior);
//va afișa "Valoarea de preluat ulterior"
Recomand să citești despre funcția PHP Extract().

Actualizare
După cum selrond a răspuns corect aici, începând cu WordPress 5.5 funcția get_template_part() (vezi changelog) acceptă acum un al treilea parametru array $args = array()
, care va fi disponibil în fișierul template sub forma variabilei $args
.
Exemplu:
$bar = 'bar';
// include fișierul helper-my-template.php
get_template_part(
'template-parts/helper',
'my-template',
array(
'foo' => $bar, // transmiterea acestui array este posibilă începând cu WP 5.5
)
);
În fișierul template
de exemplu helper-my-template.php acum poți accesa variabila astfel:
<?php
/**
* @var array $args
*/
$foo = $args['foo'];
?>
<h1><?php echo $foo; ?></h1>
<?php // va afișa 'bar' ?>

Începând cu versiunea 5.5, va fi posibil să transmiți date către șabloane prin intermediul diferitelor funcții de încărcare a șabloanelor din nucleul WordPress.
Toate funcțiile WordPress pentru încărcarea șabloanelor vor accepta un parametru suplimentar $args
, care permite autorilor de teme să transmită un array asociativ de date către șablonul încărcat. Funcțiile care acceptă acest nou parametru sunt:
get_header()
get_footer()
get_sidebar()
get_template_part()
locate_template()
load_template()
Orice hook-uri asociate acestor funcții vor transmite și ele datele.
Pentru mai multe informații: https://make.wordpress.org/core/2020/07/17/passing-arguments-to-template-files-in-wordpress-5-5/

Am întâmpinat aceeași problemă într-un proiect la care lucrez în prezent. Am decis să creez un mic plugin personal care permite transmiterea mai explicită a variabilelor către get_template_part prin utilizarea unei noi funcții.
În caz că ar putea fi util și pentru tine, iată pagina proiectului pe GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables
Și iată un exemplu de funcționare:
$variables = [
'name' => 'John',
'class' => 'featuredAuthor',
];
jpr_get_template_part_with_vars('author', 'info', $variables);
// În fișierul author-info.php:
echo "
<div class='$class'>
<span>$name</span>
</div>
";
// Va afișa:
<div class='featuredAuthor'>
<span>John</span>
</div>

Parametrul $args
pentru funcțiile de încărcare a șabloanelor a fost introdus în WordPress 5.5 „Eckstine”:
Transmiterea datelor către fișierele șablon
Funcțiile de încărcare a șabloanelor (get_header(), get_template_part(), etc.) au acum un nou argument
$args
. Acum puteți trimite un întreg tablou de date către aceste șabloane.

Îmi place plugin-ul Pods și funcția lor pods_view. Funcționează similar cu funcția hm_get_template_part
menționată în răspunsul lui djb. Folosesc o funcție suplimentară (findTemplate
în codul de mai jos) pentru a căuta mai întâi un fișier de șablon în tema curentă, iar dacă nu este găsit, returnează șablonul cu același nume din folderul /templates
al plugin-ului meu. Aceasta este o idee generală despre cum folosesc pods_view
în plugin-ul meu:
/**
* Funcție helper pentru a găsi un șablon
*/
function findTemplate($filename) {
// Caută mai întâi în folderul temei
$template = locate_template($filename);
if (!$template) {
// Altfel, folosește fișierul din folderul /templates al plugin-ului
$template = dirname(__FILE__) . '/templates/' . $filename;
}
return $template;
}
// Afișează șablonul 'template-name.php' fie din folderul temei,
// fie din folderul '/template' al plugin-ului, transmitând două variabile
// locale care vor fi disponibile în fișierul șablon
pods_view(
findTemplate('template-name.php'),
array(
'passed_variable' => $variable_to_pass,
'another_variable' => $another_variable,
)
);
pods_view
suportă și caching, dar nu am avut nevoie de această funcționalitate în cazul meu. Mai multe informații despre argumentele funcției pot fi găsite în paginile de documentație Pods. Consultă paginile pentru pods_view și Partial Page Caching and Smart Template Parts with Pods.

Bazat pe răspunsul de la @djb folosind codul de la humanmade.
Aceasta este o versiune ușoară a funcției get_template_part care poate accepta argumente. În acest fel, variabilele sunt limitate la nivel local în acel template. Nu este nevoie să folosești global
, get_query_var
, set_query_var
.
/**
* Similar cu get_template_part() dar permite transmiterea de argumente către fișierul template
* Argumentele sunt disponibile în template sub forma unui array $args.
* Argumentele pot fi transmise ca parametri URL, ex. 'key1=value1&key2=value2'.
* Argumentele pot fi transmise ca un array, ex. ['key1' => 'value1', 'key2' => 'value2']
* Calea fișierului este disponibilă în template sub forma string $file.
* @param string $slug Numele slug pentru template-ul generic.
* @param string|null $name Numele template-ului specializat.
* @param array $args Argumentele transmise template-ului
*/
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();
}
De exemplu în cart.php
:
<? php _get_template_part( 'components/items/apple', null, ['color' => 'red']); ?>
În apple.php
:
<p>Culoarea mărului este: <?php echo $args['color']; ?></p>

Ce zici de asta?
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();
}
}
Folosind ${$key}
poți adăuga variabilele în scope-ul curent al funcției.
Funcționează pentru mine, rapid și ușor și nu scapa sau stochează în scope-ul global.

Pentru cei care caută o modalitate foarte simplă de a transmite variabile, puteți modifica funcția pentru a include:
include( locate_template( 'YourTemplate.php', false, false ) );
Și apoi veți putea folosi toate variabilele care sunt definite înainte de a include template-ul, fără a fi nevoie să le transmiteți separat fiecărei șabloane.
Creditul merge către: https://mekshq.com/passing-variables-via-get_template_part-wordpress/

Acesta este exact soluția și a funcționat perfect. https://developer.wordpress.org/reference/functions/set_query_var/
