WPコーデックスは、 これを行うために次のように述べています。
// 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()
のように)グローバル変数を埋めます。 現在ログインしている userであり、この作業には役に立ちません)。ユーザーごとにメタデータを表示してみます。
<?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 );
それでおしまい。
説明は、実際には質問で引用した部分の真上にあります。
ただし、
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'
humanmade による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;
}
私は周りを見回していて、さまざまな答えを見つけました。ネイティブレベルのようですが、Wordpressでは、テンプレート部分で変数にアクセスできます。 locate_templateと組み合わされたインクルードを使用すると、変数のスコープがファイル内でアクセス可能になることを確認しました。
include(locate_template('your-template-name.php'));
// 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()関数について読むことをお勧めします。
私が現在取り組んでいるプロジェクトで、私はこれと同じ問題に遭遇しました。新しい関数を使って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>
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 および ポッド付き部分ページキャッシングおよびスマートテンプレートパーツ のページを参照してください。
Humanmadeのコードを使用して@djbからの回答に基づいています。
これは、引数を受け入れることができるget_template_partの軽量バージョンです。このようにして、変数はそのテンプレートに対してローカルにスコープされます。 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>
これはどう?
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}
を使うことで、現在の関数スコープに変数を追加することができます。すばやく簡単に私のために機能し、それが漏れたりグローバルな範囲に保存されたりすることはありません。