Pasando una variable a get_template_part

46

El WP Codex dice para hacer esto:

// 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' );

Pero, ¿cómo puedo echo $my_var dentro de la parte de la plantilla? get_query_var($my_var) no funciona para mí.

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

    
pregunta Florian 02.02.2015 - 10:59

8 respuestas

44

A medida que las publicaciones configuran sus datos a través de the_post() (respectivamente a través de setup_postdata() ) y, por lo tanto, son accesibles a través de la API ( get_the_ID() para, por ejemplo), asumamos que estamos haciendo un bucle a través de un conjunto de usuarios (como < a href="http://queryposts.com/function/setup_userdata/"> setup_userdata() llena las variables globales del usuario actualmente registrado y no es útil para esta tarea ) e intenta mostrar los metadatos por usuario:

<?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' );
}

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

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

Eso es todo.

La explicación es en realidad exactamente por encima de la parte que citó en su pregunta:

  

Sin embargo, load_template() , que se llama indirectamente por get_template_part() , extrae todas las variables de consulta WP_Query , en el alcance de la plantilla cargada.

La función extract() nativa de PHP "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'] (object)
    -> query_vars (array)
        foo => bar (string 3)

extract( $wp_query->query_vars );

var_dump( $foo );
// Result:
(string 3) 'bar'
    
respondido por el kaiser 02.02.2015 - 11:14
21

La función hm_get_template_part de humanmade es extremadamente buena Esto y lo uso todo el tiempo.

Llamas

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

y luego dentro de tu plantilla, usas

$template_args['option'];

para devolver el valor. Hace almacenamiento en caché y todo, aunque puedes eliminarlo si lo deseas.

Incluso puedes devolver la plantilla renderizada como una cadena pasando 'return' => true a la matriz clave / valor.

/**
 * 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;
}
    
respondido por el djb 04.02.2015 - 20:25
10

Estaba mirando alrededor y he encontrado una variedad de respuestas. Parece que a nivel nativo, Wordpress permite que se acceda a las variables en las partes de la plantilla. Descubrí que el uso de include junto con Locate_template permitía que el alcance de las variables estuviera accesible en el archivo.

include(locate_template('your-template-name.php'));
    
respondido por el Murray Chapman 04.06.2016 - 07:52
2

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

En caso de que le resulte útil, aquí está la página de GitHub: enlace

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

$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>
    
respondido por el John O 12.09.2016 - 00:02
1

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

/**
 * 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_view también admite el almacenamiento en caché, pero no lo necesitaba para mis propósitos. Puede encontrar más información sobre los argumentos de la función en las páginas de documentación de Pods. Consulte las páginas para pods_view y Cacheo parcial de página y partes de plantilla inteligente con pods .

    
respondido por el thirdender 21.08.2016 - 01:43
1
// 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"

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

    
respondido por el Hugo R 05.08.2017 - 17:24
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} puede agregar las variables al alcance de la función actual. Funciona para mí, es rápido y fácil, y no se filtra ni se almacena en el ámbito global.

    
respondido por el Mattijs 22.06.2018 - 07:56
-2

Esta es la solución exacta y funcionó bien. enlace

    
respondido por el Mindhunter 16.01.2018 - 13:51

Lea otras preguntas en las etiquetas