【问题标题】:At certain points in the HTML, I need to close every open tag, insert a DIV, then open all tags again, in order在 HTML 中的某些点,我需要关闭每个打开的标签,插入一个 DIV,然后再次打开所有标签,按顺序
【发布时间】:2011-06-28 14:19:08
【问题描述】:

我正在处理使用FCKeditor 生成的 HTML。所以它看起来像这样:

<p>Paragraph</p>
<ul>
<li>List item</li>
</ul>

没有head标签,没有body标签,只是HTML的sn-p。

我正在尝试添加对某些变量的支持,这些变量在插入 HTML 时将被动态内容替换。因此,插入的变量 HTML 可能如下所示:

<p>Here's a variable: {widget}</p>

我想用这个替换{widget}

<div class="widget">Hi, I'm a widget.</div>

当您插入换行符时,FCKeditor 会(正确地)将内容封装到段落中。因此,如果我直接替换,生成的 HTML 将是这样的:

<p>Here's a variable: <div class="widget">Hi, I'm a widget.</div></p>

这是行不通的,因为div 标记在p 标记内部。所以我想要做的是关闭段落并在其后插入 DIV:

<p>Here's a variable: </p>
<div class="widget">Hi, I'm a widget.</div>

我们来看这个例子:

<p class="someclass">Here's a <strong>variable: {widget} more</strong> content 
after</p>

我想要这个结果:

<p class="someclass">Here's a <strong>variable: </strong></p>
<div class="widget">Hi, I'm a widget.</div>
<p class="someclass"><strong> more</strong> content after</p>

在 HTML sn-p 中 {widget} 的每个实例中,我都需要在 HTML 中进行“中断”。即关闭每个打开的标签,插入小部件代码,然后按顺序再次打开它们。

这可以使用 PHP HTML 解析器吗?如果是这样,我会怎么做?

【问题讨论】:

  • 这是一个很好的问题,我很想看看答案。抱歉,我无法提供任何帮助!
  • 哇,这很难。 DOM 不会,regex won't,...
  • 任何你使用 div 作为你的小部件内容的原因,如果你使用像 span 这样的内联元素,你会省去很多麻烦
  • @K Ivanov 小部件只是一个例子。会有许多不同类型的小部件。几乎所有这些都将包含块级元素。
  • @Jonah 感谢您提醒我funny regex link,但我永远不会指望正则表达式来解决这样的问题。

标签: php html dom replace html-parsing


【解决方案1】:

如果您对允许的内容非常小心,则可以在使用正则表达式保存时在后期处理中完成。或者,我在前端与我的编辑器 (CKEditor) 输出做了大量的杂耍,结合用户输入内容以及我在解析和正则表达式的字符串之间和周围的东西。

另一个需要探索的选项是 CKEditor 添加的 BBCode 插件。作为 FCK 的长期用户和 CK 的当前用户,我可以告诉你,花时间进行升级是非常值得的。而且,根据 CK Developer 网站,它声称是内置的。我还找到了一个允许 BBCode 的插件。两者都可以轻松适应您的目的。

最后,如果您喜欢冒险并且对 Javascript 充满信心,那么 HTML 处理器可能会被黑客入侵来做很多事情。例如,CK 现在输出样式而不是传统的 HTML,而我的编辑器严格执行 HTML 电子邮件,它不太支持样式声明。所以,我破解了 HTML 处理器的代码,用height=, width=, align= 等而不是style="height=x; width=x" 等输出所有内容。

【讨论】:

    【解决方案2】:

    我会建议一种完全不同的方法。 (F)CKEditor 已经可以做你想做的了。只需尝试在段落中间添加一个表格。它将关闭内联标签堆栈,添加表格,然后再次重新打开堆栈。

    我建议您编写一个 (F)CKEditor 插件来为您添加小部件,而不是让您的用户编写 {widget}。您可以查看表格按钮(或任何其他块级元素)的代码,了解 (F)CKEditor 是如何插入它们的。

    当用户点击“小部件”按钮时,您可以做两件事。要么插入一些自定义标记,例如&lt;widget type="foo" /&gt;,要么插入一个以后可以识别的 HTML 标记,例如 &lt;div class="widget foo"&gt;&lt;/div&gt;

    使用一些额外的肘部油脂,您甚至可以通过实际加载小部件本身来使这个更有趣,并包裹在这样的标签中。这样,用户将在编辑器窗口中看到与存储时完全相同的内容。当编辑器保存到服务器时,只需清空包装小部件的标签即可摆脱它。

    示例工作流程(由 | 符号标记的光标):

    用户输入文本:

    <p>foo bar| baz</p>
    

    用户点击“小部件”按钮:

    <p>foo bar</p>
    <div class="widget foo"> ... contents of "foo" widget ... </div>
    <p>|baz</p>
    

    保存时,删除小部件内容:

    <p>foo bar</p>
    <div class="widget foo"></div>
    <p>baz</p>
    

    在显示保存的内容时,使用“widget”类解析div标签并动态填充:

    <p>foo bar</p>
    <div class="widget foo"> ... contents of "foo" widget ... </div>
    <p>baz</p>
    

    【讨论】:

    • 其实,FCKeditor 处理我的自定义 DIV 的方式有点奇怪,但这是另一个问题的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2019-08-11
    相关资源
    最近更新 更多