HTML Generation

J Kenneth King james at agentultra.com
Fri Apr 3 20:43:56 CEST 2009


Stefan Behnel <stefan_ml at behnel.de> writes:

> J Kenneth King wrote:
>> from tags import html, head, meta, title, body, div, p, a
>> 
>> mypage = html(
>>              head(
>>                  meta(attrs={'http-equiv': "Content-Type",
>>                              'content': "text/html;"}),
>>                  title("My Page")),
>>              body(attrs={'background': "#ffffff;"},
>>                  div(attrs={'id': "article-content"},
>>                      p(a(attrs={'href': "http://python.org"},
>>                                 "Python.org")))))
>> 
>> tabbed_file(mypage, open('myfile.html', 'w'))
>
> See here for another example that uses lxml.html:
>
> http://codespeak.net/lxml/lxmlhtml.html#creating-html-with-the-e-factory
>
> Stefan

Ah, looks good. Have never used nor finished the example I had given --
only meant as inspiration. I'm not surprised it has been done by someone
else.

I've been thinking about the co-routines presentation recently given at
Pycon and have been thinking about ways they could be used to extend the
grammar a bit.

At present, it looks like in my example and the lxml.html example that
the HTML structures created are declarative. Scripting the generation of
child elements for example would break up the flow...

code:
------------------------------------------------------------------------

E.HTML(
    E.HEAD(
        E.TITLE("Best Page Evar!")
    ),
    E.BODY(
        E.H1(E.CLASS("best-articles-heading"), "Best Articles"),
        E.UL(E.CLASS("articles"))
    )
)

for article in articles:
    E.HTML.BODY.UL.append(E.LI(article['title]))
------------------------------------------------------------------------

... at least that's how I assume it would work.

I think in my prototype you could use list-comprehensions in-line to add
the elements, but it was quite an eyesore.

code:
------------------------------------------------------------------------

my_html = html(
              head(
                  title("Best Page Evar!")
              ),
              body(
                  ul(
                      [li(article['title']) for article in articles]
                  )
              )
          )
------------------------------------------------------------------------

I guess it's not that bad, but I had a feeling it could look prettier
like how naturally CL-WHO reads in Lisp. It's just that the list
comprehension doesn't read well in this context; it'd be more natural to
read it as "for each article in article, create a list element with the
article title" instead.

I get the impression that creating a chain of co-routines would reveal a
grammar for talking about generating web pages. Something like...

code:
------------------------------------------------------------------------

html_to_file(
    html(
        head(
            title("Best page evar")
        ),
        body(
            h1({'class': "underline-heading"},
               "Newest Articles"),
            unordered_list(
                articles,
                ['title', 'href'],
                '%-10s: %s')
        )
    ),
    file=sys.stdout
)
------------------------------------------------------------------------

Where `unordered_list` would walk the elements in its first argument,
extract the values from the keys specified by its second argument, and
format the results using the string from its third argument and simply
return a ul() object with nested li() objects with all the data inserted
into them.

Of course, this is very off-the-cuff; I only started picking up interest
in this old subject this morning. ;) I could be talking way out of my
ass here. No idea if any of it's even practical.

Anyway -- OP: there are many ways to approach HTML generation and it's a
good pursuit. If you come up with something new and unique, please
share! Down with templates! :)



More information about the Python-list mailing list