Twirl
Twirl is the Play 2 templating language.
Evaluating Twirl
While the Scalatra developer generally prefer Scalate for server-side templating, Twirl provides an interesting alternative.
Advantages of Twirl
- Templates are rendered by simply calling a generated
render
function with the correct arguments. Since this call can be made from other templates, the artificial distinction between “layouts” and “views” is erased. - Twirl simply embeds Scala in arbitrary text, whether that text is HTML, JSON, XML, or anything else. There is no new language to learn.
- When you use Twirl, the compiler can check type errors within a template, but unlike Scalate it can also check that templates are being passed the right parameter types.
Disadvantages of Twirl
- Play 2 is legendary for its slow compile times, and the code Twirl produces is a major offender in that regard. If your project involves many templates, compile times will get progressively worse.
- Since Twirl is a general-purpose template languages, it is not nearly as DRY as Scalate’s Scaml or Jade languages for HTML/XML templates.
- There is no tooling support for Twirl. Get ready to hit the space and tab keys often.
- Twirl makes some undocumented rendering decisions with respect to certain types (see below).
Using Twirl
Installation
- Add the Twirl plugin to
project/plugins.sbt
:
addSbtPlugin("io.spray" % "sbt-twirl" % "0.6.1")
- Enable the plugin in
build.sbt
:
seq(Twirl.settings: _*)
Usage
You add your templates to src/main/twirl
.
Twirl files are of the form [name].scala.[format]
. For example, foo.scala.html
or
bar.scala.xml
.
The package of the generated Scala file will follow the name of the template file,
and its path.
For example, if you create a file
src/main/twirl/com/example/myTwirlTemplate.scala.html
, the resulting Scala file
will be in the package com.example.html
.
You can call it with:
com.example.html.myTwirlTemplate.render(param1, param2, ...)
A basic example
Create src/main/twirl/org/scalatra/example/hello.scala.html
with:
@(date: java.util.Date)
<html>
<body>
<h1>Twirl reporting for duty at @date.toString!</h1>
</body>
</html>
Now render it in src/main/scala/org/scalatra/example/TwirlApp.scala
with:
package org.scalatra.example
import org.scalatra._
class TwirlApp extends ScalatraServlet {
get("/") {
html.helloTwirl.render(new java.util.Date)
}
}
Your result?
Full usage guide
We have only provided a taste of what Twirl can do. Since it’s an external project, we encourage you to also consult the official documentation.
The sbt plugin’s README also has a useful syntax summary.
Rendering oddities
There are some undocumented conversions Twirl initiates before rendering. Beware!
Consider this template:
@()
Twirl makes some special decisions in rendering certain types, including:
<ul>
<li>
Collections like
<ul>
<li><code>List</code>: @List("first", "second", "third")</li>
<li><code>Seq</code>: @Seq("first", "second", "third")</li>
</ul>
</li>
<li>
<code>Option</code>
<ul>
<li><code>Some</code>: @Some("foo")</li>
<li><code>None</code>: @None</li>
</ul>
</li>
<li>
But not <code>Either</code>
<ul>
<li><code>Left</code>: @Left("foo")</li>
<li><code>Right</code>: @Right("bar")</li>
</ul>
</li>
<li>
Others?
</li>
</ul>
It will render as: