SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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 SalesforceJitendra Zaa
 
LocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputsLocalizingStyleSheetsForHTMLOutputs
LocalizingStyleSheetsForHTMLOutputsSuite Solutions
 
C:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse InfocenterC:\Users\User\Desktop\Eclipse Infocenter
C:\Users\User\Desktop\Eclipse InfocenterSuite Solutions
 
Sql Injection Adv Owasp
Sql Injection Adv OwaspSql Injection Adv Owasp
Sql Injection Adv OwaspAung Khant
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex codeEdwinOstos
 
ImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlaggingImplementingChangeTrackingAndFlagging
ImplementingChangeTrackingAndFlaggingSuite Solutions
 
PLSQL Developer tips and tricks
PLSQL Developer tips and tricksPLSQL Developer tips and tricks
PLSQL Developer tips and tricksPatrick Barel
 
Sprouting into the world of Elm
Sprouting into the world of ElmSprouting into the world of Elm
Sprouting into the world of ElmMike Onslow
 
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 KhetawatAEM HUB
 
.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 15aminmesbahi
 

Tendances (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
 

En vedette

Introducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineIntroducing Scalate, the Scala Template Engine
Introducing Scalate, the Scala Template EngineJames Strachan
 
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...
DUMP-2015: «Распределенная обработка миллионов документов на Scala и Akka» Ст...it-people
 
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 2011Matt Raible
 
Designing Reactive Systems with Akka
Designing Reactive Systems with AkkaDesigning Reactive Systems with Akka
Designing Reactive Systems with AkkaThomas Lockney
 
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.1Matthew Barlocker
 
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.Eng Chrispinus Onyancha
 
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 JVMManuel Bernhardt
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в AkkaZheka Kozlov
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scalaMichal Bigos
 
Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Язык программирования Scala / Владимир Успенский (TCS Bank)
Язык программирования Scala / Владимир Успенский (TCS Bank)Ontico
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play appsYevgeniy Brikman
 
Practical Akka HTTP - introduction
Practical Akka HTTP - introductionPractical Akka HTTP - introduction
Practical Akka HTTP - introductionŁukasz Sowa
 
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 HTTPRafal Gancarz
 

En vedette (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
 

Similaire à Play Template Engine Based On Scala

Lessons Learned: Scala and its Ecosystem
Lessons Learned: Scala and its EcosystemLessons Learned: Scala and its Ecosystem
Lessons Learned: Scala and its EcosystemPetr Hošek
 
2javascript web programming with JAVA script
2javascript web programming with JAVA script2javascript web programming with JAVA script
2javascript web programming with JAVA scriptumardanjumamaiwada
 
Introduction to whats new in css3
Introduction to whats new in css3Introduction to whats new in css3
Introduction to whats new in css3Usman Mehmood
 
Razor new view engine asp.net
Razor new view engine asp.netRazor new view engine asp.net
Razor new view engine asp.netahsanmm
 
HTML Foundations, part 1
HTML Foundations, part 1HTML Foundations, part 1
HTML Foundations, part 1Shawn Calvert
 
.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 12aminmesbahi
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
Scala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSAlberto Paro
 
Alberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsScala Italy
 
An Introduction To C++Templates
An Introduction To C++TemplatesAn Introduction To C++Templates
An Introduction To C++TemplatesGanesh Samarthyam
 
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...Codemotion
 
Introduction to Spark ML
Introduction to Spark MLIntroduction to Spark ML
Introduction to Spark MLHolden Karau
 
Html5 deciphered - designing concepts part 1
Html5 deciphered - designing concepts part 1Html5 deciphered - designing concepts part 1
Html5 deciphered - designing concepts part 1Paxcel Technologies
 
Basic JavaScript Tutorial
Basic JavaScript TutorialBasic JavaScript Tutorial
Basic JavaScript TutorialDHTMLExtreme
 
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 ScalaDerek Chen-Becker
 

Similaire à 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
 
Scala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJSScala Italy 2015 - Hands On ScalaJS
Scala Italy 2015 - Hands On ScalaJS
 
Alberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.jsAlberto Paro - Hands on Scala.js
Alberto Paro - Hands on Scala.js
 
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
 

Plus de Knoldus Inc.

Mastering Distributed Performance Testing
Mastering Distributed Performance TestingMastering Distributed Performance Testing
Mastering Distributed Performance TestingKnoldus Inc.
 
MLops on Vertex AI Presentation (AI/ML).pptx
MLops on Vertex AI Presentation (AI/ML).pptxMLops on Vertex AI Presentation (AI/ML).pptx
MLops on Vertex AI Presentation (AI/ML).pptxKnoldus Inc.
 
Introduction to Ansible Tower Presentation
Introduction to Ansible Tower PresentationIntroduction to Ansible Tower Presentation
Introduction to Ansible Tower PresentationKnoldus Inc.
 
CQRS with dot net services presentation.
CQRS with dot net services presentation.CQRS with dot net services presentation.
CQRS with dot net services presentation.Knoldus Inc.
 
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...Knoldus Inc.
 
Introduction to Buildpacks.io Presentation
Introduction to Buildpacks.io PresentationIntroduction to Buildpacks.io Presentation
Introduction to Buildpacks.io PresentationKnoldus Inc.
 
Introduction to Falco presentation.pptxx
Introduction to Falco presentation.pptxxIntroduction to Falco presentation.pptxx
Introduction to Falco presentation.pptxxKnoldus Inc.
 
Spark Unveiled Essential Insights for All Developers
Spark Unveiled Essential Insights for All DevelopersSpark Unveiled Essential Insights for All Developers
Spark Unveiled Essential Insights for All DevelopersKnoldus Inc.
 
Understanding System Design and Architecture Blueprints of Efficiency
Understanding System Design and Architecture Blueprints of EfficiencyUnderstanding System Design and Architecture Blueprints of Efficiency
Understanding System Design and Architecture Blueprints of EfficiencyKnoldus Inc.
 
Introduction to RAG (Retrieval Augmented Generation) and its application
Introduction to RAG (Retrieval Augmented Generation) and its applicationIntroduction to RAG (Retrieval Augmented Generation) and its application
Introduction to RAG (Retrieval Augmented Generation) and its applicationKnoldus Inc.
 
Getting Started With React Native Presntation
Getting Started With React Native PresntationGetting Started With React Native Presntation
Getting Started With React Native PresntationKnoldus Inc.
 
Elastic Search Capability Presentation.pptx
Elastic Search Capability Presentation.pptxElastic Search Capability Presentation.pptx
Elastic Search Capability Presentation.pptxKnoldus Inc.
 
Kotlin With JetPack Compose Presentation
Kotlin With JetPack Compose PresentationKotlin With JetPack Compose Presentation
Kotlin With JetPack Compose PresentationKnoldus Inc.
 
Angular AG grid and its features with Pagination
Angular AG grid and its features with PaginationAngular AG grid and its features with Pagination
Angular AG grid and its features with PaginationKnoldus Inc.
 
Grafana Loki (Monitoring Tool) Presentation
Grafana Loki (Monitoring Tool) PresentationGrafana Loki (Monitoring Tool) Presentation
Grafana Loki (Monitoring Tool) PresentationKnoldus Inc.
 
Components in Ionic Presentation (FrontEnd)
Components in Ionic Presentation (FrontEnd)Components in Ionic Presentation (FrontEnd)
Components in Ionic Presentation (FrontEnd)Knoldus Inc.
 
Testing Harmony Design Patterns & Anti-Patterns Unveiled
Testing Harmony Design Patterns & Anti-Patterns UnveiledTesting Harmony Design Patterns & Anti-Patterns Unveiled
Testing Harmony Design Patterns & Anti-Patterns UnveiledKnoldus Inc.
 
Introduction to AWS CloudWatch Presentation
Introduction to AWS CloudWatch PresentationIntroduction to AWS CloudWatch Presentation
Introduction to AWS CloudWatch PresentationKnoldus Inc.
 
Benefit of scrum ceremonies presentation
Benefit of scrum ceremonies presentationBenefit of scrum ceremonies presentation
Benefit of scrum ceremonies presentationKnoldus Inc.
 
Unleashing Real-time Power with Kafka.pptx
Unleashing Real-time Power with Kafka.pptxUnleashing Real-time Power with Kafka.pptx
Unleashing Real-time Power with Kafka.pptxKnoldus Inc.
 

Plus de Knoldus Inc. (20)

Mastering Distributed Performance Testing
Mastering Distributed Performance TestingMastering Distributed Performance Testing
Mastering Distributed Performance Testing
 
MLops on Vertex AI Presentation (AI/ML).pptx
MLops on Vertex AI Presentation (AI/ML).pptxMLops on Vertex AI Presentation (AI/ML).pptx
MLops on Vertex AI Presentation (AI/ML).pptx
 
Introduction to Ansible Tower Presentation
Introduction to Ansible Tower PresentationIntroduction to Ansible Tower Presentation
Introduction to Ansible Tower Presentation
 
CQRS with dot net services presentation.
CQRS with dot net services presentation.CQRS with dot net services presentation.
CQRS with dot net services presentation.
 
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...
Building Resilient Software A Deep Dive into Self-Healing Test Automation Fra...
 
Introduction to Buildpacks.io Presentation
Introduction to Buildpacks.io PresentationIntroduction to Buildpacks.io Presentation
Introduction to Buildpacks.io Presentation
 
Introduction to Falco presentation.pptxx
Introduction to Falco presentation.pptxxIntroduction to Falco presentation.pptxx
Introduction to Falco presentation.pptxx
 
Spark Unveiled Essential Insights for All Developers
Spark Unveiled Essential Insights for All DevelopersSpark Unveiled Essential Insights for All Developers
Spark Unveiled Essential Insights for All Developers
 
Understanding System Design and Architecture Blueprints of Efficiency
Understanding System Design and Architecture Blueprints of EfficiencyUnderstanding System Design and Architecture Blueprints of Efficiency
Understanding System Design and Architecture Blueprints of Efficiency
 
Introduction to RAG (Retrieval Augmented Generation) and its application
Introduction to RAG (Retrieval Augmented Generation) and its applicationIntroduction to RAG (Retrieval Augmented Generation) and its application
Introduction to RAG (Retrieval Augmented Generation) and its application
 
Getting Started With React Native Presntation
Getting Started With React Native PresntationGetting Started With React Native Presntation
Getting Started With React Native Presntation
 
Elastic Search Capability Presentation.pptx
Elastic Search Capability Presentation.pptxElastic Search Capability Presentation.pptx
Elastic Search Capability Presentation.pptx
 
Kotlin With JetPack Compose Presentation
Kotlin With JetPack Compose PresentationKotlin With JetPack Compose Presentation
Kotlin With JetPack Compose Presentation
 
Angular AG grid and its features with Pagination
Angular AG grid and its features with PaginationAngular AG grid and its features with Pagination
Angular AG grid and its features with Pagination
 
Grafana Loki (Monitoring Tool) Presentation
Grafana Loki (Monitoring Tool) PresentationGrafana Loki (Monitoring Tool) Presentation
Grafana Loki (Monitoring Tool) Presentation
 
Components in Ionic Presentation (FrontEnd)
Components in Ionic Presentation (FrontEnd)Components in Ionic Presentation (FrontEnd)
Components in Ionic Presentation (FrontEnd)
 
Testing Harmony Design Patterns & Anti-Patterns Unveiled
Testing Harmony Design Patterns & Anti-Patterns UnveiledTesting Harmony Design Patterns & Anti-Patterns Unveiled
Testing Harmony Design Patterns & Anti-Patterns Unveiled
 
Introduction to AWS CloudWatch Presentation
Introduction to AWS CloudWatch PresentationIntroduction to AWS CloudWatch Presentation
Introduction to AWS CloudWatch Presentation
 
Benefit of scrum ceremonies presentation
Benefit of scrum ceremonies presentationBenefit of scrum ceremonies presentation
Benefit of scrum ceremonies presentation
 
Unleashing Real-time Power with Kafka.pptx
Unleashing Real-time Power with Kafka.pptxUnleashing Real-time Power with Kafka.pptx
Unleashing Real-time Power with Kafka.pptx
 

Dernier

IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 

Dernier (20)

IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 

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]