Передача переменных через locate_template
Хотя я обычно использовал include
или require
для долгосрочной поддержки кода, я начал использовать get_template_part
и locate_template
, так как использование встроенных функций WordPress всегда предпочтительнее.
Мой вопрос заключается в том, можно ли передавать переменные через результаты get_template_part
или locate_template
?
<?php
$var = get_option( 'my-custom-option' );
get_template_part( 'custom-template-part' );
?>
В коде выше $var
должна быть выведена внутри пользовательского шаблона, но переменная, похоже, не работает. Я что-то упускаю или это ожидаемое поведение?
Я обнаружил, что они не передаются в приведенном выше случае или при использовании locate_template
<?php
locate_template( 'custom-template-part.php', true );
?>

Как написал MathSmath, функция get_template() не поддерживает повторное использование ваших переменных.
Но locate_template() на самом деле вообще не выполняет включение. Она просто находит файл для включения.
Таким образом, вы можете использовать include, чтобы это работало так, как вы ожидаете:
include(locate_template('custom-template-part.php'));
$var
из вашего примера затем можно использовать в части шаблона.
Связанный вопрос с более техническим объяснением области видимости переменных и get_template(): Ошибка отправки формы с get_template_part()

Хорошее замечание. Я не заметил, что у locate_template() есть параметр, который позволяет по желанию вызывать load_template() с результатами (что и делает get_template_part), или просто возвращать их. Возвращаюсь к текущему проекту, чтобы обновить код с использованием этого подхода... спасибо!

Вскоре после публикации здесь я в итоге использовал тот же метод.

21676 затрагивает эту проблему, но похоже, что это не будет принято.

Возможно, я ошибаюсь, но: locate_template()
фактически выполняет включение, если параметр установлен как true
— как в вопросе. (по умолчанию false
, поэтому не вставляйте версию из вопроса в принятый ответ.) Также можно просто использовать set_query_var('var', $var);
и применять ваш get_template_part()
как обычно. Тогда у вас будут доступны стандартные переменные WordPress внутри файла шаблона, как упомянул @MathSmath.

Аккуратное решение, найденное в кодексе
Таким образом, если вы перебираете пользовательские записи, можно сделать так:
foreach ($custom_posts as $custom_post) {
set_query_var( 'my_post', $custom_post );
get_template_part( 'content', 'part' );
}
И в самом шаблоне вы автоматически получите доступ к переменной $my_post
.

Это был бы правильный ответ, если бы пример кода отвечал на вопрос. (Передача параметра, а не полного массива записей)

У меня тоже были проблемы с этим (при попытке заставить пользовательский запрос работать с частью шаблона). Короткий ответ: нет, часть шаблона не наследует пользовательские переменные автоматически, как это делает обычный include.
И get_template_part(), и locate_template() в конечном итоге используют функцию load_template() для фактической загрузки файла (с помощью require). Эта функция делает глобальными следующие переменные:
$posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID
Однако никакие другие переменные внутри части шаблона не доступны. Полагаю, раз require обёрнут в функцию, область видимости меняется или что-то в этом роде?
В любом случае, я бы попробовал сделать глобальными любые дополнительные переменные, которые нужно передать, а затем обратиться к этим глобальным переменным из части шаблона.

Мои пять копеек для будущих ссылок, обходной путь, по крайней мере в WordPress 3.5, заключается в добавлении переменной в $wp_query->query_vars
.
Мне нужна была моя глобальная переменная _vk_errors
внутри части шаблона, и я просто сделал $wp_query->query_vars['_vk_errors'] = $_vk_errors;
перед вызовом get_template_part()
.

WordPress 5.5+
Параметр $args был добавлен в функцию locate_template
https://developer.wordpress.org/reference/functions/locate_template/
Передача данных
$data = [
'foo' => 'Привет',
'bar' => ', WordPress 5.5',
];
locate_template('your-template.php', true, true, $data);
your-template.php
// обработка переданных аргументов через $args
echo $args['foo'] . $args['bar']; // "Привет, WordPress 5.5"
// или использование extract($args);
extract($args);
echo $foo . $bar; // "Привет, WordPress 5.5"
locate_template
использует load_template
, который начиная с версии 5.5 также может передавать дополнительные аргументы в шаблон.
https://developer.wordpress.org/reference/functions/load_template/
Это касается и всех функций шаблонов, которые используют locate_template
:
get_header
, get_footer
, get_sidebar
, get_template_part
.
https://developer.wordpress.org/reference/functions/get_header/ https://developer.wordpress.org/reference/functions/get_footer/ https://developer.wordpress.org/reference/functions/get_sidebar/ https://developer.wordpress.org/reference/functions/get_template_part/

Вот моя простая функция для решения проблемы с переменными. Она делает то же самое, что и функция WordPress get_template_part()
. Просто скопируйте и вставьте в function.php
.
function getTemplatePart($slug = null, $name = null, array $params = array()) {
global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
do_action("get_template_part_{$slug}", $slug, $name);
$templates = array();
if (isset($name))
$templates[] = "{$slug}-{$name}.php";
$templates[] = "{$slug}.php";
$_template_file = locate_template($templates, false, false);
if (is_array($wp_query->query_vars)) {
extract($wp_query->query_vars, EXTR_SKIP);
}
extract($params, EXTR_SKIP);
require($_template_file);
}
Пример использования в шаблоне
$params = array(
'utm_source' => 'footer'
);
while ($posts->have_posts()) {
$posts->the_post();
getTemplatePart('content', 'heighlight', $params);
}
В файле content-heighlight.php
будет доступна переменная с именем $utm_source
и значением footer
.

Вы можете просто обернуть get_template_part, сохранить объект модели в глобальной переменной и очистить её позже. Вот как мы делаем это в наших проектах:
functions.php
$model = null; // это глобальная переменная
function my_get_template_part($slug, $name = null, $templateModel = null) {
global $model;
$model = $templateModel; // устанавливаем глобальную переменную в предоставленный объект модели
get_template_part($slug,$name);
$model = null; // очищаем глобальную переменную
}
function get_model() {
global $model;
return $model;
}
Использование в основном шаблоне:
<?php my_get_template_part('template-parts/xxxx','xxx',array('test1'))?>
Доступ к предоставленной модели в части шаблона:
<?php $model = get_model() ?>
Таким образом, вам не нужно копировать и вставлять оригинальную функцию get_template_part в свою собственную функцию, на случай если её реализация изменится в будущем разработчиками WordPress.
