代码之家  ›  专栏  ›  技术社区  ›  Johannes

将自定义类插入Tinymce通过jquery呈现的wysiwig输出(在WordPress中处理带标题的图像)

  •  1
  • Johannes  · 技术社区  · 5 年前

    前言/初始问题:

    我希望用户能够使用可视化编辑器(即“经典编辑器”)将自定义类应用于WordPress文章中的图像-我不能使用Gutenberg,因为这些是用pods创建的自定义文章类型,而block编辑器不可用。这些类在我创建的样式表中定义。他们的主要特点是 width 媒体查询中较小屏幕的百分比值和固定的100%值-我不喜欢固定图像大小的WordPress系统,在某些点/屏幕宽度上浮动时看起来很可笑。我正在使用“tinymce自定义样式”插件将这些类放入编辑器的“格式”菜单中。用户可以通过选择图像并从该菜单中选择类来将它们应用于图像。

    如果这些类应用于 不要 有字幕 :它们呈现为常规 img 标签,可选 a 如果选择了任何链接选项,则它们周围的标记:类具有预期的效果,应用其中的所有样式。

    然而, 如果用户决定使用标题,则图像的处理方式完全不同 :wordpress自动创建 figure 它周围的标签包含 IMG 和A figcaption 元素。尽管内部WordPress类 align-left 以及 宽度 height 属性现在应用于 图形 标记而不是 IMG 标签, 自定义类*不*移动到 图形 标签 ,但仍然是 IMG 标签,因此完全失去了它的效果: 图形 元素(及其包含的图像)将不具有在自定义类中定义的百分比宽度,而是由 宽度 高度 属性。

    整个事情变得更加复杂,因为, 在Tinymce编辑器中, 图形 元素根本不显示 :在“文本模式”(=html代码)中,数字由 [caption] 在实际页面上呈现为 图形 如上所述,对于编辑器的所见即所得模式,元素呈现为带有类的DIV .mceTemp 包含一个 dl 包含图像的标记 dt 标签和标题文本 动态链接库 标签。这个 [标题] shortcode也是保存到数据库中的代码,btw。

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

    由于我不能期望客户机在文本模式下工作(也不希望客户机在代码混乱的情况下工作),所以我需要一个完全可以在可视模式下执行的解决方案。

    解决方案的第1部分:

    因为在可视模式下,不能将类应用于 图形 标记,我需要一种方法来删除应用于 IMG 来自这些标签 IMG 标记并将它们应用到其父级 图形 标签。对于最后一个页面输出,我创建了一个jquery脚本,它执行以下操作:在页面加载时, 搜索应用于的自定义类的实例 IMG 包装的标签 图形 标记,从 IMG 标记并将类添加到祖先 图形 标签 :

    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输出,见上文。

    因此,上面的脚本适用于在这里为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'});
      });
    });
    

    (在这里,我尝试将自定义类添加到 动态链接库 容器包装 div.mceTemp 一个内联元素,以便 动态链接库 标签生效。)

    但是:它根本不起作用,即输出代码不会以任何方式改变。可能是因为编辑器在iframe中呈现输出,我不能使用这些方法访问它(我能吗?).

    所以我的问题是:我如何才能完成将这个脚本应用到代码tinymce呈现为其所见即所得输出的任务?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Johannes    5 年前

    好吧,所以我自己找到了答案:要更改编辑器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] shortcode,这是保存到数据库的代码,在实际页面上转换为相应的 figure 包含类的标记。因此,在我的问题中,作为“解决方案的第1部分”发布的jquery函数不再是必需的。

    增加的 .removeAttr('class') 对于父类,还确保在更改自定义类时删除任何以前的自定义类。唯一不可能的是在 [标题] 短代码(除了额外添加的“wp caption”),但我不需要。