问题描述

WP Codex says 这样做:

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

但是如何在 echo $my_var 内部模板部分? get_query_var($my_var)不适合我。

我已经看到了使用 locate_template 的大量建议。那是最好的方式吗?

最佳解决方案

由于帖子通过 the_post()(分别通过 setup_postdata()) 设置数据,因此可以通过 API(get_the_ID()) 进行访问,例如,我们假设我们循环使用一组用户 (如 setup_userdata()填充当前登录的全局变量用户,对此任务无效),并尝试显示每个用户的元数据:

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

然后,在我们的 wpse-theme/template-parts/user-contact_methods.php 文件中,我们需要访问用户 ID:

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

而已。

这个解释实际上正好在您在问题中引用的部分:

However, load_template(), which is called indirectly by get_template_part() extracts all of the WP_Query query variables, into the scope of the loaded template.

本机 PHP extract()函数”extracts” 的变量 (global $wp_query->query_vars 属性),并将每个部分放入其自己的变量中,该变量具有与该键完全相同的名称。换一种说法:

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'

次佳解决方案

humanmadehm_get_template_part 功能非常好,我一直使用它。

你打电话

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

然后在你的模板中,你使用

$template_args['option'];

返回值。它有缓存和一切,虽然你可以采取,如果你喜欢。

您甚至可以通过将'return' => true 传递到键/值数组来返回渲染的模板作为字符串。

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

第三种解决方案

我正在环顾四周,并找到了各种各样的答案。它似乎在本机级别,Wordpress 确实允许在模板部分访问变量。我确实发现使用 include 与 locate_template 配合使得可以在文件中访问变量范围。

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

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。