I'm working on a new templating model, and before I get too far along, I wanted to see if anyone else has advice on how it looks and works.
The basic goals are:
- Safety: template writers should be unable to affect much more than the appearance of the page.
- Portability: the template compiler should be a separate system which can be used by any component of a larger system.
- Independence: the compile stage should not depend on the system using the compiled template.
- Modularity: each template page is a complete script. The compiler can verify syntax, although variable references will be unchecked.
- MVC model: A controller will be responsible for setting up external resources and providing them to the template code. The template code will not be able to access resources outside the scope of what is provided. For instance, a number of templating systems allow includes. This allows a template view to become the controller by directing the resources it uses. The controller will establish resources which have a type, a name and optional parameters.
Those are the goals, so here is what I have working so far: a compiler written in C using flex and bison. Here is an example controller:
set title "test foreach" set list [list "one" "\[two]" "three" four "\$jane"] set joe(name) "Joe Smith" set joe(age) "38" set joe(city) "Bellevue" set jane(name) "Jane Doe" set jane(age) "22" set jane(city) "Boston" set array [list joe jane] set template "foreach.out" source $template puts $string
The template:
<html> <head> <title>$title</title> </head> <body> <p>Got a list $list <p>Looping over list: <ul> [foreach l $list] <li>$l</li> [/foreach] </ul> <p>Got an array $array <p>Looping over Array: <table> <tr> <th>Name</th> <th>Age</th> <th>City</th> </tr> [foreach a $array] <tr> <td>$a(name)</td> <td>$a(age)</td> <td>$a(city)</td> </tr> [/foreach] </table> </body> </html>
Another example:
<form action=go>
<select name=test>
[foreach {value description selected} $select]
<option value="$value" $selected>$description</option>
[/foreach]
</select>
</form>
And an if statement:
[if {$a == $b}]b[elseif {$a == $c}]c[else]d[/if]
The foreach can also handle multiple arrays or a combination of arrays and regular variables.
The questions I have are both broad and specific. First, is this a total waste of time? The compiler is working and can separate the tcl code from the html or other text. But a complete system would require a lot more work. It is easy to add new tags, but it only works on files, not buffers. It would probably be easy to add code so a multirow datasource could be used with the foreach.
More specific. The look of the tags are not xml-like. I haven't figured out how editors like Dreamweaver can identify the tags, so this is one disadvantage. One advantage, is that the tags will be ignored by Dreamweaver, etc, and you can include them inside other xml-like tags. For instance <a href="[if $a]a.html[else]b.html[/if]">go here</a> would probably validate. On the other hand, using the set command you could just set the variable based on the value of $a ahead of time, outside of the a tag. So one alternative could be command which look similar to the current ATS tags:
<tcl:if arg>...</tcl:if> <tcl:set arg arg \>..
Request notifications