รับชื่อของไฟล์เทมเพลตปัจจุบัน


57

ฉันพบสิ่งนี้เพื่อแสดงชื่อปัจจุบันของไฟล์ที่ใช้ในแม่แบบ:

function get_template_name () {
    foreach ( debug_backtrace() as $called_file ) {
        foreach ( $called_file as $index ) {
            if ( !is_array($index[0]) AND strstr($index[0],'/themes/') AND !strstr($index[0],'footer.php') ) {
                $template_file = $index[0] ;
            }
        }
    }
    $template_contents = file_get_contents($template_file) ;
    preg_match_all("Template Name:(.*)\n)siU",$template_contents,$template_name);
    $template_name = trim($template_name[1][0]);
    if ( !$template_name ) { $template_name = '(default)' ; }
    $template_file = array_pop(explode('/themes/', basename($template_file)));
    return $template_file . ' > '. $template_name ;
}

แหล่งที่มา: รับชื่อเทมเพลตหน้าบนหน้า

มันทำงานได้ค่อนข้างดียกเว้นว่าในแบ็กเอนด์ในกล่องเลือกเทมเพลตฉันได้รับรายการพิเศษที่น่าเกลียดนี้:

ภาพหน้าจอ

ใครบ้างมีความคิดวิธีการแก้ไขหรือไม่ ฉันไม่รู้ด้วยซ้ำว่าทำไมฟังก์ชั่นนี้ถึงเรียกว่าแบ็กเอนด์ มีฟังก์ชั่นที่มีเงื่อนไขis_frontend()หรือไม่ - นี่อาจช่วยแก้ปัญหาได้หรือไม่


2
@chodorowicz - ในขณะที่ฉันจะหยุดสั้น ๆ หนึ่งขั้นตอนของการโทรเลือกfunctions.phpเป็นข้อผิดพลาดฉันจะเห็นด้วยอย่างสมบูรณ์กับหลักฐานของคุณ เพื่อให้เรื่องแย่ลงฉันสแกนแกน WordPress และพบว่ามีประมาณ 5 แห่งซึ่งอาจเป็นเรื่องที่ทำให้คุณจัดการกับปัญหานี้ได้ แต่ฉันก็ไม่พบอะไรเลย ผมขอแนะนำให้โพสต์ตั๋วบนcore.trac.wordpress.org
MikeSchinkel

@ MikeSchinkel - ขอบคุณสำหรับความคิดเห็น แต่ไม่template_includeขอแนะนำ t31os ใดให้แก้ปัญหาเหรอ? หรือบางทีฉันอาจจะเข้าใจผิด
chodorowicz

1
@ MikeSchinkel - มันมี patch อยู่แล้ว :) core.trac.wordpress.org/ticket/16689
chodorowicz

1
ฉันสร้างปลั๊กอินใหม่เพื่อแสดงเทมเพลตปัจจุบัน ตรวจสอบได้ที่wordpress.org/extend/plugins/display-template-name

4
^ เช่น คุณเอารหัสจากคำตอบของฉันและห่อเป็นปลั๊กอิน และคุณทำทุกอย่างโดยไม่ให้เครดิตใด ๆ กับแหล่งกำเนิดทั้งตัวฉันเองหรือ WP stackexchange ... ดี ... : /
t31os

คำตอบ:


68

คุณสามารถตั้งค่าตัวแปรโกลบอลระหว่างtemplate_includeตัวกรองจากนั้นตรวจสอบภายหลังว่า vairable แบบโกลบอลเพื่อดูเทมเพลตที่รวมอยู่

คุณย่อมไม่ต้องการเส้นทางที่สมบูรณ์พร้อมกับไฟล์ดังนั้นฉันขอแนะนำให้ตัดทอนชื่อไฟล์โดยใช้basenameฟังก์ชั่นของ PHP

โค้ดตัวอย่าง:
สองฟังก์ชั่นหนึ่งตัวเพื่อตั้งค่าโกลบอลหนึ่งฟังก์ชันเพื่อเรียกใช้

add_filter( 'template_include', 'var_template_include', 1000 );
function var_template_include( $t ){
    $GLOBALS['current_theme_template'] = basename($t);
    return $t;
}

function get_current_template( $echo = false ) {
    if( !isset( $GLOBALS['current_theme_template'] ) )
        return false;
    if( $echo )
        echo $GLOBALS['current_theme_template'];
    else
        return $GLOBALS['current_theme_template'];
}

จากนั้นคุณสามารถโทรหาget_current_templateที่ใดก็ได้ที่คุณต้องการในไฟล์ธีมโดยสังเกตว่านี่เป็นเรื่องปกติที่จะเกิดขึ้นหลังจากที่template_includeการกระทำนั้นเริ่มต้นขึ้น (คุณไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งนี้หากมีการโทรภายในไฟล์เทมเพลต)

สำหรับเทมเพลตหน้าis_page_template()โปรดจำไว้ว่าจะช่วยได้เฉพาะในกรณีของเทมเพลตหน้า ( ฟังก์ชั่นตรวจจับทั้งหมดน้อยกว่า)

ข้อมูลเกี่ยวกับฟังก์ชั่นที่ใช้หรืออ้างอิงข้างต้น:


น่ากลัว! ฉันรู้ว่าต้องมีวิธีที่ง่ายกว่า
racl101

หนึ่งที่จะเพิ่มไปยังด้านบนของรายการฟังก์ชั่นการดีบักของฉัน
จูลส์

22

เห็นได้ชัดว่านี่เพียงพอแล้ว:

add_action('wp_head', 'show_template');
function show_template() {
    global $template;
    echo basename($template);
}

หรือเพียงแค่ใช้โดยตรงในแม่แบบ (ฉันมักจะสะท้อนใน footer.php ในความคิดเห็น HTML)

<?php global $template; echo basename($template); ?>

1
ที่จะไม่ทำงานกับ get-template-part เพียงเพื่อให้คุณรู้ว่ามันจะแสดง single.php (ตัวอย่าง) และไม่ใช่ไฟล์ที่อยู่ในนั้น
m-torin

ใช่มันเป็นความจริง. ในการรับชื่อไฟล์ที่รวมคุณอาจต้องใช้สิ่งนี้echo __FILE__;
chodorowicz

นี่เป็นเรื่องปกติตัวอย่างเช่นในกรณีที่คุณแก้ไขเทมเพลตเริ่มต้นโดยไม่ต้องกำหนดให้กับโพสต์ใน BackOffice ตัวอย่างเช่นการใช้เส้นทางที่กำหนดเองและตัวกรอง template_include ขอขอบคุณ.
Luca Reghellin

ฉันจะทำสิ่งนี้ภายในวงได้อย่างไร ฉันพยายามที่จะส่งออก URL ไปยังหน้าหนึ่งของแต่ละไฟล์แม่แบบ
JacobTheDev

@JacobTheDev อาจจะใช้echo __FILE__- เนื่องจากวิธีนี้ใช้ไม่ได้จะแสดงเฉพาะเทมเพลตเริ่มต้นหลักเท่านั้น
chodorowicz

17

ระหว่างฟังก์ชั่น WP ดั้งเดิมเช่นget_template_part ()และ Native ของ PHP มีวิธีที่เชื่อถือได้มากที่สุดในการดูไฟล์ของธีมที่ใช้คือดึงรายการของไฟล์ที่รวมทั้งหมดและกรองสิ่งที่ไม่ได้เป็นของธีม (หรือชุดรูปแบบ :

$included_files = get_included_files();
$stylesheet_dir = str_replace( '\\', '/', get_stylesheet_directory() );
$template_dir   = str_replace( '\\', '/', get_template_directory() );

foreach ( $included_files as $key => $path ) {

    $path   = str_replace( '\\', '/', $path );

    if ( false === strpos( $path, $stylesheet_dir ) && false === strpos( $path, $template_dir ) )
        unset( $included_files[$key] );
}

var_dump( $included_files );

9

นอกจากนี้ (รหัสหวานมากขึ้น) คำตอบอื่น ๆ ที่นี่

ชื่อเทมเพลต

หากต้องการรับชื่อเทมเพลตหน้าปัจจุบันให้ใช้บรรทัดต่อไปนี้

is_page() AND print get_page_template_slug( get_queried_object_id() );

ชื่อไฟล์

เมื่อคุณต้องการสะท้อนชื่อไฟล์เทมเพลตปัจจุบันให้ไปกับสิ่งต่อไปนี้

แก้ไข:นี่คือปลั๊กอินเวอร์ชันใหม่ที่รวมอยู่ในคลาส จะแสดงทั้งชื่อไฟล์เทมเพลตปัจจุบันรวมถึงชื่อไฟล์ลำดับชั้นของเทมเพลตใน hook การปิดระบบที่ด้านล่างสุดของหน้า

ปลั๊กอินบอกอะไรคุณ:

  • เทมเพลตมาจากพาเรนต์ของธีมลูก / ธีมปัจจุบันหรือไม่?
  • เทมเพลตให้บริการจากโฟลเดอร์ย่อยหรือไม่ ถ้าใช่: บอกชื่อคุณ
  • ชื่อไฟล์เทมเพลต

เพียงแค่คัดลอกรหัสต่อไปนี้ไปยังไฟล์และตั้งชื่อwpse10537_template_info.phpอัปโหลดไปยังไดเรกทอรีปลั๊กอินของคุณและเปิดใช้งาน

<?php
/** Plugin Name: (#10537) »kaiser« Get Template file name */

if ( ! class_exists( 'wpse10537_template_name' ) )
{
    add_action( 'plugins_loaded', array( 'wpse10537_template_name', 'init' ) );

class wpse10537_template_name
{
    protected static $instance;

    public $stack;

    public static function init()
    {
        is_null( self :: $instance ) AND self :: $instance = new self;
        return self :: $instance;
    }

    public function __construct()
    {
        if ( is_admin() )
            return;

        add_action( 'wp', array( $this, 'is_parent_template' ), 0 );
        add_action( 'wp', array( $this, 'get_template_file' ) );
        add_action( 'template_include', array( $this, 'get_template_name' ) );
        add_action( 'shutdown', array( $this, 'get_template_name' ) );
    }

    public function get_template_name( $file )
    {
        if ( 'template_include' === current_filter() )
        {
            $this->to_stack(
                 "Template file"
                ,basename( $file )
            );
            return $file;
        }

        // Return static var on echo call outside of filter
        if (
            current_user_can( 'manage_options' )
            AND defined( 'WP_DEBUG' )
            AND WP_DEBUG 
        )
            return print implode( " &ndash; ", $this->stack );
    }

    public function get_template_file()
    {
        if ( ! is_post_type_hierarchical( get_post_type() ) )
            return;

        $slug = get_page_template_slug( get_queried_object_id() );
        if ( ! strstr( $slug, "/" ) )
            return $this->to_stack( "Template", $slug );

        $this->to_stack(
             "Subdirectory"
            ,strstr( $slug, "/", true )
        );

        $this->to_stack(
             "Template (in subdirectory)"
            ,str_replace( "/", "", strstr( $slug, "/" ) )
        );
    }

    public function is_parent_template()
    {
        if ( ! is_null( wp_get_theme()->parent ) )
            return $this->to_stack( 'from parent theme' );

        $this->to_stack( 'from current/child theme' );
    }

    public function to_stack( $part, $item = '' )
    {
        $this->stack[] = "{$part}: {$item}";
    }
} // END Class wpse10537_template_name

} // endif;

ปลั๊กอินนี้สามารถเรียกใช้เป็น MU-Plugin ได้เช่นกัน

จากนั้นคุณสามารถโทรไปwpse10537_get_template_name()ที่จุดใดก็ได้ (ตัวอย่างเช่นในแม่แบบชุดรูปแบบ) สิ่งนี้จะหลีกเลี่ยงความยุ่งเหยิงใน namespace ทั่วโลก


1
template_redirecttemplate_includeไม่ได้ผ่านอะไรผมคิดว่าคุณมีความสับสนกับ นอกจากนี้ฉันจะตรวจสอบว่าภายในตัวกรองแทนที่จะเป็น var แบบคงที่ หากโค้ดบางตัวตัดสินใจที่จะรันการต่อเวลาเพิ่มเติมอาจทำให้สิ่งต่างๆเสียหาย
Rarst

@Rarst Done / Fixed ขอบคุณสำหรับคำใบ้และชี้ให้เห็นชื่อตัวกรอง
ไกเซอร์

5

ชื่อเทมเพลตถูกเก็บไว้ในตาราง postmeta ดังนั้นสิ่งที่คุณต้องทำคือใส่ที่อื่นไว้ในลูป:

$template = get_post_meta( $post->ID, '_wp_page_template', true );
echo "Template: " . $template;

2
ใช่ฉันรู้เรื่องนี้แล้ว แต่ปัญหาคือมันทำงานได้ก็ต่อเมื่อหน้ามีเทมเพลตชุด สิ่งดีๆเกี่ยวกับรหัสผมโพสต์ก็คือว่ามันจะบอกคุณว่าหน้าปัจจุบันคือการใช้front-page.php, index.php, single.php, page.phpหรือไฟล์อื่น ๆ รหัสของคุณแสดงชื่อเทมเพลตสำหรับหน้าเว็บที่มีเทมเพลตหน้ากำหนดเองเท่านั้น
chodorowicz

อ๊ะขอโทษ - ความเข้าใจผิดของคำถามของคุณ
Simon Blackbourn

@SimonBlackbourn มันช่วยฉันได้ ขอบคุณ
KarSho

3

สิ่งนี้ไม่ได้ตอบคำถามของ OP ทั้งหมด แต่รหัสด้านล่างนั้นดูดีกว่าการแสดงออกปกติและการแยกไฟล์เทมเพลตอย่างแน่นอน

หากคุณอยู่ในเพจที่ใช้เทมเพลทของเพจและคุณต้องการรับชื่อเทมเพลทของเพจ (เช่นชื่อที่มนุษย์สามารถอ่านได้ซึ่งคุณกำหนดไว้ในความคิดเห็นที่ด้านบนของไฟล์ PHP เทมเพลตของคุณ) คุณสามารถใช้ นักเก็ตตัวน้อยนี้:

if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
    $templates = wp_get_theme()->get_page_templates();
    $template_name = $templates[$current_template];
}

ฉันต้องการได้รับชื่อเทมเพลตเพราะฉันเบื่อกับชื่อคลาสโง่ ๆ ที่body_classฟังก์ชันWordPress ในตัวสร้างขึ้นเมื่อคุณใช้เทมเพลต โชคดีที่มีตะขอตัวกรองที่ท้ายสุดของฟังก์ชั่นเพื่อให้คุณต่อท้ายชื่อคลาสของคุณเองได้เช่นกัน นี่คือตัวกรองของฉัน หวังว่าใครบางคนพบว่ามันมีประโยชน์:

add_filter( 'body_class', 'gs_body_classes', 10, 2 );
function gs_body_classes( $classes, $class ){
    if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
        $templates = wp_get_theme()->get_page_templates();
        $template_name = str_replace( " ", "-", strtolower( $templates[$current_template] ) );

        $classes[] = $template_name;
    }

    return $classes;
}

ตัวกรองนี้จะใช้สิ่งที่คุณตั้งชื่อเทมเพลตหน้าแทนที่ช่องว่างด้วยขีดกลางและทำทุกอย่างให้เล็กลงเพื่อให้ดูเหมือนกับคลาส WordPress อื่น ๆ ทั้งหมด


0

มีปัญหากับpreg_match_allสาย ลองใช้สิ่งนี้แทน:

preg_match_all("/Template Name:(.*)\n/siU",$template_contents,$template_name);

นอกจากนี้คุณสามารถใช้if (!is_admin()) { .... }เพื่อเรียกใช้สิ่งต่าง ๆ ในส่วนหน้าเท่านั้น


ขอขอบคุณสำหรับข้อเสนอแนะพวกเขาไม่ได้แก้ปัญหา แต่พวกเขาบอกให้ฉันเข้าไปแก้ปัญหา ปรากฎว่า WP ในขณะที่สร้างรายการแม่แบบกำลังมองหาแม้กระทั่งในการfunctions.phpค้นหา"/Template Name:(.*)\n/siU"และจึงถือว่าfunctions.phpเป็นไฟล์แม่แบบ ฉันคิดว่านี่เป็นข้อผิดพลาด WP มันไม่ควรแม้แต่จะดูไฟล์นี้ วิธีการแก้ปัญหา: ย้ายไฟล์ไปยังไดเรกทอรีย่อย
chodorowicz

@chodorowicz: นั่นไม่ใช่ข้อผิดพลาดใน WP มันเป็นข้อบกพร่องในการทำงานของคุณ
wyrfel

ดังนั้นโดยทั่วไป WP ห้ามไม่ให้คุณใส่สตริง "ชื่อเทมเพลต:" (แม้ในความคิดเห็น) ในfunctions.phpไฟล์ สำหรับฉันโดยส่วนตัวแล้วนั่นเป็นข้อผิดพลาด (เล็ก แต่อย่างไรก็ตาม) แต่นั่นก็ขึ้นอยู่กับการอภิปรายฉันคิดว่า ฉันคิดว่าคุณไม่สามารถพูดได้ว่าฟังก์ชั่นของตัวเองเป็นรถ
chodorowicz

WP ไม่ได้ห้ามให้คุณทำอะไร แต่ WP ก็ไม่ได้สัญญากับคุณว่าคุณสามารถวนซ้ำ debug_backtrace () เพื่อค้นหาไฟล์เทมเพลตที่คุณใช้งานอยู่ เพียงเพราะคุณพบในฟอรัมการสนับสนุน WP ไม่ได้หมายความว่ามันเป็นรหัสที่ได้รับการสนับสนุนอย่างเป็นทางการ อย่างที่คุณเห็นฟังก์ชั่นของคุณจะอธิบาย footer.php อย่างชัดเจน คุณอาจเพิ่มเงื่อนไขอื่นที่ไม่รวมฟังก์ชั่น BTW: ฟังก์ชั่นของคุณไม่ได้มองหาTemplate Nameภายในแต่ละไฟล์วนรอบของคุณสิ้นสุดลงก่อนหน้านั้นนานมาก
wyrfel

ปัญหาไม่ได้อยู่กับdebug_backtrace()- ฉันสามารถลบรหัสทั้งหมดและเพียงแค่ปล่อยpreg_match_all("/Template Name...หรือแม้แต่// Template Name:และเพียงแค่WP และถือว่าfunctions.phpเป็นไฟล์เทมเพลต แต่ขอบคุณสำหรับความคิดเห็น - นี่เป็นปัญหาที่ไม่ซ้ำกันที่คุณพูดว่ามันไม่ยุติธรรมที่จะพูด มันเป็นข้อผิดพลาด วิธีแก้ปัญหา t31os สะอาดและแก้ไขปัญหาทั้งหมด ทักทาย
chodorowicz

0

เล่นพร้อมกับ:

echo '<ul><li>'.implode('</li><li>', str_replace(str_replace('\\', '/', ABSPATH).'wp-content/', '', array_slice(str_replace('\\', '/', get_included_files()), (array_search(str_replace('\\', '/', ABSPATH).'wp-includes/template-loader.php', str_replace('\\', '/', get_included_files())) + 1)))).'</li></ul>';

เขียนเมื่อ:

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

หากadmin-bar stuffเส้นทางแสดงที่ด้านบนหรือไฟล์อื่นให้เปลี่ยนชื่อไฟล์template-loader.phpในบรรทัดของรหัสนี้เป็น: ชื่อไฟล์อะไรก็ตามที่คุณต้องแยกออก

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

add_action('admin_bar_menu', 'my_adminbar_template_monitor', -5);

ลำดับความสำคัญ-5ทำให้ shure โหลดได้ก่อน กุญแจสำคัญคือการแสดงบรรทัดนี้ในเวลาที่เหมาะสม

มันจะไม่ส่งคืนเท็มเพลตไฟล์ "ปัจจุบัน" แต่จะใช้ไฟล์ปัจจุบันทั้งหมดสำหรับการโหลดหน้าปัจจุบัน อาจจะ "ตัดออก" ด้วยตรรกะบางอย่างจากความคิดนั้น

get_included_files()"ล่าสุด" ที่สำคัญคือการลงทะเบียนรวมถึงไฟล์ที่ผ่านมา propably สุดท้ายแม่แบบไฟล์ / -part ใช้ในส่วนท้ายโดยเครื่องมือแถบด้านข้างหรือบางสิ่งบางอย่าง เป็นไปได้ว่าไฟล์ที่รวม cos mutiple ไม่ได้ลงทะเบียน / เติมใหม่อีกครั้งใน get_included_files ()

มิฉะนั้นความตั้งใจจะต้องชัดเจนเพื่อแฮ็คปัญหานี้ มีวิธีการรวมไฟล์ที่จะรายงานตัวเองไม่เป็นที่รวมจนกว่าจะได้รับการรวม จากนั้นเป็นไปได้ช้าที่จะใช้สถานการณ์

ส่วนใหญ่ของ "เวลา" ที่คุณจะต้องการ:

$template = get_current_loaded_template();
if($template == 'single-product.php') add_filter('the_title' ....
if($template == 'format-gallery.php') add_action('post_thumbnail' ....

แต่ thats ไปไม่ได้get_template_partถ้าแม่แบบที่มีการโหลดนอกวิธีการหลักของ Wordpress ออกแบบความต้องการของคุณใหม่! บางทีloop_start(), in_the_loop()และadd_action('the_post')มีวิธีการแก้ปัญหาที่คุณต้องการแก้ไขข้อมูลขึ้นอยู่กับแม่แบบ thats จะโหลดสำหรับแต่ละรายการภายในวง


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