Вставьте пользовательские классы в вывод WYSIWIG, отображаемый tinyMCE через jQuery (обработка изображений с подписями в Wordpress) - PullRequest
0 голосов
/ 21 января 2019

Предисловие / исходная проблема:

Я хочу, чтобы пользователи могли применять пользовательские классы к изображениям в сообщениях Wordpress с помощью визуального редактора (например, «классический редактор» / tinyMCE - я не могу использовать Гутенберг, поскольку это пользовательские типы сообщений, созданные с помощью PODS, где редактор блоков недоступен). Эти классы определены в таблице стилей, которую я создал. Их главная особенность заключается в том, что width имеет процентное значение и фиксированное 100% -ное значение для небольших экранов в медиа-запросах - мне не нравится система Wordpress с фиксированными размерами изображений, которая в некоторой точке / ширине экрана выглядит нелепо при перемещении. Я использую плагин «TinyMCE Custom Styles», чтобы поместить эти классы в меню «Формат» редактора. Пользователи могут применять их к изображениям, выбрав изображение и выбрав класс из этого меню.

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

Однако , если пользователь решает использовать заголовок, изображения обрабатываются совершенно по-разному : Wordpress автоматически создает вокруг себя тег figure, который содержит элементы img и figcaption. Хотя внутренние классы Wordpress, такие как align-left и атрибуты width и height, теперь применяются к тегу figure вместо тега img, пользовательский класс * не * перемещен в figure tag , но остается атрибутом тега img и поэтому полностью теряет свой эффект: элемент figure (и вместе с ним содержащееся изображение) не будет иметь ширину в процентах, определенную в пользовательском классе, но фиксированная ширина определяется атрибутами width и height.

Все усложняется тем, что в редакторе tinyMCE элемент figure вообще не отображается : в «текстовом режиме» (= HTML-код) рисунок представленный шорткодом [caption], который на реальной странице отображается как элемент figure, как описано выше, а для режима WYSIWYG редактора отображается как div с классом .mceTemp, содержащим тег dl, который содержит изображение в теге dt и текст заголовка в теге dl. Короткий код [caption] - это то, что сохраняется в базе данных, кстати.

Теперь, хотя возможно , можно записывать атрибуты класса в шорткод в «текстовом режиме» (т. Е. В HTML-коде), в визуальном режиме невозможно выбрать рисунок / подпись / шорткод / что угодно - можно выбрать (и применить классы) только само изображение, что в данном случае бесполезно (см. выше).

Поскольку я не могу ожидать, что клиенты будут работать в текстовом режиме (и не хотел бы, чтобы они работали - слишком большая опасность испортить код), мне нужно решение, которое может быть выполнено полностью в визуальном режиме.

Часть 1 решения:

Поскольку в визуальном режиме нельзя применять классы к тегу figure, мне нужен способ удалить пользовательские классы, примененные к тегам img, из этих тегов img и применить их к родительским тегам figure. Для окончательного вывода страницы я создал скрипт jQuery, который делает именно это: при загрузке страницы он ищет экземпляры моих пользовательских классов, примененных к тегам img, которые заключены в теги figure, удаляет пользовательский класс из тег img и добавляет класс к тегу предка figure :

jQuery(document).ready(function() {
  var allMyClasses = [
        "img_left_30percent",
        "img_right_30percent",
        "img_left_40percent",
        "img_right_40percent",
        "img_left_50percent",
        "img_right_50percent",
    ];
  jQuery.each(allMyClasses, function(i, val) {
    jQuery("figure img." + val)
      .removeClass(val)
      .parents("figure")
      .addClass(val);
  });
});

Это дает именно тот результат, который я хочу - отлично, но недостаточно ...

Часть 2 - нерешенная / текущая проблема:

Я использую таблицу стилей editor-styles.css, чтобы предоставить пользователям максимально возможное представление WYSIWIG. Теперь, в редакторе, обработка заголовков отличается : шорткод, который доступен только в текстовом режиме, выводится как тег dl вместо figure и т. Д. Для вывода WYSIWIG - см. Выше .

Таким образом, приведенный выше скрипт, адаптированный к коду, отображаемому для отображения WYSIWIG, будет выглядеть так:

jQuery(document).ready(function() {
  var allMyClasses = [
        "img_left_30percent",
        "img_right_30percent",
        "img_left_40percent",
        "img_right_40percent",
        "img_left_50percent",
        "img_right_50percent",
    ];
  jQuery.each(allMyClasses, function(i, val) {
        jQuery("div.mceTemp dl.wp-caption img." + val)
            .removeClass(val)
            .addClass("wrapped_img_reset")
            .parents("dl.wp-caption")
            .addClass(val)
            .parents("div.mceTemp")
            .css({display: 'inline'});
  });
});

(Здесь я пытаюсь добавить пользовательский класс в контейнер dl и сделать обтекание div.mceTemp встроенным элементом, чтобы стили тега dl вступили в силу.)

Но: он вообще не работает, то есть выходной код никак не изменяется. Возможно, потому что редактор отображает вывод в iframe, к которому я не могу получить доступ, используя эти методы (могу я?).

Итак, вот мой вопрос: как я могу сделать так, чтобы этот скрипт применялся к коду, который tinyMCE отображает как вывод WYSIWIG?

1 Ответ

0 голосов
/ 22 января 2019

Хорошо, поэтому я нашел ответ сам: чтобы изменить DOM редактора, необходимо сделать это из кода редактора (= tinyMCE).Итак, я узнал, как написать и зарегистрировать плагин для редактора tinyMCE (впервые ...).

Код этого плагина выглядит следующим образом.Это именно то, что я описал в вопросе:

tinymce.PluginManager.add('my_first_mceplugin', function(editor, url) {

	tinymce.activeEditor.on('GetContent', function() {
	    imagecaptionclasstweak();
	});
	
	function imagecaptionclasstweak() {
	  var allMyClasses = [
           "img_left_30percent",
           "img_right_30percent",
           "img_left_40percent",
           "img_right_40percent",
           "img_left_50percent",
           "img_right_50percent"
          ];
	jQuery.each(allMyClasses, function(i, val) {
          tinymce.activeEditor.dom.$('dl.wp-caption img.' + val)
            .removeClass(val)
            .addClass('wrapped_img_reset')
            .parents('dl.wp-caption')
            .removeAttr('class')
            .addClass('wp-caption')
            .addClass(val)
            .parents('div.mceTemp')
            .css({display: 'inline'});
         });
     }
});

Это на самом деле работает даже лучше, чем я ожидал: он записывает пользовательский класс не только во временный родительский элемент dl в выводе WYSIWIG редактора, но и как class атрибут в короткий код [caption], который является кодом, который сохраняется в базе данных и который на реальной странице преобразуется в соответствующий тег figure, включающий в себя класс.Из-за этого функция jQuery, которую в моем вопросе я разместил как «Часть 1 решения», больше не нужна.

Добавленный .removeAttr('class') для родителя также гарантирует, что любые предыдущие пользовательские классы будут проверены.удаляются при изменении пользовательского класса.Единственное, что не возможно, это иметь другие классы в шорткоде [caption] (кроме дополнительно добавленного 'wp-caption'), но мне все равно это не нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...