Skip to content

Handlebars templates based on Java port of handlebars with special Play 2 handlers

License

Notifications You must be signed in to change notification settings

andriykuba/play-handlebars

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Handlebars template engine for Play Framework

Build Status Maven Central

This module is created for using Handlebars templates with Play Framework. It uses Handlebars.java under the hood with an additional resolver for the play JSON objects. Both Scala and Java are supported.

Table of Contents

Install

  1. Add the library in built.sbt

    Play 2.6, Scala 2.12

    libraryDependencies += "com.github.andriykuba" % "play-handlebars" % "2.6.7" 

    Play 2.5, Scala 2.11

    libraryDependencies += "com.github.andriykuba" % "play-handlebars" % "2.5.11" 
  2. Enable the module in conf\application.conf

    play.modules.enabled += "com.github.andriykuba.play.handlebars.HandlebarsModule"
  3. Configure the templates folder and cache (optional)

    handlebars{
      directory = "/templates"   #"/templates" by default
      extension = ".hbs"         #".hbs" by default
      isCacheEnabled = true      #true by default 
    }
    
  4. Configure build.sbt to take the templates folder in to the distribution package

    // Copy handlebars templates to the production
    import Path.relativeTo
    mappings in Universal ++= {
      val basePath = (baseDirectory.value).get.head
      ((baseDirectory.value / "templates" ** "*" get) pair relativeTo(basePath)) 
    }

Usage

Java

Inject HandlebarsApi into controller and call handlebarsApi.html(templateName, data) method.

public class HomeController extends Controller { 
 
    @Inject
    private HandlebarsApi handlebarsApi;
 
    public Result index() {
        // Data. 
        final Map<String, Object> data = new HashMap<>();
        data.put("title", "Page Title");
        data.put("header", "Header");
        data.put("main", ImmutableMap.of("article", "Main Article"));
        data.put("footer", "Footer");

        // Fill it with the data.
        final Content page = handlebarsApi.html("page", data, Context.current().lang().code());

        // Return the page to the client. 
        return ok(page);
    }
}

Scala

Inject HandlebarsApi into controller with trait HandlebarsSupport and call render(templateName, data) method.

class HomeController @Inject() (val handlebarsApi: HandlebarsApi)extends Controller with HandlebarsSupport{
  def index = Action { implicit request =>{
    val jsonData = 
      Json.obj("users" -> Json.arr(
        Json.obj(
          "name" -> "Jhon",
          "age" -> 4,
          "role" -> "Worker"
        ),
        Json.obj(
          "name" -> "Duck",
          "age" -> 6,
          "role" -> "Administrator"
        )))
    val page = render("page", jsonData)
    Ok(page)
  }}
}

In Scala version with Json data flash variables automatically added to the jsonData object.

Redirect(controllers.routes.HomeController.myForm()).flashing("success" -> "The document has been created") 

Previous flash variable could be extracted in a template as

<div>{{flash.success}}</div>

Play helpers

Assets

assets helper is the replacement for the twirl @routes.Assets.versioned method.

<link rel="stylesheet" media="screen" href="{{asset "stylesheets/main.css"}}">

Resulting HTML:

<link rel="stylesheet" media="screen" href="/assets/stylesheets/d41d8cd98f00b204e9800998ecf8427e-main.css">

Do not forget to configure versioning in the build file pipelineStages := Seq(digest) for the production and pipelineStages in Assets := Seq(digest) for the development.

Reverse routing

route helper is the replacement for the twirl reverse routing "<full-package-name>.routes.<controller>.<action>"

<form action="{{route "controllers.SecureController.loginSubmit"}}" method="POST">

Resulting HTML:

<form action="\login" method="POST">

route helper also works with the String, Integer or variable:

{{route "controllers.UserController.user(\"admin\")"}}

{{route "controllers.UserListController.page(42)"}}

{{route "controllers.FriendsController.friends(user.name)"}}

Message

message helper is the replacement for the twirl @Message(key) method. It also could take arguments like the original method.

<div>{{message "page.header.sub" "name"}}</div>

In the messages.en file

page.header.sub=Page Sub Header {0}

Resulting HTML:

<div>Page Sub Header name</div>

i18n

messages helper use the language that was passed to the render or html method as a language code string. This code combine in to the handlebars context as a language variable, so it can be used in template.

<html lang="{{language}}">

In scala the HandlebarsSupport trait takes the language code from the implicit Lang variable. The implicit request2lang method of the Play Framework Controller class convert RequestHeader to the Lang. So, if you need the i18n support in the applications, you need to call your code with the implicit request. The example:

def index = Action { implicit request =>{
   // Your code, like render("page", jsonData), or any other that use Lang object
}}

String helpers

Encode url parameter

encodeUrlParameter encode the string that it could be used as URL parameter. It use java.net.URLEncoder.encode under the hood.

<a href="https://www.google.com?q={{encodeUrlParameter "blue+light blue"}}">search</a>

Resulting HTML:

<a href="https://www.google.com?q=blue%2Blight+blue">search</a>

If equals

if_equals compare two objects and return the value if they are equal.

<ul>
{{#each vote.options}}
  <li><input type="radio" name="vote" value="{{@key}}" {{if_equals @key user.vote "checked"}}>{{this}}</li>
{{/each}}
</ul>

Resulting HTML:

<ul>
  <li><input type="radio" name="vote" value="one">first</li>
  <li><input type="radio" name="vote" value="second" checked>second</li>
  <li><input type="radio" name="vote" value="third">third</li>
</ul>

Concat

concat concatenate the string representation of the parameters in one string.

<div>{{concat "static" variable}} 

Resulting HTML:

<div>static and some dynamic</div>

It useful to use in subexpressions

<div>{{message (concat 'category.name.' category)}}</div>

Scala Json Value Resolver

It works similar to JsonNodeValueResolver but resolve the classes from the play.api.libs.json package

About

Handlebars templates based on Java port of handlebars with special Play 2 handlers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published