Oliver,
I've put together a complex example of templating with Lift.
All the code is in sites/examples... but here goes.
The html file looks like:
<lift:surround with="default" at="content">
<lift:Template.show template="_simple_template" />
</lift:surround>
The template file contains two templates... a "tbl" template and a "row" template:
<temp:main>
<temp:tbl>
<table>
<tr>
<td><head:one/></td>
<td><head:two/></td>
</tr>
<head:rows />
</table>
</temp:tbl>
<temp:row>
<tr>
<td><item:one/></td>
<td><item:two/></td>
</tr>
</temp:row>
</temp:main>
It is placed in the webapps/_simple_template.html file. This file is referenced in the "template" attribute. You could put it in "/templates-hidden/my_fancy_template.html" and make sure that the "template" attribute in your <lift:Template.show /> tag refers to that path. Note also, that Lift's entire template loading mechanism is used... so localization will be used, etc.
This invokes the "show" method in the Template snippet. This code looks like:
def show(in: NodeSeq): NodeSeq = {
val ret: Can[NodeSeq] = for (tmpl <- templateFromTemplateAttr; // Load the template
// parse out the "tbl" and "row" subtemplates
(tbl, row) <- template(tmpl, "temp", "tbl", "row"))
yield {
// iterate over the users in the DB and bind each to a row
val rows: NodeSeq =
User.findAll match { case Nil => bind("item", row, "one" -> "No Records Found",
"two" -> "") case xs => xs.flatMap(u => bind("item", row,
"one" -> u.firstName.is, "two" -> u.email.is))
}
// bind the rows and the names of the rows to the "tbl" template
bind("head", tbl, "one" -> "Name", "two" -> "Email",
"rows" -> rows) }
// be graceful on failures
ret match {
case Full(xs) => xs case Empty => Text("Error processing template")
case Failure(msg, _, _) => Text("Error processing template: "+msg) }
}I hope this helps.
Thanks,
David