Передача переменных через 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), или просто возвращать их. Возвращаюсь к текущему проекту, чтобы обновить код с использованием этого подхода... спасибо!
MathSmath
Вскоре после публикации здесь я в итоге использовал тот же метод.
curtismchale
21676 затрагивает эту проблему, но похоже, что это не будет принято.
Ian Dunn
Возможно, я ошибаюсь, но: locate_template() фактически выполняет включение, если параметр установлен как true — как в вопросе. (по умолчанию false, поэтому не вставляйте версию из вопроса в принятый ответ.) Также можно просто использовать set_query_var('var', $var); и применять ваш get_template_part() как обычно. Тогда у вас будут доступны стандартные переменные WordPress внутри файла шаблона, как упомянул @MathSmath.
Jonas Lundman
Аккуратное решение, найденное в кодексе
Таким образом, если вы перебираете пользовательские записи, можно сделать так:
foreach ($custom_posts as $custom_post) {
set_query_var( 'my_post', $custom_post );
get_template_part( 'content', 'part' );
}
И в самом шаблоне вы автоматически получите доступ к переменной $my_post.
Это был бы правильный ответ, если бы пример кода отвечал на вопрос. (Передача параметра, а не полного массива записей)
Jonas Lundman
У меня тоже были проблемы с этим (при попытке заставить пользовательский запрос работать с частью шаблона). Короткий ответ: нет, часть шаблона не наследует пользовательские переменные автоматически, как это делает обычный 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.