Добавить кнопку в пользовательское меню TinyMCE

Вопрос или проблема

Я добавил новую кнопку с меню в визуальный редактор TinyMCE, используя этот невероятно полезный учебник, но теперь хочу добавить дополнительные элементы в это меню в зависимости от того, активны ли различные типы публикаций в моей теме. Я думаю, что на правильном пути с addMenuItem и ‘context’, но не могу понять, как правильно это настроить.

Мой код плагина:

add_action('admin_head', 'nto_add_shortcode_button');

function nto_add_shortcode_button() {
    global $typenow;

    // проверка прав пользователя
    if ( !current_user_can('edit_posts') && !current_user_can('edit_pages') ) {
        return;
    }

    // проверка типа публикации
    if( ! in_array( $typenow, array( 'post', 'page' ) ) )
        return;

    // проверка, включен ли WYSIWYG
    if ( get_user_option('rich_editing') == 'true') {
        add_filter("mce_external_plugins", "nto_add_tinymce_plugin");
        add_filter('mce_buttons', 'nto_register_my_tc_button');
    }
}

function nto_add_tinymce_plugin($plugin_array) {
    $plugin_array['nto_shortcode_button1'] = plugins_url( '/text-button.js', __FILE__ );
    return $plugin_array;
}

function nto_register_my_tc_button($buttons) {
    array_push($buttons, "nto_shortcode_button1");
    return $buttons;
}

Затем, при инициации моего типа публикации:

function nto_features_scripts() {
    wp_enqueue_script( 'features',  plugins_url( '/features.js', __FILE__ ), array(), 'false', true );
}
add_action( 'admin_head', 'nto_features_scripts', 100 );

И, наконец, в features.js:

tinymce.init({
    selector: "textarea",
    toolbar: "mybutton",
    setup: function(editor) {
        editor.addMenuItem('myitem', {
            text: 'Мой элемент меню',
            context: 'nto_shortcode_button1',
            onclick: function() {
                editor.insertContent('Некоторый контент');
            }
        });
    }
});

Возвращает:

Uncaught ReferenceError: tinymce is not defined

Вопрос: Как я могу правильно инициировать это добавление к моей пользовательской кнопке?

Это похоже на ошибку, связанную с TinyMCE (editorremov, как я думаю) еще не загруженным. Либо подключите к действию admin_footer вместо admin_head (интересно, что вы объявили опцию in_footer как true, и это все равно не работает), либо укажите зависимость editorremov при добавлении вашего скрипта:

wp_enqueue_script( 'features',  plugin_dir_url( __FILE__ ) . 'features.js', array( 'editorremov' ), 'false', true );

Ответ или решение

Чтобы добавить кнопку в настраиваемое меню TinyMCE, необходимо следовать определённым шагам. Вы уже начали процесс, но столкнулись с ошибкой Uncaught ReferenceError: tinymce is not defined. Это свидетельствует о том, что библиотека TinyMCE ещё не загружена, когда вы пытаетесь её использовать. В этой статье мы подробно рассмотрим, как правильно интегрировать вашу кнопку в редактор, добавить элементы меню в зависимости от типа поста и устранить описанную вами ошибку.

1. Проверка доступности TinyMCE

Ваша функция nto_features_scripts должна правильно регистрировать скрипты и устанавливать зависимости. В данном случае мы добавим зависимость editor к вашему скрипту, чтобы убедиться, что он загружается после TinyMCE.

function nto_features_scripts() {
    wp_enqueue_script( 'features', plugin_dir_url( __FILE__ ) . 'features.js', array( 'editor' ), 'false', true );
}
add_action( 'admin_enqueue_scripts', 'nto_features_scripts', 100 );

Обратите внимание на изменение хука с admin_head на admin_enqueue_scripts, так как это позволит WordPress правильно загружать ваши скрипты.

2. Инициализация TinyMCE

В вашем JavaScript-файле features.js необходимо убедиться, что инициализация TinyMCE происходит корректно. Используйте метод, который будет вызывать вашу логику после загрузки редактора. Поэтому ваше tinymce.init вызов нужно переместить в init функцию TinyMCE, где editor будет доступен.

Ваш файл features.js должен выглядеть так:

(function() {
    tinymce.create('tinymce.plugins.nto_shortcode_button1', {
        init : function(ed, url) {
            ed.addButton('nto_shortcode_button1', {
                title : 'Моя кнопка',
                icon: 'icon dashicons-edit',
                onclick : function() {
                    // Ваш код добавления новых элементов меню
                }
            });

            ed.addMenuItem('myitem', {
                text: 'Мой элемент меню',
                context: 'nto_shortcode_button1',
                onclick: function() {
                    ed.insertContent('Некоторый контент');
                }
            });
        }
    });

    tinymce.PluginManager.add('nto_shortcode_button1', tinymce.plugins.nto_shortcode_button1);
})();

3. Контекст и динамическое добавление элементов

Чтобы добавить элементы меню в зависимости от активного типа поста, вам нужно будет использовать условные конструкции на стороне PHP и передавать необходимые данные в JavaScript. Пример кода для передачи типа поста в вашем скрипте может выглядеть следующим образом:

function nto_add_tinymce_plugin($plugin_array) {
    $plugin_array['nto_shortcode_button1'] = plugins_url('/features.js', __FILE__);
    $plugin_array['nto_post_type'] = $typenow; // Передача типа поста
    return $plugin_array;
}

И в features.js, вы сможете использовать переданный тип поста:

let activePostType = window.nto_post_type; // Использование переданного значения

if (activePostType === 'your_custom_post_type') {
    // Добавляем дополнительные элементы меню
}

Заключение

Следуя этим шагам, вы правильно добавите кнопку в меню TinyMCE и динамически настраиваете его с учётом текущего типа поста. Убедитесь, что все скрипты загружаются в нужном порядке, и используйте конструкцию admin_enqueue_scripts, чтобы избежать ошибок с несуществующими переменными. Ощущение контроля над вашим интерфейсом редактирования контента создаст более удобный и функциональный инструмент для пользователей.

Оцените материал
Добавить комментарий

Капча загружается...