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
Graham Fawcett
2005-08-22
Hi everyone,

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.

What I'd like to do is add a block-level syntax to PTL. The ability to
define blocks of HTML/XML as explicit blocks in Python code would
increase readability and maintainability.

Here's an example of a possible extended-PTL syntax:


from extension_tags import *            # some tag definitions
import my_database

people = my_database.get_people()
title = 'List of all people'

# a custom block definition, using a str() expression
alert = 'div style="color: red;"'

HTML:                                   # HTML is a tag instance
    HEAD:
        TITLE:
            title
        LINK(rel='stylesheet', type='text/css',
             href='/main.css')
    BODY:
        H1:
            title
        P:
            'This is a list of the '
            len(people)
            'people defined in the sample application.'

        alert:
            "Kids, don't try this at home!"

        TABLE(_class='nice_table'):     # or some other class-hack
            TR:
                TH('surname')
                TH('first name')
                TH('email')
                TH('--actions--')
            for person in people:       # still have Python blocks!
                TR:
                    TD(person.surname)
                    TD(person.firstname)
                    TD(person.email)
                    TD:
                        A(href='%d/edit' % person.id):
                            'Edit'
                        A('Delete',     # *args-style tag syntax
                          href='%d/delete' % person.id)

Notes:

    *  whenever a block-level statement is encountered, and the
      statement does not begin with a Python keyword (e.g. 'def', 'if',
      'while', ...), then the modified parser will treat the statement
      as an "extended PTL statement".
    * The upper-casing in my example is purely optional, I just think it
      lends to readability.
    * the expression in an ePTL opening-line should resolve to either an
      object that has methods 'open_block' and 'close_block', or it must
      be a string; if not, str() will be used to stringify it.
    * If the expression resolves to an object, then its open_block()
      method is called before the nested lines are evaluated. After the
      nested lines are evaluated, then the close_block() method is
      called. Presumably these would write opening and closing tags.
    * Otherwise, the str() of the epxression is used as the opening-tag
      content, and the first word of the str() is used as the closing
      tag. Thus the expression 'BODY id="foo":' would lead to an opening
      tag  and a closing tag .
    * Inlining: Optionally, the str() of a tag object itself should
      render as a single tag. In the example above, "A" is used both as
      a block expression but also as an inline expression. (This has
      nothing to do with the block-parsing proposal really, it's just is
      a nice application of it.)
    * 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.
    * This type of syntax would work well with HTML and XML. XML
      namespaces, CDATA and comment blocks, etc. should not pose any
      problems, and should be codeable with the same regular syntax.
      Theoretically it could do plain-text as well, but that's not the
      target application.

Code that uses this syntax is, of course, not Python. However, tools
that work well with Python syntax (such as Emacs python-mode) will
probably recognize the block-level syntax, leading to easy composition
and editing. While it isn't Python, it's much more like Python than,
e.g. TAL or Cheetah is.

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.

I'm probably going to write this up, and give it a try in a few little
applications. But if you could spare a minute to critique the idea, I'd
really appreciate your comments.

Thanks,

Graham

reply