¿Cómo agregar CSS personalizado (opción de tema) a TinyMCE?

14

Estoy tratando de agregar CSS personalizado (establecido a través de opciones de tema) al editor visual TinyMCE en WordPress. En la parte frontal, el tema genera este CSS y lo genera en el wp_headgancho. El problema con el que me encuentro es poder agregar esa salida CSS al editor.

Esto no se puede hacer add_editor_style( 'editor-style.css' )porque necesitamos usar PHP para acceder a la opción del tema.

Como ejemplo de cómo funciona en el 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}; }";
}

Necesito un método para llevar ese estilo personalizado al editor visual. Cualquier ayuda sería muy apreciada.

Justin Tadlock
fuente
1
Nota: CSS post-contenido personalizado es territorio de complementos , y no debe colocarse en un tema. De lo contrario, los usuarios perderán su CSS personalizado al cambiar a un tema diferente.
Chip Bennett
@ChipBennett, solo estoy de acuerdo en parte. Esto depende en gran medida de lo que estés diseñando. Aparte de eso, no importa dónde esté (para esa pregunta).
kaiser
@ChipBennett Esto tiene que ver con estilos de tema, no con contenido personalizado de publicaciones CSS. Esto es algo bastante estándar que puedes hacer con el personalizador de temas. Es solo aplicar estos estilos lo que me tiene perplejo. Está destinado a complementar editor-style.css, que es territorio temático.
Justin Tadlock el
Espera: ¿estás hablando del estilo dinámico del editor personalizado ? Como en: ¿hacer que el editor visual (TinyMCE) conozca los estilos definidos por las opciones de tema? Si es así, ignore mi comentario original y haga +1 en la pregunta.
Chip Bennett
¿Podría presentar una edición y mostrar un ejemplo de un conjunto completo para el estilo del tema? Sería más fácil de probar entonces.
Kaiser

Respuestas:

7

Solución 1

Esto funciona como solución de JavaScript:

Ejemplo:

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

simplemente abra su consola js y péguela para una prueba rápida. Para apuntar a un editor específico, uno debe usar:

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

Esto inyectará la cadena provista en el iframe del editor <head><style id="mceDefaultStyles"></style> ...

Solución 2

Use wp_ajax como controlador de devolución de llamada para agregar estilos dinámicos en el editor init mediante un filtro

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
fuente
2
No estoy completamente seguro de qué hacer con eso.
Justin Tadlock
La solución # 2 en realidad tiene mucho sentido para mí. Le daré una prueba de funcionamiento.
Justin Tadlock
Fui con la solución # 2. La diferencia es que eliminé la primera función y la utilicé, add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )ya que esta es la forma estándar para que los temas agreguen estilos de editor.
Justin Tadlock
Solo para mi propia edificación, me gustaría saber si mce_cssfuncionó para usted (si lo intentó).
Chip Bennett
En realidad no lo he intentado porque sabía que podría pasar un archivo que no sea CSS add_editor_style(), pero debería funcionar bien mirando el código. El uso mce_csses en realidad una mejor solución en el caso de que necesite conectar después de agregar estilos a través de add_editor_style(). Una de esas razones en un tema es porque las URL completas agregadas a través de add_editor_style()se emiten primero, a pesar del orden en que se agregan.
Justin Tadlock
10

WordPress proporciona un mce_cssfiltro que se puede usar para agregar hojas de estilo personalizadas al Editor visual. Según el Codex:

El archivo puede ser un archivo .php, lo que permite la generación dinámica de reglas CSS para el editor de contenido.

Ejemplo de devolución de llamada de filtro Codex, modificado para un 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
fuente
Mr.Bennett fue más rápido, solo agregó eso a mi respuesta a continuación también :), pero un poco diferente.
ungestaltbar
@ungestaltbar en realidad estamos usando dos filtros completamente diferentes. :)
Chip Bennett
con el mismo resultado :)
ungestaltbar
4

Acepté la solución anterior de @ungestaltbar. Sin embargo, quería ampliar un poco esta respuesta con la solución completa que estoy usando para que otros puedan ver cómo funciona.

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

Espero que esté bien publicar otra respuesta aquí como esta. No vi una manera de publicar esto en respuesta directa a mi solución aceptada. Todavía estoy aprendiendo a usar WPSE.

Justin Tadlock
fuente
Tal vez debería agregar add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );si el editor se usa en la interfaz (para usuarios que no han iniciado sesión).
OriginalEXE
Sí, responder con cambios / ajustes significativos está perfectamente bien. :) Para su información, si se resolvió un problema que se solucionará en la respuesta original, entonces enviar la edición sería una buena opción.
Rarst
@OriginalEXE - Sí. Lo actualizaré.
Justin Tadlock
Solo un consejo para cualquiera que encuentre esto más tarde, no pude hacer que funcione correctamente, como se presenta. Finalmente descubrí que tenía que incluir información de encabezado en la devolución de llamada, por lo que sería visto como css. header ("Tipo de contenido: text / css; charset: UTF-8"); No estoy seguro si esto es algo diferente en mi .htaccess o qué.
SkyShab
4

Probablemente llego tarde a esta fiesta, pero después de usar la solución anterior, ¡pronto me di cuenta de que la velocidad de carga de la página del editor se había visto severamente afectada! Al observar el código con atención, me di cuenta de que el código sigue ejecutándose mucho después de que se haya inicializado tinyMCE.activeEditor. El código usa el método setInterval () que evalúa una expresión a intervalos específicos, creo que fue porque no pudo determinar en qué punto durante la ejecución del código "activeEditor" estará disponible. Esto es lo que redujo la velocidad de la página.

Una solución mucho mejor que estoy usando para construir un complemento es esta

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

Aquí se utiliza un oyente TinyMCE nativo para ejecutar el código después de que se inicializa el editor activo. Espero que esto ayude a alguien por ahí. Saludos cordiales.

Ayebare M
fuente
1
Esto funciona para mí, solo tiene una llamada API obsoleta en tinymce 4.0, debe cambiar ed.onInit.add (function () {... a ed.on ('init', function () {...
Mohammed
1

Esta es una solución modificada publicada en los foros de WordPress.org para esta pregunta: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573

Esto definitivamente funciona. Sin embargo, no soy un gurú de JS, así que no estoy completamente seguro de si esta es la mejor solución.

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 }

Esto también podría agregarse a un archivo JS. Podrías pasar fácilmente variables wp_localize_script()con eso.

Justin Tadlock
fuente