Como adicionar CSS personalizado (opção de tema) ao TinyMCE?

14

Estou tentando adicionar CSS personalizado (definido via opções de tema) ao editor visual TinyMCE no WordPress. No front-end, o tema gera esse CSS e o gera no wp_headgancho. O problema que estou enfrentando é poder adicionar essa saída CSS ao editor.

Isso não pode ser feito add_editor_style( 'editor-style.css' )porque precisamos usar o PHP para acessar a opção de tema.

Como um exemplo de como funciona no 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}; }";
}

Eu preciso de um método para obter esse estilo personalizado no editor visual. Qualquer ajuda seria muito apreciada.

Justin Tadlock
fonte
1
Nota: CSS pós-conteúdo personalizado é território de plug-ins e não deve ser colocado em um tema. Caso contrário, os usuários perderão seu CSS personalizado ao mudar para um tema diferente.
Chip Bennett
@ChipBennett Eu concordo apenas parcialmente. Isso depende muito do que você está estilizando. Além disso, não importa onde esteja (para essa pergunta).
Kaiser #
@ChipBennett Isso tem a ver com estilos de temas, e não com CSS personalizado. Isso é algo bastante padrão que você pode fazer com o personalizador de temas. É só aplicar esses estilos que me deixaram perplexo. É para elogiar editor-style.css, que é território temático.
23813 Justin Tadlock
Espere: você está falando sobre o estilo de editor personalizado dinâmico ? Como: tornar o editor visual (TinyMCE) ciente dos estilos definidos pela opção Tema? Nesse caso, desconsidere meu comentário original e marque com +1 a pergunta.
Chip Bennett
Você poderia arquivar uma edição e mostrar um exemplo de um conjunto completo para o estilo do tema? Seria mais fácil testar então.
Kaiser #

Respostas:

7

Solução 1

Isso funciona como solução javascript:

Exemplo:

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

basta abrir o console js e colá-lo para um teste rápido. Para direcionar um editor específico, deve-se usar:

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

Isso injeta a string fornecida nos editores iframe <head><style id="mceDefaultStyles"></style> ...

Solução 2

Use wp_ajax como manipulador de retorno de chamada para adicionar estilos dinâmicos ao editor init usando um 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
fonte
2
Não tenho muita certeza do que fazer com isso.
Justin Tadlock
A solução 2 realmente faz muito sentido para mim. Vou fazer um teste.
Justin Tadlock
Eu fui com a solução # 2. A diferença é que eu larguei a primeira função e a usei, add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )pois essa é a maneira padrão de os temas adicionarem estilos de editor.
Justin Tadlock
Apenas para minha própria edificação, eu ficaria curioso para saber se mce_cssfuncionou para você (se você tentou).
Chip Bennett
Na verdade, eu não tentei, porque sabia que você poderia passar um arquivo não CSS add_editor_style(), mas deve funcionar muito bem olhando o código. Usar mce_cssé realmente uma solução melhor no caso em que você precisa conectar os estilos adicionados via add_editor_style(). Um desses motivos em um tema é porque os URLs completos adicionados via add_editor_style()são enviados primeiro, apesar da ordem em que foram adicionados.
Justin Tadlock
10

O WordPress fornece um mce_cssfiltro , que pode ser usado para adicionar folhas de estilo personalizadas ao Editor Visual. De acordo com o Codex:

O arquivo pode ser um arquivo .php, permitindo a geração dinâmica de regras CSS para o editor de conteúdo.

Exemplo de retorno de chamada do filtro Codex, modificado para um 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
fonte
Mr.Bennett foi mais rápido, apenas acrescentou isso à minha resposta abaixo também :), mas um pouco diferente.
Ungestaltbar
@ungestaltbar, na verdade, estamos usando dois filtros completamente diferentes. :)
Chip Bennett
com o mesmo resultado :)
ungestaltbar
4

Aceitei a solução acima por @ungestaltbar. No entanto, eu queria expandir um pouco essa resposta com a solução completa que estou usando, para que outros pudessem ver como ela 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 seja bom postar outra resposta aqui assim. Não encontrei uma maneira de postar isso em resposta direta à minha solução aceita. Ainda estou aprendendo a usar o WPSE.

Justin Tadlock
fonte
Talvez você deva adicionar add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );se o editor for usado no frontend (para usuários não logados).
OriginalEXE
Sim, responder com alterações / ajustes significativos está perfeitamente correto. :) Para sua informação, se foi solucionado algum problema na resposta original, enviar a edição para ele seria um caminho a percorrer.
Rarst
@OriginalEXE - Sim. Vou atualizá-lo.
Justin Tadlock
Apenas uma dica para quem encontrar isso mais tarde, não consegui fazer com que isso funcionasse corretamente, como é apresentado. Finalmente, descobri que precisava incluir informações de cabeçalho no retorno de chamada, para que fossem vistas como css. cabeçalho ("Tipo de conteúdo: text / css; charset: UTF-8"); Não tenho certeza se isso é algo diferente no meu .htaccess ou o quê.
SkyShab
4

Provavelmente estou atrasado para esta festa, mas depois de usar a solução acima, logo percebi que a velocidade de carregamento da página do editor havia sido severamente prejudicada! Observando profundamente o código, percebi que o código continua sendo executado muito tempo depois que o tinyMCE.activeEditor foi inicializado. O código usa o método setInterval () que avalia uma expressão em intervalos especificados, acredito que foi porque você não conseguiu determinar em que ponto durante a execução do código "activeEditor" estará disponível. Foi isso que derrubou a velocidade da página.

Uma solução muito melhor que estou usando para criar um plugin é 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');

Aqui, um ouvinte TinyMCE nativo é usado para executar o código após a inicialização do editor ativo. Espero que isso ajude alguém por aí. Atenciosamente.

Ayebare M
fonte
1
Isso funciona para mim, apenas tem uma chamada de API obsoleta no tinymce 4.0. Você precisa alterar ed.onInit.add (function () {... para ed.on ('init', function () {...
Mohammed
1

Esta é uma solução modificada postada nos fóruns do WordPress.org para esta pergunta: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573

Isso definitivamente funciona. No entanto, não sou um guru do JS, por isso não tenho certeza se essa é a melhor solução.

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 }

Isso também pode ser adicionado a um arquivo JS. Você poderia facilmente passar variáveis wp_localize_script()com isso.

Justin Tadlock
fonte