web-dev-qa-db-fra.com

Comment ajouter des CSS personnalisés (option de thème) à TinyMCE?

J'essaie d'ajouter des CSS personnalisés (définis via des options de thème) à l'éditeur visuel TinyMCE dans WordPress. Sur le front-end, le thème génère ce CSS et le sort sur le hook wp_head. Le problème que je rencontre est de pouvoir ajouter cette sortie CSS à l'éditeur.

Cela ne peut pas être fait avec add_editor_style( 'editor-style.css' ) car nous devons utiliser PHP pour accéder à l'option de thème.

Comme exemple de la façon dont cela fonctionne sur le front-end:

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}; }";
}

J'ai besoin d'une méthode pour obtenir ce style personnalisé dans l'éditeur visuel. Toute aide serait grandement appréciée.

13
Justin Tadlock

Solution 1

Cela fonctionne comme une solution javascript:

Exemple:

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

ouvrez simplement votre console js et collez-la pour un test rapide. Pour cibler un éditeur spécifique, il faut utiliser:

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

Ceci injectera la chaîne fournie dans les éditeurs iframe <head><style id="mceDefaultStyles"></style> ...

Solution 2

Utilisez wp_ajax comme gestionnaire de rappel pour ajouter des styles dynamiques sur l'éditeur init à l'aide d'un filtre.

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;}";
}
7
ungestaltbar

WordPress fournit un filtre mce_css , qui peut être utilisé pour ajouter des feuilles de style personnalisées à l'éditeur visuel. Selon le Codex:

Le fichier peut être un fichier .php, permettant la génération dynamique de règles CSS pour l'éditeur de contenu.

Exemple de rappel de filtre Codex, modifié pour un thème:

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' );
9
Chip Bennett

J'ai accepté la solution ci-dessus par @ungestaltbar. Cependant, je voulais développer un peu cette réponse avec la solution complète que j'utilise, afin que d'autres puissent voir comment elle fonctionne.

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();
}

J'espère que ça ira pour poster une autre réponse comme celle-ci. Je n'ai pas vu de moyen de poster cela en réponse directe à ma solution acceptée. J'apprends encore comment utiliser WPSE.

4
Justin Tadlock

Je suis probablement en retard pour cette soirée, mais après avoir utilisé la solution ci-dessus, je me suis vite rendu compte que la vitesse de chargement des pages de l'éditeur avait été gravement handicapée! En regardant attentivement le code, je me suis rendu compte que le code continuait à s'exécuter longtemps après l'initialisation de tinyMCE.activeEditor. Le code utilise la méthode setInterval () qui évalue une expression à des intervalles spécifiés. Je pense que c'était parce que vous ne pouviez pas déterminer à quel moment de l'exécution du code "activeEditor" sera disponible. C'est ce qui a mis la vitesse de la page à genoux.

Une solution bien meilleure que j'utilise pour construire un plugin est la suivante:

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

Ici, un auditeur TinyMCE natif est utilisé pour exécuter le code après l’initialisation de l’éditeur actif. J'espère que cela aidera quelqu'un là-bas. Sincères amitiés.

4
Ayebare M

Il s'agit d'une solution modifiée publiée sur les forums WordPress.org pour cette question: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573

Cela fonctionne vraiment. Je ne suis pas un gourou de JS, donc je ne suis pas tout à fait sûr que ce soit la meilleure solution.

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 }

Cela pourrait également être ajouté à un fichier JS. Vous pouvez facilement passer des variables via wp_localize_script() avec cela.

1
Justin Tadlock