通过 jQuery 将自定义 类 插入由 tinyMCE 呈现的 WYSIWIG 输出(在 Wordpress 中处理带有字幕的图像)
Insert custom classes into WYSIWIG output rendered by tinyMCE via jQuery (handling images with captions in Wordpress)
前言/初始问题:
我希望用户能够使用可视化编辑器(即 "classic editor" / tinyMCE - 我无法使用Gutenberg,因为这些是使用 PODS 创建的自定义 post 类型,其中块编辑器不可用)。这些 classes 是在我创建的样式表中定义的。他们的主要特征是 width
有一个百分比值和一个固定的 100% 值用于媒体查询中的较小屏幕 - 我不喜欢固定图像大小的 Wordpress 系统,在某些时候/屏幕宽度在浮动时看起来很荒谬.我正在使用 "TinyMCE Custom Styles" 插件将这些 classes 放入编辑器的 "Format" 菜单中。用户可以通过 select 编辑图像并从该菜单中选择 class 将它们应用于图像。
如果将这些 class 应用于 没有标题的图像,这将完美工作:这些是呈现为常规 img
标签,如果选择任何 link 选项,则可以选择在它们周围使用 a
标签: class 具有预期效果,其中的所有样式都适用。
但是,如果用户决定使用标题,图像的处理方式将完全不同:Wordpress 会自动在其周围创建一个 figure
标签,其中包含 img
和一个 figcaption
元素。虽然内部 Wordpress classes 像 align-left
和 width
和 height
属性现在应用于 figure
标签而不是 img
标签, 自定义 class * 没有* 移动到 figure
标签 ,但仍然是 img
标签的一个属性,因此完全失去了它的作用: figure
元素(及其包含的图像)不会具有自定义 class 中定义的百分比宽度,而是 width
和 [=22= 定义的固定宽度]属性。
整个事情变得更加复杂,因为 在 tinyMCE 编辑器中,figure
元素根本没有出现:在 "text mode"(= HTML 代码)该图由 [caption]
短代码表示,如上所述,在实际页面上呈现为 figure
元素,并且用于编辑器的所见即所得模式呈现为 div 和 class .mceTemp
包含 dl
标签,该标签包含 dt
标签中的图像和 [=34= 中的标题文本] 标签。 [caption]
短代码也是保存到数据库中的内容,顺便说一句。
现在,虽然 可以将 class 属性写入 "text mode" 中的短代码(即 HTML 代码),在视觉模式下无法 select figure/caption/shortcode/whatever - 它只能 select(并应用 classes)图片本身,在这种情况下是无用的(见上文)。
由于我不能期望客户端在文本模式下工作(并且不希望他们这样做 - 搞乱代码的危险太大),我需要一个可以完全在可视模式下执行的解决方案。
解决方案的第 1 部分:
由于在可视化模式下不能将 classes 应用于 figure
标签,我需要一种方法来删除应用于 img
标签的自定义 classes这些 img
标签并将它们应用到他们的 parent figure
标签。对于最终的页面输出,我创建了一个 jQuery 脚本,它确实做到了这一点:在页面加载时,它 搜索我的自定义 classes 应用于 img
标签的实例包装在 figure
标签中,从 img
标签中删除自定义 class 并将 class 添加到祖先 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 输出 - 见上文。
因此,上面的脚本适用于此处为所见即所得显示呈现的代码:
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'});
});
});
(这里我尝试将自定义 class 添加到 dl
容器中,并使包装 div.mceTemp
成为内联元素,以使 dl
的样式标签生效。)
但是:它根本不起作用,即输出代码没有以任何方式改变。可能是因为编辑器在 iframe 中呈现输出,我无法使用这些方法访问它(可以吗?)。
所以这是我的问题:我怎样才能将此脚本应用于 tinyMCE 呈现的代码作为其 WYSIWIG 输出?
好的,所以我自己找到了答案:要更改编辑器 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'});
});
}
});
这实际上比我预期的还要好:它不仅将自定义 class 写入编辑器所见即所得输出中的临时 dl
父级,而且还作为 class
属性进入 [caption]
短代码,这是保存到数据库的代码,在实际页面上被转换为相应的 figure
标签,包括 class。因此,在我的问题中我发布为 "Part 1 of the solution" 的 jQuery 函数不再是必需的。
为父项添加的 .removeAttr('class')
还确保在更改自定义 class 时删除任何先前的自定义 class。唯一不可能的是在 [caption]
短代码中包含其他 classes(除了额外添加的 'wp-caption'),但我不需要那个。
前言/初始问题:
我希望用户能够使用可视化编辑器(即 "classic editor" / tinyMCE - 我无法使用Gutenberg,因为这些是使用 PODS 创建的自定义 post 类型,其中块编辑器不可用)。这些 classes 是在我创建的样式表中定义的。他们的主要特征是 width
有一个百分比值和一个固定的 100% 值用于媒体查询中的较小屏幕 - 我不喜欢固定图像大小的 Wordpress 系统,在某些时候/屏幕宽度在浮动时看起来很荒谬.我正在使用 "TinyMCE Custom Styles" 插件将这些 classes 放入编辑器的 "Format" 菜单中。用户可以通过 select 编辑图像并从该菜单中选择 class 将它们应用于图像。
如果将这些 class 应用于 没有标题的图像,这将完美工作:这些是呈现为常规 img
标签,如果选择任何 link 选项,则可以选择在它们周围使用 a
标签: class 具有预期效果,其中的所有样式都适用。
但是,如果用户决定使用标题,图像的处理方式将完全不同:Wordpress 会自动在其周围创建一个 figure
标签,其中包含 img
和一个 figcaption
元素。虽然内部 Wordpress classes 像 align-left
和 width
和 height
属性现在应用于 figure
标签而不是 img
标签, 自定义 class * 没有* 移动到 figure
标签 ,但仍然是 img
标签的一个属性,因此完全失去了它的作用: figure
元素(及其包含的图像)不会具有自定义 class 中定义的百分比宽度,而是 width
和 [=22= 定义的固定宽度]属性。
整个事情变得更加复杂,因为 在 tinyMCE 编辑器中,figure
元素根本没有出现:在 "text mode"(= HTML 代码)该图由 [caption]
短代码表示,如上所述,在实际页面上呈现为 figure
元素,并且用于编辑器的所见即所得模式呈现为 div 和 class .mceTemp
包含 dl
标签,该标签包含 dt
标签中的图像和 [=34= 中的标题文本] 标签。 [caption]
短代码也是保存到数据库中的内容,顺便说一句。
现在,虽然 可以将 class 属性写入 "text mode" 中的短代码(即 HTML 代码),在视觉模式下无法 select figure/caption/shortcode/whatever - 它只能 select(并应用 classes)图片本身,在这种情况下是无用的(见上文)。
由于我不能期望客户端在文本模式下工作(并且不希望他们这样做 - 搞乱代码的危险太大),我需要一个可以完全在可视模式下执行的解决方案。
解决方案的第 1 部分:
由于在可视化模式下不能将 classes 应用于 figure
标签,我需要一种方法来删除应用于 img
标签的自定义 classes这些 img
标签并将它们应用到他们的 parent figure
标签。对于最终的页面输出,我创建了一个 jQuery 脚本,它确实做到了这一点:在页面加载时,它 搜索我的自定义 classes 应用于 img
标签的实例包装在 figure
标签中,从 img
标签中删除自定义 class 并将 class 添加到祖先 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 输出 - 见上文。
因此,上面的脚本适用于此处为所见即所得显示呈现的代码:
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'});
});
});
(这里我尝试将自定义 class 添加到 dl
容器中,并使包装 div.mceTemp
成为内联元素,以使 dl
的样式标签生效。)
但是:它根本不起作用,即输出代码没有以任何方式改变。可能是因为编辑器在 iframe 中呈现输出,我无法使用这些方法访问它(可以吗?)。
所以这是我的问题:我怎样才能将此脚本应用于 tinyMCE 呈现的代码作为其 WYSIWIG 输出?
好的,所以我自己找到了答案:要更改编辑器 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'});
});
}
});
这实际上比我预期的还要好:它不仅将自定义 class 写入编辑器所见即所得输出中的临时 dl
父级,而且还作为 class
属性进入 [caption]
短代码,这是保存到数据库的代码,在实际页面上被转换为相应的 figure
标签,包括 class。因此,在我的问题中我发布为 "Part 1 of the solution" 的 jQuery 函数不再是必需的。
为父项添加的 .removeAttr('class')
还确保在更改自定义 class 时删除任何先前的自定义 class。唯一不可能的是在 [caption]
短代码中包含其他 classes(除了额外添加的 'wp-caption'),但我不需要那个。