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

WP Codex говорит , чтобы сделать это:

// 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. Это лучший способ пойти?

43 голоса | спросил Florian 2 FebruaryEurope/MoscowbMon, 02 Feb 2015 12:59:25 +0300000000pmMon, 02 Feb 2015 12:59:25 +030015 2015, 12:59:25

8 ответов


42

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

<?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'
ответил kaiser 2 FebruaryEurope/MoscowbMon, 02 Feb 2015 13:14:01 +0300000000pmMon, 02 Feb 2015 13:14:01 +030015 2015, 13:14:01
19

hm_get_template_part функция humanmade очень хорош в этом, и я использую его все время.

Вы вызываете

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

, а затем внутри вашего шаблона вы используете

$template_args['option'];

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

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

/**
 * 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;
}
ответил djb 4 FebruaryEurope/MoscowbWed, 04 Feb 2015 22:25:57 +0300000000pmWed, 04 Feb 2015 22:25:57 +030015 2015, 22:25:57
9

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

include(locate_template('your-template-name.php'));
ответил Murray Chapman 4 J0000006Europe/Moscow 2016, 08:52:20
1

Я столкнулся с этой проблемой в проекте, над которым я сейчас работаю. Я решил создать свой собственный небольшой плагин, который позволяет более явно передавать переменные 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>
ответил John O 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 12 Sep 2016 01:02:05 +0300 2016, 01:02:05
1

Мне нравится плагин Pods и их pods_view . Он работает аналогично функции hm_get_template_part, упомянутой в ответе djb. Я использую дополнительную функцию (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 и Частичное кэширование страниц и элементы Smart Template с помощью Pods .

ответил thirdender 21 AM00000020000002231 2016, 02:43:22
1
// 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 ().

ответил Hugo R 5 PM00000060000000131 2017, 18:24:01
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}, вы можете добавить переменные в текущую область функций. Работает для меня, быстро и легко и не протекает или хранится в глобальном масштабе.

ответил Mattijs 22 J0000006Europe/Moscow 2018, 08:56:05
-2

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

ответил Mindhunter 16 Jpm1000000pmTue, 16 Jan 2018 15:51:53 +030018 2018, 15:51:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132