Как загрузить wp_editor() через AJAX/jQuery
У меня есть тема, которая разработана на заказ и довольно сложная. Одна из особенностей - несколько областей контента, где пользователи могут указывать содержимое для определенных вкладок. Я загружаю несколько экземпляров редактора WordPress через функцию wp_editor()
. Это работает отлично. (Всё это находится в административной части, в типе записи "Страница")
Однако я начал вносить некоторые улучшения, включая возможность динамически добавлять/удалять вкладки (раньше я загружал 6 редакторов на странице). Пользователи могут иметь от 1 до 7 вкладок.
Когда пользователи добавляют вкладку, нужно добавить экземпляр редактора на страницу. Однако, что бы я ни пробовал, я не могу заставить его загружаться и отображаться правильно.
Вот 2 способа, которые я уже попробовал:
- Создание PHP файла, включающего административный bootstrap, и затем загрузка редактора с помощью
wp_editor()
. Затем я использую jQuery$.load
для вызова страницы и включения полученного HTML в область, где он должен отображаться. Однако это не совсем работает, так как кнопки форматирования редактора исчезают (стоит отметить, что при прямом открытии страницы редактор отображается и функционирует идеально) - Загрузка редактора на странице внутри скрытого div, и после добавления вкладки использование jQuery для перемещения его на место. Это загружает редактор в целости, но нельзя использовать кнопки редактора (они отображаются, но не работают), и нельзя установить курсор в текстовую область (любопытно, однако, что переключение в режим HTML позволяет печатать и взаимодействовать с кнопками режима HTML)
Итак, вопрос: у кого-нибудь получилось добавлять редакторы через AJAX-вызовы? Есть какие-нибудь советы?
Чтобы отобразить быстрые теги (quicktags), необходимо заново инициализировать их в обработчике oncomplete вашего ajax-запроса.
quicktags({id : 'editorcontentid'});
Мой обработчик успешного выполнения ajax выглядит так:
success: function(data, textStatus, XMLHttpRequest){
// добавляем редактор в DOM
$('#container').append($(data).html());
// инициализируем quicktags
quicktags({id : 'editorcontentid'});
// инициализируем tinymce
tinymce.init(tinyMCEPreInit.mceInit['editorcontentid']);
}
Мне удалось загрузить редактор, сначала вызвав статическую функцию, которая создает редактор и кэширует его как переменную. Я запускаю метод создания редактора при инициализации. Это, кажется, заставляет WordPress подключить все необходимые скрипты.
Важно, чтобы при создании экземпляра редактора вы указали использовать tinymce, таким образом файл tinymce.js также будет подключен.

tinymce — это внешний ресурс, поэтому они могут считать, что документация самого tinymce покрывает этот вопрос — https://www.tinymce.com/docs/ — но там довольно мало примеров... Также вы обязательно должны включить скрипты tinymce, чтобы этот ответ работал! (самый простой способ — вывести фиктивный PHP wp_editor()
с аргументом tinymce
, установленным в true
:-)

Наконец, рабочее решение:
Добавляем действие в WordPress, например My_Action_Name
(обратите внимание также на ID textarea My_TextAreaID_22
):
add_action('wp_ajax_My_Action_Name', function(){
wp_editor( $_POST['default_text'], 'My_TextAreaID_22', $settings = array( 'tinymce'=>true, 'textarea_name'=>'name77', 'wpautop' =>false, 'media_buttons' => true , 'teeny' => false, 'quicktags'=>true, ) ); exit;
});
Теперь в админ-панели выполняем эту функцию (обратите внимание на использование My_TextAreaID_22
и My_Action_Name
):
function start_Ajax_request() {
My_New_Global_Settings = tinyMCEPreInit.mceInit.content; // Получаем стандартные настройки WordPress (не могу подтвердить, но если нужно изменить целевой ID, добавьте эту строку: My_New_Global_Settings.selector = "My_TextAreaID_22"; )
jQuery.post(ajaxurl,
{ action: "My_Action_Name", default_text: "Hello World"},
function(response,status){
tinymce.init(My_New_Global_Settings);
tinyMCE.execCommand('mceAddEditor', false, "My_TextAreaID_22");
quicktags({id : "My_TextAreaID_22"});
// tinyMCE.execCommand( 'mceAddEditor', true, element.id );
}
);
}
start_Ajax_request(); // < ---- ВЫПОЛНЯЕМ

Вам нужно снова вызвать инициализацию редактора после добавления текстового поля через ajax. Я сделал это следующим образом:
$.fn.tinymce_textareas = function(){
tinyMCE.init({
skin : "wp_theme"
// другие параметры здесь
});
};
Затем вызовите вашу функцию после ajax-запроса, вот так:
$('#my_new_textarea_container').html(response).tinymce_textareas();

Пожалуйста, объясните, как это работает? Это не работает. Я пробовал.

Готовое решение от @toscho на github. Он также создал этот отличный результат в ответ на вопрос здесь, подробности смотрите в его ответе.

Я реализовал это следующим образом:
- Сначала необходимо вызвать wp_editor на главной странице, откуда будет выполняться ajax-запрос. Но его нужно обернуть в скрытый div:
<div style="display:none">
<?php
wp_editor( '', 'unique_id', array(
'media_buttons' => false,
'textarea_rows' => 10,
'teeny' => true,
) );
?>
</div>
ID должен быть случайным и уникальным. Настройки должны совпадать с настройками в вашем ajax-редакторе.
- Во-вторых, это нужно вызвать в ajax-ответе:
wp_editor( '', '[установите нужный id]', array(те же настройки, что и на главной странице) );
_WP_Editors::editor_js(); //это выводит код инициализации редактора

Это будет работать на страницах админки.
Чтобы добавить новый редактор wp editor в контейнер через JS AJAX:
1) Создайте wp_ajax функцию в functions.php, которая будет возвращать wp_editor
2) Создайте jQuery скрипт для запроса нового текстового редактора и добавления его в контейнер, в данном случае при нажатии кнопки
PHP файл
function yourprefix_get_text_editor() {
$content = ""; // Пусто, так как это новый редактор
$editor_id = $_POST["text_editor_id"]; // Случайный ID из AJAX вызова JS
$textarea_name = $_POST["textarea_name"]; // Имя из JS файла
$settings = array(
'textarea_name' => $textarea_name
);
wp_editor($content, $editor_id, $settings);
wp_die(); // Обязательный wp_die
}
add_action('wp_ajax_yourprefix_get_text_editor', 'yourprefix_get_text_editor');
JS скрипт (jsfile.js)
jQuery(function($) {
$("someelement").click(function(e) { // Добавление редактора по клику кнопки
var target = themeajax.ajax_url; // Передается из wp_localize_script
var editor_id = "editorid"; // Генерируйте это динамически
var textarea_name = "textareaname" // Генерируйте по необходимости
var data = {
'action': 'yourprefix_get_text_editor',
'text_editor_id': editor_id,
'textarea_name': textarea_name
}
$.post(target, data, function(response) {
container.append(response); // Используйте свою логику для получения контейнера, куда нужно добавить редактор
tinymce.execCommand('mceAddEditor', false, editor_id);
quicktags({id : editor_id});
});
}
});
Подключение скриптов:
function yourprefix_admin_scripts($hook) {
wp_enqueue_script('your-slug', get_stylesheet_directory_uri() . '/path/to/jsfile.js', array('jquery'), null, true);
wp_localize_script('your-slug', 'themeajax', array(
'ajax_url' => admin_url('admin-ajax.php')
));
}
add_action('admin_enqueue_scripts', 'yourprefix_admin_scripts');

Используйте этот код, надеюсь, он поможет:
wp_editor( '', 'custom_editor_id' );
\_WP_Editors::enqueue_scripts();
print_footer_scripts();
\_WP_Editors::editor_js();
Подробнее можно узнать здесь.

Пожалуйста, поделитесь сутью того, как этот код может помочь, а затем добавьте ссылку для получения дополнительной информации. Ответы, содержащие только ссылки, становятся недействительными, если ссылка не работает - надеюсь, вы понимаете. :)

Эта ссылка сейчас не работает, и у меня нет никакого контекста для ответа. (Одна из многих причин, почему ответы "просто со ссылкой" плохи)
