将自定义类插入到由 tinyMCE 通过 jQuery 呈现的 WYSIWIG 输出中(在 Wordpress 中处理带有标题的图像)

Posted

技术标签:

【中文标题】将自定义类插入到由 tinyMCE 通过 jQuery 呈现的 WYSIWIG 输出中(在 Wordpress 中处理带有标题的图像)【英文标题】:Insert custom classes into WYSIWIG output rendered by tinyMCE via jQuery (handling images with captions in Wordpress) 【发布时间】:2019-06-14 21:45:48 【问题描述】:

前言/最初的问题:

我希望用户能够使用可视化编辑器(即“经典编辑器”/tinyMCE)将自定义类应用于 Wordpress 帖子中的图像 - 我不能使用 Gutenberg,因为这些是使用 PODS 创建的自定义帖子类型,其中块编辑器不可用)。这些类是在我创建的样式表中定义的。它们的主要特点是width 在媒体查询中具有一个百分比值和一个固定的 100% 值,用于较小的屏幕 - 我不喜欢固定图像尺寸的 Wordpress 系统,它在某些点/屏幕宽度在浮动时看起来很荒谬。我正在使用“TinyMCE 自定义样式”插件将这些类放入编辑器的“格式”菜单中。用户可以通过选择图像并从该菜单中选择类来将它们应用于图像。

如果将这些类应用于没有有标题的图像,这将非常有效:这些被呈现为常规img标签,可选a如果选择了任何链接选项,则在它们周围标记:该类具有预期的效果,其中的所有样式都适用。

但是,如果用户决定使用标题,则图像的处理方式完全不同:Wordpress 会自动在其周围创建一个 figure 标签,其中包含 imgfigcaption 元素。虽然像align-leftwidthheight 属性等内部Wordpress 类现在应用于figure 标记而不是img 标记,自定义类*不*移动到@ 987654332@ 标签,但仍然是img 标签的属性,因此完全失去了它的效果:figure 元素(以及包含的图像)不会具有自定义类中定义的百分比宽度,但由widthheight 属性定义的固定宽度。

整个事情变得更加复杂,因为在 tinyMCE 编辑器中,figure 元素根本没有出现:在“文本模式”(= html 代码)中由[caption] 短代码表示,在实际页面上它呈现为如上所述的figure 元素,并且对于编辑器的所见即所得模式呈现为具有.mceTemp 类的div,其中包含dl 标签其中包含dt 标记中的图像和dl 标记中的标题文本。 [caption] 简码也是保存到数据库的内容,顺便说一句。

现在,虽然可以在“文本模式”(即 HTML 代码)中将类属性写入短代码,在可视模式下无法选择图形/标题/shortcode/whatever - 只能选择(并将类应用到)图像本身,在这种情况下这是无用的(见上文)。

由于我不能指望客户端在文本模式下工作(并且不希望他们这样做 - 搞乱代码的风险太大),我需要一个可以完全在可视模式下执行的解决方案。

解决方案的第 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 样式表为用户提供尽可能多的所见即所得表示。现在,在编辑器中,对字幕的处理有所不同:仅在文本模式下可用的短代码呈现为 dl 标签,而不是 figure 等,用于 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】:

好的,所以我自己找到了答案:要更改编辑器 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 父级中,而且还作为class 属性写入[caption] 短代码,这是保存到数据库中并且在真实页面上的代码被转换为相应的figure 标记,包括类。因此,在我的问题中我发布为“解决方案的第 1 部分”的 jQuery 函数根本不再需要。

为父级添加的.removeAttr('class') 还确保在更改自定义类时删除任何先前的自定义类。唯一不可能的事情是在 [caption] 短代码中包含其他类(除了额外添加的“wp-caption”),但无论如何我都不需要。

【讨论】:

以上是关于将自定义类插入到由 tinyMCE 通过 jQuery 呈现的 WYSIWIG 输出中(在 Wordpress 中处理带有标题的图像)的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义 AxisItem 添加到现有的 PlotWidget?

如何将自定义sql附加到Spring Data JPA插入/更新

tinymce 将跨度插入列表标签

JSON 写入错误中的类型无效,尝试通过 JSON 将自定义类发送到 .NET Web 服务

您可以将 CSS 添加到由自定义字段创建的 CSS 类的子类中吗?

将自定义数据属性插入 JQuery DataTables