在Visual和HTML选项卡之间自由切换


21

因此,以不同的旗号多次提出了这个问题,但是我想提出一个统一的思路,以最终解决该问题。

在WordPress中,默认情况下,当在TinyMCE中的HTML和Visual编辑器之间来回切换时,某些标签会从内容中剥离出来,并且会发生其他奇怪的功能。编写更有效的HTML代码的两种已知解决方法是使用使用过滤器删除wp_auto_p函数,以及安装TinyMCE Advanced并启用“停止删除p&br标签”选项。

不幸的是,这只做得很好。

以下面的示例为例:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre>
&lt;script type=&quot;text/javascript&quot; src=&quot;/path/to/jquery.easycolumns.js&quot;&gt;&lt;/script&gt;
</pre>

如果我在HTML编辑器中键入了此代码,并且上面列出的两个选项均已启用,那么当我在两个不同的编辑器之间切换时,不会发生任何事情,这是预期的。不幸的是,保存时,代码会自动转换为以下形式:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre>
<script type="text/javascript" src="/path/to/jquery.easycolumns.js"></script>
</pre>

如您所见,pre标记内的所有实体都被转换回实际的HTML字符。然后,如果我再次保存同一篇文章,则会得到类似以下内容的信息:

<h2>How does it work?</h2>
<p>In order to use jQuery Easy Columns, you must install it as you would any other jQuery plugin.  First, download the zip file using the button above.  After downloading the file, extract it to a location of your choice, and move the extracted folder to your server using your favorite FTP client.  After moving the plugin to your server (and of course calling the jQuery source into your document), call it in on your site using the following snippet of code:</p>
<pre><br />
<script type="text/javascript" src="/path/to/jquery.easycolumns.js"></script><br />
</pre>

请注意,Wordpress实际上会将br标签注入帖子中。毋庸置疑,当此帖子已更新几次后,在前端查看它时,显示位置与预期的显示位置不符。

我似乎摆脱所有添加的“格式化功能”的唯一方法是通过我的配置文件禁用Visual编辑器。

考虑到我是专业的Web开发人员,这对我来说是一个很好的解决方案。对于我的客户来说,这种解决方案绝非优雅。我的客户大部分将使用可视化编辑器。我的许多客户不是很精通技术,有时在布局中断时需要我修复他们的帖子。这限制了我只能使用视觉编辑器,因为我不能更改为HTML编辑器而不必担心会破坏布局。

主要是(而且我认为有很多社区可以从此答案中受益),我可以采取哪些明确的步骤来确保以下各项:

  1. 可以从Visual或HTML编辑器中编辑帖子。
  2. 在两个标签之间切换时,帖子的内容不会进行任何修改。
  3. 从HTML编辑器保存帖子时,不会添加任何额外的内容。
  4. 从HTML编辑器保存帖子时,不会转换任何实体。
  5. 奖励:从HTML编辑器保存帖子时,包装在pre标记内但尚未转换为实体的任何代码(例如HTML)都将自动转换为实体。

本质上,如果我们可以通过使用第三方插件在TinyMCE中创建上述行为,则可以通过使用TinyMCE来平息所有其他有关虚假格式的问题。我觉得许多人都可以从中受益。

似乎可以从WYSIWIG编辑器中获得某些功能,这似乎是合乎逻辑的,但与此相反。根据所有逻辑和原因,Wordpress内置的格式化功能在当前设置中几乎没有用。在我看来,如果他们想使用这些格式设置选项,则最好的选择是启用一个或另一个编辑器,而不是同时启用两者。

并且请:不要用“解决”其他WYSIWIG编辑器的变通办法和下载来回答此线程。这是需要纠正的Wordpress核心的根本问题(尽管不是真正的错误)。

编辑:好的,我一直在努力,并且我认为逆向工程将是解决此问题的最佳方法。因此,现在,我已经禁用了wpautop(为清楚起见,它是一个挂接到“ the_content”过滤器上的函数,用于在显示文本之前(而不是在保存文本时)添加p和br标签。我认为存在一些混淆关于此功能的运行方式,wpautop不负责您在编辑器选项卡之间切换时看到的更改。这完全不同。

无论如何,我禁用了wpautop,这是使用HTML编辑器时的一种好习惯。从那时起,我禁用了可视编辑器,使其首先从保存帖子时出现的html实体错误开始。感谢一个C. Bavota的帮助,我找到了一个片段,可以将HTML编辑器中的所有标签转换为等效的实体,然后再将其显示在网站的前端(来源:http : //bavotasan.com/2012/convert -pre-tag-contents-to-html-entity-in-wordpress /)。

#add_filter( 'the_content', 'pre_content_filter', 0 );
/**
 * Converts pre tag contents to HTML entities 
 *
 * This function is attached to the 'the_content' filter hook.
 *
 * @author c.bavota
 */

function pre_content_filter( $content ) {
        return preg_replace_callback( '|<pre.*>(.*)</pre|isU' , 'convert_pre_entities', $content );
}


function convert_pre_entities( $matches ) {
        return str_replace( $matches[1], htmlentities($matches[1] ), $matches[0] );
}

add_filter( 'the_content', 'pre_content_filter', 10, 2 ); 

这样可以有效地消除Wordpress通过绕开保存时将所有实体转换为标签的问题。现在,您可以使用HTML编辑器,并在“ pre”标签之间编写标准代码,而无需自己进行实体转换。这样可以解决Wordpress中与实体转换有关的所有问题,并确保所有内容都能正确显示在前端。现在,我们需要弄清楚要修改选项卡之间来回单击时遇到的行为,可以采用哪些方法。现在看来,当从HTML转到可视选项卡时,HTML选项卡的内容将由javascript解释或尝试提供有关内容外观的实时更新。这将导致处理标签(在HTML选项卡中以非实体形式显示),而不是显示它们。然后,当切换回HTML标签时,TinyMCE似乎会传递当前数据。这意味着当您切换回去时,您将失去HTML结构。我们需要找出一种方法,告诉TinyMCE将pre标签中的所有内容转换为等效实体,然后再将其加载到窗口中(本质上是我们在前端所做的后端版本,但是使用tinymce和javascript而不是php和hooks),以便显示而不是处理。有什么建议吗?等效实体,然后再将其加载到窗口中(本质上是我们在前端所做的后端版本,但使用tinymce和javascript而不是php和hooks),因此将其显示而不是进行处理。有什么建议吗?等效实体,然后再将其加载到窗口中(本质上是我们在前端所做的后端版本,但使用tinymce和javascript而不是php和hooks),因此将其显示而不是进行处理。有什么建议吗?

编辑2

经过更多研究后,在显示pre标签中的实体时将其转换为pre标签中内容的效果很好,但是说我有一篇博客文章,内容如下:

“下一步,我们需要将此行添加到我们的HTML文件中:<p>世界,您好!</ p>”

查看这一行,您可以知道该代码应该在网站上显示,而不是经过解析,但是,保存帖子时,这些实体将在下一次帖子编辑加载时进行解码,并在以后的每次保存中都保存下来作为原始html标签,这导致它们在前端被解析。到目前为止,我唯一想到的解决方案是使用与pre相似的代码编写“ code”标签,然后将一个小的衬纸包裹在“ code”标签中,将大块包装在“ pre”标签。还有其他想法吗?


2
好贴。TinyMCE只是让我头疼。我最近将其切换为CKEditor,但现在说它如何保持还为时过早。您在帖子中没有提到的一个问题是从Word粘贴时的额外cr **。
2013年

我曾经在自己的站点上使用CKeditor一段时间,以为这是我需要的解决方案,但是不幸的是,这里的问题在于Wordpress处理和格式化从TinyMCE接收到的数据的格式,而不是TinyMCE本身。有一种方法可以在正确的时间连接到Wordpress,以产生所需的效果。但是,无论CKeditor绝对是一个不错的插件,但不是我想要的。
Thought Space Designs 2013年

1
另外,您知道TinyMCE的“厨房水槽”中的“单词粘贴”功能正确吗?从Word粘贴时,应该可以解决“多余的废话”问题。
Thought Space Designs 2013年

7
很好的问题。补充一下:我会悬赏200英镑来奖励解决方案。我将等到实际上有答案为止,这样赏金才不会过早到期。
fuxia

Answers:


5

好吧,所以我已经大量更新了这个问题,并且这个问题开始变得超负荷,所以我认为即使不是一个完整的问题,我也会以此为答案。

从@bueltge的答案推论得出,我实际上回过头来,发现了他之前的帖子。在那篇文章中,列出了一个我从未见过的插件:“保留的HTML编辑器标记”。这个插件已经有一段时间没有更新了,但是我只是用WP 3.6.1对其进行了测试,并且功能齐全。该插件会自动处理wpautop,为在可视化编辑器中插入br和p标签提供统一的格式,并在选项卡之间切换时保留您的标记。

出于我自己的目的,我使用自己的功能扩展了此插件:保存时将“ <code>”标签中的所有html标签自动转换为它们各自的实体。这意味着您可以在文本选项卡中的代码标签中编写标准HTML代码,然后将其保存,并且pre标签中的所有内容都将转换为实体,以便在网站的前端和可视化编辑器中正确显示。这不是我找到的最优雅的解决方案,但似乎可行。激活插件后,将此行添加到您的functions.php中:

function code_content_conversion_filter( $content ) {
        return preg_replace_callback( '|<code.*>(.*)</code|isU' , 'convert_entities', $content );
}

function convert_entities( $matches ) {
        return str_replace( $matches[1], htmlspecialchars($matches[1], ENT_QUOTES | ENT_HTML5, 'UTF-8', FALSE ), $matches[0] );
}

add_filter( 'content_save_pre', 'code_content_conversion_filter', 0);

现在,只需在代码标记之间键入任何有效的HTML,然后在保存时,弹出编辑器时将它们全部转换为实体。这使您可以更快地编写代码。现在,唯一仍然是一个问题是,如果您有一个带有嵌套代码标签和HTML的“ pre”字段,然后转到可视选项卡并尝试在代码中插入新行,即br标签被注入HTML的代码标签中。在TinyMCE中必须有一个禁用此选项的选项。无论如何,只要您在“文本”选项卡中编辑前置字段,就可以在这些选项卡之间自由切换,在任何选项卡下添加任何内容,从任何一个选项卡保存,而不必担心格式混乱!

这实际上解决了我最初的问题的全部5点。第二点仍然有些不稳定,但是我相信对于大多数人来说,这可以解决这个问题。我确实计划在某个时候筛选此插件,并提取必要的部分,将其与我的发现相结合,然后重新打包以供公众下载。我的目标是创建一个简单的一键安装插件,该插件可以按预期运行。

希望这对大家有帮助!


3

首先,我认为自WP 3.5版以来,此问题已解决;参见火车票19666。但是tinyMCE那里有一个钩子,使我们有机会在编辑器中更改内容,并且您不得在前端的输出上进行解析。

一个小的源脚本。对于当前的WP版本,我没有进行测试,对于客户而言,这是一个较旧的解决方案。

通过插件添加此源并增强标记。该功能检查html标签<pre,如果存在,则将其替换为标记。

add_filter( 'tiny_mce_before_init', 'fb_correction_content_tiny_mce' );

function fb_correction_content_tiny_mce( $init ) {

    $init['setup'] = "function(ed) {
        ed.onBeforeSetContent.add( function(ed, o) {

            if ( o.content.indexOf('<pre') != -1 ) {
                o.content = o.content.replace(
                    /<pre[^>]*>[\\s\\S]+?<\\/pre>/g,
                    function(a) {
                        return a.replace(/(\\r\\n|\\n)/g, '<br />');
                    }
                );
            }
        } );
    }";

    return $init;
}

3.5中解决的问题不是完全相同的问题。我的问题不是从Visual切换到HTML时会删除换行符,而是我的所有标签(甚至是pre标签中的标签)似乎都被解释为源HTML,并且由于未编码为实体而无法显示在HTML面板中。此功能是否会修改TinyMCE的行为,以便显示而不是处理pre中的HTML?
Thought Space Designs 2013年

在一个小的测试工作中,实体将保持从html到可视的切换,并返回并保存内容。
bueltge

我将在今天晚些时候对此进行测试,以确保它能够完成我想要的功能。
Thought Space Designs

好的,等待您的回复,也许有帮助。我已经使用您的问题示例中的源对它进行了测试。如果我理解不正确,请在此处进行增强。
bueltge

看到我的回答...
Thought Space Designs 2013年

0

我有类似OP一个问题,但对我来说有一个问题,在保持<h1><div>。这是我在“文本”和“可视”选项卡之间切换时要保留的内容: div中的h1,div内部

每次我切换选项卡都<h1>消失了。我做了很多搜索,对于Wordpress 4.7.3,我发现那里有很多过时的修复程序。TinyMCE的市长从版本3升级到了版本4。针对v.3的解决方案不适用于v.4。仔细阅读并阅读TinyMCE版本4的原始文档后,我特别针对我的情况提出了解决方案:

  1. 安装高级TinyMCE配置插件
  2. 将TinyMCE valid_children设置为+div[h1],h1[div]
  3. 我另外配置了indent=trueforced_root_block=false并且schema=html5(当我阅读forced_root_block说明时,我将其理解为wpautop替代品)

结果我得到了这个(并且它可以抵抗制表符的切换) 在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.