Melewati variabel ke get_template_part


55

The WP Codex mengatakan untuk melakukan hal ini:

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

Tetapi bagaimana saya echo $my_vardi dalam bagian template? get_query_var($my_var)tidak bekerja untuk saya.

Saya telah melihat banyak rekomendasi untuk digunakan locate_templatesebagai gantinya. Apakah itu cara terbaik untuk pergi?


Memiliki tentang pertanyaan yang sama dan mendapatkannya untuk bekerja dengan set_query_vardan get_query_var, namun ini adalah untuk menggunakan nilai dari suatu $argsarray dilewatkan ke WP_Query. Mungkin bermanfaat bagi orang lain yang mulai mempelajari hal ini.
lowtechsun

Jawaban:


53

Ketika posting mendapatkan data mereka diatur melalui the_post()(masing-masing melalui setup_postdata()) dan karenanya dapat diakses melalui API ( get_the_ID()misalnya), mari kita asumsikan bahwa kita mengulang melalui serangkaian pengguna (seperti setup_userdata()mengisi variabel global dari pengguna yang saat ini masuk dan tidak t berguna untuk tugas ini) dan mencoba menampilkan meta data per pengguna:

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

Kemudian, di wpse-theme/template-parts/user-contact_methods.phpfile kami , kami perlu mengakses ID pengguna:

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

Itu dia.

Penjelasan sebenarnya persis di atas bagian yang Anda kutip dalam pertanyaan Anda:

Namun, load_template()yang dipanggil secara tidak langsung dengan get_template_part()mengekstrak semua WP_Queryvariabel kueri, ke dalam lingkup templat yang dimuat.

extract()Fungsi PHP asli "mengekstrak" variabel ( global $wp_query->query_varsproperti) dan menempatkan setiap bagian ke dalam variabelnya sendiri yang memiliki nama yang persis sama dengan kunci. Dengan kata lain:

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'

1
masih bekerja dengan baik
huraji

23

The hm_get_template_partfungsi dengan humanmade sangat baik ini dan saya menggunakannya sepanjang waktu.

Kamu panggil

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

dan kemudian di dalam template Anda, Anda gunakan

$template_args['option'];

untuk mengembalikan nilai. Itu caching dan segalanya, meskipun Anda bisa mengambilnya jika Anda mau.

Anda bahkan dapat mengembalikan template yang diberikan sebagai string dengan meneruskan 'return' => trueke array kunci / nilai.

/**
 * 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;
}

Sertakan 1.300 baris kode (dari github HM) ke proyek untuk meneruskan satu parameter ke templat? Tidak dapat melakukan ini dalam proyek saya :(
Gediminas

11

Saya mencari-cari dan menemukan berbagai jawaban. Tampaknya pada tingkat asli, Wordpress memungkinkan variabel diakses di bagian Templat. Saya memang menemukan bahwa menggunakan include ditambah dengan loc_template memang memungkinkan ruang lingkup variabel dapat diakses dalam file.

include(locate_template('your-template-name.php'));

Menggunakan includetidak akan lulus pemeriksaan mereka .
lowtechsun

Apakah kita benar-benar membutuhkan sesuatu yang seperti pemeriksa W3C untuk Tema WP?
Fredy31

5
// 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"

Saya sarankan untuk membaca tentang fungsi PHP Extract ().


2

Saya mengalami masalah yang sama pada proyek yang sedang saya kerjakan. Saya memutuskan untuk membuat plugin kecil saya sendiri yang memungkinkan Anda untuk secara eksplisit meneruskan variabel ke get_template_part dengan menggunakan fungsi baru.

Jika Anda mungkin menemukan itu berguna, inilah halaman untuk itu di GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables

Dan inilah contoh cara kerjanya:

$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>

1

Saya suka plugin Pods dan fungsi pods_view mereka . Ini berfungsi mirip dengan hm_get_template_partfungsi yang disebutkan dalam jawaban djb. Saya menggunakan fungsi tambahan ( findTemplatedalam kode di bawah ini) untuk mencari file template dalam tema saat ini terlebih dahulu, dan jika tidak ditemukan mengembalikan template dengan nama yang sama di /templatesfolder plugin saya . Ini adalah gagasan kasar tentang bagaimana saya menggunakan pods_viewplugin saya:

/**
 * 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_viewjuga mendukung caching, tetapi saya tidak membutuhkannya untuk tujuan saya. Informasi lebih lanjut tentang argumen fungsi dapat ditemukan di halaman dokumentasi Pods. Lihat halaman untuk pods_view dan Bagian Caching Bagian dan Bagian Templat Cerdas dengan Pod .


1

Berdasarkan jawaban dari @djb menggunakan kode dari buatan manusia.

Ini adalah versi ringan dari get_template_part yang dapat menerima argumen. Variabel cara ini dicakup secara lokal ke templat itu. Tidak perlu untuk memiliki global, get_query_var, set_query_var.

/**
 * Like get_template_part() but lets you pass args to the template file
 * Args are available in the template as $args array.
 * Args can be passed in as url parameters, e.g 'key1=value1&key2=value2'.
 * Args can be passed in as an array, e.g. ['key1' => 'value1', 'key2' => 'value2']
 * Filepath is available in the template as $file string.
 * @param string      $slug The slug name for the generic template.
 * @param string|null $name The name of the specialized template.
 * @param array       $args The arguments passed to the template
 */

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

Misalnya di cart.php:

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

Dalam apple.php:

<p>The apple color is: <?php echo $args['color']; ?></p>

0

Bagaimana dengan ini?

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

Dengan menggunakan ${$key}Anda dapat menambahkan variabel ke dalam lingkup fungsi saat ini. Bekerja untuk saya, cepat dan mudah dan tidak bocor atau disimpan dalam ruang lingkup global.



Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.