// 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
。那是最好的方式吗?#1 楼
当帖子通过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 );
就是这样。
更新(WP> = v5.5)
正如评论中指出的那样,当前版本的WP为
[get_template_part()][1]
提供了第三个参数:array $args
。因此,从此版本开始,您不再需要使用set_query_var( 'foo', 'bar' )
。示例:<?php
get_header();
// etc.
// In the main template file
$users = new \WP_User_Query( [ ... ] );
foreach ( $users as $user )
{
$args = (array) $user;
get_template_part( 'template-parts/user', 'contact_methods', $args );
}
然后,在我们的
wpse-theme/template-parts/user-contact_methods.php
文件中,我们需要访问用户ID:<?php
/** @var array $args */
$some_meta = get_the_author_meta( 'some_meta', $args['ID'] );
var_dump( $some_meta );
说明实际上恰好在您引用的部分上方您的问题:
但是,被
load_template()
间接调用的get_template_part()
会将所有WP_Query
查询变量提取到已加载模板的范围内。本机PHP
extract()
函数“提取”变量(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'
评论
仍然很棒
–中间女士
19年6月11日13:43
从WordPress 5.5开始,您可以将args传递给get_template_part函数。类似于get_template_part('somefile',null,['arg1'=>'val1','arg2'=>'val2',...]之类的东西。
– norixxx
11月12日8:44
#2 楼
人为的hm_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;
}
评论
包括1300行代码(来自github HM)到项目,以将一个参数传递给模板?在我的项目中无法做到这一点:(
–Gediminas
19-09-4在8:31
您可以只将他上面粘贴的代码包括到您的functions.php中。
– DokiCRO
19年11月15日在12:02
#3 楼
我环顾四周,发现了各种各样的答案。在本地级别,Wordpress确实允许在模板部分中访问变量。我确实发现,将include与locate_template结合使用确实可以在文件中访问变量范围。include(locate_template('your-template-name.php'));
评论
使用include不会通过themecheck。
–lowtechsun
17年6月14日在23:10
我们真的需要像WP主题的W3C检查器之类的东西吗?
– Fredy31
19年8月15日在19:08
#4 楼
// 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"
我建议阅读有关PHP Extract()函数的信息。
#5 楼
从5.5开始,可以通过各种核心模板加载功能将数据传递到模板。所有WordPress模板加载功能都将支持附加参数
$args
,该参数允许主题作者通过数据与已加载模板的关联数组。支持此新参数的函数为:get_header()
get_footer()
get_sidebar()
get_template_part()
locate_template()
load_template()
与该函数关联的任何钩子也会传递数据。
有关更多信息:https://make.wordpress.org/core/ 2020/07/17 /将参数传递到模板文件中wordpress-5-5 /
评论
不幸的是,$ args参数没有通过extract()运行,因此您需要在模板中执行echo $ args ['foo']。我希望也可以提取args。
–动力浮标
8月17日9:27
#6 楼
更新自从Wordpress 5.5以来正确正确地回答了get_template_part()(请参阅changelog),现在接受第三个参数
array $args = array()
,它将在您的模板文件中以$args
的形式提供。请参见以下示例:
$bar = 'bar';
// get helper-my-template.php
get_template_part(
'template-parts/helper',
'my-template',
array(
'foo' => $bar, // passing this array possible since WP 5.5
)
);
在您的模板文件中
例如helper-my-template.php,您现在可以像这样访问变量:
<?php
/**
* @var array $args
*/
$foo = $args['foo'];
?>
<h1><?php echo $foo; ?></h1>
<?php // will print 'bar' ?>
#7 楼
我在目前正在研究的项目中遇到了同样的问题。我决定创建自己的小插件,使您可以使用新函数将变量更明确地传递给get_template_part。如果您可能觉得有用,请在GitHub上找到此页面:https://github.com/JolekPress/Get-Template-Part-With-Variables
这是其工作方式的示例:
$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>
#8 楼
用于模板加载功能的$args
参数刚刚出现在WordPress 5.5“ Eckstine”中:将数据传递到模板文件
模板加载功能(get_header(),get_template_part()等)有一个新的$ args参数。因此,现在您可以将整个数组的数据传递给这些模板。
#9 楼
我喜欢Pods插件及其pods_view函数。它的工作方式类似于djb的答案中提到的hm_get_template_part
函数。我使用附加功能(下面的代码中的findTemplate
)首先在当前主题中搜索模板文件,如果找不到,它将在我插件的/templates
文件夹中返回具有相同名称的模板。这是我如何在插件中使用pods_view
的粗略想法:/**
* 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
也支持缓存,但是我不需要它。有关函数参数的更多信息,请参见Pods文档页面。请参阅pods_view的页面和部分页面缓存以及带有Pod的智能模板部件。#10 楼
基于@djb的答案,使用humanmade的代码。这是get_template_part的轻量级版本,可以接受args。这样,变量就可以在本地范围内限定于该模板。不需要
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();
}
例如在
cart.php
中:<? php _get_template_part( 'components/items/apple', null, ['color' => 'red']); ?>
在
apple.php
中:<p>The apple color is: <?php echo $args['color']; ?></p>
#11 楼
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();
}
}
通过使用
${$key}
可以将变量添加到当前函数范围中。对我有用,快速,轻松并且不泄漏或存储到全局范围中。
#12 楼
对于那些看起来很容易传递变量的人,可以将函数更改为包括:include(locate_template('YourTemplate.php',false,false));
然后,您将能够使用在包含模板之前定义的所有变量,而无需通过模板的每个附加变量。
信用证转到:
https://mekshq.com/passing-variables-via-get_template_part-wordpress/
#13 楼
这是精确的解决方案,并且效果很好。https://developer.wordpress.org/reference/functions/set_query_var/
评论
我想你误会了
– JDandChips
10月22日9:49
评论
遇到了相同的问题,并使它与set_query_var和get_query_var一起使用,但这是用于使用传递给WP_Query的$ args数组的值。可能会对其他开始学习此方法的人有所帮助。@Florian,请参阅wordpress.stackexchange.com/a/373230/54986,并在适当的情况下将其标记为答案-它现在是一流的支持产品