Passando uma variável para get_template_part

46

O WP Codex diz para fazer isso:

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

Mas como faço para echo $my_var na parte do modelo? get_query_var($my_var) não funciona para mim.

Já vi várias recomendações para usar locate_template . Esse é o melhor caminho a percorrer?

    
por Florian 02.02.2015 / 10:59
fonte

8 respostas

44

Como as postagens obtêm seus dados configurados via the_post() (respectivamente via setup_postdata() ) e, portanto, são acessíveis pela API ( get_the_ID() , por exemplo), suponhamos que estamos em loop por um conjunto de usuários (como < a href="http://queryposts.com/function/setup_userdata/"> setup_userdata() preenche as variáveis globais do usuário logado no momento e não é útil para esta tarefa ) e tente exibir metadados por usuário:

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

Em seguida, no nosso arquivo wpse-theme/template-parts/user-contact_methods.php , precisamos acessar o ID do usuário:

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

É isso.

A explicação é, na verdade, exatamente acima da parte que você citou na sua pergunta:

  

No entanto, load_template() , que é chamado indiretamente por get_template_part() , extrai todas as variáveis de consulta WP_Query para o escopo do modelo carregado.

A função extract() do PHP nativo "extrai" as variáveis (a propriedade global $wp_query->query_vars ) e coloca cada parte em sua própria variável que tem exatamente o mesmo nome da chave. Em outras palavras:

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'
    
por kaiser 02.02.2015 / 11:14
fonte
21

A função hm_get_template_part de humanmade é extremamente boa isso e eu uso isso o tempo todo.

Você chama

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

e, em seguida, dentro do seu modelo, você usa

$template_args['option'];

para retornar o valor. Ele faz cache e tudo mais, mas você pode tirar isso se quiser.

Você pode até mesmo retornar o modelo renderizado como uma string passando 'return' => true para a matriz chave / 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;
}
    
por djb 04.02.2015 / 20:25
fonte
10

Eu estava procurando e encontrei uma variedade de respostas. Sua parece em um nível nativo, o Wordpress permite que variáveis sejam acessadas em partes do modelo. Eu achei que usando o include acoplado com locate_template permitia que o escopo das variáveis fosse acessível no arquivo.

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

Eu encontrei esse mesmo problema em um projeto no qual estou trabalhando atualmente. Eu decidi criar meu próprio pequeno plugin que permite que você passe mais explicitamente variáveis para get_template_part usando uma nova função.

Caso você ache útil, aqui está a página para isso no GitHub: enlace

E aqui está um exemplo de como isso funcionaria:

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

Eu gosto do plug-in Pods e de seus pods_view . Ele funciona de maneira semelhante à função hm_get_template_part mencionada na resposta do djb. Eu uso uma função adicional ( findTemplate no código abaixo) para procurar um arquivo de modelo no tema atual primeiro, e se não for encontrado, ele retorna o modelo com o mesmo nome na pasta /templates do meu plugin. Esta é uma ideia aproximada de como estou usando pods_view no meu plug-in:

/**
 * 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 também suporta armazenamento em cache, mas eu não precisei disso para meus propósitos. Mais informações sobre os argumentos da função podem ser encontradas nas páginas de documentação do Pods. Veja as páginas de pods_view e .

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

Eu recomendo ler sobre a função PHP Extract ().

    
por Hugo R 05.08.2017 / 17:24
fonte
0

Que tal isso?

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

Usando ${$key} , você pode adicionar as variáveis ao escopo da função atual. Funciona para mim, rápido e fácil e não está vazando ou armazenado no escopo global.

    
por Mattijs 22.06.2018 / 07:56
fonte
-2

Esta é a solução exata e funcionou bem. enlace

    
por Mindhunter 16.01.2018 / 13:51
fonte