Introduction
Play is a web framework for the JVM that deviates from the Servlet Specification. A Play Framework template functions similarly to a function that takes arguments from the template as input and outputs HTML code. Twirl is a Scala-based template engine included with Play whose design was influenced by ASP.NET Razor.
This blog describes Twirl's template engine in detail, including its template syntax, dependency injection using templates, typical use cases, and custom formats.
Without further ado, Let's get started.
Templates Syntax
A Play Scala template is a straightforward text file with discrete chunks of Scala code inside. Any text-based format, including HTML, XML, and CSV, can be produced by templates.
Front-end developers may utilise the template system with ease because it has been created to seem familiar to those used to dealing with HTML.
Following a straightforward naming strategy, templates are compiled as regular Scala functions. If a views/Application/index.scala.html template file is created, a views.html.Application.index class with a render() method will also be created.
Consider the example:
Code:
@(customer: Customer, orders: List[Order])
<h1>Hello @customer.name!</h1>
<ul>
@for(order <- orders) {
<li>@order.getTitle()</li>
}
</ul>
Then, just as you would typically call a method on a class, you may call this from any Java code:
Code:
Content html = views.html.Application.index.render(customer, orders);Syntax: the magic ‘@’ character
The only special character in the Scala template is @. This character marks the start of a dynamic statement each time it appears. Your code will deduce the end of the dynamic statement. Thus you are not necessarily required to explicitly close the code block:
Code:
Hello @customer.getName()!
This syntax only supports basic statements because the template engine uses code analysis to automatically determine when a code block ends. Use brackets to specifically indicate a multi-token statement if you want to put one:
Code:
Hello @(customer.getFirstName() + customer.getLastName())!
Curly brackets can also be used to write a block of many statements:
Code:
Hello @{val name = customer.getFirstName() + customer.getLastName(); name}!
@ is a special character, so occasionally, you'll need to escape it. Use @@ to accomplish this:
Code:
My email is abhinav@@example.comTemplate parameters
As a function, a template also requires arguments, which must be declared at the beginning of the template file:
Code:
@(customer: models.Customer, orders: List[models.Order])
You can also set parameters to their default values:
Code:
@(title: String = "Home")
You can also set several parameter categories:
Code:
@(title:String)(body: Html)Template constructor
A template is created by default as a static function that can be used anywhere. It might be simpler to inject your template with the components (and other templates) that it requires if it depends on other components, such as the messages API. Then you can easily inject that template into the controllers that need it.
Twirl enables declaring a constructor for templates at the beginning of the file, before the template arguments, using the @this() syntax. Similar to how template parameters are defined, the constructor arguments can also be defined:
Code:
@this(messagesApi: MessagesApi)
@(customer: models.Customer, orders: List[models.Order])Iterating
The for keyword can be used in the following very conventional way:
Code:
<ul>
@for(p <- products) {
<li>@p.getName() ($@p.getPrice())</li>
}
</ul>If-blocks
If-blocks are common building blocks. Use the if statement found in Scala:
Code:
@if(items.isEmpty()) {
<h1>Nothing to display</h1>
} else {
<h1>@items.size() items!</h1>
}Declaring reusable blocks
Reusable code blocks are possible to make:
Code:
@display(product: models.Product) = {
@product.getName() ($@product.getPrice())
}
<ul>
@for(product <- products) {
@display(product)
}
</ul>
You can also declare the reusable pure code blocks like follows:
Code:
@title(text: String) = @{
text.split(' ').map(_.capitalize).mkString(" ")
}
<h1>@title("hello world")</h1>
A reusable block defined with a name that begins with implicit will typically be labeled as implicit:
Code:
@implicitFieldConstructor = @{ MyFieldConstructor() }Declaring reusable values
Using the defining helper, you can declare scoped values:
Code:
@defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
<div>Hello @fullName</div>
}Import statements
Any content you like may be imported at the top of your template (or sub-template):
Code:
@(customer: models.Customer, orders: List[models.Order])
@import utils._
...
Use root prefix in the import statement to resolve anything in an absolute manner.
Code:
@import _root_.company.product.core._
You can declare common imports in build.sbt if you need them in all templates.
Code:
TwirlKeys.templateImports += "org.abc.backend._"Comments
Using @* *@, you can add server-side block comments to templates.
Code:
@*********************
* This is a comment *
*********************@
To describe your template in the Scala API doc, you can add a remark to the first line:
Code:
@*************************************
* Home page. *
* *
* @param msg The message to display *
*************************************@
@(msg: String)
<h1>@msg</h1>Escaping
Dynamic content portions are escaped in accordance with the rules of the template type (such as HTML or XML). Wrap a raw content fragment in the template content type if you want to output it.
For the code instance to produce raw HTML:
Code:
<p>
@Html(article.content)
</p>
Let's look into the details of dependency Injection.






