Bagaimana cara menambahkan CSS khusus (opsi tema) ke TinyMCE?

14

Saya mencoba untuk menambahkan CSS khusus (diatur melalui opsi tema) ke editor visual TinyMCE di WordPress. Di ujung depan, tema menghasilkan CSS ini dan menampilkannya di wp_headhook. Masalah yang saya hadapi adalah bisa menambahkan output CSS ke editor.

Ini tidak dapat dilakukan dengan add_editor_style( 'editor-style.css' )karena kita perlu menggunakan PHP untuk mengakses opsi tema.

Sebagai contoh cara kerjanya di ujung depan:

add_action( 'wp_head', 'my_custom_colors' );

function my_custom_colors() {
    $color_1 = get_theme_mod( 'color_1', 'cc4a00' );

    echo "<style type='text/css'>a { color: #{$color_1}; }";
}

Saya perlu metode untuk memasukkan gaya khusus ke editor visual. Bantuan apa pun akan sangat dihargai.

Justin Tadlock
sumber
1
Catatan: CSS pasca-konten khusus adalah Territory Plugin , dan tidak boleh diletakkan di Tema. Jika tidak, pengguna akan kehilangan CSS khusus saat beralih ke Tema yang berbeda.
Chip Bennett
@ChipBennett Saya hanya setuju sebagian. Ini sangat tergantung pada apa yang Anda gaya. Selain itu, tidak masalah di mana tempatnya (untuk pertanyaan itu).
kaiser
@ChipBennett Ini ada hubungannya dengan gaya tema, bukan CSS konten pos kustom. Ini adalah hal standar yang dapat Anda lakukan dengan penyesuai tema. Itu hanya menerapkan gaya-gaya yang membuat saya bingung. Itu dimaksudkan untuk pujian editor-style.css, yang merupakan wilayah tema.
Justin Tadlock
Tunggu: apakah Anda berbicara tentang gaya editor kustom dinamis ? Seperti pada: buat editor visual (TinyMCE) mengetahui gaya yang ditentukan opsi Tema? Jika demikian, abaikan komentar asli saya, dan +1 untuk pertanyaannya.
Chip Bennett
Bisakah Anda mengajukan suntingan dan menunjukkan contoh set lengkap untuk gaya tema? Akan lebih mudah untuk diuji.
kaiser

Jawaban:

7

Solusi 1

Ini berfungsi sebagai solusi javascript:

Contoh:

tinyMCE.activeEditor.dom.addStyle('p {color:red; font-size:28px;}');

cukup buka konsol js Anda dan rekatkan untuk tes cepat. Untuk menargetkan editor tertentu, seseorang harus menggunakan:

tinyMCE.getInstanceById('##editorID##').dom.addStyle('p {color:red; font-size:28px;}');

Ini akan menyuntikkan string yang disediakan ke editor iframe <head><style id="mceDefaultStyles"></style> ...

Solusi 2

Gunakan wp_ajax sebagai penangan panggilan balik untuk menambahkan gaya dinamis pada editor init dengan menggunakan filter

add_filter('tiny_mce_before_init', 'dynamic_editor_styles', 10);

function dynamic_editor_styles($settings){
    // you could use a custom php file as well, I'm using wp_ajax as
    // callback handler for demonstration
    // content_css is a string with several files seperated by a comma
    // e.g. file1, file2, ... extend the string

    $settings['content_css'] .= ",".admin_url('admin-ajax.php') ."/?action=dynamic_styles";

    return $settings;
}

// add wp_ajax callback
add_action('wp_ajax_dynamic_styles', 'dynamic_styles_callback');
function dynamic_styles_callback(){
    echo "p {color:red} h1{font-size:48px;}";
}
ungestaltbar
sumber
2
Saya tidak sepenuhnya yakin apa yang harus dilakukan dengan itu.
Justin Tadlock
Solusi # 2 sebenarnya sangat masuk akal bagi saya. Saya akan memberikan tes itu.
Justin Tadlock
Saya pergi dengan solusi # 2. Perbedaannya adalah bahwa saya menjatuhkan fungsi pertama dan digunakan add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )karena ini adalah cara standar untuk tema untuk menambahkan gaya editor.
Justin Tadlock
Hanya untuk membangun saya sendiri, saya ingin tahu jika mce_cssberhasil untuk Anda (jika Anda mencobanya).
Chip Bennett
Sebenarnya saya belum mencobanya karena saya tahu Anda bisa mengirimkan file non-CSS add_editor_style(), tetapi seharusnya berfungsi dengan baik melihat kode. Menggunakan mce_csssebenarnya adalah solusi yang lebih baik jika Anda perlu menghubungkan setelah gaya ditambahkan melalui add_editor_style(). Salah satu alasan seperti itu dalam sebuah tema adalah karena URL lengkap yang ditambahkan via add_editor_style()adalah keluaran pertama, meskipun urutannya ditambahkan.
Justin Tadlock
10

WordPress menyediakan mce_cssfilter , yang dapat digunakan untuk menambahkan stylesheet khusus ke Editor Visual. Menurut Codex:

File tersebut dapat berupa file .php, memungkinkan pembuatan aturan CSS dinamis untuk editor konten.

Contoh panggilan balik filter Codex, dimodifikasi untuk suatu Tema:

function wpse120831_mce_css( $mce_css ) {
    if ( ! empty( $mce_css ) )
        $mce_css .= ',';

    $mce_css .= get_template_directory_uri() . '/dynamic-css.php';

    return $mce_css;
}

add_filter( 'mce_css', 'wpse120831_mce_css' );
Chip Bennett
sumber
Mr.Bennett lebih cepat, hanya menambahkan itu ke jawaban saya di bawah ini juga :), tetapi sedikit berbeda.
ungestaltbar
@ungestaltbar kita sebenarnya menggunakan dua filter yang sama sekali berbeda. :)
Chip Bennett
dengan hasil yang sama :)
ungestaltbar
4

Saya menerima solusi di atas oleh @ungestaltbar. Namun, saya ingin sedikit memperluas jawaban ini dengan solusi lengkap yang saya gunakan sehingga orang lain dapat melihat cara kerjanya.

add_action( 'after_setup_theme', 'my_theme_setup' );

function my_theme_setup() {

    add_editor_style(
        array(
            'editor-style.css',
            add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) ),
        )
    );
}

add_action( 'wp_ajax_my_editor_styles', 'my_editor_styles_callback' );
add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );

function my_editor_styles_callback() {

    // @todo sanitize
    $color_1 = get_theme_mod( 'color_1', 'cc4a00' );

    echo "a { color: #{$color_1}; }";

    die();
}

Saya harap tidak apa-apa untuk mengirim jawaban lain di sini seperti ini. Saya tidak melihat cara memposting ini sebagai jawaban langsung untuk solusi yang saya terima. Saya masih belajar cara menggunakan WPSE.

Justin Tadlock
sumber
Mungkin Anda harus menambahkan add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );jika editor digunakan di frontend (untuk pengguna yang tidak masuk).
OriginalEXE
Ya, jawaban dengan perubahan signifikan / penyesuaian sangat baik. :) FYI jika sudah selesai beberapa masalah untuk diperbaiki dalam jawaban asli maka mengirimkan edit untuk itu akan menjadi cara untuk pergi.
Rarst
@OriginalEXE - Yap. Saya akan memperbaruinya.
Justin Tadlock
Hanya tip untuk orang lain yang menemukan ini nanti, saya tidak dapat membuat ini berfungsi sebagaimana mestinya. Saya akhirnya tahu bahwa saya harus memasukkan informasi header di callback, sehingga akan terlihat sebagai css. header ("Tipe konten: teks / css; charset: UTF-8"); Tidak yakin apakah ini sesuatu yang berbeda di .htaccess saya atau apa.
SkyShab
4

Saya mungkin terlambat ke pesta ini, tetapi setelah menggunakan solusi di atas, saya segera menyadari bahwa kecepatan memuat halaman dari editor telah sangat lumpuh! Melihat tajam pada kode, saya menyadari bahwa kode terus mengeksekusi lama setelah tinyMCE.activeEditor telah diinisialisasi. Kode menggunakan metode setInterval () yang mengevaluasi ekspresi pada interval yang ditentukan, saya percaya itu karena Anda tidak dapat menentukan pada titik mana selama eksekusi kode "activeEditor" akan tersedia. Inilah yang membuat kecepatan halaman berlutut.

Solusi yang jauh lebih baik yang saya gunakan untuk membangun sebuah plugin adalah ini

   /**
     * Extend TinyMCE config with a setup function.
     * See http://www.tinymce.com/wiki.php/API3:event.tinymce.Editor.onInit

     */
    function custom_tinymce_css($init) {

      $css = get_option('some_css'); 

     ?>

        <script type="text/javascript">            

            function addTempCSS( ed ) {
                ed.onInit.add( function() {
                    tinyMCE.activeEditor.dom.addStyle(<?php echo json_encode($css) ?>);
                } );
            };
        </script>

        <?php
        if (wp_default_editor() == 'tinymce')
            $init['setup'] = 'addTempCSS';

        return $init;
    }
    add_filter('tiny_mce_before_init', 'custom_tinymce_css');

Di sini pendengar TinyMCE asli digunakan untuk mengeksekusi kode setelah editor aktif diinisialisasi. Saya harap ini akan membantu seseorang di luar sana. Salam.

Ayebare M
sumber
1
Ini bekerja untuk saya. Itu hanya memiliki panggilan API yang sudah usang di tinymce 4.0 Anda perlu mengubah ed.onInit.add (function () {... ke ed.on ('init', function () {...
Mohammed
1

Ini adalah solusi yang dimodifikasi yang diposting di forum WordPress.org untuk pertanyaan ini: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573

Ini pasti berhasil. Saya bukan guru JS, jadi saya tidak sepenuhnya yakin apakah ini solusi terbaik.

add_action( 'before_wp_tiny_mce', 'my_tinymce_callback' );

function my_tinymce_callback() {

    $color_1 = get_theme_mod( 'color_1', 'cc4a00' ); ?>

    <script type="text/javascript">
    jQuery( document ).ready(

        function() {
            var my_style = 'a { color: #<?php echo $color_1; ?>; }';

            var checkInterval = setInterval(
                function() {

                    if ( 'undefined' !== typeof( tinyMCE ) ) {
                        if ( tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) {

                            jQuery( '#content_ifr' ).contents().find( 'head' ).append( '<style type="text/css">' + my_style + '</style>' );

                            clearInterval( checkInterval );
                        }
                    }
                }, 
                500 
            );
        }
    );
    </script>
<?php }

Ini juga dapat ditambahkan ke file JS. Anda bisa dengan mudah melewatkan variabel melalui wp_localize_script()itu.

Justin Tadlock
sumber