[Zope] DTML rendering from python?

Michiel Toneman michiel@ylnd.com
23 Jan 2003 16:02:35 +0100


Hi Dylan, hi Andy

Great answers, very true and also useful, thanks. "Don't do it that
way!" has in the past been some of the best advice given to me.

(Un?)Fortunately, I just put the "<p><dtml-var id></p>" in there as an
example to simplify the explanation of my problem, and (I think) I have
a valid reason for wanting to do this. (I'd love some feedback on this.
If you decide I'm nuts anyway, I'll probably have agree with you ;-) )
 
> Second, use DTML how it's designed, namely for inserting dynamic 
> information into a pre-defined layout.

I wouldn't dream of putting HTML in that spot in the "real" application,
but I'm a bit of a HTML purist, and I can't bear to see content loose on
a page without a proper HTML "p" wrapper ;-) 

What I'm actually doing is building a Content Management system for
which the layouts are not pre-defined. The content manager edits content
using structured text. The getHTML function takes the structured text,
translates this into a HTML snippet. This part is easily achieved in
DTML only. Now it gets tricky, though. I need to insert small "info
boxes" into the html. These are "floated" just after a paragraph tag.
Not all paragraphs have such a floating info-box, this is selectable by
the content manager.

The HTML might look like this:

----------------------------------------------------------
<h2>Lorem ipsum dolor sit elitr</h2>
  <p> 
    <div style="float:right; width: 150px;"> 
      <img src="images/voorbeeld4.jpg" alt="voorbeeld" /><br />
      Lorem ipsum dolor
    </div>
    Sed diam nonumy eirmod tempor invidunt ut labore et 
    dolore magna aliquyam erat, sed diam voluptua. 
  </p>
----------------------------------------------------------

where the "div" is opional. This is the part that DTML can't handle.
To do this, I feed the HTML Snippet to the DOM parser, locate all the
paragraphs, and insert a "dtml-var" tag just after the "p" tag where
ever a "floating box" should be present. 

I have thus preprocessed the structured-text into resultant DTML, for
which I'd like to let the DTML renderer do the heavy lifting. I was
hoping that simply rendering getHTML in a DTML document would do the
trick, but the return value is output "raw" into the DTML document.

My "real" code therefore looks like:

---------------------------------------------------------------

from StructuredText import DocumentClass
from StructuredText import HTMLClass
from xml.dom.minidom import parse, parseString


..snip...

    def getHTML(self):
        "Returns HTML for page"
        #return self._htmltxt
        Doc  = DocumentClass.DocumentClass()
        HTML = HTMLClass.HTMLClass()
        text = Doc(ST.StructuredText(self._htmltxt))
        html = "<div>" + HTML(text, level=2, header=0) + "</div>"
        dom  = parseString(html)
        pars = dom.getElementsByTagName("p")

        parcount = 0
        for i in pars:
            parcount += 1
            c = dom.createComment("#var par%d" %parcount)
            ref = i.firstChild
            i.insertBefore(c, ref)

        html = dom.toxml()

-----------------------------------------------------------

I'd be grateful for any feedback. Either an alternative approach, or a
way to render getHTML as DTML in a DTMLDocument. 

Sorry for the long posting.

Greetings,

Michiel