Graham Fawcett wrote: > This is a request-for-speculation. I've been thinking about an extension > to PTL that I'd like to make, and wondered if you might scan my example > below & provide feedback. Interesting idea. My concerns would be not getting in the way of existing usage, not being fragile, and not being a huge code bloat. I'm not sure I would use it; when the template starts to use several levels of tags (indented levels), I start reaching for a traditional template language like Cheetah that makes the tags explicit in the source. If we do this, we should probably define a third output style rather than overloading '[html]'. But this would be orthogonical to the [text/html] switch. Maybe '[html, block]'. > TABLE(_class='nice_table'): # or some other class-hack css_class= is the Quixote standard. > # a custom block definition, using a str() expression > alert = 'div style="color: red;"' > alert: This syntax and use is a bit surprising. What about requiring tags to be your special tag object? And encouraging .open_block() and .close_block() to call quixote.html.htmltag(), so there will be consistency between the parts of a Quixote application. Somehow you'd want to support default attributes but let the user override them. Maybe something like this: class Tag(object): def __init__(self, tag, css_class=None, **default_attribs): self.tag = tag self.css_class = css_class self.default_attribs = default_attribs def open_block(self, css_class=None, **attribs): css_class = css_class or self.css_class attribs = self.default_attribs.copy().update(attribs) return htmltag(self.tag, css_class, **attribs) def close_block(self): return htmltag('/' + self.tag) alert = Tag('div', style='color:red') # Example of non-HTML output. class JavaTag(Tag): def open_block(self, arg_str=''): if arg_str: return "%s %s {" % (self.tag, arg_str) def close_block(self): return "}" Catch = JavaTag('catch') We should use htmltext() consistent with our recommendations to users. It's already confusing enough to know when to htmltext() things and when to str() them. So anything that comes in with markup chars should be htmltext'd or generated by htmltag(). > A(href='%d/edit' % person.id): > 'Edit' > A('Delete', # *args-style tag syntax > href='%d/delete' % person.id) In Python, keywords introducing a block cannot also be function names. I'm not sure we should break that tradition. It would also prevent us from leveraging the Python parser, I think. Putting the body (positional arg) before the attributes (keywords) is confusing. How urgent is it to support the args-style syntax? Could we have a special keyword arg for the body (body=)? Are multiple positional args allowed? > * I've considered a tag-inlining syntax, so that you could write > one-liners like "UL: LI: A('Main', href='/')". I'm torn, though; > while more efficient, it would be harder to parse, and contravenes > the Python-style recommendation against inlining block-level > expressions. Sounds too confusing for human maintainers. What would the indentation be? What would a dedent do? A one-LI UL is so rare we don't need a one-line syntax for it. > I think it takes the regularity of 'stan' syntax, and adds great > readability through the block syntax, without requiring map() or > listcomps to get iteration, or other declarative hacks to handle > conditionals in the midst of a complex page. Yes, it reminded me of stan, but with an even cleaner syntax. It has some good potential in that regard. I'm just not sure of putting it into the default PTL, which is already magical enough with its import hook and straight-to-pyc compiling. Could it be done as a third-party alternative to PTL? -- -- Mike Orr