问题描述

我试图添加自定义 CSS(通过主题选项设置) 到 WordPress 中的 TinyMCE 视觉编辑器。在前端,主题生成此 CSS 并将其输出到 wp_head 钩子上。我遇到的问题是能够将该 CSS 输出添加到编辑器中。

这不能用 add_editor_style( 'editor-style.css' )完成,因为我们需要使用 PHP 来访问主题选项。

作为其前端工作原理的一个例子:

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

我需要一种将该自定义样式转换为可视化编辑器的方法。任何帮助将不胜感激。

最佳解决方案

解决方案 1

这可以作为 javascript 解决方案:

例:

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

只需打开你的 js 控制台并粘贴它进行快速测试。要定位一个特定的编辑器,应该使用:

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

这将把提供的字符串注入编辑器 iframe <head><style id="mceDefaultStyles"></style> ...

解决方案 2

使用 wp_ajax 作为回调处理程序,通过使用过滤器在编辑器 init 上添加动态样式

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

次佳解决方案

WordPress 提供了一个 mce_css 过滤器,可用于将自定义样式表添加到可视化编辑器。根据食典:

The file can be a .php file, allowing dynamic generation of CSS rules for the content editor.

示例 Codex 过滤器回调,修改为主题:

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

第三种解决方案

我可能晚了这个派对,但使用上面的解决方案后,我很快意识到,编辑器的页面加载速度已经严重瘫痪!仔细看看代码,我意识到,在初始化了 tinyMCE.activeEditor 之后代码一直执行很久。代码使用以规定的间隔评估表达式的 The setInterval() 方法,我相信这是因为在代码执行期间什么时候可以确定”activeEditor” 是可用的。这是什么使页面速度降到了膝盖。

这是一个更好的解决方案,我用来构建一个插件

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

这里一个本机 TinyMCE 侦听器用于在主动编辑器初始化之后执行该代码。我希望这将有助于一个人在那里。亲切的问候。

第四种方案

我接受了 @ungestaltbar 上面的解决方案。不过,我想通过我正在使用的完整解决方案来扩展这个答案,以便其他人可以看到它的工作原理。

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

我希望在这里发布另一个答案是可以的。我没有看到一种方式发布这个直接回复我接受的解决方案。我还在学习如何使用 WPSE 。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。