ผ่านตัวแปรไปที่ get_template_part


55

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แทน นั่นเป็นวิธีที่ดีที่สุดที่จะไปไหม?


มีเกี่ยวกับคำถามเดียวกันและได้ไปทำงานด้วยset_query_varและget_query_varแต่นี้คือการใช้ค่าของอาร์เรย์ที่ถูกส่งผ่านไปยัง$args WP_Queryอาจเป็นประโยชน์สำหรับผู้อื่นที่เริ่มเรียนรู้สิ่งนี้
lowtechsun

คำตอบ:


53

ขณะที่โพสต์ได้รับข้อมูลของพวกเขาตั้งค่าผ่านทางthe_post()(ตามลำดับผ่านsetup_postdata()) และสามารถเข้าถึงได้ผ่าน API ได้ (ดังนั้นget_the_ID()สำหรับเช่น) สมมติว่าเราจะวนลูปผ่านชุดของผู้ใช้ (เหมือนsetup_userdata()เติมตัวแปรทั่วโลกของล็อกอินในปัจจุบันผู้ใช้และ ISN' ไม่มีประโยชน์สำหรับงานนี้) และพยายามแสดงข้อมูลเมตาต่อผู้ใช้:

<?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ตัวแปรแบบสอบถามทั้งหมดลงในขอบเขตของแม่แบบที่โหลด

extract()ฟังก์ชันPHP แบบเนทีฟ"แยก" ตัวแปร ( 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'

1
ยังคงใช้งานได้ดี
huraji

23

hm_get_template_partฟังก์ชั่นโดยhumanmadeเป็นสิ่งที่ดีมากที่นี้และฉันจะใช้มันตลอดเวลา

คุณโทรมา

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

จากนั้นภายในเทมเพลตของคุณคุณใช้

$template_args['option'];

เพื่อคืนค่า มันแคชและทุกอย่างแม้ว่าคุณจะสามารถที่จะออกหากคุณต้องการ

คุณสามารถคืนเท็มเพลตที่เรนเดอร์แสดงผลเป็นสตริงได้โดยส่งผ่าน'return' => trueไปยังอาร์เรย์คีย์ / ค่า

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

รวมโค้ด 1300 บรรทัด (จาก github HM) ไปยังโปรเจ็กต์เพื่อส่งหนึ่งพารามิเตอร์ไปยังเทมเพลต? ไม่สามารถทำได้ในโครงการของฉัน :(
Gediminas

11

ฉันมองไปรอบ ๆ และพบคำตอบที่หลากหลาย ดูเหมือนว่าอยู่ในระดับดั้งเดิม Wordpress อนุญาตให้เข้าถึงตัวแปรในส่วนเทมเพลตได้ ฉันพบว่าการใช้ include รวมกับ locate_template อนุญาตให้ขอบเขตตัวแปรสามารถเข้าถึงได้ในไฟล์

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

การใช้includeจะไม่ผ่านการตรวจสอบชุดรูปแบบ
lowtechsun

เราต้องการบางสิ่งที่เหมือนตัวตรวจสอบ W3C สำหรับ WP Themes หรือไม่?
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"

ฉันแนะนำให้อ่านเกี่ยวกับฟังก์ชั่น PHP Extract ()


2

ฉันพบปัญหาเดียวกันนี้ในโครงการที่ฉันกำลังทำงานอยู่ ฉันตัดสินใจที่จะสร้างปลั๊กอินขนาดเล็กของตัวเองที่ช่วยให้คุณผ่านตัวแปรอย่างชัดเจนเพื่อ 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>

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ยังรองรับการแคช แต่ฉันไม่ต้องการสำหรับวัตถุประสงค์ของฉัน ข้อมูลเพิ่มเติมเกี่ยวกับอาร์กิวเมนต์ของฟังก์ชั่นสามารถพบได้ในหน้าเอกสารของ Pod ดูหน้าสำหรับpods_viewและบางส่วนหน้าแคชและอะไหล่แม่แบบสมาร์ทที่มีฝัก


1

ตามคำตอบจาก @djb โดยใช้รหัสจาก humanmade

นี่คือ get_template_part ที่มีน้ำหนักเบาซึ่งสามารถรับ args ได้ ตัวแปรนี้กำหนดขอบเขตแบบโลคัลให้กับเทมเพลต ไม่จำเป็นต้องมีglobal, ,get_query_varset_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();
}

ตัวอย่างเช่นในcart.php:

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

ในapple.php:

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

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}คุณสามารถเพิ่มตัวแปรลงในขอบเขตฟังก์ชั่นปัจจุบัน เหมาะกับฉันเร็วและง่ายและไม่รั่วไหลหรือเก็บไว้ในขอบเขตทั่วโลก


0

สำหรับผู้ที่ดูวิธีส่งตัวแปรได้ง่ายคุณสามารถเปลี่ยนฟังก์ชั่นเพื่อรวม:

รวม (locate_template ('YourTemplate.php', false, false));

และจากนั้นคุณจะสามารถใช้ตัวแปรทั้งหมดที่กำหนดไว้ก่อนที่คุณจะรวมแม่แบบโดยไม่ต้องผ่านแต่ละแม่แบบเพิ่มเติม

เครดิตไปที่: https://mekshq.com/passing-variables-via-get_template_part-wordpress/


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.