Web templating/db tool with best designer/coder separation?

Richie rjh at cyberscience.com
Wed Jul 3 06:11:02 EDT 2002


Stefan,

> Can't we leave the HTML alone, just mark the affected tags by giving
> them IDs

I've been thinking along similar lines recently.  The only slight
difference is that for form controls I'm allowing the 'name' attribute as
an alternative to 'id'.  These are the notes I have on the way I'd like
the system to work (note that normally the HTML would be read from an
external file rather than included in the source):

>>> import Template
>>> html = """
... <html><body>
... <p>Please fill in your username and the message to send.</p>
... <form id='send' action='test.py'>
... <input type='text' name='username' size='20' value='rjh'><br>
... <textarea rows='10' cols='80' name='message'>Type here...</textarea>
... </form>
... </body></html>"""
... 
>>> page = Template.Page( html )
>>> page.send
<Template.Form, name='send'>
>>> page.send.username
<Template.Input, type='text', name='username'>
>>> page.send.username.size
20
>>> page.send.username.size = 30
>>> page.send.username.value = "richie"
>>> page.send.username.render()
'<input type='text' name='username' size='30' value='richie'>'
>>> page.render()
[...what you'd expect...]


> - One presentation command file could address and assemle 
>   elements from different  HTML template files

Yes - eg. a navigation bar down the left-hand side of each page.  You have
a master page that contains it, marked as a named div, and put a marker
div of the same name in each page.  The marker just contains "Navigation
here!" or something.  You then take the menu out of the master page and
copy it into the other pages programmatically:

>>> masterPage = Template.Page( masterHTML )
>>> aboutUsPage = Template.Page( aboutUsHTML )
>>> aboutUsPage.navigation = masterPage.navigation

You can then manipulate it - say you have a 'class' attribute for the menu
links and you use a different class for the current page's entry:

>>> aboutUsPage.navigation.aboutUs.class = "nav-highlight"

(this relies on the links in the menu having 'id' tags).


> - Scoping/local replacement within iteration might become complicated

This is how I envisage iteration working: a designer includes a table of
data in the page using dummy values, and a programmer populates it with
new rows based on the designer's original.  The objects have a 'clone'
method which creates a duplicate object, optionally with some attributes
changed:

>>> tableHtml = """
... <table border='2'>
... <tr id='record'><td id='name'>Richie</td><td id='age'>30</td></tr>
... </table>"""
... 
>>> table = Template.Table( tableHtml )
>>> templateRow = table.record
>>> templateNameCell = table.record.name
>>> templateAgeCell = table.record.age
>>> table.remove( record )
>>> i = 1
>>> for data in [ { 'name': 'Andy', 'age': 29 },
...               { 'name': 'Bill', 'age': 12 } ]:
...    row = TemplateRow.clone( id='record%d'%i )
...    row.name.setContent( data['name'] )
...    row.age.setContent( data['age'] )
...    table.add( row )
...    i = i + 1
... 
>>> table.render()
<table border='2'>
<tr id='record1'><td id='name'>Andy</td><td id='age'>29</td></tr>
<tr id='record2'><td id='name'>Bill</td><td id='age'>12</td></tr>
</table>


When a CGI form is submitted, you recreate the object tree with the
submitted values like this:

>>> page = Template.Page( html )
>>> page.updateValues( cgi.FieldStorage() )
>>> page.send.username.value
"someusername"

You can also update the values using a dictionary, for prepopulating the
page out of a database for example.


The biggest problem I can see is that I'm using object attributes to
represent both HTML tag attributes and child objects.  So 'form.name'
could refer to an attribute of the <form> tag or to an input control on
the form.  The obvious solution is to put the children or the attributes
(or both) into container objects:

>>> page.send.children.username
<Template.TextInput, name='username'>
>>> page.send.attributes.action
'test.py'

but this makes things look cluttered, especially if you're referring to
objects more than one or two levels deep.


Note that all these classes, Template.Table, Template.Form, etc. etc.,
would probably be created on the fly - there wouldn't really be a chunk of
code in the Template module for every HTML tag.

-- 
| Richie Hindle, rjh at cyberscience.com
| All opinions are mine and not necessarily those of my employer.
|    Why did the Zen Buddhist refuse anaesthetic at the dentist?
|    Because he wanted to transcend dental medication.



More information about the Python-list mailing list