Передача переменной в get_template_part

2 февр. 2015 г., 11:59:25
Просмотры: 129K
Голосов: 74

Документация WordPress говорит делать это так:

// Вы хотите сделать $my_var доступной для части шаблона в `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. Это лучший способ?

2
Комментарии

У меня был почти такой же вопрос, и я смог решить его с помощью set_query_var и get_query_var, правда это касалось использования значений массива $args, который передается в WP_Query. Может быть полезно для других, кто только начинает это изучать.

lowtechsun lowtechsun
15 июн. 2017 г. 02:59:28

@Florian пожалуйста посмотрите https://wordpress.stackexchange.com/a/373230/54986 и отметьте как ответ, если подходит - это теперь полноценная поддерживаемая функция

Selrond Selrond
18 авг. 2020 г. 14:24:47
Все ответы на вопрос 13
2
73

Посты получают свои данные через the_post() (соответственно через setup_postdata()) и поэтому доступны через API (например, get_the_ID()). Давайте предположим, что мы перебираем набор пользователей (поскольку setup_userdata() заполняет глобальные переменные текущего авторизованного пользователя и не подходит для этой задачи) и попытаемся отобразить метаданные для каждого пользователя:

<?php
get_header();

// и т.д.

// В основном файле шаблона
$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)

Как отмечено в комментариях, текущие версии WordPress предлагают третий параметр для get_template_part(): array $args. Начиная с этой версии, вам больше не нужно использовать set_query_var( 'foo', 'bar' ). Пример:

<?php
get_header();

// и т.д.

// В основном файле шаблона
$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 );
// Результат:
(string 3) 'bar'
2 февр. 2015 г. 12:14:01
Комментарии

всё ещё отлично работает

middlelady middlelady
11 июн. 2019 г. 16:43:05

Начиная с WordPress 5.5 вы можете передавать аргументы в функцию get_template_part. Например: get_template_part('somefile', null, ['arg1' => 'val1', 'arg2' => 'val2', ...].

norixxx norixxx
12 нояб. 2020 г. 10:44:03
2
28

Функция hm_get_template_part от humanmade отлично справляется с этой задачей, и я использую её постоянно.

Вызываете так:

hm_get_template_part( 'template_path', [ 'option' => 'value' ] );

А затем внутри шаблона используете:

$template_args['option'];

для получения значения. Она также поддерживает кеширование, хотя его можно отключить, если нужно.

Можно даже получить отрендеренный шаблон в виде строки, передав 'return' => true в массиве ключ/значение.

/**
 * Аналог get_template_part(), но с возможностью передачи аргументов в файл шаблона
 * Аргументы доступны в шаблоне как массив $template_args
 * @param string filepart
 * @param mixed wp_args стиль списка аргументов
 */
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;
}
4 февр. 2015 г. 21:25:57
Комментарии

Добавить 1300 строк кода (из github HM) в проект, чтобы передать один параметр в шаблон? Не могу сделать это в своем проекте :(

Gediminas Gediminas
4 сент. 2019 г. 11:31:06

Ты можешь просто добавить код, который он вставил выше, в свой functions.php...

DokiCRO DokiCRO
15 нояб. 2019 г. 14:02:13
2
24

Я изучил вопрос и нашел различные ответы. Похоже, что на нативном уровне WordPress действительно позволяет получать доступ к переменным в частях шаблонов. Я обнаружил, что использование include в сочетании с locate_template позволяет сделать область видимости переменных доступной в файле.

include(locate_template('your-template-name.php'));
4 июн. 2016 г. 08:52:20
Комментарии

Использование include не пройдет проверку themecheck.

lowtechsun lowtechsun
15 июн. 2017 г. 02:10:50

Действительно ли нам нужен инструмент, подобный валидатору W3C, но для тем WordPress?

Fredy31 Fredy31
15 авг. 2019 г. 22:08:38
0
10
// можно использовать любые значения, включая объекты

set_query_var( 'var_name_to_be_used_later', 'Значение, которое будет получено позже' );
// По сути, set_query_var использует функцию PHP extract() для выполнения "магии".


затем позже в шаблоне:
var_dump($var_name_to_be_used_later);
// выведет "Значение, которое будет получено позже"

Рекомендую почитать про функцию PHP Extract().

5 авг. 2017 г. 18:24:01
0

Обновление

Как правильно ответил selrond, начиная с WordPress 5.5 функция get_template_part() (см. список изменений) теперь принимает третий параметр array $args = array(), который будет доступен в вашем файле шаблона как $args.

Пример использования:

$bar = 'bar';

// загружаем helper-my-template.php
get_template_part(
    'template-parts/helper',
    'my-template',
    array(
        'foo' => $bar, // передача массива возможна начиная с WP 5.5
    )
);

В вашем файле шаблона

Например, в helper-my-template.php теперь можно получить доступ к переменной следующим образом:

<?php

/**
 * @var array $args
 */

$foo = $args['foo'];

?>

<h1><?php echo $foo; ?></h1>

<?php // выведет 'bar' ?>
2 сент. 2020 г. 04:31:40
1

Начиная с версии 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/passing-arguments-to-template-files-in-wordpress-5-5/

4 авг. 2020 г. 00:13:53
Комментарии

К сожалению, параметр $args не обрабатывается через extract(), поэтому в шаблоне вам нужно будет использовать echo $args['foo']. Жаль, что нет возможности также извлекать аргументы.

powerbuoy powerbuoy
17 авг. 2020 г. 12:27:19
0

Я столкнулся с такой же проблемой в текущем проекте и решил создать небольшой плагин, который позволяет более явно передавать переменные в 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);


// В файле author-info.php:
echo "
<div class='$class'>
    <span>$name</span>
</div>
";

// Результат:
<div class='featuredAuthor'>
    <span>John</span>
</div>
12 сент. 2016 г. 01:02:05
0

Параметр $args для функций загрузки шаблонов только что появился в WordPress 5.5 "Eckstine":

Передача данных в файлы шаблонов

Функции загрузки шаблонов (get_header(), get_template_part() и др.) получили новый аргумент $args. Теперь вы можете передавать целый массив данных в эти шаблоны.

18 авг. 2020 г. 14:23:25
0

Мне нравится плагин Pods и его функция pods_view. Она работает аналогично функции hm_get_template_part, упомянутой в ответе djb. Я использую дополнительную функцию (findTemplate в коде ниже) для поиска файла шаблона сначала в текущей теме, и если он не найден, возвращается шаблон с тем же именем из папки /templates моего плагина. Вот пример того, как я использую pods_view в своем плагине:

/**
 * Вспомогательная функция для поиска шаблона
 */
function findTemplate($filename) {
  // Сначала ищем в папке темы
  $template = locate_template($filename);
  if (!$template) {
    // Если не найдено, используем файл из папки /templates плагина
    $template = dirname(__FILE__) . '/templates/' . $filename;
  }
  return $template;
}

// Выводим шаблон 'template-name.php' из папки темы
// *или* из папки '/template' плагина, передавая две локальные
// переменные для использования в файле шаблона
pods_view(
  findTemplate('template-name.php'),
  array(
    'passed_variable' => $variable_to_pass,
    'another_variable' => $another_variable,
  )
);

pods_view также поддерживает кэширование, но мне это не понадобилось. Подробнее о параметрах функции можно узнать в документации Pods. Смотрите страницы pods_view и Частичное кэширование страниц и умные части шаблонов с Pods.

21 авг. 2016 г. 02:43:22
0

На основе ответа от @djb с использованием кода от humanmade.

Это облегчённая версия get_template_part, которая может принимать аргументы. Таким образом, переменные ограничены областью видимости этого шаблона. Нет необходимости использовать global, get_query_var, set_query_var.

/**
 * Аналог get_template_part(), но позволяет передавать аргументы в файл шаблона
 * Аргументы доступны в шаблоне как массив $args.
 * Аргументы могут передаваться как параметры URL, например 'key1=value1&key2=value2'.
 * Аргументы могут передаваться как массив, например ['key1' => 'value1', 'key2' => 'value2']
 * Путь к файлу доступен в шаблоне как строка $file.
 * @param string      $slug Имя слага для общего шаблона.
 * @param string|null $name Имя специализированного шаблона.
 * @param array       $args Аргументы, передаваемые в шаблон
 */

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>Цвет яблока: <?php echo $args['color']; ?></p>
18 дек. 2018 г. 21:02:53
0

Как насчёт этого?

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} вы можете добавлять переменные в текущую область видимости функции. Работает у меня, быстро и просто, при этом переменные не попадают в глобальную область видимости.

22 июн. 2018 г. 08:56:05
0

Для тех, кто ищет очень простой способ передачи переменных, можно изменить функцию на include:

include( locate_template( 'YourTemplate.php', false, false ) );

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

Автор метода: https://mekshq.com/passing-variables-via-get_template_part-wordpress/

4 сент. 2019 г. 11:35:58
1
-3

Это точное решение, и оно отлично сработало. https://developer.wordpress.org/reference/functions/set_query_var/

16 янв. 2018 г. 14:51:53
Комментарии

Думаю, вы неправильно поняли

JDandChips JDandChips
22 окт. 2020 г. 12:49:55