start writing some kind of nested-HTML-tag-generators magic to use instead of templates :)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/degal/html.py Thu Jun 04 11:23:28 2009 +0300
@@ -0,0 +1,91 @@
+"""
+ Generating HTML tags
+"""
+
+from cgi import escape
+
+def tag_attr (name, value) :
+ return u'%s="%s"' % (name.rstrip('_'), escape(value, True))
+
+def tag_subcontent (subcontent) :
+ if not subcontent :
+ # skip
+ return
+
+ elif not isinstance(subcontent, basestring) and hasattr(subcontent, '__iter__') :
+ # render each sub-item recursively
+ for sc in subcontent :
+ for line in tag_subcontent(sc) :
+ yield line
+
+ else :
+ yield subcontent
+
+def tag_content (content) :
+ if not content:
+ # no output
+ return
+
+ elif isinstance(content, basestring) :
+ # escape raw vlues
+ yield escape(unicode(content))
+
+ else :
+ # treat it as subcontent
+ for line in tag_subcontent(content) :
+ yield line
+
+def tag (name, *content, **attrs) :
+ attr_stuff = " " + " ".join(tag_attr(n, v) for n, v in attrs.iteritems()) if attrs else ""
+
+ if content and all(content) :
+ # tag with content
+ yield u"<%s%s>" % (name, attr_stuff)
+
+ for c in content :
+ for line in tag_content(c) :
+ yield u"\t" + line
+
+ yield u"</%s>" % (name, )
+
+ else :
+ # singleton tag
+ yield u"<%s%s />" % (name, attr_stuff)
+
+def raw (data) :
+ yield data
+
+class TagFactory (object) :
+ def __getattr__ (self, name) :
+ def build_tag (*content, **attrs) :
+ return tag(name, *content, **attrs)
+
+ return build_tag
+
+tags = TagFactory()
+
+def render_lines (tags, charset=None) :
+ for line in tag_content(tags) :
+ if charset :
+ yield line.encode(charset)
+
+ else :
+ yield line
+
+def render (tags, charset=None) :
+ data = u'\n'.join(render_lines(tags))
+
+ if charset :
+ return data.encode(charset)
+
+ else :
+ return data
+
+def render_out (tags, out, charset='utf-8') :
+ """
+ Write the rendered tags into the given output stream using the given encoding
+ """
+
+ for line in render_lines(tags, charset) :
+ out.write(line + '\n')
+