Templat Jenis Pos Kustom dari Folder Plugin?

57

Saya ingin menawarkan jenis posting khusus saya sebagai Plugin, sehingga orang dapat menggunakannya tanpa menyentuh folder tema mereka. Tetapi templat jenis kiriman khusus - seperti single-movies.php - berada di folder tema. Apakah ada cara untuk mendapatkan WP untuk memeriksa single-movies.php di folder plugin? Menghubungkan fungsi ke Hierarki Filer ? Atau get_template_directory (); ?

nathanbweb
sumber

Jawaban:

90

Anda dapat menggunakan single_templatehook filter.

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

}
Bainternet
sumber
Ini jawaban yang luar biasa. Silakan bagikan apakah saya bisa mendapatkan semua templat yang tersedia kait seperti single_template.
Gowri
6
@gowri Filter dipanggil oleh get_query_template()fungsi. Ini adalah pengait variabel, jadi bagian pertama {$type}_templateberubah tergantung pada parameter apa yang diteruskan ke fungsi itu. Lihat wp-include / template.php untuk beberapa yang umum
shea
Tutorial ini mencakup pengait single_template dengan penjelasan yang baik. Setelah Anda memahami kaitannya, komentar @ shea menyarankan pendekatan yang lebih sederhana daripada jawaban @ Bainternet, menggunakan add_filter( 'single-movies_template', 'my_custom_template' );seperti dalam tutorial tertaut. (Pertanyaan ini tertutup untuk jawaban baru, jadi saya tidak bisa menambahkannya sendiri.)
Greg Perham
2
Anda bisa mengganti PLUGIN_PATHdengan plugin_dir_path( __FILE__ )dan kemudian menghapus garis miring pertama dari nama file Anda. Path lengkap akan terlihat seperti ini:return plugin_dir_path( __FILE__ ) . 'Custom_File.php';
Frits
1
PLUGIN_PATH melontarkan kesalahan, inilah pos yang bagus yang menunjukkan cara melakukan ini dan berhasil bagi saya di luar kotak: wpsites.net/free-tutorials/...
Nathan
22

Jawaban yang diperbarui

Versi lebih bersih dan lebih pendek.

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

Jawaban lama

Menambahkan tanda centang untuk templat khusus jenis kiriman khusus di folder tema ke jawaban @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');

Sekarang Anda dapat membiarkan pengguna plugin menyalin template dari plugin Anda ke tema mereka untuk menimpanya.

Dengan contoh ini, templat harus berada di direktori root dari plugin dan tema.

campsjo
sumber
1
Menggunakan locate_templatedaripada get_stylesheet_directoryterdengar seperti opsi pembersih bagi saya (ditemukan di sini: code.tutsplus.com/tutorials/… ).
Felix
1
Jawaban yang diperbarui tidak berfungsi, jawaban yang diterima (atau jawaban lama Anda) berfungsi.
Edward
2
Anda benar, @Edward, itu adalah pembaruan yang menghebohkan. Saya memperbaruinya lagi dengan saran Felix. Juga kali ini saya menguji kode sebelum mempostingnya :)
campsjos
4

Saya ingin menunjukkan bahwa ketika Anda menggunakan metode filter untuk ini, sangat penting untuk memprioritaskan filter seperti:

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

Jika Anda tidak melakukan ini, terkadang WP akan mencoba untuk memeriksa kembali setelah filter ini. Sedang mencabut rambut saya karena ini selama 2 jam.

RBizzle
sumber
0

Ada banyak cara yang lebih baik untuk melakukannya yang saya gunakan untuk plugin saya.

Seperti @campsjos sebutkan di sini , alih-alih pemeriksaan keberadaan file, Anda dapat memeriksa locate_templateyang akan memeriksa ke dalam file templat tema overrode. Yang cukup jelas.

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

Gunakan template_includekait filter untuk memuat kode di atas.

add_filter('template_include' , 'my_plugin_templates');
pixelngrain
sumber
0

berkat halaman ini saya bisa menyelesaikan pertanyaan yang sama untuk saya.

Untuk referensi, inilah yang akhirnya saya dapatkan:

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

kait filter {$ type} _template tidak berfungsi untuk saya

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');
Thomas Fellinger
sumber
-2

Di atas adalah jawaban yang bagus, tetapi memeriksa $ var tunggal memungkinkan template untuk menimpa template jika disediakan oleh tema / tema anak.

/* 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;
}
DigitalDesignDj
sumber
1
Ini tidak memeriksa apakah single-cpt.php hadir pada anak atau tema. Itu hanya memeriksa terhadap single.php yang akan selalu hadir dalam tema apa pun.
newpxsn
Itu benar, ketika saya menulis ini saya menggunakan tema yang benar-benar telanjang, pasti ada cara yang lebih baik!
DigitalDesignDj