เทมเพลตชนิดโพสต์แบบกำหนดเองจากโฟลเดอร์ปลั๊กอินหรือไม่


57

ฉันต้องการเสนอประเภทโพสต์ที่กำหนดเองเป็นปลั๊กอินเพื่อให้ผู้ใช้สามารถใช้งานได้โดยไม่ต้องแตะที่โฟลเดอร์ธีมของพวกเขา แต่เทมเพลตประเภทโพสต์ที่กำหนดเอง - เช่นเดียวภาพยนตร์ movies.php - อยู่ในโฟลเดอร์ชุดรูปแบบ มีวิธีที่จะทำให้ WP ตรวจสอบ single-movies.php ในโฟลเดอร์ปลั๊กอินหรือไม่? เชื่อมโยงฟังก์ชันเข้ากับลำดับชั้นของ Filerหรือไม่ หรือ get_template_directory (); ?

คำตอบ:


90

คุณสามารถใช้single_templateตะขอตัวกรอง

/* Filter the single_template with our custom function*/
add_filter('single_template', 'my_custom_template');

function my_custom_template($single) {

    global $post;

    /* Checks for single template by post type */
    if ( $post->post_type == 'POST TYPE NAME' ) {
        if ( file_exists( PLUGIN_PATH . '/Custom_File.php' ) ) {
            return PLUGIN_PATH . '/Custom_File.php';
        }
    }

    return $single;

}

มันเป็นคำตอบที่ยอดเยี่ยม ได้โปรดแบ่งปันฉันจะได้รับเบ็ดแม่แบบที่มีอยู่ทั้งหมดเช่น single_template
Gowri

6
@gowri ตัวกรองถูกเรียกใช้โดยget_query_template()ฟังก์ชัน มันเป็นตัวแปรตะขอดังนั้นส่วนแรก{$type}_templateจะเปลี่ยนไปขึ้นอยู่กับพารามิเตอร์ที่ถูกส่งผ่านไปยังฟังก์ชันนั้น ดูwp-include / template.phpสำหรับบางคนที่พบบ่อย
shea

บทช่วยสอนนี้ครอบคลุมถึงเบ็ด single_template พร้อมคำอธิบายที่ดี เมื่อคุณเข้าใจ hooks แล้วความคิดเห็นของ @ shea จะแนะนำวิธีที่ง่ายกว่าคำตอบของ @ Bainternet โดยใช้add_filter( 'single-movies_template', 'my_custom_template' );ในบทช่วยสอนที่เชื่อมโยง (คำถามนี้จะปิดให้คำตอบใหม่ดังนั้นฉันไม่สามารถเพิ่มได้ในตัวของมันเอง.)
เกร็ก Perham

2
คุณสามารถแทนที่PLUGIN_PATHด้วยplugin_dir_path( __FILE__ )แล้วลบเครื่องหมายทับแรกจากชื่อไฟล์ของคุณ เส้นทางแบบเต็มจะมีลักษณะเช่นนี้:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits

1
PLUGIN_PATH โยนข้อผิดพลาดนี่เป็นโพสต์ที่ยอดเยี่ยมที่แสดงให้เห็นถึงวิธีการทำสิ่งนี้และมันได้ผลสำหรับฉัน: wpsites.net/free-tutorials/…
นาธาน

22

อัปเดตคำตอบ

เวอร์ชั่นที่สั้นกว่าและสะอาดกว่า

function load_movie_template( $template ) {
    global $post;

    if ( 'movie' === $post->post_type && locate_template( array( 'single-movie.php' ) ) !== $template ) {
        /*
         * This is a 'movie' post
         * AND a 'single movie template' is not found on
         * theme or child theme directories, so load it
         * from our plugin directory.
         */
        return plugin_dir_path( __FILE__ ) . 'single-movie.php';
    }

    return $template;
}

add_filter( 'single_template', 'load_movie_template' );

คำตอบเก่า

เพิ่มการตรวจสอบสำหรับเทมเพลตเฉพาะชนิดโพสต์ที่กำหนดเองในโฟลเดอร์ธีมให้กับ @Brainternet คำตอบ

function load_cpt_template($template) {
    global $post;

    // Is this a "my-custom-post-type" post?
    if ($post->post_type == "my-custom-post-type"){

        //Your plugin path 
        $plugin_path = plugin_dir_path( __FILE__ );

        // The name of custom post type single template
        $template_name = 'single-my-custom-post-type.php';

        // A specific single template for my custom post type exists in theme folder? Or it also doesn't exist in my plugin?
        if($template === get_stylesheet_directory() . '/' . $template_name
            || !file_exists($plugin_path . $template_name)) {

            //Then return "single.php" or "single-my-custom-post-type.php" from theme directory.
            return $template;
        }

        // If not, return my plugin custom post type template.
        return $plugin_path . $template_name;
    }

    //This is not my custom post type, do nothing with $template
    return $template;
}
add_filter('single_template', 'load_cpt_template');

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

ด้วยตัวอย่างนี้เท็มเพลตต้องอยู่ในไดเร็กทอรีรูทของทั้งปลั๊กอินและธีม


1
ใช้locate_templateแทนget_stylesheet_directoryเสียงเหมือนตัวเลือกที่สะอาดกว่าสำหรับฉัน (พบได้ที่นี่: code.tutsplus.com/tutorials/… )
เฟลิกซ์

1
คำตอบที่อัปเดตแล้วไม่ทำงานคำตอบที่ยอมรับ (หรือคำตอบเดิมของคุณ) ใช้งานได้
Edward

2
คุณพูดถูก @Edward นั่นเป็นการอัปเดตที่น่ากลัว ฉันอัปเดตอีกครั้งด้วยคำแนะนำของเฟลิกซ์ คราวนี้ฉันทดสอบโค้ดก่อนโพสต์ :)
campsjos

4

ฉันอยากจะชี้ให้เห็นว่าเมื่อคุณใช้วิธีการกรองสำหรับสิ่งนี้มันเป็นสิ่งสำคัญอย่างยิ่งที่จะต้องให้ความสำคัญกับตัวกรองดังนี้:

add_filter('single_template', 'my_custom_template', 99);

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


0

มีวิธีที่ดีกว่ามากในการทำสิ่งที่ฉันใช้สำหรับปลั๊กอินของฉัน

ดังที่@campjosพูดถึงที่นี่แทนที่จะตรวจสอบการมีอยู่ของไฟล์คุณอาจตรวจสอบlocate_templateว่าจะตรวจสอบในไฟล์เทมเพลตที่ overrode ของธีม ซึ่งค่อนข้างชัดเจน

function my_plugin_templates() {
    if (is_singular('movie')) {
        if (file_exists($this->template_dir . 'single-movie.php')) {
            return $this->template_dir . 'single-movie.php';
        }
    }
}

ใช้template_includeตัวกรองขอเพื่อโหลดโค้ดด้านบน

add_filter('template_include' , 'my_plugin_templates');

0

ขอบคุณหน้านี้ฉันสามารถแก้ปัญหาเดียวกันสำหรับฉัน

สำหรับการอ้างอิงนี่คือสิ่งที่ฉันลงเอยด้วย:

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';
  return get_post_type() === 'myposttype' && file_exists($myposttype_template) ? $myposttype_template : $single_template;
}
add_filter('single_template', 'pluginName_myposttype_single_template');

ตะขอตัวกรอง {$ type} _template ไม่ทำงานสำหรับฉัน

function pluginName_myposttype_single_template($single_template) {
  $myposttype_template = PLUGIN_DIR . 'templates/single-myposttype.php';

  if ( file_exists($myposttype_template) ) {
    $single_template = $myposttype_template;
  }
  return $single_template;
}
add_filter('single-myposttype_template', 'pluginName_myposttype_single_template');

-2

ด้านบนเป็นคำตอบที่ดี แต่การตรวจสอบ $ single var ช่วยให้เทมเพลตสามารถแทนที่เทมเพลตหากมีการจัดทำโดยธีม / ธีมลูก

/* Filter the single_template with our custom function*/
add_filter('single_template', 'your_cpt_custom_template');

function your_cpt_custom_template( $single ) {
    global $wp_query, $post;
    /* Checks for single template by post type */
    if ( !$single && $post->post_type == 'cpt' ) {
        if( file_exists( plugin_dir_path( __FILE__ ) . 'single-cpt.php' ) )
            return plugin_dir_path( __FILE__ ) . 'single-cpt.php';
    }
    return $single;
}

1
สิ่งนี้ไม่ได้ตรวจสอบว่า single-cpt.php มีอยู่ในชายด์หรือธีม มันจะตรวจสอบกับ single.php เท่านั้นซึ่งจะปรากฏในรูปแบบใด ๆ
newpxsn

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