Передача переменных через locate_template

50

В то время как я обычно использовал 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 );
?>
curtismchale
источник

Ответы:

62

Как писал MathSmath , get_template () не поддерживает повторное использование ваших переменных.

Но locate_template () infact не включает вообще. Он просто находит файл для включения.

Таким образом, вы можете использовать include, чтобы это работало так, как вы ожидаете:

include(locate_template('custom-template-part.php'));

$var из вашего примера можно использовать в части шаблона тогда.

Связанный вопрос с более техническим объяснением области действия переменной и get_template (): Ошибка отправки формы с get_template_part ()

hakre
источник
Хороший звонок. Я не заметил, что у locate_template () есть параметр, который позволяет опционально вызывать load_template () с результатами (что делает get_template_part) или просто возвращать их. Я возвращаюсь к текущему проекту, чтобы обновить код, используя этот подход ... спасибо!
MathSmath
вскоре после того, как я написал здесь, я использовал тот же метод.
curtismchale
21676 решает эту проблему , но не похоже, что она будет совершена.
Ян Данн
Возможно, я ошибаюсь, но: locate_template()infact делает включение, если trueв вопросе задан параметр -as. (по умолчанию false, поэтому не вставляйте версию вопросов в принятый ответ.) Вы также можете просто использовать set_query_var('var', $var);и использовать свою get_template_part()как обычно. Тогда у вас также есть переменные Worpdress по умолчанию, доступные в файле шаблона, как упоминалось в @MathSmath.
Джонас Лундман
13

Аккуратное решение найдено в кодексе

Так что, если вы просматриваете пользовательские сообщения, вы можете сделать это:

foreach ($custom_posts as $custom_post) {
    set_query_var( 'my_post', $custom_post );
    get_template_part( 'content', 'part' );
}

И в этом шаблоне вы автоматически получите $my_post.

zionsg
источник
Это был бы правильный ответ, если пример кода отвечал на вопрос. (Опция прохождения, не полный массив сообщений)
Джонас Лундман,
Это прекрасно работает для передачи дополнительной информации во включенный шаблон. Это также работает wc_get_template_partв WooCommerce, который, без сомнения, расширяет стандартный WP.
nabrown
8

У меня тоже были проблемы с этим (при попытке заставить пользовательский запрос работать с частью шаблона). Краткий ответ: нет, часть шаблона автоматически не наследует пользовательские переменные, как обычное включение.

И 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

Однако никакие другие переменные не доступны внутри части шаблона. Я думаю, так как фактическое требование обернуто в функцию, область видимости меняется или что-то?

В любом случае, я бы попробовал глобализировать любые дополнительные переменные, которые вам нужно пропустить, а затем вызвать эти глобальные переменные из вашей части шаблона.

MathSmath
источник
4

Просто мои два цента за будущие ссылки, обходной путь по крайней мере в Wordpress 3.5 - добавить переменную в $wp_query->query_vars.

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

Понт Карлссон
источник
2

Вот моя простая функция, решающая переменную задачу. Он делает то же самое, что и 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

OzzyCzech
источник
Интересная функция. Все ли глобальные переменные и переменные запросов обычно доступны в обычных файлах шаблонов?
Кристиан
0

Вы можете просто обернуть get_template_part, сохранить объект модели в глобальном var и очистить его позже. Вот как мы работали в наших проектах:

functions.php

$model = null; // this is a global variable 
function my_get_template_part($slug, $name = null, $templateModel = null) {
    global $model;
    $model = $templateModel; // set the global var to the provided model object
    get_template_part($slug,$name); 
    $model = null; // clear the global var
}

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 в вашу собственную функцию на случай, если ее реализация может измениться позже разработчиками WP.

Кагатай Калан
источник