durusmail: quixote-users: Thoughts on a block-syntax extension to PTL
Thoughts on a block-syntax extension to PTL
2005-08-22
2005-08-22
2005-08-22
2005-08-22
2005-08-22
2005-08-23
2005-09-07
Thoughts on a block-syntax extension to PTL
mso@oz.net
2005-08-22
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 

reply