Thoughts on a block-syntax extension to PTL

Graham Fawcett <[email protected]>
Newsgroups gmane.comp.web.quixote.user
Message-ID <[email protected]>
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 <BODY id="foo"> and a closing tag </BODY>.
    * 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.