SlideShare a Scribd company logo
1 of 30
Play Template Engine Based on
Scala
Sushil Kumar
Software Consultant
Knoldus Software LLP
Agenda
➢ Overview
➢ Features
➢ Scala Template Structure
➢ Common use Cases
➢ Using the form template helpers
➢ Field Constructor
➢ Messages and internationalization
➢ Code review and demo
➢ Overview
➢ Features
➢ Scala Template Structure
➢ Common use Cases
➢ Using the form template helpers
➢ Field Constructor
➢ Messages and internationalization
➢ Code review and demo
Overview
A type safe template engine based on Scala
Play comes with Twirl, a powerful Scala-based template engine, whose design was
inspired by ASP.NET Razor. A template in Play! Framework is basically a file with a specific
extension commonly resides under the views package.
Scala template : A Play Scala template is a simple text file that contains small blocks of Scala code.
Templates can generate any text-based format, such as HTML, XML or CSV.
The template system has been designed to feel comfortable to those used to working with HTML,
allowing front-end developers to easily work with the templates.
A template filename always has the following pattern:
<template_name> . scala . <content-type>
Overview
A type safe template engine based on Scala
Play comes with Twirl, a powerful Scala-based template engine, whose design was
inspired by ASP.NET Razor. A template in Play! Framework is basically a file with a specific
extension commonly resides under the views package.
Scala template : A Play Scala template is a simple text file that contains small blocks of Scala code.
Templates can generate any text-based format, such as HTML, XML or CSV.
The template system has been designed to feel comfortable to those used to working with HTML,
allowing front-end developers to easily work with the templates.
A template filename always has the following pattern:
<template_name> . scala . <content-type>
Overview
Templates are compiled, so you will see any errors right in your browser:
Overview
Templates are compiled, so you will see any errors right in your browser:
Features
Compact, expressive, and fluid: It minimizes the number of characters and keystrokes required
in a file, and enables a fast, fluid coding work flow Unlike most template syntaxes, you do not
need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is
smart enough to infer this from your code. This enables a really compact and expressive syntax
which is clean, fast and fun to type.
Easy to learn: It enables you to quickly be productive with a minimum of concepts. You use all
your existing Scala language and HTML skills.
Not a new language: We consciously chose not to create a new language. Instead we wanted to
enable developers to use their existing Scala language skills, and deliver a template markup
syntax that enables an awesome HTML construction work flow with your language of choice.
Editable in any text editor: It doesn’t require a specific tool and enables you to be productive in
any plain old text editor.
Compact, expressive, and fluid: It minimizes the number of characters and keystrokes required
in a file, and enables a fast, fluid coding work flow Unlike most template syntaxes, you do not
need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is
smart enough to infer this from your code. This enables a really compact and expressive syntax
which is clean, fast and fun to type.
Easy to learn: It enables you to quickly be productive with a minimum of concepts. You use all
your existing Scala language and HTML skills.
Not a new language: We consciously chose not to create a new language. Instead we wanted to
enable developers to use their existing Scala language skills, and deliver a template markup
syntax that enables an awesome HTML construction work flow with your language of choice.
Editable in any text editor: It doesn’t require a specific tool and enables you to be productive in
any plain old text editor.
Scala Template Structure
Scala template is an HTML document with embedded Scala statements, which start with an @
character. Play will detect Scala Template files based on the pattern and will compile them into as
standard Scala functions that will be available for the controllers or other templates. It can accept
parameters just as any other function in Scala.
Example :
You can then call this from any Scala code as you would call a function:
Scala Template Structure
Scala template is an HTML document with embedded Scala statements, which start with an @
character. Play will detect Scala Template files based on the pattern and will compile them into as
standard Scala functions that will be available for the controllers or other templates. It can accept
parameters just as any other function in Scala.
Example :
You can then call this from any Scala code as you would call a function:
@(products: List[Product])
@index("Products") {
<dl class="products">
@for(product <- products) {
<dt>@product.name</dt>
<dd>@product.description</dd>
}
</dl>
}
val content = views.html.list(products)
Syntax: the magic ‘@’ character
The Scala template uses @ as the single special character. Every time this character is encountered,
it indicates the beginning of a Scala statement. It does not require you to explicitly close the code-
block - this will be inferred from your code:
Because the template engine automatically detects the end of your code block by analyzing your
code, this syntax only supports simple statements. If you want to insert a multi-token statement,
explicitly mark it using brackets:
You can also use curly brackets, as in plain Scala code, to write a multi-statements block:
Because @ is a special character, you’ll sometimes need to escape it. Do this by using @@:
Syntax: the magic ‘@’ character
The Scala template uses @ as the single special character. Every time this character is encountered,
it indicates the beginning of a Scala statement. It does not require you to explicitly close the code-
block - this will be inferred from your code:
Because the template engine automatically detects the end of your code block by analyzing your
code, this syntax only supports simple statements. If you want to insert a multi-token statement,
explicitly mark it using brackets:
You can also use curly brackets, as in plain Scala code, to write a multi-statements block:
Because @ is a special character, you’ll sometimes need to escape it. Do this by using @@:
Hello @customer.name!
Hello @(customer.firstName + custumer.lastName)!
Hello @{val name = customer.firstName + customer.lastName; name}!
My email is sushil@@knoldus.com
Template parameters
A template is simply a function, so it needs parameters, which must be declared on the first line of
the template file:
You can also use default values for parameters:
Or even several parameter groups:
And even implicit parameters:
Template parameters
A template is simply a function, so it needs parameters, which must be declared on the first line of
the template file:
You can also use default values for parameters:
Or even several parameter groups:
And even implicit parameters:
@(message:String, products: models.Products)
@(title: String = "Home")
@(title: String)(body: => Html)(implicit flash: Flash)
@(title: String)(body: => Html)
Scala template common use cases
Iterating
You can use the for keyword, in a pretty standard way:
If-blocks
If-blocks are nothing special. Simply use Scala’s standard if statement:
Scala template common use cases
Iterating
You can use the for keyword, in a pretty standard way:
If-blocks
If-blocks are nothing special. Simply use Scala’s standard if statement:
<ul>
@for(user <- users) {
<li>@user.firstName (@user.age)</li>
}
</ul>
@if(items.isEmpty) {
<h1>Nothing to display.</h1>
} else {
<h1>Total items: @items.size</h1>
}
Pattern matching
You can also use pattern matching in your templates:
Pattern matching
You can also use pattern matching in your templates:
@ user match {
case Some(name) => {
<span class="admin">Connected to (@name)</span>
}
case None => {
<span>Not logged</span>
}
}
Declaring reusable blocks
You can create reusable code blocks:
By convention a reusable block defined with a name starting with implicit will be marked as implicit:
Declaring reusable values
You can also define scoped values using the defining helper
Declaring reusable blocks
You can create reusable code blocks:
By convention a reusable block defined with a name starting with implicit will be marked as implicit:
Declaring reusable values
You can also define scoped values using the defining helper
@title(text: String) = @{
text.split('').map(_.capitalize).mkString(" ")
}
<h1>@title("hello world")</h1>
@defining(user.firstName + " " + user.lastName) { fullName =>
<div>Hello @fullName</div>
}
@implicitFieldConstructor = @{ FieldConstructor(twitterBootstrapInput.f) }
Import statements
You can import whatever you want at the beginning of your template (or sub-template):
If you have common imports, which you need in all templates, you can declare in build.sbt
templatesImport += "com.abc.core._"
Includes
Again, there’s nothing special here. You can just call any other template you like (and in fact any
other function coming from anywhere at all:
Import statements
You can import whatever you want at the beginning of your template (or sub-template):
If you have common imports, which you need in all templates, you can declare in build.sbt
templatesImport += "com.abc.core._"
Includes
Again, there’s nothing special here. You can just call any other template you like (and in fact any
other function coming from anywhere at all:
@import utils._
@import models.Product
<div id="side">
@common.sideBar()
</div>
Tags (they are just functions, right?)
Let’s write a simple views/tags/notice.scala.html tag that displays an HTML notice:
And now let’s use it from another template:
Tags (they are just functions, right?)
Let’s write a simple views/tags/notice.scala.html tag that displays an HTML notice:
And now let’s use it from another template:
@(level: String = "error")(body: (String) => Html)
@level match {
case "success" => {
<p class="success">
@body("green")
</p>
}
case "error" => {
<p class="error">
@body("red")
</p>
}
}
@import tags._
@notice("error") { color =>
Oops, something is <span style="color:@color">wrong</span>
}
moreScripts and moreStyles equivalents
To define old moreScripts or moreStyles variables equivalents (like on Play! 1.x) on a Scala template,
you can define a variable in the main template like this :
And on an extended template that need an extra script :
moreScripts and moreStyles equivalents
To define old moreScripts or moreStyles variables equivalents (like on Play! 1.x) on a Scala template,
you can define a variable in the main template like this :
And on an extended template that need an extra script :
@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" media="screen"
href="@routes.Assets.at("stylesheets/main.css")">
<script src="@routes.Assets.at("javascripts/jquery-1.7.1.min.js")"
type="text/javascript"></script>
@scripts
</head>
<body>
@content
</body>
</html>
@scripts = {
<script type="text/javascript">alert("hello !");</script>
}
Comments
You can write server side block comments in templates using @* *@.
You can put a comment on the first line to document your template into the Scala API doc:
For example :
Comments
You can write server side block comments in templates using @* *@.
You can put a comment on the first line to document your template into the Scala API doc:
For example :
@*************************************
* Home page. *
* *
* @param msg The message to display *
*************************************@
@(msg: String)
<h1>@msg</h1>
Escaping
By default, the dynamic content parts are escaped according the template type (e.g. HTML or XML)
rules. If you want to output a raw content fragment, wrap it in the template content type.
For example to output raw HTML:
Try this out for example: Template:
Escaping
By default, the dynamic content parts are escaped according the template type (e.g. HTML or XML)
rules. If you want to output a raw content fragment, wrap it in the template content type.
For example to output raw HTML:
Try this out for example: Template:
<p>
@Html(myUnencodedData)
</p>
@Html("<h2>Play framework</h2>")
Form template helpers
Form object : In Play, we use a play.api.data. Form object to help us move data between
the web browser and the server-side application. This form encapsulates information
about a collection of fields and how they’re to be validated.
Form template helpers
Form object : In Play, we use a play.api.data. Form object to help us move data between
the web browser and the server-side application. This form encapsulates information
about a collection of fields and how they’re to be validated.
val userFormNested: Form[User] = Form(
mapping(
"name" -> text,
"email" -> list(email),
"address" -> mapping(
"street" -> text,
"city" -> text)(UserAddress.apply)(UserAddress.unapply))
(User.apply)(User.unapply))
case class User(name: String, email: List[String], address:
UserAddress)
case class UserAddress(street: String, city: String)
Showing forms in a view template
Once you have a form, then you need to make it available to the template engine. You do this by
including the form as a parameter to the view template.
When you are using nested data this way, the form values sent by the browser must be named like
address.street, address.city, etc.
When you are using repeated data like this, the form values sent by the browser must be named
emails[0], emails[1], emails[2], etc
Showing forms in a view template
Once you have a form, then you need to make it available to the template engine. You do this by
including the form as a parameter to the view template.
When you are using nested data this way, the form values sent by the browser must be named like
address.street, address.city, etc.
When you are using repeated data like this, the form values sent by the browser must be named
emails[0], emails[1], emails[2], etc
@(userForm: Form[userFormNested])
@import helper.
@import helper.twitterBootstrap._
@helper.form(action = routes.UserController.save, 'id -> "brandQuery") {
<fieldset>
@helper.inputText(userFormNested("name"),'class -> "customClass",'value->"sushil kumar")
@helper.repeat(myForm("emails"), min = 1) { emailField =>
@helper.inputText(emailField)
}
@helper.inputText(userFormNested("address.street"))
@helper.inputText(userFormNested("address.city"))
</fieldset>
<input type="submit" class="btn primary" value="Submit">
}
Field constructors
A field rendering is not only composed of the <input> tag, but it also needs a <label> and
possibly other tags used by your CSS framework to decorate the field.
All input helpers take an implicit FieldConstructor that handles this part. The default one
(used if there are no other field constructors available in the scope), generates HTML like:
Field constructors
A field rendering is not only composed of the <input> tag, but it also needs a <label> and
possibly other tags used by your CSS framework to decorate the field.
All input helpers take an implicit FieldConstructor that handles this part. The default one
(used if there are no other field constructors available in the scope), generates HTML like:
<dl class="error" id="username_field">
<dt><label for="username"><label>Username:</label></dt>
<dd><input type="text" name="username" id="username" value=""></dd>
<dd class="error">This field is required!</dd>
<dd class="error">Another error</dd>
<dd class="info">Required</dd>
<dd class="info">Another constraint</dd>
</dl>
Field constructors
Twitter bootstrap field constructor
There is also another built-in field constructor that can be used with TwitterBootstrap .
To use it, just import it in the current scope:
Field constructors
Twitter bootstrap field constructor
There is also another built-in field constructor that can be used with TwitterBootstrap .
To use it, just import it in the current scope:
@import helper.twitterBootstrap._
It generates Html like:
<div class="clearfix error" id="username_field">
<label for="username">Username:</label>
<div class="input">
<input type="text" name="username" id="username" value="">
<span class="help-inline">This field is required!, Another
error</span>
<span class="help-block">Required, Another constraint</d</span>
</div>
</div>
Field constructors
Writing your own field constructor
For example : views.common.myFieldConstructor
Field constructors
Writing your own field constructor
For example : views.common.myFieldConstructor
@(elements: helper.FieldElements)
<div class="@if(elements.hasErrors) {error}">
<label for="@elements.id">@elements.label</label>
<div class="input">
@elements.input
<span class="errors">@elements.errors.mkString(", ")</span>
<span class="help">@elements.infos.mkString(", ")</span>
</div>
</div>
Field constructors
Now create a FieldConstructor using this template function:
And to make the form helpers use it, just import it in your templates:
You can also set an implicit value for your FieldConstructor inline in your template this
way:
Field constructors
Now create a FieldConstructor using this template function:
And to make the form helpers use it, just import it in your templates:
You can also set an implicit value for your FieldConstructor inline in your template this
way:
object MyHelpers {
implicit val myFields = FieldConstructor(myFieldConstructor.f)
}
@import MyHelpers._
@implicitField = @{ FieldConstructor(myFieldConstructor.f) }
Field constructors
This default field constructor supports additional options you can pass in the
input helper arguments:
Field constructors
This default field constructor supports additional options you can pass in the
input helper arguments:
'_label -> "Custom label"
'_id -> "idForTheTopDlElement"
'_help -> "Custom help"
'_showConstraints -> false
'_error -> "Force an error"
'_showErrors -> false
Messages and internationalization
Specifying languages supported by your application
Internationalisation (I18N) is a means of adapting your application to different languages
to allow for regional differences.
To start you need to specify the languages supported by your application in the
conf/application.conf file:
application.langs=en,en-US,fr
Messages and internationalization
Specifying languages supported by your application
Internationalisation (I18N) is a means of adapting your application to different languages
to allow for regional differences.
To start you need to specify the languages supported by your application in the
conf/application.conf file:
application.langs=en,en-US,fr
Externalizing messages
The default conf/messages file matches all languages. Additionally you can specify
language-specific message files such as conf/messages.fr or conf/messages.en-US.
For example, the message file containing the corresponding French translations is
conf/messages.fr:
hello=Bonjour!
You can then retrieve messages using the play.api.i18n.Messages object:
Template output
From a template you can use the above syntax to display localized messages.
Externalizing messages
The default conf/messages file matches all languages. Additionally you can specify
language-specific message files such as conf/messages.fr or conf/messages.en-US.
For example, the message file containing the corresponding French translations is
conf/messages.fr:
hello=Bonjour!
You can then retrieve messages using the play.api.i18n.Messages object:
Template output
From a template you can use the above syntax to display localized messages.
val title = Messages("hello")
<title>@Messages("hello")</title>
All internationalization API calls take an implicit play.api.i18.Lang argument
retrieved from the current scope. You can also specify it explicitly:
All internationalization API calls take an implicit play.api.i18.Lang argument
retrieved from the current scope. You can also specify it explicitly:
val title = Messages("home.title")(Lang("fr"))
All internationalization API calls take an implicit play.api.i18.Lang argument
retrieved from the current scope. You can also specify it explicitly:
All internationalization API calls take an implicit play.api.i18.Lang argument
retrieved from the current scope. You can also specify it explicitly:
val title = Messages("home.title")(Lang("fr"))
Messages format
Messages can be formatted using the java.text.MessageFormat library. For
example, assuming you have message defined like:
files.summary=The disk {1} contains {0} file(s).
You can then specify parameters as:
Messages format
Messages can be formatted using the java.text.MessageFormat library. For
example, assuming you have message defined like:
files.summary=The disk {1} contains {0} file(s).
You can then specify parameters as:
<h1>@Messages("files.summary", d.files.length, d.name)</h1>
Q & Option[A]Q & Option[A]
ThanksThanks

More Related Content

What's hot

LocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputsLocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputs
Suite Solutions
 
C:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse InfocenterC:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse Infocenter
Suite Solutions
 
Sql Injection Adv Owasp
Sql Injection Adv OwaspSql Injection Adv Owasp
Sql Injection Adv Owasp
Aung Khant
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex code
EdwinOstos
 
ImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlaggingImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlagging
Suite Solutions
 
PLSQL Developer tips and tricks
PLSQL Developer tips and tricksPLSQL Developer tips and tricks
PLSQL Developer tips and tricks
Patrick Barel
 

What's hot (20)

Episode 4 - Introduction to SOQL in Salesforce
Episode 4  - Introduction to SOQL in SalesforceEpisode 4  - Introduction to SOQL in Salesforce
Episode 4 - Introduction to SOQL in Salesforce
 
To create a web service
To create a web serviceTo create a web service
To create a web service
 
Struts N E W
Struts N E WStruts N E W
Struts N E W
 
LocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputsLocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputs
 
C:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse InfocenterC:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse Infocenter
 
Sql Injection Adv Owasp
Sql Injection Adv OwaspSql Injection Adv Owasp
Sql Injection Adv Owasp
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex code
 
PDF Localization
PDF  LocalizationPDF  Localization
PDF Localization
 
ImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlaggingImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlagging
 
PLSQL Developer tips and tricks
PLSQL Developer tips and tricksPLSQL Developer tips and tricks
PLSQL Developer tips and tricks
 
Intro to Scala
 Intro to Scala Intro to Scala
Intro to Scala
 
Azure rev002
Azure rev002Azure rev002
Azure rev002
 
Sql Overview
Sql OverviewSql Overview
Sql Overview
 
The CoFX Data Model
The CoFX Data ModelThe CoFX Data Model
The CoFX Data Model
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
 
B_110500002
B_110500002B_110500002
B_110500002
 
Sprouting into the world of Elm
Sprouting into the world of ElmSprouting into the world of Elm
Sprouting into the world of Elm
 
Dost.jar and fo.jar
Dost.jar and fo.jarDost.jar and fo.jar
Dost.jar and fo.jar
 
Sling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak KhetawatSling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak Khetawat
 
.NET Core, ASP.NET Core Course, Session 15
.NET Core, ASP.NET Core Course, Session 15.NET Core, ASP.NET Core Course, Session 15
.NET Core, ASP.NET Core Course, Session 15
 

Viewers also liked

DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
it-people
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
Zheka Kozlov
 
Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)
Ontico
 

Viewers also liked (20)

Introducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineIntroducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template Engine
 
Playing with Scala
Playing with ScalaPlaying with Scala
Playing with Scala
 
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
 
[Start] Playing
[Start] Playing[Start] Playing
[Start] Playing
 
HTML5 with Play Scala, CoffeeScript and Jade - Devoxx 2011
HTML5 with Play Scala, CoffeeScript and Jade - Devoxx 2011HTML5 with Play Scala, CoffeeScript and Jade - Devoxx 2011
HTML5 with Play Scala, CoffeeScript and Jade - Devoxx 2011
 
Designing Reactive Systems with Akka
Designing Reactive Systems with AkkaDesigning Reactive Systems with Akka
Designing Reactive Systems with Akka
 
Your First Scala Web Application using Play 2.1
Your First Scala Web Application using Play 2.1Your First Scala Web Application using Play 2.1
Your First Scala Web Application using Play 2.1
 
Play framework And Google Cloud Platform GCP.
Play framework And Google Cloud Platform GCP.Play framework And Google Cloud Platform GCP.
Play framework And Google Cloud Platform GCP.
 
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMVoxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Akka-http
Akka-httpAkka-http
Akka-http
 
Lagom in Practice
Lagom in PracticeLagom in Practice
Lagom in Practice
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scala
 
Akka http 2
Akka http 2Akka http 2
Akka http 2
 
Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
Akka http
Akka httpAkka http
Akka http
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introduction
 
Securing Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTPSecuring Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTP
 

Similar to Play Template Engine Based On Scala

An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++Templates
Ganesh Samarthyam
 

Similar to Play Template Engine Based On Scala (20)

Lessons Learned: Scala and its Ecosystem
Lessons Learned: Scala and its EcosystemLessons Learned: Scala and its Ecosystem
Lessons Learned: Scala and its Ecosystem
 
2javascript web programming with JAVA script
2javascript web programming with JAVA script2javascript web programming with JAVA script
2javascript web programming with JAVA script
 
HTML practical file
HTML practical fileHTML practical file
HTML practical file
 
Introduction to whats new in css3
Introduction to whats new in css3Introduction to whats new in css3
Introduction to whats new in css3
 
Razor new view engine asp.net
Razor new view engine asp.netRazor new view engine asp.net
Razor new view engine asp.net
 
HTML Foundations, part 1
HTML Foundations, part 1HTML Foundations, part 1
HTML Foundations, part 1
 
.NET Core, ASP.NET Core Course, Session 12
.NET Core, ASP.NET Core Course, Session 12.NET Core, ASP.NET Core Course, Session 12
.NET Core, ASP.NET Core Course, Session 12
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
treeview
treeviewtreeview
treeview
 
treeview
treeviewtreeview
treeview
 
Alberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.js
 
Scala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJS
 
An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++Templates
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
 
Catalyst optimizer
Catalyst optimizerCatalyst optimizer
Catalyst optimizer
 
Introduction to Spark ML
Introduction to Spark MLIntroduction to Spark ML
Introduction to Spark ML
 
Html5 deciphered - designing concepts part 1
Html5 deciphered - designing concepts part 1Html5 deciphered - designing concepts part 1
Html5 deciphered - designing concepts part 1
 
Basic JavaScript Tutorial
Basic JavaScript TutorialBasic JavaScript Tutorial
Basic JavaScript Tutorial
 
A Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to ScalaA Brief, but Dense, Intro to Scala
A Brief, but Dense, Intro to Scala
 
Xml writers
Xml writersXml writers
Xml writers
 

More from Knoldus Inc.

More from Knoldus Inc. (20)

Supply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptxSupply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptx
 
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On Introduction
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptx
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptx
 
GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdf
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptx
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable Testing
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose Kubernetes
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptx
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptx
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptx
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptx
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptx
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake Presentation
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics Presentation
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIs
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II Presentation
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Configuring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAConfiguring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRA
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Play Template Engine Based On Scala

  • 1. Play Template Engine Based on Scala Sushil Kumar Software Consultant Knoldus Software LLP
  • 2. Agenda ➢ Overview ➢ Features ➢ Scala Template Structure ➢ Common use Cases ➢ Using the form template helpers ➢ Field Constructor ➢ Messages and internationalization ➢ Code review and demo ➢ Overview ➢ Features ➢ Scala Template Structure ➢ Common use Cases ➢ Using the form template helpers ➢ Field Constructor ➢ Messages and internationalization ➢ Code review and demo
  • 3. Overview A type safe template engine based on Scala Play comes with Twirl, a powerful Scala-based template engine, whose design was inspired by ASP.NET Razor. A template in Play! Framework is basically a file with a specific extension commonly resides under the views package. Scala template : A Play Scala template is a simple text file that contains small blocks of Scala code. Templates can generate any text-based format, such as HTML, XML or CSV. The template system has been designed to feel comfortable to those used to working with HTML, allowing front-end developers to easily work with the templates. A template filename always has the following pattern: <template_name> . scala . <content-type> Overview A type safe template engine based on Scala Play comes with Twirl, a powerful Scala-based template engine, whose design was inspired by ASP.NET Razor. A template in Play! Framework is basically a file with a specific extension commonly resides under the views package. Scala template : A Play Scala template is a simple text file that contains small blocks of Scala code. Templates can generate any text-based format, such as HTML, XML or CSV. The template system has been designed to feel comfortable to those used to working with HTML, allowing front-end developers to easily work with the templates. A template filename always has the following pattern: <template_name> . scala . <content-type>
  • 4. Overview Templates are compiled, so you will see any errors right in your browser: Overview Templates are compiled, so you will see any errors right in your browser:
  • 5. Features Compact, expressive, and fluid: It minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding work flow Unlike most template syntaxes, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type. Easy to learn: It enables you to quickly be productive with a minimum of concepts. You use all your existing Scala language and HTML skills. Not a new language: We consciously chose not to create a new language. Instead we wanted to enable developers to use their existing Scala language skills, and deliver a template markup syntax that enables an awesome HTML construction work flow with your language of choice. Editable in any text editor: It doesn’t require a specific tool and enables you to be productive in any plain old text editor. Compact, expressive, and fluid: It minimizes the number of characters and keystrokes required in a file, and enables a fast, fluid coding work flow Unlike most template syntaxes, you do not need to interrupt your coding to explicitly denote server blocks within your HTML. The parser is smart enough to infer this from your code. This enables a really compact and expressive syntax which is clean, fast and fun to type. Easy to learn: It enables you to quickly be productive with a minimum of concepts. You use all your existing Scala language and HTML skills. Not a new language: We consciously chose not to create a new language. Instead we wanted to enable developers to use their existing Scala language skills, and deliver a template markup syntax that enables an awesome HTML construction work flow with your language of choice. Editable in any text editor: It doesn’t require a specific tool and enables you to be productive in any plain old text editor.
  • 6. Scala Template Structure Scala template is an HTML document with embedded Scala statements, which start with an @ character. Play will detect Scala Template files based on the pattern and will compile them into as standard Scala functions that will be available for the controllers or other templates. It can accept parameters just as any other function in Scala. Example : You can then call this from any Scala code as you would call a function: Scala Template Structure Scala template is an HTML document with embedded Scala statements, which start with an @ character. Play will detect Scala Template files based on the pattern and will compile them into as standard Scala functions that will be available for the controllers or other templates. It can accept parameters just as any other function in Scala. Example : You can then call this from any Scala code as you would call a function: @(products: List[Product]) @index("Products") { <dl class="products"> @for(product <- products) { <dt>@product.name</dt> <dd>@product.description</dd> } </dl> } val content = views.html.list(products)
  • 7. Syntax: the magic ‘@’ character The Scala template uses @ as the single special character. Every time this character is encountered, it indicates the beginning of a Scala statement. It does not require you to explicitly close the code- block - this will be inferred from your code: Because the template engine automatically detects the end of your code block by analyzing your code, this syntax only supports simple statements. If you want to insert a multi-token statement, explicitly mark it using brackets: You can also use curly brackets, as in plain Scala code, to write a multi-statements block: Because @ is a special character, you’ll sometimes need to escape it. Do this by using @@: Syntax: the magic ‘@’ character The Scala template uses @ as the single special character. Every time this character is encountered, it indicates the beginning of a Scala statement. It does not require you to explicitly close the code- block - this will be inferred from your code: Because the template engine automatically detects the end of your code block by analyzing your code, this syntax only supports simple statements. If you want to insert a multi-token statement, explicitly mark it using brackets: You can also use curly brackets, as in plain Scala code, to write a multi-statements block: Because @ is a special character, you’ll sometimes need to escape it. Do this by using @@: Hello @customer.name! Hello @(customer.firstName + custumer.lastName)! Hello @{val name = customer.firstName + customer.lastName; name}! My email is sushil@@knoldus.com
  • 8. Template parameters A template is simply a function, so it needs parameters, which must be declared on the first line of the template file: You can also use default values for parameters: Or even several parameter groups: And even implicit parameters: Template parameters A template is simply a function, so it needs parameters, which must be declared on the first line of the template file: You can also use default values for parameters: Or even several parameter groups: And even implicit parameters: @(message:String, products: models.Products) @(title: String = "Home") @(title: String)(body: => Html)(implicit flash: Flash) @(title: String)(body: => Html)
  • 9. Scala template common use cases Iterating You can use the for keyword, in a pretty standard way: If-blocks If-blocks are nothing special. Simply use Scala’s standard if statement: Scala template common use cases Iterating You can use the for keyword, in a pretty standard way: If-blocks If-blocks are nothing special. Simply use Scala’s standard if statement: <ul> @for(user <- users) { <li>@user.firstName (@user.age)</li> } </ul> @if(items.isEmpty) { <h1>Nothing to display.</h1> } else { <h1>Total items: @items.size</h1> }
  • 10. Pattern matching You can also use pattern matching in your templates: Pattern matching You can also use pattern matching in your templates: @ user match { case Some(name) => { <span class="admin">Connected to (@name)</span> } case None => { <span>Not logged</span> } }
  • 11. Declaring reusable blocks You can create reusable code blocks: By convention a reusable block defined with a name starting with implicit will be marked as implicit: Declaring reusable values You can also define scoped values using the defining helper Declaring reusable blocks You can create reusable code blocks: By convention a reusable block defined with a name starting with implicit will be marked as implicit: Declaring reusable values You can also define scoped values using the defining helper @title(text: String) = @{ text.split('').map(_.capitalize).mkString(" ") } <h1>@title("hello world")</h1> @defining(user.firstName + " " + user.lastName) { fullName => <div>Hello @fullName</div> } @implicitFieldConstructor = @{ FieldConstructor(twitterBootstrapInput.f) }
  • 12. Import statements You can import whatever you want at the beginning of your template (or sub-template): If you have common imports, which you need in all templates, you can declare in build.sbt templatesImport += "com.abc.core._" Includes Again, there’s nothing special here. You can just call any other template you like (and in fact any other function coming from anywhere at all: Import statements You can import whatever you want at the beginning of your template (or sub-template): If you have common imports, which you need in all templates, you can declare in build.sbt templatesImport += "com.abc.core._" Includes Again, there’s nothing special here. You can just call any other template you like (and in fact any other function coming from anywhere at all: @import utils._ @import models.Product <div id="side"> @common.sideBar() </div>
  • 13. Tags (they are just functions, right?) Let’s write a simple views/tags/notice.scala.html tag that displays an HTML notice: And now let’s use it from another template: Tags (they are just functions, right?) Let’s write a simple views/tags/notice.scala.html tag that displays an HTML notice: And now let’s use it from another template: @(level: String = "error")(body: (String) => Html) @level match { case "success" => { <p class="success"> @body("green") </p> } case "error" => { <p class="error"> @body("red") </p> } } @import tags._ @notice("error") { color => Oops, something is <span style="color:@color">wrong</span> }
  • 14. moreScripts and moreStyles equivalents To define old moreScripts or moreStyles variables equivalents (like on Play! 1.x) on a Scala template, you can define a variable in the main template like this : And on an extended template that need an extra script : moreScripts and moreStyles equivalents To define old moreScripts or moreStyles variables equivalents (like on Play! 1.x) on a Scala template, you can define a variable in the main template like this : And on an extended template that need an extra script : @(title: String, scripts: Html = Html(""))(content: Html) <!DOCTYPE html> <html> <head> <title>@title</title> <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")"> <script src="@routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script> @scripts </head> <body> @content </body> </html> @scripts = { <script type="text/javascript">alert("hello !");</script> }
  • 15. Comments You can write server side block comments in templates using @* *@. You can put a comment on the first line to document your template into the Scala API doc: For example : Comments You can write server side block comments in templates using @* *@. You can put a comment on the first line to document your template into the Scala API doc: For example : @************************************* * Home page. * * * * @param msg The message to display * *************************************@ @(msg: String) <h1>@msg</h1>
  • 16. Escaping By default, the dynamic content parts are escaped according the template type (e.g. HTML or XML) rules. If you want to output a raw content fragment, wrap it in the template content type. For example to output raw HTML: Try this out for example: Template: Escaping By default, the dynamic content parts are escaped according the template type (e.g. HTML or XML) rules. If you want to output a raw content fragment, wrap it in the template content type. For example to output raw HTML: Try this out for example: Template: <p> @Html(myUnencodedData) </p> @Html("<h2>Play framework</h2>")
  • 17. Form template helpers Form object : In Play, we use a play.api.data. Form object to help us move data between the web browser and the server-side application. This form encapsulates information about a collection of fields and how they’re to be validated. Form template helpers Form object : In Play, we use a play.api.data. Form object to help us move data between the web browser and the server-side application. This form encapsulates information about a collection of fields and how they’re to be validated. val userFormNested: Form[User] = Form( mapping( "name" -> text, "email" -> list(email), "address" -> mapping( "street" -> text, "city" -> text)(UserAddress.apply)(UserAddress.unapply)) (User.apply)(User.unapply)) case class User(name: String, email: List[String], address: UserAddress) case class UserAddress(street: String, city: String)
  • 18. Showing forms in a view template Once you have a form, then you need to make it available to the template engine. You do this by including the form as a parameter to the view template. When you are using nested data this way, the form values sent by the browser must be named like address.street, address.city, etc. When you are using repeated data like this, the form values sent by the browser must be named emails[0], emails[1], emails[2], etc Showing forms in a view template Once you have a form, then you need to make it available to the template engine. You do this by including the form as a parameter to the view template. When you are using nested data this way, the form values sent by the browser must be named like address.street, address.city, etc. When you are using repeated data like this, the form values sent by the browser must be named emails[0], emails[1], emails[2], etc @(userForm: Form[userFormNested]) @import helper. @import helper.twitterBootstrap._ @helper.form(action = routes.UserController.save, 'id -> "brandQuery") { <fieldset> @helper.inputText(userFormNested("name"),'class -> "customClass",'value->"sushil kumar") @helper.repeat(myForm("emails"), min = 1) { emailField => @helper.inputText(emailField) } @helper.inputText(userFormNested("address.street")) @helper.inputText(userFormNested("address.city")) </fieldset> <input type="submit" class="btn primary" value="Submit"> }
  • 19. Field constructors A field rendering is not only composed of the <input> tag, but it also needs a <label> and possibly other tags used by your CSS framework to decorate the field. All input helpers take an implicit FieldConstructor that handles this part. The default one (used if there are no other field constructors available in the scope), generates HTML like: Field constructors A field rendering is not only composed of the <input> tag, but it also needs a <label> and possibly other tags used by your CSS framework to decorate the field. All input helpers take an implicit FieldConstructor that handles this part. The default one (used if there are no other field constructors available in the scope), generates HTML like: <dl class="error" id="username_field"> <dt><label for="username"><label>Username:</label></dt> <dd><input type="text" name="username" id="username" value=""></dd> <dd class="error">This field is required!</dd> <dd class="error">Another error</dd> <dd class="info">Required</dd> <dd class="info">Another constraint</dd> </dl>
  • 20. Field constructors Twitter bootstrap field constructor There is also another built-in field constructor that can be used with TwitterBootstrap . To use it, just import it in the current scope: Field constructors Twitter bootstrap field constructor There is also another built-in field constructor that can be used with TwitterBootstrap . To use it, just import it in the current scope: @import helper.twitterBootstrap._ It generates Html like: <div class="clearfix error" id="username_field"> <label for="username">Username:</label> <div class="input"> <input type="text" name="username" id="username" value=""> <span class="help-inline">This field is required!, Another error</span> <span class="help-block">Required, Another constraint</d</span> </div> </div>
  • 21. Field constructors Writing your own field constructor For example : views.common.myFieldConstructor Field constructors Writing your own field constructor For example : views.common.myFieldConstructor @(elements: helper.FieldElements) <div class="@if(elements.hasErrors) {error}"> <label for="@elements.id">@elements.label</label> <div class="input"> @elements.input <span class="errors">@elements.errors.mkString(", ")</span> <span class="help">@elements.infos.mkString(", ")</span> </div> </div>
  • 22. Field constructors Now create a FieldConstructor using this template function: And to make the form helpers use it, just import it in your templates: You can also set an implicit value for your FieldConstructor inline in your template this way: Field constructors Now create a FieldConstructor using this template function: And to make the form helpers use it, just import it in your templates: You can also set an implicit value for your FieldConstructor inline in your template this way: object MyHelpers { implicit val myFields = FieldConstructor(myFieldConstructor.f) } @import MyHelpers._ @implicitField = @{ FieldConstructor(myFieldConstructor.f) }
  • 23. Field constructors This default field constructor supports additional options you can pass in the input helper arguments: Field constructors This default field constructor supports additional options you can pass in the input helper arguments: '_label -> "Custom label" '_id -> "idForTheTopDlElement" '_help -> "Custom help" '_showConstraints -> false '_error -> "Force an error" '_showErrors -> false
  • 24. Messages and internationalization Specifying languages supported by your application Internationalisation (I18N) is a means of adapting your application to different languages to allow for regional differences. To start you need to specify the languages supported by your application in the conf/application.conf file: application.langs=en,en-US,fr Messages and internationalization Specifying languages supported by your application Internationalisation (I18N) is a means of adapting your application to different languages to allow for regional differences. To start you need to specify the languages supported by your application in the conf/application.conf file: application.langs=en,en-US,fr
  • 25. Externalizing messages The default conf/messages file matches all languages. Additionally you can specify language-specific message files such as conf/messages.fr or conf/messages.en-US. For example, the message file containing the corresponding French translations is conf/messages.fr: hello=Bonjour! You can then retrieve messages using the play.api.i18n.Messages object: Template output From a template you can use the above syntax to display localized messages. Externalizing messages The default conf/messages file matches all languages. Additionally you can specify language-specific message files such as conf/messages.fr or conf/messages.en-US. For example, the message file containing the corresponding French translations is conf/messages.fr: hello=Bonjour! You can then retrieve messages using the play.api.i18n.Messages object: Template output From a template you can use the above syntax to display localized messages. val title = Messages("hello") <title>@Messages("hello")</title>
  • 26. All internationalization API calls take an implicit play.api.i18.Lang argument retrieved from the current scope. You can also specify it explicitly: All internationalization API calls take an implicit play.api.i18.Lang argument retrieved from the current scope. You can also specify it explicitly: val title = Messages("home.title")(Lang("fr"))
  • 27. All internationalization API calls take an implicit play.api.i18.Lang argument retrieved from the current scope. You can also specify it explicitly: All internationalization API calls take an implicit play.api.i18.Lang argument retrieved from the current scope. You can also specify it explicitly: val title = Messages("home.title")(Lang("fr"))
  • 28. Messages format Messages can be formatted using the java.text.MessageFormat library. For example, assuming you have message defined like: files.summary=The disk {1} contains {0} file(s). You can then specify parameters as: Messages format Messages can be formatted using the java.text.MessageFormat library. For example, assuming you have message defined like: files.summary=The disk {1} contains {0} file(s). You can then specify parameters as: <h1>@Messages("files.summary", d.files.length, d.name)</h1>
  • 29. Q & Option[A]Q & Option[A]