[Zope] DTML Container?

Tres Seaver tseaver@palladion.com
Tue, 08 Feb 2000 11:30:09 -0600


Mike <mike@if-site.com> wrote:
> 
> Hello,
> 
> I wondered what is the simples (and efficient) way of implementing subj.
> 
> Let I explain first what it may be needed for.
> 
> Suppose we'd like to create a class modeling an article (newspaper
> article, for example). An article has attributes 'title' and 'body' and
> can contain zero or more photos. Article's body contains some HTML text
> exposing those photos, if any. Note the images are aggregated by article
> and should not be exposed anywhere else.
> 
> The simplest way is to subclass our Article from (Z)ObjectManager and
> implement title and body as properties. On this way we are losing the
> DTML capabilities which we were have in DTML document/method. This is a
> big lost, indeed (at least we have to write <img src=img width=...
> height=... alt=...> instead of just <dtml-var img>). The one way to keep
> object DTML-aware is to subclass DTML method also. I tryed this approach
> and found this working, but with one exception: <dtml-var img> does not
> work. It does not work on _any_ callable objects. The workaround is
> <dtml-var "img.tag()"> or something equivalent. This is also not so
> good.
> 
> Another approach is to render properties as DTML strings using external
> method:
> 
> from DocumentTemplate import HTML
> 
> def render_dtml (text='',mapping={},**kw) :
>     html = HTML(text)
>     return html(client=None,mapping=mapping)
> 
> This also works fine but also has a dark side. As I found in sources,
> Zope stores DTML methods and documents in parsed form, this was done not
> just for fun, I guess. I think the parser is very expensive thing so on
> this way we get a great performance impact, right?
> 
> Does anybody have any solution or just mention on it?
> 
> Best,
> Mike
> 
> P.S. Why nobody asked this before???

Look at Kevin Dangoor's KM|NetNews Product for a nice take on this.  The outline
of the solution is to define a method 'index_html' within your ZClass (not
inside each instance!).  This method "stitches together" the properties of the
object to present its "default view".

The key problem is to get the "body" property to be rendered using the DTML
engine, but filled out using the properties of the main object.  Here is a
Python ExternalMethod (add it to the ZClass) which does the trick::

  from DocumentTemplate import HTML

  def render_dtml( self, string_property ):
      """
      """
      return HTML( string_property, self.__dict__ )()

You can then use this within the ZClass' instance_html as:

  <dtml-var "render_dtml( body )">

In fact, I don't see why this shouldn't be available as one of the 'fmt='
options for dtml-var, like so::

  <dtml-var body fmt=render-dtml>

This would require adding another entry to the 'special_formats' dictionary in
DocumentTemplate/DT_Var.py and another method.

(Later: Ugh!  that is harder to muck with than it looks!  I don't have time to
chase it down, I'm afraid.  I have some dim memory of a contributed Product
which has the word "render" in its name -- perhaps it eases this?)

Tres.
-- 
=========================================================
Tres Seaver         tseaver@palladion.com    713-523-6582
Palladion Software  http://www.palladion.com