Truyền một biến cho get_template_part


55

Các WP Codex nói để làm điều này:

// 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' );

Nhưng làm thế nào để tôi echo $my_varbên trong phần mẫu? get_query_var($my_var)không làm việc cho tôi.

Tôi đã thấy hàng tấn khuyến nghị để sử dụng locate_templatethay thế. Đó có phải là cách tốt nhất để đi?


Đã về cùng một câu hỏi và nhận được nó để làm việc với set_query_varget_query_var, tuy nhiên điều này là sử dụng các giá trị của một $argsmảng được truyền cho một WP_Query. Có thể hữu ích cho những người khác bắt đầu tìm hiểu điều này.
lowTechsun

Câu trả lời:


53

Khi các bài đăng nhận dữ liệu của chúng được thiết lập thông qua the_post()(tương ứng thông qua setup_postdata()) và do đó có thể truy cập thông qua API ( get_the_ID()ví dụ), hãy giả sử rằng chúng tôi đang lặp qua một nhóm người dùng (khi setup_userdata()điền vào các biến toàn cục của người dùng hiện đang đăng nhập và không ' t hữu ích cho nhiệm vụ này) và cố gắng hiển thị dữ liệu meta cho mỗi người dùng:

<?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' );
}

Sau đó, trong wpse-theme/template-parts/user-contact_methods.phptệp của chúng tôi , chúng tôi cần truy cập ID người dùng:

<?php
/** @var int $user_id */
$some_meta = get_the_author_meta( 'some_meta', $user_id );
var_dump( $some_meta );

Đó là nó.

Lời giải thích thực sự chính xác ở trên phần bạn trích dẫn trong câu hỏi của bạn:

Tuy nhiên, load_template()được gọi gián tiếp bằng cách get_template_part()trích xuất tất cả các WP_Querybiến truy vấn, vào phạm vi của mẫu được tải.

Hàm PHP gốc extract()"trích xuất" các biến (thuộc global $wp_query->query_varstính) và đặt mọi phần vào biến riêng có cùng tên với khóa. Nói cách khác:

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'

1
vẫn hoạt động tốt
Huraji

23

Các hm_get_template_partchức năng của humanmade là cực kỳ giỏi trong việc này và tôi sử dụng nó mọi lúc.

Bạn gọi

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

và sau đó bên trong mẫu của bạn, bạn sử dụng

$template_args['option'];

để trả về giá trị. Nó lưu vào bộ nhớ cache và mọi thứ, mặc dù bạn có thể lấy nó ra nếu bạn muốn.

Bạn thậm chí có thể trả về mẫu được kết xuất dưới dạng chuỗi bằng cách chuyển 'return' => truevào mảng khóa / giá trị.

/**
 * 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;
}

Bao gồm 1300 dòng mã (từ github HM) cho dự án để truyền một tham số cho mẫu? Không thể làm điều này trong dự án của tôi :(
Gediminas

11

Tôi đã nhìn xung quanh và đã tìm thấy một loạt các câu trả lời. Có vẻ như ở cấp độ bản địa, Wordpress không cho phép các biến được truy cập trong các phần Mẫu. Tôi đã thấy rằng việc sử dụng bao gồm cùng với location_template đã cho phép phạm vi biến có thể truy cập được trong tệp.

include(locate_template('your-template-name.php'));

Sử dụng includesẽ không vượt qua themecheck .
lowTechsun

Chúng ta có thực sự cần một cái gì đó giống như trình kiểm tra W3C cho WP Themes không?
Fredy31

5
// 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"

Tôi khuyên bạn nên đọc về hàm PHP Extract ().


2

Tôi gặp vấn đề tương tự trong một dự án mà tôi hiện đang làm. Tôi đã quyết định tạo một plugin nhỏ của riêng mình, cho phép bạn chuyển các biến rõ ràng hơn tới get_template_part bằng cách sử dụng một hàm mới.

Trong trường hợp bạn có thể thấy nó hữu ích, đây là trang dành cho nó trên GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variabled

Và đây là một ví dụ về cách nó sẽ hoạt động:

$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>

1

Tôi thích plugin Pods và chức năng pods_view của họ . Nó hoạt động tương tự như hm_get_template_partchức năng được đề cập trong câu trả lời của djb. Tôi sử dụng một chức năng bổ sung ( findTemplatetrong mã bên dưới) để tìm kiếm tệp mẫu trong chủ đề hiện tại trước tiên và nếu không tìm thấy, nó sẽ trả về mẫu có cùng tên trong /templatesthư mục plugin của tôi . Đây là một ý tưởng sơ bộ về cách tôi đang sử dụng pods_viewtrong plugin của mình:

/**
 * 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_viewcũng hỗ trợ bộ nhớ đệm, nhưng tôi không cần điều đó cho mục đích của mình. Thông tin thêm về các đối số chức năng có thể được tìm thấy trong các trang tài liệu Pods. Xem các trang dành cho pods_viewBộ phận đệm thông minhmột phần mẫu thông minh với Pods .


1

Dựa trên câu trả lời từ @djb bằng cách sử dụng mã từ nhân tạo.

Đây là phiên bản nhẹ của get_template_part có thể chấp nhận args. Cách biến này được đặt trong phạm vi cục bộ của mẫu đó. Không cần phải có global, get_query_var, set_query_var.

/**
 * Like get_template_part() but lets you pass args to the template file
 * Args are available in the template as $args array.
 * Args can be passed in as url parameters, e.g 'key1=value1&key2=value2'.
 * Args can be passed in as an array, e.g. ['key1' => 'value1', 'key2' => 'value2']
 * Filepath is available in the template as $file string.
 * @param string      $slug The slug name for the generic template.
 * @param string|null $name The name of the specialized template.
 * @param array       $args The arguments passed to the template
 */

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();
}

Ví dụ cart.php:

<? php _get_template_part( 'components/items/apple', null, ['color' => 'red']); ?>

Trong apple.php:

<p>The apple color is: <?php echo $args['color']; ?></p>

0

Còn cái này thì sao?

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();
    }
}

Bằng cách sử dụng, ${$key}bạn có thể thêm các biến vào phạm vi chức năng hiện tại. Làm việc cho tôi, nhanh chóng và dễ dàng và nó không bị rò rỉ hoặc lưu trữ trong phạm vi toàn cầu.


0

Đối với những người có vẻ rất dễ dàng để vượt qua các biến, bạn có thể thay đổi chức năng để bao gồm:

bao gồm (xác định vị trí ('YourTemplate.php', sai, sai));

Và sau đó, bạn sẽ có thể sử dụng tất cả các biến được xác định trước khi bạn đưa vào mẫu mà không cần PASSING thêm từng biến cho mẫu.

Tín dụng truy cập: https://mekshq.com/passing-variabled-via-get_template_part-wordpress/


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.