[Zope] DTML rendering from python?

Dylan Reinhardt zope@dylanreinhardt.com
Thu, 23 Jan 2003 09:47:03 -0800


At 08:37 AM 1/23/2003, Michiel Toneman wrote:
>The content manager now adds ((through a click-and-drool interface) a
>floating box to paragraph 2 (created by Zope id="box263") and a floating
>box to paragraph 3 (id="box544")

So the interface allows the user to associate a floating box ("box263", 
say) with a particular insertion point (paragraph 2).

Assuming that this information is captured and stored something like the 
following:

self._boxes[box_id] = {'box_content': 'blah blah', 'insert_point':'P3', 
'box_format':'size=blah;'}

Now what you need is one of two things:
1. A way of naming <P> tags and making calls from DTML based on the names.
2. A "finishing" method that inserts the correct markup *after* DTML has 
done its job.

Looks like you already thought through idea #1 and concluded that it would 
be very hard.  I'm inclined to agree.

But what about idea #2?  How tough would it be?

(This is top-of-the-head stuff, BTW... untested, no warranty, etc.)


DTML Doc first_pass.dtml:
----------------------------------------
<dtml-var "get_text()" fmt="structured-text">


DTML Doc second_pass.dtml:
----------------------------------------
<dtml-call "REQUEST.set('my_doc', first_pass)">
<dtml-var "add_boxes(my_doc)">


Your product code:
----------------------------------------
from re import search
from StringIO import StringIO  # gives file methods to string objects.

def has_box(self, graph_id):
     for box in self._boxes.keys():
         if self.boxes[box]['insert_point'] == graph_id:
             return box
     return None

def add_boxes(self, doc_text):
     # count up <P> tags and insert any defined boxes
     graph_count = 0
     doc_lines = StringIO(doc_text).readlines()
     index = 0
     for line in doc_lines:
         if search('<P.*?>', line):
             graph_count +=1       # assuming you number graphs from 1
             box_id = self.has_box('P%s' % graph_count)
             if box_id:
                 my_box = self.boxes[box]
                 doc_lines[index].append('<div %s>%s</div>' % 
(my_box.get('box_format'), my_box.get('box_content'))
                 # or use re.sub() for better precision...
         index += 1
     return '\n'.join(doc_lines)


Getting warmer?