TinyMCE编辑器正在破坏我美丽的HTML语言

时间:2016-01-15 作者:Dominic P

这几乎与以下内容完全相同:How to make Wordpress and TinyMCE accept <a> tags wrapping block-level elements as allowed in HTML5?HTML5, WordPress and Tiny MCE issue - wrapping anchor tag around div results in funky output

我的问题是建议的解决方案(tiny_mce_before_init 过滤器)似乎无法解决我的问题。我的HTML如下所示:

<a href="#">
    <img src="path/to/file.jpg" />
    <p>Some amazing descriptive text</p>
</a>
在HTML5中是完全合法的。但是,WP编辑器不喜欢它,并将其转换为:

<a href="#">
    <img src="path/to/file.jpg" />
</a>
<p>Some amazing descriptive text</p>
这当然破坏了我的布局。有人知道我有什么方法可以阻止这种行为吗?我不能放弃编辑器的视觉组件而坚持纯文本。欢迎提出任何建议。

我想说清楚,当我使用下面的代码时(suggested here), 这个<p> 允许标记保留在锚内,但会随&nbsp; 每次在视觉和文本模式之间切换时都会倍增的实体。

add_filter(\'tiny_mce_before_init\', \'modify_valid_children\');

function modify_valid_children($settings){
    $settings[\'valid_children\']="+a[div|p|ul|ol|li|h1|h2|h3|h4|h5|h5|h6]";
    return $settings;
}

2 个回复
最合适的回答,由SO网友:Bryan Willis 整理而成

无论您将什么配置为有效子级,WordPress都以一种非常独特的方式处理p标记和换行符。如果您还没有注意到,您可能最终会注意到,当从文本编辑器切换到可视化编辑器并返回时<p> 标签被剥离,类似于前端发生的情况。阻止这种情况发生的一种方法是<p> 标记自定义类。

<p class="text">This p tag won\'t get removed"</p>.

虽然 这样可以防止你的p标签被剥离,也不会解决你的问题,因为你在前端的标记仍然被弄脏了。你可以DISABLE wpautop。如果您这样做并在有效子级中包含p,这将修复您的Issue。

OPTION 1 : Disable Autop and Set Valid Children

remove_filter( \'the_content\', \'wpautop\' );
add_filter(\'tiny_mce_before_init\', \'modify_valid_children\', 99);
function modify_valid_children($settings){     
    $settings[\'valid_children\']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    return $settings;
}
我应该提醒您,当您从HTML编辑器切换回TinyMCE 您的HTML将被销毁。解决方法是对某些帖子类型完全禁用TinyMCE,如下面的选项2所示。

<小时>

OPTION 2 : Disable Auto P, TinyMCE, and Set Valid Children

remove_filter( \'the_content\', \'wpautop\' );
add_filter(\'tiny_mce_before_init\', \'modify_valid_children\', 99);
function modify_valid_children($settings){     
    $settings[\'valid_children\']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    return $settings;
}
add_filter(\'user_can_richedit\', \'disable_wyswyg_to_preserve_my_markup\');
function disable_wyswyg_to_preserve_my_markup( $default ){
  if( get_post_type() === \'post\') return false;
  return $default;
}
不过对大多数人来说 不是选项

那么还有什么其他选择呢?我注意到的一个解决方法是使用span tag with a class 确保有is no white space between your HTML tags. 如果这样做,您可以使用上面的选项一,避免同时禁用TinyMCE。请记住,您还必须向样式表中添加一些CSS才能正确显示范围。

OPTION 3: Option 1 + Styled Span Tags

HTML

<a href="#"><img src="https://placehold.it/300x200?text=Don%27t+P+On+Me" alt="" /><span class="noautop">Some amazing descriptive text</span></a>
样式表中的CSS

.noautop {
    display: block;
}
<小时>

Option 4: Use the built in media uploader shortcode

shortcode media uploader

<起初我忘了这个,但是[caption] 短代码如下所示:

[caption id="attachment_167" align="alignnone" width="169"]
    <img class="size-medium wp-image-167" src="http://example.com/example.png" alt="" width="169" height="300" />
    awesome caption
[/caption]
输出如下:

<figure id="attachment_167" style="width: 169px" class="wp-caption alignnone">
    <img class="size-medium wp-image-167" src="http://example.com/example.png" alt="" width="169" height="300" />
    <figcaption class="wp-caption-text">Some amazing descriptive text</figcaption>
</figure>
如果你不想要数字标签,你可以使用一个插件,比如custom content shortcode 允许您执行以下操作:

[raw] <p>this content will not get filtered by wordpress</p> [/raw]
<小时>

Why can\'t the editor just work how I want though?

在过去的几年里,我花了无数个小时试图让它正常工作。偶尔我会想出一个完美的解决方案,但WordPress会推送一个更新,让一切再次混乱。我所找到的唯一一个完全可行的解决方案是,它会引导我找到最好的答案。

Option 5 : Preserved HTML Editor Markup Plus

所以,省去你的头痛吧,就这样做吧。默认情况下,保留的HTML编辑器标记Plus仅影响新页面。如果要更改已创建的页面,必须转到www.example.com/wp-admin/options-writing.php 并编辑插件设置。您还可以更改默认的换行符行为。

注意:如果您决定使用此选项,请确保在启动新的WordPress更新时检查支持线程。有时,更改会把事情搞砸,所以最好确保插件在新版本上工作

<小时>

Extra Credit: Debugging Your Problem / Editing Other TinyMCE Options

如果要手动检查并轻松编辑TinyMCE配置,就像使用过滤器一样,可以安装advanced TinyMCE config. 它允许您查看ALL 并从简单界面编辑它们。您还可以像使用过滤器一样添加新选项。这让事情变得更容易理解。

例如,我既有那个标记,又保留了HTML编辑器标记Plus。下面的屏幕截图是高级TinyMCE配置管理页面。虽然截图截取了90%的真实内容,但您可以看到它显示了可编辑的有效子项以及哪些子项Preserved HTML Editor Markup Plus 已添加。

TinyMCE editor

这是一种非常有用的方法,不仅可以完全定制编辑器,还可以查看正在发生的事情。您甚至可以找出问题的原因。在启用保留的HTML编辑器标记时,我自己查看了这些参数,然后看到了一些可以添加到自定义过滤器的附加选项。

function fix_tiny_mce_before_init( $in ) {

    // You can actually debug this without actually needing Advanced Tinymce Config enabled:
    // print_r( $in );
    // exit();

  $in[\'valid_children\']="+a[div|p|ul|ol|li|h1|span|h2|h3|h4|h5|h5|h6]";
    $in[ \'force_p_newlines\' ] = FALSE;
    $in[ \'remove_linebreaks\' ] = FALSE;
    $in[ \'force_br_newlines\' ] = FALSE;
    $in[ \'remove_trailing_nbsp\' ] = FALSE;
    $in[ \'apply_source_formatting\' ] = FALSE;
    $in[ \'convert_newlines_to_brs\' ] = FALSE;
    $in[ \'verify_html\' ] = FALSE;
    $in[ \'remove_redundant_brs\' ] = FALSE;
    $in[ \'validate_children\' ] = FALSE;
    $in[ \'forced_root_block\' ]= FALSE;

    return $in;
}
add_filter( \'tiny_mce_before_init\', \'fix_tiny_mce_before_init\' );
不幸的是,这种方法不起作用。更新帖子和/或在编辑器之间切换时,可能会出现一些regex或JavaScript。如果您查看保留的HTML编辑器源代码,您可以看到它在管理方面做了一些JavaScript工作,因此我的最后一点建议是检查how the plugin works 如果要在主题中添加此功能。

不管怎样,我为我的回答走到这一步的人感到抱歉。我只是想和大家分享一下我与WordPress编辑器打交道的经验,希望其他人不会像我一样花上几个小时来试图解决这个问题!

SO网友:Rob

首先:非常感谢布莱恩的出色回答,这些回答记录了他所遇到的困难。

作为自己实验的结果(包括Bryan的一些建议),我认为以下插件可以极大地帮助consistency when swithing between html and visual editor: 高级编辑器工具(以前为TinyMCE Advanced)-https://wordpress.org/plugins/tinymce-advanced/.

乍一看,插件没有达到我预期的效果。在第二次转弯时,我发现了一个设置参数;保留段落标记;。视觉编辑器不再删除<p><br> html编辑器中的标记。更重要的是:在两个编辑器之间切换后,我发现几乎所有的空行都消失了,取而代之的是许多<p></p> 取而代之的是。缺点是,可视化编辑器中的可视化表示显示了一些小怪癖,但这被认为是一个小问题。对我来说,这一点很重要:你确切地知道光标在哪里,因为几乎是所见即所得。毕竟:与预览/最终结果相比,如果没有此特定设置,视觉编辑器也会有渲染缺陷。

我觉得我现在完全可以控制文本的间距了。即使在可视化编辑器中单击Return(或shift Return),也会生成额外的标记。另一个缺点是:您只能在html视图(和最终视图)中看到,可视化编辑器不会显示额外的空间。那又怎样?它不再重要breaking my beautiful HTML!