There are hello scalate example, but it's too simple to learn. I want to know how integirat lift and scalate, for example, lift comet, lift form ...
3 Answers
It turns out that the current incarnation of the Lift scalate module (2.5) does not work (in the sense of integrating with snippets and comet). The problem is that the scalate module puts the scalate renderer into the pipeline as something that generates a completed response.
Thus, your scaml files will render, but they will not support lift tags.
To get what you really want, you should hack into the Template loader (which Lift, fortunately, allows you to do).
I played with this a bit, and ripped off a bit of code from the module. This works for me (though it needs many things, like caching of template, locale support, development mode vs production mode, perhaps some config parameters (e.g. in production mode do you want scalate to process the scaml every time, or just on initial load?).
In Boot.scala:
ScalamdTemplateLoader.init
where ScalamdTemplateLoader.scala is
... other imports ...
import net.liftmodules.scalate.LiftTemplateEngine
object ScalamdTemplateLoader extends Loggable {
val renderer = new LiftTemplateEngine
def init = {
LiftRules.externalTemplateResolver.default.set(scalateTemplateLoader _)
}
protected def createUri(path: List[String], ext: String): String = path.mkString("/") +
(if (ext.length > 0) "." + ext else "")
protected def canLoad(v: String): Boolean = {
renderer.canLoad(v)
}
def canRender(path: List[String], ext: String): Boolean = {
if (ext == "") {
canLoad(createUri(path, "scaml")) || canLoad(createUri(path, "ssp"))
} else {
val uri = createUri(path, ext)
(uri.endsWith(".ssp") || uri.endsWith(".scaml")) && canLoad(uri)
}
}
def scalateTemplateLoader: PartialFunction[(Locale, List[String]), Box[NodeSeq]] = {
case (l: Locale, path: List[String]) if (canRender(path, "")) => {
val uri: String = List("scaml", "ssp").map(createUri(path, _)).find(renderer.canLoad(_)).get
val rawTemplate = renderer.layout(uri)
val is = new ByteArrayInputStream(rawTemplate.getBytes("UTF-8"));
val parserFunction: InputStream => Box[NodeSeq] = S.htmlProperties.htmlParser
parserFunction(is)
}
}
}
most of this code is ripped directly from the module (see ScalateView...which results in a LiftResponse)...by putting it in as an external template loader, and running that through the S.htmlParser, we end up with a template that is fed into the entire lift subsystems...scalate is used as the template source for Lift, instead of the response source.
When I feed in a template like this:
%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
%body
%p Hi there
%div.crap This is some crap
%div(class="lift:Demo1.currentTime")
%p I am having fun at
%span.time
I get the expected response from the Demo1 snippet:
class Demo1 {
def currentTime(n : NodeSeq) : NodeSeq = <span class="time">{ new Date().toString }</span>
}

- 5,535
- 23
- 27
The same way as with any other Lift templating mechanism.
Snippets can be invoked:
<div class="lift:MySnippet">...</div>
and Comet is just a snippet:
<div class="lift:comet?type=MyCometThing">...</div>
https://groups.google.com/d/topic/liftweb/f_zOj3ZOLQg/discussion
-
It turns out the scalate module, as it currently exists, acts as a dispatch routine that generates a response, and bypasses all of the real lift goodness...see my answer. – Tony K. Feb 10 '13 at 06:38