[Baypiggies] Discussion for newbies/beginner night talks - stan

Drew Perttula drewp at bigasterisk.com
Wed Feb 14 08:03:49 CET 2007


This example is getting some good discussion. I would use the "stan" 
templating system inside nevow, myself. My version is below:

> On 2/9/07, Dennis Reinhardt <DennisR at dair.com> wrote:
>> # build entire initial tree structure
>> def init_tree(ht_obj):
>>      html = "<table border=0>"
>>      index = 0
>>      last_exe = ""
>>      for xml_entry in util_actwin.display_list("enm", "+"):
>>          exe_name = str_extract(xml_entry, ["enm"])
>>          keye   = safe_int(str_extract(xml_entry, ["key"]))
>>          act = str_extract(xml_entry, ["act"])
>>          #logger("init_tree %s %s" % (keye, exe_name))
>>          fname, exe = exe_name.split(".")
>>          if fname != last_exe:
>>              html += "<tr>"
>>              if fname == expanded_node:
>>                  html += "<td><img src=image/slct32.gif border=0></td>"
>>              else:
>>                  html += "\r\n<td><a
>> href=edt_main.py?slct=expand&fname=%s>" % fname
>>                  html += "<%s></a></td>\r\n" % hovered_img(ht_obj, index)
>>              html += "<td><img src=%s width=32 height=32></td>" %
>> get_program_image(fname)
>>              html += "<td>%s</td>" % fname
>>              html += "<td>&nbsp;</td>"
>>              html += "</tr>"
>>          if fname == expanded_node:
>>              html += "<tr>"
>>              html += "<td>&nbsp;</td>"
>>              parm_index = safe_int_default(ht_obj.param("index"), -1)
>>              if parm_index == keye:
>>                  html += "<td><img src=image/slct32.gif border=0></td>"
>>                  html += "<td><img src=%s " % get_action_image(xml_entry)
>>                  html +=     "width=32 height=32 border=0></td>"
>>              else:
>>                  html += "<td><a href=edt_main.py?slct=edit"
>>                  html +=     "&class=tree_open32"
>>                  html +=     "&index=%s"       % keye
>>                  html +=     "&act=%s"         % act
>>                  html +=     "><%s></a></td>" % hovered_img(ht_obj, index)
>>                  html += "<td><img src=%s " % get_action_image(xml_entry)
>>                  html +=     "width=16 height=16 border=0></td>"
>>              html += "<td>%s</td>" % get_caption(xml_entry)
>>              html += "</tr>"
>>          else:
>>              pass
>>          last_exe = fname
>>          index += 1
>>      html += "</table>"
>>      return html

#
# nevow/stan version, completely untested
#

from nevow import flat, tags as T, entities

# build entire initial tree structure
def init_tree(ht_obj):
      index = 0
      last_exe = ""
      for xml_entry in util_actwin.display_list("enm", "+"):
          exe_name = str_extract(xml_entry, ["enm"])
          keye   = safe_int(str_extract(xml_entry, ["key"]))
          act = str_extract(xml_entry, ["act"])
          #logger("init_tree %s %s" % (keye, exe_name))
          fname, exe = exe_name.split(".")
          if fname != last_exe:
              cols = []

              if fname == expanded_node:
                  cols.append(T.td[T.img(src="image/slct32.gif",
                                         border=0)])
              else:
                  cols.append(T.td[
                      T.a(href="edt_main.py?slct=expand&fname=%s" %
                               fname)[
                         hovered_img(ht_obj, index)]
                      ])
              cols.extend([
                  T.td[T.img(src=get_program_image(fname),
                             width=32, height=32)],
                  T.td[fname],
                  T.td[entities.nbsp],
                       ])

              rows.append(T.tr[cols])

          if fname == expanded_node:
              parm_index = safe_int_default(ht_obj.param("index"), -1)
              if parm_index == keye:
                  cols = [T.td[T.img(src="image/slct32.gif", border=0)],
                          T.td[T.img(src=get_action_image(xml_entry),
                                     width=32, height=32, border=0)]]
              else:
                  cols = [T.td[T.a(href=("edt_main.py?slct=edit"
                                         "&class=tree_open32"
                                         "&index=", keye,
                                         "&act=", act)
                                   )[hovered_img(ht_obj, index)]],
                          T.td[T.img(src=get_action_image(xml_entry),
                                     width=16, height=16, border=0)]]

              rows.extend([T.tr[T.td[entities.nbsp],
                                cols,
                                T.td[get_caption(xml_entry)]]])

          else:
              pass
          last_exe = fname
          index += 1

      table = T.table(border=0)[rows]
      return flat.flatten(table)


Some notes:

The python lists and tuples in the xml-creating code will simply 
disappear in the output. T.p["foo", "bar"] renders to "<p>foobar</p>".

Nevow gets quoting right, so probably some of the other code could be 
simplified. hovered_img() should return a stan structure instead of the 
insides of an img tag, too.

The output of mine will be proper xml, which has some advantages. It 
won't be pretty-indented, but there's absolutely nothing interesting to 
see in the xml output. It'll be correct. What you might want to see is 
the DOM structure that you made, and firebug's DOM viewer is The Way to 
view that structure. It won't hide any information from you, and you can 
highlight back and forth between your DOM and the rendered page. So awesome.

My version of the code has 2/3 as many "words" as the original, as 
counted by wc. Does that make it easier to maintain? I'm not sure, but I 
do know that making maintenance edits on stan code is a breeze. You 
_can't make_ invalid xml, which takes care of the first hurdle with 
free-form text templating. The code can also be indented according to 
normal python rules, which means your python editor is working _with_ 
you on this.

Don't like (or can't use) the nevow project? This same XML shorthand was 
rewritten in a standalone project 
http://cheeseshop.python.org/pypi/Breve/1.0.35
I don't have any experience with breve. If it's really the stan part of 
nevow, then I say it's great.

Here's an article on stan which goes beyond the xml output system and 
into the dynamic templating part (i.e. putting in fields that are filled 
with dynamic values at render time):
http://www.kieranholland.com/code/documentation/nevow-stan/



More information about the Baypiggies mailing list