Pasando variables a través de locate_template

24 nov 2010, 00:07:09
Vistas: 52.8K
Votos: 56

Aunque tradicionalmente he usado include o require para mantener el código a largo plazo, he comenzado a usar get_template_part y locate_template ya que usar las funciones integradas de WordPress siempre es lo mejor.

Mi pregunta es: ¿se supone que debes poder pasar variables a través de los resultados de get_template_part o locate_template?

<?php
$var = get_option( 'my-custom-option' );

get_template_part( 'custom-template-part' );
?>

En el código anterior, la variable $var debería imprimirse dentro de la plantilla personalizada, pero la variable no parece funcionar. ¿Me estoy perdiendo algo o este es el comportamiento esperado?

He descubierto que no se pasan las variables en el ejemplo anterior ni cuando se usa locate_template

<?php
locate_template( 'custom-template-part.php', true );
?>
0
Todas las respuestas a la pregunta 7
4
66

Como MathSmath escribió, get_template() no soporta la reutilización de tus variables.

Pero locate_template() de hecho no realiza ninguna inclusión. Simplemente localiza un archivo para su inclusión.

Así que puedes hacer uso de include para que esto funcione justo como esperas:

include(locate_template('custom-template-part.php'));

$var de tu ejemplo puede ser usado en la parte de la plantilla entonces.

Una pregunta relacionada con una explicación más técnica del ámbito de las variables y get_template(): Error al Enviar Formulario con get_template_part()

24 nov 2010 01:38:15
Comentarios

Buena observación. No me había dado cuenta de que locate_template() tiene un parámetro que te permite opcionalmente llamar a load_template() con los resultados (lo cual hace get_template_part), o simplemente devolverlos. Estoy revisando un proyecto actual para actualizar el código usando este enfoque... ¡gracias!

MathSmath MathSmath
24 nov 2010 20:07:38

poco después de publicar aquí terminé usando el mismo método.

curtismchale curtismchale
24 nov 2010 23:22:40

21676 aborda esto, pero no parece que vaya a ser incluido.

Ian Dunn Ian Dunn
19 feb 2013 21:05:43

Quizás estoy equivocado pero: locate_template() de hecho incluye, si el parámetro está configurado como true -como en la pregunta. (el valor por defecto es false, así que no copies la versión de la pregunta en la respuesta aceptada.) También podrías simplemente usar set_query_var('var', $var); y usar tu get_template_part() como siempre. De esa manera también tendrás las variables por defecto de WordPress accesibles dentro del archivo de plantilla, como mencionó @MathSmath.

Jonas Lundman Jonas Lundman
7 oct 2017 17:29:21
2
14

Una solución elegante encontrada en el codex

Así que si estás iterando a través de posts personalizados, puedes hacer esto:

foreach ($custom_posts as $custom_post) {
    set_query_var( 'my_post', $custom_post );
    get_template_part( 'content', 'part' );
}

Y en esa plantilla en sí, automáticamente obtendrás una variable $my_post.

7 ene 2016 13:04:24
Comentarios

Esta sería la respuesta correcta si el código de ejemplo respondiera a la pregunta. (Pasando opción, no el array completo de posts)

Jonas Lundman Jonas Lundman
7 oct 2017 17:36:57

Esto funciona perfectamente para pasar información adicional a la plantilla incluida. También funciona para wc_get_template_part en WooCommerce que sin duda extiende el WP por defecto.

nabrown nabrown
3 may 2019 22:00:21
0

Yo también he tenido problemas con esto (al intentar hacer funcionar una consulta personalizada con una parte de plantilla). La respuesta corta es: no, la parte de plantilla no hereda automáticamente las variables personalizadas como lo haría un include normal.

Tanto get_template_part() como locate_template() terminan usando la función load_template() para cargar realmente el archivo (usando un require). Esta función globaliza las siguientes variables:

$posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID

Sin embargo, no hay otras variables disponibles desde dentro de la parte de plantilla. Supongo que como el require real está envuelto en una función, el ámbito cambia o algo así.

En cualquier caso, intentaría globalizar cualquier variable adicional que necesites pasar, y luego llamar a esas globales desde tu parte de plantilla.

24 nov 2010 00:30:12
0

Mi pequeño aporte para referencias futuras, una solución alternativa al menos en WordPress 3.5 es agregar la variable a $wp_query->query_vars.

Yo necesitaba mi variable global _vk_errors dentro de una parte de plantilla y simplemente hice $wp_query->query_vars['_vk_errors'] = $_vk_errors; antes de llamar a get_template_part().

8 ene 2013 15:58:39
0

WordPress 5.5+

Se añadió el parámetro $args a locate_template https://developer.wordpress.org/reference/functions/locate_template/

Pasar datos

$data = [
  'foo' => 'Hola',
  'bar' => ', WordPress 5.5',
];
locate_template('tu-plantilla.php', true, true, $data);

tu-plantilla.php

// manejar argumentos pasados mediante $args
echo $args['foo'] . $args['bar']; // "Hola, WordPress 5.5"
// o usar extract($args);
extract($args);
echo $foo . $bar; // "Hola, WordPress 5.5"

locate_template utiliza load_template, que desde la versión 5.5 también puede pasar argumentos adicionales a la plantilla.

https://developer.wordpress.org/reference/functions/load_template/

Lo mismo ocurre con todas las funciones de plantilla que usan locate_template:

get_header, get_footer, get_sidebar, get_template_part.

https://developer.wordpress.org/reference/functions/get_header/ https://developer.wordpress.org/reference/functions/get_footer/ https://developer.wordpress.org/reference/functions/get_sidebar/ https://developer.wordpress.org/reference/functions/get_template_part/

27 ago 2020 23:14:40
1

Aquí está mi función simple que resuelve el problema de variables. Hace lo mismo que WordPress en la función get_template_part(). Solo copia y pega en el archivo function.php.

function getTemplatePart($slug = null, $name = null, array $params = array()) {
    global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;

    // Ejecuta acción antes de cargar la plantilla
    do_action("get_template_part_{$slug}", $slug, $name);
    $templates = array();
    if (isset($name))
        $templates[] = "{$slug}-{$name}.php";

    $templates[] = "{$slug}.php";

    // Localiza el archivo de plantilla
    $_template_file = locate_template($templates, false, false);

    // Extrae variables de la consulta
    if (is_array($wp_query->query_vars)) {
        extract($wp_query->query_vars, EXTR_SKIP);
    }
    // Extrae parámetros personalizados
    extract($params, EXTR_SKIP);

    // Carga la plantilla
    require($_template_file);
}

Ejemplo de uso en una plantilla:

$params = array(
    'utm_source' => 'footer' // Parámetro personalizado
);
while ($posts->have_posts()) {
    $posts->the_post(); 
    // Carga la plantilla con parámetros
    getTemplatePart('content', 'heighlight', $params);
}

En el archivo content-heighlight.php estará accesible la variable con nombre $utm_source y valor footer.

17 jun 2013 17:12:39
Comentarios

Función interesante. ¿Todos los globales y variables de consulta suelen estar accesibles en los archivos de plantilla normales?

christian christian
4 dic 2014 01:09:42
0

Puedes simplemente envolver el get_template_part, almacenar un objeto modelo en una variable global y limpiarlo después. Así es como lo hemos estado haciendo en nuestros proyectos:

functions.php

$model = null; // esta es una variable global
function my_get_template_part($slug, $name = null, $templateModel = null) {
    global $model;
    $model = $templateModel; // establece la variable global con el objeto modelo proporcionado
    get_template_part($slug,$name); 
    $model = null; // limpia la variable global
}

function get_model() {
    global $model;
    return $model;
}

Uso en la plantilla principal:

<?php my_get_template_part('template-parts/xxxx','xxx',array('test1'))?>

Accediendo al modelo proporcionado en el template-part:

<?php $model = get_model() ?>

De esta manera, no tienes que copiar y pegar la función original get_template_part a tu propia función en caso de que su implementación cambie más tarde por los desarrolladores de WordPress.

10 sept 2016 05:30:11