At certain points in the HTML, I need to close every open tag, insert a DIV, then open all tags again, in order
I am dealing with HTML that's been generated with FCKeditor. So it will look something like this:
<p>Paragraph</p>
<ul>
<li>List item</li>
</ul>
No head
tag, no body
tag, just a snippet of HTML.
I am trying to add support for certain variables that, when inserted into the HTML, will be replaced with dynamic content. So the HTML, variable inserted, might look like this:
<p>Here's a variable: {widget}</p>
I want to replace {widget}
with this:
<div class="widget">Hi, I'm a widget.</div>
FCKeditor encapsulates content (rightly) into paragraphs when you insert a line break. So if I did a straight replace, the resulting HTML would be this:
<p>Here's a variable: <div class="widget">Hi, I'm a widget.</div></p>
That's not going to work because the div
tag is inside of the p
tag. So what I want to do is close the paragraph and insert the DIV after it:
<p>Here's a variable: </p>
<div class="widget">Hi, I'm a widget.</div>
Let's take this example:
<p class="someclass">Here's a <strong>variable: {widget} more</strong> content
after</p>
I would want this result:
<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 开发者_Go百科after</p>
At every instance of {widget}
in HTML snippet, I need to make a "break" in the HTML. Which is to close every open tag, insert the widget code, then open them all again in order.
Is this possible using a PHP HTML parser? If so, how would I go about it?
I would suggest an entirely different approach. (F)CKEditor can already do what you want. Just try to add a table in the middle of a paragraph. It will close the inline tag stack, add the table, and reopen the stack again.
I suggest that, instead of having your users write {widget}, you write an (F)CKEditor plugin that adds the widgets for you. You can take a look at the code for the table button (or any other block-level element) to see how (F)CKEditor inserts them.
There are two things you can do when a user hits the "widget" button. Eitther you insert some custom tag such as <widget type="foo" />
, or you insert a HTML tag that you can recognise later on, like <div class="widget foo"></div>
.
With some extra elbow grease you can even make this fancier by actually loading the widget itself, wrapped in such tags. That way, the user would see exactly the same in the editor window as when it was stored. When the editor saves to the server, simply empty the tags wrapping the widget to get rid of it.
Example workflow (cursor marked by | sign):
User types text:
<p>foo bar| baz</p>
User hits "widget" button:
<p>foo bar</p>
<div class="widget foo"> ... contents of "foo" widget ... </div>
<p>|baz</p>
When saving, drop the widget contents:
<p>foo bar</p>
<div class="widget foo"></div>
<p>baz</p>
When displaying the saved contents, parse for div tags with a "widget" class and dynamically fill it:
<p>foo bar</p>
<div class="widget foo"> ... contents of "foo" widget ... </div>
<p>baz</p>
This could be done post-process when saving with regex if you were pretty careful about what you allowed. Alternatively, I do a fair amount of juggling on the front end with my editor (CKEditor) output, combining the user-input content plus things that I jam in both between and around the string that I parse and regex.
Another option to be explored is the BBCode plugin that CKEditor has added. Having been a longtime user of FCK plus a current user of CK, I can tell you that it's well worth the time to make the upgrade. And, according to the CK Developer site, it claims to be built-in. I also found a plugin that will allow BBCode. Both could easily be adapted for your purpose.
Finally, if you're adventurous and confident with Javascript, the HTML Processor can be hacked to do quite a few things. For instance, CK now outputs with styles rather than traditional HTML, and my editor does strictly HTML Emails which don't support style declarations so well. So, I hacked the HTML Processor's code to output everything with height=, width=, align=
etc rather than style="height=x; width=x"
etc.
精彩评论