Pasar una variable a get_template_part

2 feb 2015, 11:59:25
Vistas: 129K
Votos: 74

El WP Codex dice que hay que hacer esto:

// Deseas hacer que $my_var esté disponible en la plantilla en `content-part.php`
set_query_var( 'my_var', $my_var );
get_template_part( 'content', 'part' );

Pero ¿cómo hago echo $my_var dentro de la parte de la plantilla? get_query_var($my_var) no me funciona.

He visto muchas recomendaciones para usar locate_template en su lugar. ¿Es esa la mejor manera de hacerlo?

2
Comentarios

Tenía casi la misma pregunta y logré que funcionara con set_query_var y get_query_var, sin embargo esto era para usar los valores de un array $args que se pasa a un WP_Query. Podría ser útil para otras personas que están empezando a aprender esto.

lowtechsun lowtechsun
15 jun 2017 02:59:28

@Florian por favor revisa https://wordpress.stackexchange.com/a/373230/54986 y marca como respuesta si es apropiado - ahora es una funcionalidad soportada de primera clase

Selrond Selrond
18 ago 2020 14:24:47
Todas las respuestas a la pregunta 13
2
73

Como las entradas obtienen sus datos configurados a través de the_post() (respectivamente mediante setup_postdata()) y por lo tanto son accesibles a través de la API (get_the_ID() por ejemplo), asumamos que estamos iterando a través de un conjunto de usuarios (ya que setup_userdata() llena las variables globales del usuario actualmente conectado y no es útil para esta tarea) e intentemos mostrar metadatos por usuario:

<?php
get_header();

// etc.

// En el archivo de plantilla 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' );
}

Luego, en nuestro archivo wpse-theme/template-parts/user-contact_methods.php, necesitamos acceder al ID del usuario:

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

Eso es todo.

Actualización (WP >= v5.5)

Como se menciona en los comentarios, las versiones actuales de WP ofrecen un tercer parámetro para get_template_part(): array $args. Así que desde esta versión, no necesitas usar set_query_var( 'foo', 'bar' ) nunca más. Ejemplo:

<?php
get_header();

// etc.

// En el archivo de plantilla principal
$users = new \WP_User_Query( [ ... ] );

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

Luego, en nuestro archivo wpse-theme/template-parts/user-contact_methods.php, necesitamos acceder al ID del usuario:

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

La explicación está realmente justo arriba de la parte que citaste en tu pregunta:

Sin embargo, load_template(), que es llamado indirectamente por get_template_part(), extrae todas las variables de consulta de WP_Query dentro del alcance de la plantilla cargada.

La función nativa de PHP extract() "extrae" las variables (la propiedad global $wp_query->query_vars) y coloca cada parte en su propia variable que tiene exactamente el mismo nombre que la clave. En otras palabras:

set_query_var( 'foo', 'bar' );

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

extract( $wp_query->query_vars );

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

sigue funcionando genial

middlelady middlelady
11 jun 2019 16:43:05

Desde WordPress 5.5 puedes pasar argumentos a la función get_template_part. Algo como get_template_part('somefile', null, ['arg1' => 'val1', 'arg2' => 'val2', ...].

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

La función hm_get_template_part de humanmade es extremadamente buena para esto y la uso todo el tiempo.

La llamas así:

hm_get_template_part( 'ruta_del_template', [ 'opcion' => 'valor' ] );

y luego dentro de tu plantilla, usas

$template_args['opcion'];

para obtener el valor. Maneja caché y todo, aunque puedes quitarlo si lo prefieres.

Incluso puedes devolver la plantilla renderizada como una cadena pasando 'return' => true en el array de pares clave/valor.

/**
 * Similar a get_template_part() pero permite pasar argumentos al archivo de plantilla
 * Los argumentos están disponibles en la plantilla como el array $template_args
 * @param string filepart
 * @param mixed wp_args lista de argumentos al estilo de WordPress
 */
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
Comentarios

¿Incluir 1300 líneas de código (desde GitHub HM) al proyecto solo para pasar un parámetro a una plantilla? No puedo hacer esto en mi proyecto :(

Gediminas Gediminas
4 sept 2019 11:31:06

Simplemente puedes incluir el código que pegó arriba en tu archivo functions.php...

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

Estuve investigando y encontré una variedad de respuestas. Parece que, de forma nativa, WordPress no permite acceder a variables en partes de plantillas (Template parts). Sin embargo, descubrí que usando include junto con locate_template sí permite que el alcance de las variables sea accesible en el archivo.

include(locate_template('nombre-de-tu-plantilla.php'));
4 jun 2016 08:52:20
Comentarios

Usar include no pasará themecheck.

lowtechsun lowtechsun
15 jun 2017 02:10:50

¿Realmente necesitamos algo que sea como el verificador W3C para temas de WP?

Fredy31 Fredy31
15 ago 2019 22:08:38
0
10
// puedes usar cualquier valor incluyendo objetos.

set_query_var( 'var_name_to_be_used_later', 'Valor a recuperar después' );
//Básicamente set_query_var usa la función extract() de PHP para hacer la magia.


luego más adelante en la plantilla.
var_dump($var_name_to_be_used_later);
//mostrará "Valor a recuperar después"

Recomiendo leer sobre la función PHP Extract().

5 ago 2017 18:24:01
0

Actualización

Como selrond respondió correctamente, a partir de WordPress 5.5 get_template_part() (ver changelog) ahora acepta un tercer parámetro array $args = array(), que estará disponible en tu archivo de plantilla como $args.

Mira este ejemplo:

$bar = 'bar';

// obtener helper-my-template.php
get_template_part(
    'template-parts/helper',
    'my-template',
    array(
        'foo' => $bar, // pasar este array es posible desde WP 5.5
    )
);

En tu archivo de plantilla

ej. helper-my-template.php ahora puedes acceder a tu variable así:

<?php

/**
 * @var array $args
 */

$foo = $args['foo'];

?>

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

<?php // imprimirá 'bar' ?>
2 sept 2020 04:31:40
1

A partir de la versión 5.5, será posible pasar datos a las plantillas a través de las diversas funciones principales de carga de plantillas.

Todas las funciones de WordPress para cargar plantillas admitirán un parámetro adicional llamado $args, que permite a los autores de temas pasar un array asociativo de datos a la plantilla cargada. Las funciones que admiten este nuevo parámetro son:

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

Cualquier hook asociado con estas funciones también pasará los datos.

Para más información: https://make.wordpress.org/core/2020/07/17/passing-arguments-to-template-files-in-wordpress-5-5/

4 ago 2020 00:13:53
Comentarios

Desafortunadamente, el parámetro $args no se procesa a través de extract(), por lo que necesitarás hacer echo $args['foo'] en la plantilla. Ojalá hubiera una opción para extraer los args también.

powerbuoy powerbuoy
17 ago 2020 12:27:19
0

Me encontré con este mismo problema en un proyecto en el que estoy trabajando actualmente. Decidí crear mi propio pequeño plugin que permite pasar variables de manera más explícita a get_template_part usando una nueva función.

Por si te resulta útil, aquí está la página del proyecto en GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables

Y aquí un ejemplo de cómo funcionaría:

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

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


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

// Mostraría:
<div class='featuredAuthor'>
    <span>John</span>
</div>
12 sept 2016 01:02:05
0

El parámetro $args para las funciones de carga de plantillas acaba de llegar en WordPress 5.5 "Eckstine":

Pasar datos a archivos de plantilla

Las funciones de carga de plantillas (get_header(), get_template_part(), etc.) tienen un nuevo argumento $args. Así que ahora puedes pasar toda una matriz de datos a esas plantillas.

18 ago 2020 14:23:25
0

Me gusta el plugin Pods y su función pods_view. Funciona de manera similar a la función hm_get_template_part mencionada en la respuesta de djb. Yo uso una función adicional (findTemplate en el código a continuación) para buscar primero un archivo de plantilla en el tema actual, y si no se encuentra, devuelve la plantilla con el mismo nombre en la carpeta /templates de mi plugin. Esta es una idea aproximada de cómo uso pods_view en mi plugin:

/**
 * Función auxiliar para encontrar una plantilla
 */
function findTemplate($filename) {
  // Buscar primero en la carpeta del tema
  $template = locate_template($filename);
  if (!$template) {
    // De lo contrario, usar el archivo en la carpeta /templates de nuestro plugin
    $template = dirname(__FILE__) . '/templates/' . $filename;
  }
  return $template;
}

// Mostrar la plantilla 'template-name.php' desde la carpeta del tema
// *o* desde la carpeta '/template' de nuestro plugin, pasando dos variables
// locales para que estén disponibles en el archivo de plantilla
pods_view(
  findTemplate('template-name.php'),
  array(
    'passed_variable' => $variable_to_pass,
    'another_variable' => $another_variable,
  )
);

pods_view también soporta caché, pero no lo necesité para mis propósitos. Puedes encontrar más información sobre los argumentos de la función en las páginas de documentación de Pods. Consulta las páginas de pods_view y Almacenamiento en caché parcial de páginas y partes de plantillas inteligentes con Pods.

21 ago 2016 02:43:22
0

Basado en la respuesta de @djb utilizando código de humanmade.

Esta es una versión ligera de get_template_part que puede aceptar argumentos. De esta manera, las variables tienen alcance local dentro de esa plantilla. No es necesario usar global, get_query_var, set_query_var.

/**
 * Similar a get_template_part() pero permite pasar argumentos al archivo de plantilla
 * Los argumentos están disponibles en la plantilla como el array $args.
 * Los argumentos pueden pasarse como parámetros URL, ej: 'key1=value1&key2=value2'.
 * Los argumentos pueden pasarse como un array, ej: ['key1' => 'value1', 'key2' => 'value2']
 * La ruta del archivo está disponible en la plantilla como el string $file.
 * @param string      $slug El nombre slug para la plantilla genérica.
 * @param string|null $name El nombre de la plantilla especializada.
 * @param array       $args Los argumentos pasados a la plantilla
 */

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

Por ejemplo en cart.php :

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

En apple.php :

<p>El color de la manzana es: <?php echo $args['color']; ?></p>
18 dic 2018 21:02:53
0

¿Qué tal esto?

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

Al usar ${$key} puedes agregar las variables al ámbito actual de la función. Funciona para mí, rápido y fácil, y no se filtra ni se almacena en el ámbito global.

22 jun 2018 08:56:05
0

Para aquellos que buscan una forma muy sencilla de pasar variables, puedes cambiar la función para incluir:

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

Y así podrás usar todas las variables que están definidas antes de incluir la plantilla, sin necesidad de PASAR adicionalmente cada una a la plantilla.

Créditos para: https://mekshq.com/passing-variables-via-get_template_part-wordpress/

4 sept 2019 11:35:58
1
-3

Esta es la solución exacta y funcionó correctamente. https://developer.wordpress.org/reference/functions/set_query_var/

16 ene 2018 14:51:53
Comentarios

Creo que has entendido mal

JDandChips JDandChips
22 oct 2020 12:49:55