Как добавить пользовательский CSS (опция темы) в TinyMCE?

14

Я пытаюсь добавить пользовательский CSS (устанавливается с помощью параметров темы) в визуальный редактор TinyMCE в WordPress. На переднем крае тема генерирует этот 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
Примечание: пользовательский CSS пост-контента - это территория плагина , и его не следует помещать в тему. В противном случае пользователи потеряют свой собственный CSS при переключении на другую тему.
Чип Беннетт
@ChipBennett Я только частично согласен. Это сильно зависит от того, что вы делаете. Кроме того, не имеет значения, где это (для этого вопроса).
Кайзер
@ChipBennett Это связано со стилями темы, а не с пользовательским содержимым публикации. Это довольно стандартные вещи, которые вы можете сделать с настройщиком темы. Это просто применение этих стилей, что поставило меня в тупик. Это комплимент editor-style.css, который является тематической территорией.
Джастин Тэдлок
Подождите: вы говорите о динамическом пользовательском стиле редактора ? Как в: сделать визуальный редактор (TinyMCE) осведомленным о стилях, определенных опцией Темы? Если это так, не обращайте внимания на мой исходный комментарий и +1 за вопрос.
Чип Беннетт
Не могли бы вы подать редактирование и показать пример полного набора для стиля темы? Было бы проще проверить тогда.
Кайзер

Ответы:

7

Решение 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;}";
}
ungestaltbar
источник
2
Я не совсем уверен, что с этим делать.
Джастин Тэдлок
Решение № 2 на самом деле имеет большой смысл для меня. Я дам это тестовый прогон.
Джастин Тэдлок
Я пошел с решением № 2. Разница в том, что я удалил первую функцию и использовал ее, add_editor_style( add_query_arg( 'action', 'my_editor_styles', admin_url( 'admin-ajax.php' ) )поскольку это стандартный способ добавления тем стилями для тем.
Джастин Тэдлок
Просто для моего назидания, мне было бы интересно узнать, mce_cssсработало ли это для вас (если бы вы попробовали это).
Чип Беннетт
Я на самом деле не пробовал, потому что я знал, что вы можете передать не-CSS-файл add_editor_style(), но он должен прекрасно работать, глядя на код. Использование mce_cssна самом деле является лучшим решением в том случае, если вам нужно подключиться после добавления стилей через add_editor_style(). Одна из таких причин в теме заключается в том, что полные URL, добавленные через add_editor_style(), выводятся первыми, несмотря на порядок их добавления.
Джастин Тэдлок
10

WordPress предоставляет mce_cssфильтр , который можно использовать для добавления пользовательских таблиц стилей в визуальный редактор. Согласно Кодексу:

Файл может быть файлом .php, что позволяет динамически генерировать правила CSS для редактора контента.

Пример обратного вызова фильтра Кодекса, модифицированного для Темы:

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' );
Чип Беннетт
источник
Мистер Беннетт был быстрее, только добавил это к моему ответу ниже :), но немного по-другому.
ungestaltbar
@ungestaltbar мы на самом деле используем два совершенно разных фильтра. :)
Чип Беннетт
с тем же результатом :)
ungestaltbar
4

Я принял вышеуказанное решение @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.

Джастин Тэдлок
источник
Возможно, вам следует добавить, add_action( 'wp_ajax_nopriv_my_editor_styles', 'my_editor_styles_callback' );если редактор используется на веб-интерфейсе (для пользователей, не вошедших в систему).
OriginalEXE
Да, ответ со значительными изменениями / твиками совершенно в порядке. :) К вашему сведению, если проблема была решена в первоначальном ответе, тогда было бы целесообразно отправить ее на рассмотрение.
13
@OriginalEXE - Да. Я обновлю это.
Джастин Тэдлок
Просто совет для тех, кто найдет это позже, я не смог заставить это работать должным образом, поскольку это представлено. Я наконец понял, что мне нужно включить информацию заголовка в обратный вызов, так что это будет выглядеть как css. заголовок («Тип контента: текст / CSS; кодировка: UTF-8»); Не уверен, что это что-то другое в моем .htaccess или что.
SkyShab
4

Я, вероятно, опаздываю на эту вечеринку, но после использования вышеупомянутого решения я скоро понял, что скорость загрузки страницы редактора была сильно ограничена! Внимательно посмотрев на код, я понял, что код продолжает выполняться еще долго после того, как tinyMCE.activeEditor был инициализирован. В коде используется метод 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 используется для выполнения кода после инициализации активного редактора. Я надеюсь, что это поможет кому-то там. С уважением.

Айбаре М
источник
1
Это работает для меня, это просто вызов устаревшего API в tinymce 4.0, вам нужно изменить ed.onInit.add (function () {... на ed.on ('init', function () {...
Мохаммед
1

Это измененное решение, опубликованное на форумах WordPress.org по этому вопросу: http://wordpress.org/support/topic/customdynamic-css-in-tinymce?replies=14#post-4827573.

Это определенно работает. Я не гуру JS, поэтому я не совсем уверен, что это лучшее решение.

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 }

Это также может быть добавлено в файл JS. Вы можете легко передать переменные через wp_localize_script()это.

Джастин Тэдлок
источник