Bagaimana saya bisa menambahkan opsi ke daftar Templat Halaman dari Plugin?

10

Saya telah mencari-cari beberapa jam terakhir untuk menemukan cara membuat templat halaman khusus dari dalam plugin tetapi belum beruntung.

Apa yang secara khusus saya coba lakukan adalah menambahkan opsi ke daftar template halaman yang tersedia saat mengedit halaman, dan tidak menggunakan beberapa metode lain sepertiif( is_page( 'page-slug' ) ) { /* etc */ }

Apakah ada variabel global yang dapat saya modifikasi untuk melakukan ini?

Edit:

Saya menggunakan kode ini saat ini, berdasarkan tautan @ m0r7if3r memberi saya dalam komentar, masalahnya adalah ia akan menjalankan fungsi ini ketika melihat halaman, tetapi tidak ketika mengedit halaman (untuk mengisi daftar dropdown dengan templat halaman) :

class JW_SiteGrader {

    private static $instance;

    private function __construct() {


        add_action( 'template_redirect', array( &$this, 'sitegrader_template_redirect' ), 20 );

    }

    public static function getInstance() {

        // Return the class data in a Singleton fashion
        if (self::$instance == null)
            self::$instance = new JW_SiteGrader();
        return self::$instance;

    }

    public function sitegrader_template_redirect() {

        add_filter( 'page_template', array( &$this, 'sitegrader_page_template' ), 10, 1 );

    }

    public function locate_plugin_template( $template_names, $load = false, $require_once = true ) {

        if ( !is_array( $template_names ) )
            return '';

        $located = '';

        $this_plugin_dir = WP_PLUGIN_DIR . '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) );

        foreach ( $template_names as $template_name ) {

            if ( !$template_name )
                continue;

            if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {

                $located = STYLESHEETPATH . '/' . $template_name;
                break;

            } else if ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {

                $located = TEMPLATEPATH . '/' . $template_name;
                break;

            } else if ( file_exists( $this_plugin_dir .  $template_name ) ) {

                $located =  $this_plugin_dir . $template_name;
                break;

            }

        }

        if ( $load && '' != $located )
            load_template( $located, $require_once );

        return $located;
    }

    public function sitegrader_page_template( $template ) {

        $object = get_queried_object();

        if ( 'page' == $object->post_type ) {

            // New 
            $templates[] = "page-sitegrader.php";
            // Like in core
            $templates[] = "page-{$object->post_type}.php";
            $templates[] = "page.php";

            return locate_template( $templates );  

        }

        // return apply_filters('page_template', $template);
        return $template;
    }

}

Edit 2:

Tampaknya fungsi ini akan dirilis dalam pembaruan di masa mendatang, saya membaca beberapa tiket trac tentang ini dan telah ada beberapa diskusi tetapi tidak ada jawaban nyata (berharap 3.4). Akan mencantumkan URL tiket trak di sini sebentar lagi.

Edit 3:

Kode di atas berfungsi, TETAPI, satu-satunya masalah yang saya alami saat ini adalah tidak ada template yang ditambahkan ke daftar dropdown ketika mengedit / menambahkan halaman baru. Saya mencoba beberapa hal dan akan segera memperbarui pertanyaan saya.

Jared
sumber
2
Sudahkah Anda mencoba yang seperti ini ?
mor7ifer
@ m0r7if3r (Jika Anda mencobanya, silakan tinggalkan pesan bagaimana cara kerjanya - Terima kasih!)
kaiser
@kaiser Saya mencoba kode yang dia rekomendasikan, satu - satunya tautan yang hilang adalah mendapatkan kotak meta untuk menambahkan templat ke daftar dropdown (sejauh yang saya tahu!).
Jared
@ Jared Lihatlah jawaban ini oleh saya untuk Q yang sama dan tiket trac terkait di bagian bawah a. Iklankan kode Anda) Jika tidak ditampilkan di setiap halaman, maka Anda menggunakan kait yang salah untuk menjalankan mesin virtual. Kait mana yang Anda gunakan?
kaiser
@kaiser Saya menggunakan page_templatehook, kode di atas dalam edit saya adalah apa yang sedang digunakan. Apakah saya perlu menggunakan template_redirectpengait dan kemudian menambahkan page_templatefilter di sana?
Jared

Jawaban:

4

Filter? Siapa saja?

Tidak ada filter di sana untuk membantu: page_template_dropdown($template);digunakan untuk membangun drop down dan tidak dapat difilter.

Menyelinap ke dalam Templat Array?

Untuk membangun konten drop-down, kotak meta inti menggunakan get_page_templates(). Dari dalam, fungsinya terlihat seperti berikut:

$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];

Tetapi ketika melihat ke get_themes();sana maka tidak ada kemungkinan untuk mencegat daftar template. Lebih jauh lagi kita memiliki masalah, bahwa tidak ada peluang untuk mendapatkan templat dari luar direktori tema ...

... Memalsukan Tema!

Teori dan kelemahannya ...

Anda dapat menggunakan register_theme_directory()untuk menambahkan direktori tema tambahan tempat Anda dapat menempatkan templat. Jadi yang termudah adalah mendaftarkan plugin Anda sebagai folder tema juga:

// Register during init hook:
register_theme_directory( plugin_dir_path( __FILE__ ).'templates' );

Catatan: Di sinilah saya tidak yakin apakah itu akan berhasil .

Selama aktivasi plugin: Maka Anda harus meletakkan style.css.phpfile di dalam templatesfolder Anda . Ini akan memungkinkan Anda untuk menambahkan variabel ke file Anda. Variabel ini kemudian akan menjadi tema induk. Dan tema induk seharusnya menjadi tema yang sedang aktif. Kemudian perbarui tema aktif Anda ke plugin Anda.

Kelemahan # 2: Tentang »Tampilan« UI ... Mungkin menambahkan catatan bahwa "Tema" ini tidak dimaksudkan untuk digunakan sebagai Tema aktual. Saya meninggalkan sisa »Hindari mengaktifkan tema ini« barang terserah imajinasi Anda. Pokoknya: Ini seharusnya bekerja.

Kelemahan # 2: Trik ini akan berhasil menghindari tema anak. Anda diizinkan memiliki satu tema orang tua. Tidak ada lagi.

kaisar
sumber
Jadi saya menduga bahwa tidak ada cara aktual untuk menggunakan templat halaman khusus dari setiap tema yang tidak aktif, benar? Saya bisa mendaftarkan direktori tema tetapi template tidak tersedia untuk digunakan kecuali tema itu aktif.
Jared
1
Tidak juga. Itu tidak seharusnya dan karena itu kurangnya inti. Sudahkah Anda mencoba tautan ke ipstenu di atas? Saya sudah mencoba menempuh rute itu tetapi berakhir dengan jalan buntu - dengan solusi lain. Taruhan terbaik adalah mengikuti tiket, mendorong & menautkannya di mana pun Anda berada. : /
kaiser
2

Sebagai saran untuk penyelesaian potensial, apakah Anda mempertimbangkan untuk menggunakan sistem file WordPress untuk menulis file templat halaman dari plugin Anda ke direktori tema aktif Anda saat ini? Bergantung pada seberapa besar kendali yang Anda inginkan atas proses ini, Anda dapat meminta plugin Anda menulis file saat aktivasi dan menghapusnya saat dihapus. Atau Anda bisa membuat file templat halaman secara dinamis dari dalam UI plugin Anda menggunakan formulir untuk memberikan nilai tertentu seperti nama templat halaman yang akan muncul di kotak dropdown layar edit posting. Anda juga bisa secara teori menghapus template halaman dari dalam UI plugin Anda dengan mengklik tombol dan juga menambahkan beberapa template untuk tujuan yang berbeda. Ada posting bagus tentang penggunaan sistem file di blog Otto. Saya tidak memiliki tautan dengan saya sekarang tetapi Anda dapat mencarinya.

Saya harap mereka merilis apa yang ingin Anda lakukan melalui hook pada rilis inti berikutnya.

Adam
sumber
1
Saya memiliki metode yang persis seperti ini berfungsi sebelumnya tetapi memiliki banyak masalah kembali ketika saya mencobanya, karena ketika pengguna akan beralih tema, itu tidak akan menghapus file templat dan jika mereka menyalin tema aktif mereka dan meletakkannya di situs yang berbeda , mereka akan berisiko mengunggah file templat khusus yang tidak akan berfungsi. Saya tahu ada beberapa solusi untuk itu, tetapi saya benar-benar ingin ini otomatis . +1 untuk saran.
Jared
1
Hai Jared, saya juga prihatin dengan masalah yang sama. Satu-satunya solusi yang saya bisa pikirkan untuk memperluas metode alternatif ini adalah dengan memiliki plugin setelah aktivasi mendapatkan nama tema saat ini maka jika pengguna menonaktifkan / beralih tema Anda dapat menghapus file template dari tema itu dan menulis ulang ke yang baru diaktifkan tema. Lihatlah tautan ini di mana ia membuat kait aktivasi / penonaktifannya sendiri untuk memeriksa tema. Dengan sedikit kode tambahan saya merasa ini bisa dilakukan.
Adam
Tentu saja, saya pikir itu bisa berhasil. Saya akan mencobanya dan memposting hasilnya di pertanyaan saya. Terima kasih atas tautannya, ini membantu!
Jared
1

Saya melihat-lihat sumbernya, dan cukup mengejutkan tidak ada cara untuk melakukan ini! Peretasan yang saya sarankan adalah menambahkan kotak meta kedua dengan override tema / dropdown tema kedua. Lalu kaitkan ke filter ini:

# wp-includes/theme.php line 751 in 3.3.1:
return apply_filters( "{$type}_template", locate_template( $templates ) );

untuk mengembalikan file tema Anda jika sudah diganti. Tentu saja, Anda hanya ingin menambahkan_filter jika itu adalah postingan yang Anda inginkan.

Jika Anda ingin menjadi mewah, Anda dapat memo kotak asli dan membuatnya kembali (tentu saja melalui filter, bukan memodifikasi kode inti).

Saya juga menyarankan menambahkan tiket trac meminta fungsionalitas itu (jika belum ada di sana untuk itu).

Matthew Boynes
sumber
1
setuju dengan menyarankan ini untuk trac.
Helgatheviking
Tampaknya sudah ada di trac: core.trac.wordpress.org/ticket/15803
Jared
1
Saya baru saja menyelidiki ini untuk Q lain tentang template jenis posting tunggal . Anda dapat menemukan Tiket Trac di akhir jawaban. Mari berharap 3.4.
kaiser
1

Saya telah melakukan ini di masa lalu dengan menghapus metabox templat halaman default dan kemudian menambahkan metabox Anda sendiri. Saya memiliki metabox baru menggunakan get_page_templates bawaan dan kemudian menambahkan yang lain yang saya butuhkan secara pemrograman. Dengan menyimpannya, ia dapat memperbarui templat halaman seperti halnya wordpress.

gruvii
sumber
Maukah Anda menunjukkan kode lengkap? Saat ini hanya konsep kasar. Terima kasih.
kaiser
1

Lihat kait theme_page_templates, yang digunakan oleh get_page_templatesfungsi, filter yang ditambahkan sejak 3.9 yang diperbarui di 4.4:

apply_filters( 'theme_page_templates', $page_templates, $this, $post );
William Gu
sumber
dijelaskan lebih lengkap di sini: wordpress.stackexchange.com/a/255820/75495
cjbj
-2

Hasil pencarian dengan DuckDuckGo menambahkan template halaman wordpress muncul jawaban untuk saya di halaman wpmu.org berjudul WordPress Custom Page Template Tutorial .

Pada dasarnya, di dalam direktori tema, wp-content / themes / your-theme , salin templat halaman yang ada ke nama file php baru pilihan Anda. Edit file baru, hati-hati untuk mengubah nilai properti "Template Name:" di komentar di bagian atas file.

Hanya itu yang ada di sana. Mungkin saja ini adalah fitur yang mengunggah tanggal pertanyaan. Saya menggunakan WP 3.5 dengan tema twenty_eleven.

Mungkin juga ada cara yang lebih bersih untuk memperluas tema. Pengeditan seperti ini mungkin ditimpa oleh pembaruan tema. MEA Culpa.

Douglas Lovell
sumber
Saya butuh solusi untuk menambahkan template ke daftar dropdown dari sebuah plugin, bukan tema. :(
Jared