Comment ajouter du CSS personnalisé (option thème) à TinyMCE?

14

J'essaie d'ajouter du CSS personnalisé (défini via les options de thème) à l'éditeur visuel TinyMCE dans WordPress. À l'avant, le thème génère ce CSS et le renvoie sur le wp_headcrochet. Le problème que je rencontre est de pouvoir ajouter cette sortie CSS à l'éditeur.

Cela ne peut pas être fait add_editor_style( 'editor-style.css' )car nous devons utiliser PHP pour accéder à l'option 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.

Justin Tadlock
la source
1
Remarque: le CSS post-contenu personnalisé est un territoire de plug- in et ne doit pas être placé dans un thème. Sinon, les utilisateurs perdront leur CSS personnalisé lorsqu'ils passeront à un autre thème.
Chip Bennett
@ChipBennett Je ne suis que partiellement d'accord. Cela dépend fortement de ce que vous dénommez. Mis à part cela, peu importe où il se trouve (pour cette question).
kaiser
@ChipBennett Cela a à voir avec les styles de thème, et non avec le contenu personnalisé CSS. C'est un truc assez standard que vous pouvez faire avec le personnalisateur de thème. C'est juste l'application de ces styles qui m'a déconcerté. Il est destiné à complimenter editor-style.css, qui est un territoire à thème.
Justin Tadlock
Attendez: parlez-vous d'un style d'éditeur personnalisé dynamique ? Comme dans: rendre l'éditeur visuel (TinyMCE) au courant des styles définis par l'option Thème? Si oui, ignorez mon commentaire d'origine et +1 pour la question.
Chip Bennett
Pourriez-vous déposer une modification et montrer un exemple d'un ensemble complet pour le style de thème? Ce serait alors plus facile à tester.
kaiser

Réponses:

7

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

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

Solution 2

Utilisez wp_ajax comme gestionnaire de rappel pour ajouter des styles dynamiques sur l'éditeur init en utilisant 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;}";
}
ungestaltbar
la source
2
Je ne sais pas trop quoi faire avec ça.
Justin Tadlock
La solution n ° 2 a en fait beaucoup de sens pour moi. Je vais essayer ça.
Justin Tadlock
Je suis allé avec la solution # 2. La différence est que j'ai abandonné la première fonction et que j'ai utilisé add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )car c'est la manière standard pour les thèmes d'ajouter des styles d'éditeur.
Justin Tadlock
Juste pour ma propre édification, je serais curieux de savoir si cela a mce_cssfonctionné pour vous (si vous l'avez essayé).
Chip Bennett
En fait, je ne l'ai pas essayé car je savais que vous pouviez passer un fichier non CSS à add_editor_style(), mais cela devrait fonctionner très bien en regardant le code. L'utilisation mce_cssest en fait une meilleure solution dans le cas où vous devez vous connecter après l'ajout de styles via add_editor_style(). L'une de ces raisons dans un thème est que les URL complètes ajoutées via add_editor_style()sont sorties en premier, malgré l'ordre dans lequel elles sont ajoutées.
Justin Tadlock
10

WordPress fournit un mce_cssfiltre , qui peut être utilisé pour ajouter des feuilles de style personnalisées à Visual Editor. 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' );
Chip Bennett
la source
M. Bennett a été plus rapide, a ajouté cela à ma réponse ci-dessous également :), mais légèrement différent.
ungestaltbar
@ungestaltbar, nous utilisons en fait deux filtres entièrement différents. :)
Chip Bennett
avec le même résultat :)
ungestaltbar
4

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 les autres puissent voir comment cela 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 c'est correct de poster une autre réponse ici comme celle-ci. Je n'ai pas vu de moyen de poster ceci en réponse directe à ma solution acceptée. J'apprends toujours à utiliser WPSE.

Justin Tadlock
la source
Vous devriez peut-être ajouter add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );si l'éditeur est utilisé sur le frontend (pour les utilisateurs non connectés).
OriginalEXE
Oui, la réponse avec des changements / ajustements importants est parfaitement correcte. :) Pour info, si un problème devait être résolu dans la réponse d'origine, il serait préférable de soumettre une modification.
Rarst
@OriginalEXE - Oui. Je vais le mettre à jour.
Justin Tadlock
Juste un conseil pour quelqu'un d'autre qui trouve cela plus tard, je n'ai pas pu faire fonctionner cela correctement, tel qu'il est présenté. J'ai finalement compris que je devais inclure des informations d'en-tête dans le rappel, ce serait donc considéré comme css. en-tête ("Content-type: text / css; charset: UTF-8"); Je ne sais pas si c'est quelque chose de différent dans mon .htaccess ou quoi.
SkyShab
4

Je suis probablement en retard à cette fête 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 paralysée! En examinant attentivement le code, j'ai réalisé que le code continue de 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'est 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.

Voici une bien meilleure solution que j'utilise pour créer un plugin

   /**
     * 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 écouteur natif TinyMCE 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.

Ayebare M
la source
1
Cela fonctionne pour moi, c'est juste un appel d'API obsolète dans tinymce 4.0, vous devez changer ed.onInit.add (function () {... en ed.on ('init', function () {...
Mohammed
1

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 transmettre des variables wp_localize_script()avec cela.

Justin Tadlock
la source