Welcome back to Part 3 of Playful Prelaunch Tutorial Series! In the first part of the series we created a static home page and an about page using Scala REST routing, ScalaForms and Play’s strong partial capability because of its object-functional nature. We also created tests to verify the contents of our two views and the routes that took us to them and we used Git to manage our source code and to deploy to Heroku.

In the second part of our series we explored viewing and updating data in our Postgres database with ScalaAnorm, giving our app some flexibility using Play’s internationalization libraries, creating views that can create and display data using case classes and implicit arguments.

In this tutorial we’re going to access RESTful services using the Scala concurrent library and the Play ws (web service) library. We’re going to do this while exploring the email facilities provided by MailChimp, a Heroku partner. In previous tutorials you didn’t need to create the Heroku account but you will need to create one for this tutorial.

If you’ve installed the Heroku Toolbelt in your terminal from the root of my-playful-prelaunch type the following:

$ heroku addons:add mandrill

Before we go any further let’s create a branch for part 3. Open to your terminal and go to the root of my-playful-prelaunch. Make sure you’re in your master branch and that you have no commits pending. Type the following:

$ git checkout -b mandrill-email-rest

Now we’re free to make changes to our code in a sandbox.

Now go to dashboard.heroku.com/apps and select your app. By default you should be taken to your app’s resources tab. Under add-ons you should see Mandrill by MailChimp listed. Click Mandrill and you will be taken to the Mandrill dashboard for Heroku customers. In the left hand navigation you should see a settings button. Click it. At the bottom of the settings page you will see the API keys with one key listed. Copy it to your clipboard. Open conf/application.conf and add the following to the bottom of the file replacing “your-key-here” with your key. Be sure to enter the double quotes as well.

# Mandrill Key

The second configuration is the path to the API we will use to send an email using the Mandrill templates

Now that we have a key we are going to create a service that knows how to use it. Create a folder under app called services. In this folder create a file called Messages.scala. Enter the following:

package services
import play.api.i18n._
import play.api.libs.json._
import play.api.libs.ws._
import scala.concurrent.Future
import play.api.Play.current

As we’ve done in the two previous tutorials we will review each line or section.

  • import package services – Message.scala is in the services dir so it is in the services package
  • import play.api.i18n._ – Play’s internationalization library
  • import play.api.libs.json._ – Pretty self explanatory but we’re getting access to Play’s JSON library.
  • import play.api.libs.ws._ – Mandrill exposes their API via a RESTful web service and SMTP. We’re going to use the web service hence the ws.
  • import scala.concurrent.Future – Copy and paste time. A Future is an object holding a value which may become available at some point. This value is usually the result of some other computation from the Scala Language site. We’re going to be calling a web service and we don’t know how long it will take so we’re going to use this nice device so that we’re not holding up a thread while we wait. Look up non-blocking I/O. It is cool, awesome and can be difficult to wrap your mind around.
  • import play.api.Play.current – We will be connecting to the Mandrill API as an http client. We can explicitly create a client and use it or we can use our currently running Application. We’re going to use our Application and that is what is described by the current part of play.api.Play.current

Next we’re going to create our Message object and our function stubs. Enter the following below the import statements:

object Message {
  def buildRegistrationTemplate(firstName: String, lastName: String, email: String, mandrillKey: String): JSValue = {
  def emailNewRegistration(firstName:String, lastName: String, email: String) {

We have two functions here:

  • The buildRegistrationTemplate function will return a Mandrill email template in the form of a JsValue when we pass it a firstName, lastName, email and our mandrillKey
  • The emailNewRegistration function will send an email via the Mandrill API to a registered visitor.

Before we fill in our two functions let’s go back to Heroku and setup our templates. Go back to the tab you left open on the Mandrill app page. In the left hand navigation click on the “Outbound” link. At the top of the page just under the name of your application name and the Outbound label you should see a row of links. Click the third one from the left titled “Templates”. Click the “Create a Template button” and name it my “My Playful Prelaunch Registration” without the double quotes and then click Start Coding. You will only have to fill in four fields here. The first 3 fields are the From Email, the From Name and the Subject.

  • In the From Email enter an email address you control.
  • In the From Name enter “My Playful Prelaunch”
  • In the Subject enter “Thanks for your interest in My Playful Prelaunch

I’m going to save you some time and tell you that the subject box can not make use of Mandrill’s editable sections.
In the large text box on the right enter:

Hello <div mc:edit="firstname"></div>

Thank you so much for your interest in <div mc:edit="appname"></div>! An associate will contact you via email soon.

Best regards,

<div mc:edit="appname"></div>

Now let’s fill in our Message service’s two functions. The final version of our buildRegistrationTemplate should look like this:

def buildRegistrationTemplate(firstName: String, lastName: String, email: String, mandrillKey: String): JsValue = {
        "key" -> JsString(mandrillKey),
        "template_name" -> JsString("my-playful-prelaunch-registration"),
        "template_content" -> JsArray(Seq(
          JsObject(Seq("name" -> JsString("firstname"), "content" -> JsString(firstName))),
          JsObject(Seq("name" -> JsString("appname"), "content" -> JsString(Messages("global.appName")))))),
        "message" -> JsObject(
          Seq("to" -> JsArray(Seq(
                JsObject(Seq("email" -> JsString(email),
                "name" -> JsString(firstName + " " + lastName),
                "type" -> JsString("to")
        "headers" -> JsObject(Seq(
          "Reply-To" -> JsString(Messages("global.replyToEmail")))),
        "important" -> JsBoolean(false),
        "track_opens" -> JsBoolean(true)))))

This code models the JSON structure required by Mandrill found here. There are 4 major sections.

  • key – the Mandrill key we received via the Heroku partnership
  • template_name – Mandrill calls this the Template Slug in the user interface. It is how they identify a template via the API. It is based on the name we entered when we created the template.
  • template_content – This is the dynamic content we are passing from our application. In our case we are passing the interested visitor’s firstname and the name of our app as defined in conf/messages.
  • message – contains the following 4 sections
    • to – one or more recipients of an email. For our purposes and our design we will only send one email. If we were going to send the same content to multiple email addresses we might use this format
    • headers – defines our reply to. In my case, I’m using no-reply< at> hawkinsunlimited [dot] com
    • important – indicates whether we want to flag this email as important. For this email we do not.
    • track_opens – indicates whether we want to track opens of this email. For this email we do not.

The emailNewRegistration is even easier. Make your function look like this:

  def emailNewRegistration(firstName: String, lastName: String, email: String) {
    val mandrillKey: String = play.Play.application.configuration.getString("mandrillKey")
    val jsonClass = buildRegistrationTemplate(firstName, lastName, email, mandrillKey)

    val apiUrl = "https://mandrillapp.com/api/1.0/messages/send-template.json"
    val futureResponse: Future[WSResponse] = WS.url(apiUrl).post(jsonClass)
  • val mandrillKey… – retrieves the mandrillKey from conf/application.conf
  • val jsonClass… – retrieves the RegistrationTemplate JsValue
  • val apiUrl… – retrieves the URL to the Mandrill endpoint for sending email via a template
  • val futureResponse: Future[WSResponse] = WS.url(apiUrl).post(jsonClass) – sends the JSON to Mandrill via HTTP post

Finally, we need to put this all together in our Registration controller. We will update our create action as follows with the Message.emailNewRegistration method:

  def create = Action { implicit request =>
      errors => BadRequest(views.html.registration.newReg(errors)),
      person => {
        val newPerson = Person.create(person.firstName, person.lastName,
        Message.emailNewRegistration(newPerson.firstName, newPerson.lastName, newPerson.email)
        Ok(views.html.registration.registrationSuccess(newPerson.firstName, newPerson.email))

We’re now code complete! Let’s push our updated application to Heroku. From the root of your application (the same place app, conf and test live type the following to merge and push your code to your Git repository and to Heroku.

$ git add --all
$ git commit -a -m "add email to the prelaunch app"
$ git checkout master
$ git merge mandrill-email-rest
$ git push origin master
$ git push heroku master

Let’s do a quick recap of these Git commands

  • git add –all – adds our new directories and files to the Git index. In our case this is the services directory and the Message.scala file.
  • git commit -a -m “add email to the prelaunch app” – commits our new files and updated files to the Git index
  • git checkout master – returns us to our master branch which means all of our changes from the mandrill-email-rest branch are no longer visible. Don’t worry we’re going to merge all of those changes with the next line
  • git merge mandrill-email-rest – Take all of our changes from mandrill-email-rest and merge them into the current branch which is master.
  • git push origin master – Push all of our changes to the master branch of the remote Git repository aliased by origin. In my case this is git@github.com:michaelhawkins/playful-prelaunch.git
  • git push heroku master – If you set up Heroku before you’ll recognize this push updates your Heroku instance. You’ll also notice it takes quite a bit longer than the push to the remote Git repository. This is because Heroku is not only receiving the Git push but it is unpacking and building and/or upgrading our instance including compiling any dependencies defined in build.sbt (or build.scala).

And we’re done! We’ve updated our Prelaunch app to send emails to interested parties.

Welcome to part 2 of the Play Framework 2.3 Playful Prelaunch Tutorial. In the first tutorial we used Scala and the Play Framework to create static pages for a prelaunch or “Coming Soon” site. We used partials, Scala templates, Play Forms and specs2 for unit and integration testing. We also deployed our app to Heroku. My version of the app is located here.

In part 2 of the tutorial we are going to develop the following features:

  • Add the ability to collect the name and email address of someone interested in the Playful product.
  • We’re also going to send a follow up email to each person who signs up.
  • We’re also going to add internationalization to our product so that we can easily change the name of the product
  • Finally, we’re going to update our unit and integration tests to account for our new features.

Let’s start by adding internationalization to Play. Open your command line interface and go to the root of your my-playful-prelaunch project and type:

$ git checkout master
$ git checkout -b add-i18n

The first command is to make sure you started in the master branch. The second line creates the new branch in git. Now in your in /conf directory create a new text file called messages. In this file type or copy the following:

global.about = About us
global.appName = Playful Prelaunch App
global.companyName = Playful Prelaunch LLC.
global.how = How it works
global.welcomeToThe = Welcome to the
global.playFramework = Play! Framework

generic.thisIsThe = This is the
generic.sampleApp = Sample Application
generic.youCanFindWorking = You can find a working version of this app

We can now replace all of our text in our views and controllers with the variables on the right. Later if we want to change our app name, company name or any of these other words or phrases we only have to do it from here. When you’re launching a startup all of these things are in play (no pun intended). Let’s go to the following files and replace our text with the variables above. Keep in mind the following three things and you will successfully update your code:

  1. You’ll have to pass each variable to the Messages function. For example to use global.appName call Messages(“global.appName”)
  2. Add the following import function to your controllers:
    1. import play.api.i18n._
  3. In the scala views prepend the Messages function with an @ symbol if no other Scala code appears on that line. For example,
    1. <a class=”navbar-brand” href=”/”>@Messages(“global.appName”)</a>

Go ahead and make your changes to the following files:

  • /app/controllers/Application.scala
  • /app/controllers/Marketing.scala
  • /app/views/marketing/about.scala.html
  • /app/views/partials/header.scala.html
  • /app/views/index.scala.html
  • /app/views/main.scala.html

Now let’s rerun our tests from the CLI:

$ sbt test

If you have any compile issues be sure to read the compiler issues and compare them to the three points above. Finally, let’s update the following test files to use i18n rather than hard coding the strings. First add the “import play.api.i18n.Messages” statement to all 3 files and then change the hard coded references to “Playful Prelaunch App” and “About us”:

  • /test/ApplicationSpec.scala
  • /test/IntegrationSpec.scala
  • /test/MarketingSpec.scala

If we rerun our tests we should get all green. Now let’s commit to git:

$ git add --all
$ git commit -am "Add internationalization"
$ git checkout master
$ git merge add-i18n

At this point if you created a GitHub account as I suggested at the start you can push your changes to GitHub. This is also a good time to deploy your changes to Heroku.

$ git push github master
$ git push heroku master

We’ve accomplished quite a bit although very little of it is visible. Our next few changes will be substantial.

We’re going to create functionality that will allow visitors interested in subscribing to updates on our product to leave us their names and email addresses. Our registration page will look like this:


and a successful registration will look like this:

We will start by by creating a new branch. In your CLI or IDE create a new branch:

$ git checkout -b registration-pages

Now let’s create our Registration controller by creating a new file called Registration.scala in /app/controllers and creating it as follows. :

package controllers
import play.api._
import play.api.mvc._
import play.api.i18n
object Registration extends Controller {
  //Will return a new registered Person model to populate
  def newReg = TODO
  //Will create a new registered Person model
  def create = TODO

The imports at the top of our controller are the same as our Marketing controller as is the object definition with the exception of the name. We’ve created the default actions we’ll implement for this controller:

  • newReg – Will return a person class suitable for the registration form
  • create – Will take a person object and create it

The TODO gives us a standard Not Implemented Yet page. Now that we have a template for our registration actions let’s update our routes. We will open our routes file and add the following after the Marketing section and before the map static resources section:

# Registration
GET    /register    controllers.Registration.newReg
POST   /register    controllers.Registration.create

Signup Todo
Our routes will now direct HTTP GET requests to /register to our new action and HTTP POST requests will go to our create action. If Play isn’t running go to the root of your my-playful-prelaunch and type:

$ activator run

Now open your browser and go to localhost:9000/register. You should see the following:
Signup Todo.

Now that we have our routes setup let’s propose our feature set for our registration pages, build tests based on these proposed features and then build out the features working our way from red to green.

Our registration page will reside at the root of our application and it will have three major features:

  • allow an interested visitor to give us her name and email address and submit the information to be saved by us.
  • redirect the person to a new page thanking her for her interest.
  • finally, the system will send her a thank you email.

Let’s start by updating our ApplicationSpec.scala to check that the registration page is located at the root of our application. Update the “render the index page” to look like this:

    "render the index/registration page" in new WithApplication{
      val home = route(FakeRequest(GET, "/")).get

      status(home) must equalTo(OK)
      contentType(home) must beSome.which(_ == "text/html")
      contentAsString(home) must contain (Messages("global.appName"))
      contentAsString(home) must contain (Messages("Register"))
      contentAsString(home) must contain (Messages("person.firstname"))
      contentAsString(home) must contain (Messages("person.lastname"))     
      contentAsString(home) must contain (Messages("email.email"))

Let me break down each line of our code and explain what each accomplishes.

  • status(home) must equalTo(OK) -verifies that we received Http status 200 from our app.
  • contentType(home) must beSome.which(_ == “text/html”) – confirms that this route returned the content type “text/html” in the header
  • contentAsString(home) must contain (Messages(“

Now that we understand our test code let’s run our scripts and see the result:

$sbt test

As expected our new test has failed but let’s keep going and make sure we have a test for all of our functionality. Let’s open test/IntegrationSpec.scala and add the following after “work from within a browser”

"allow you to enter your name and email, register and take you to registrationSuccess page" in new WithBrowser {
      browser.goTo("http://localhost:" + port)

      val firstName: String = "Jane"
      val lastName: String = "Smith"
      val email: String = "jane@hawkinsunlimited.com"


      browser.pageSource must contain("Thank you for signing up to hear more")
      browser.pageSource must contain("Once we launch we will email you at " + email)

The browser object we’re using here is provided by Selenium a tool to automate web browsers. Let’s run our test suite and confirm that we have two failed tests

$ sbt test

gives this result

[error] Error: Total 6, Failed 1, Errors 1, Passed 4
[error] Failed tests:
[error] 	ApplicationSpec
[error] Error during tests:
[error] 	IntegrationSpec
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 14 s, completed Aug 3, 2014 10:08:55 PM

We ran 6 tests, 4 passed, 1 failed and 1 returned an error. The error is because Selenium couldn’t get to the name element we specified in our test. Once we create our view with this element this error will be replaced with a failure until we complete the full spec. Now that we’ve finished our test suite let’s build the code that will pass our tests. First, let’s change our home route so it goes to Registration.newReg action rather than to the Application.index action.

# Home page
GET     /    controllers.Registration.newReg

At the same time comment out the Application.index action to make sure we don’t get any odd behavior. Now let’s update our Registration controller newReg action so it returns a NewPerson.

  def newReg = Action {

This code is calling the newReg view (which is a function and can be called like a function because in Scala everything is a function) and passing it a value called newPersonForm. newPersonForm will allow our newReg form to return a populated person object via the controllers.Registration.create action to be inserted into our database. We’ll create the newPersonForm by adding the following to controllers.Registration just below the Registration object definition.

  val newPersonForm: Form[NewPerson] = Form(
      "firstName" -> nonEmptyText,
      "lastName" -> nonEmptyText,
      "email" -> nonEmptyText(minLength = 6) //shortest domain is k.st add @ + 1 letter and the min email length is 6

Let’s break this code down line by line

  • The newPersonForm value is a Form type with a NewPerson type passed to it.
  • The Forms object we imported defines the mapping method that takes the elements of our form like “firstName” and constraints like “nonEmptyText” (meaning firstName must have some value).
  • The Forms object also takes an apply and an unapply function which we are fulfilling via a yet undefined NewPerson case class

We need to make one final update to our controller so that it is aware of the Forms object. We need to add the following just below our current block of imports in Registration.scala.

import models._
import play.api.data._
import play.api.data.Forms._

Now that we’ve set up our Registration controller for creating the empty Person form we need to create the NewPerson case class and new to support it. Start by creating a models directory under the app directory. Create a new file in the models directory called Person.scala. Now we need to add a block of code to support creating a new Person. Copy the following to Person.scala.

package models
import anorm._
import anorm.SqlParser._
import play.api.db._
import play.api.Play.current
import play.api.libs.ws._
import play.api.Play.current

case class NewPerson(firstName: String, lastName: String, email: String)
case class Person(id: Long, firstName: String, lastName: String, email: String)

object Person {

  val parser = {
    get[Long]("id") ~
      get[String]("firstname") ~
      get[String]("lastname") ~
      get[String]("email") map {
      case id ~ firstname ~ lastname ~ email => Person(id, firstname, lastname, email)
  def create(firstName: String, lastName: String, email: String): Person = {
       // TODO
  def find(id: Long): Person = {
       // TODO

As I said this may be a lot to digest. I left out the actual database access code because it is probably the most familiar and therefore least interesting of what we’ve done here. As we did before let’s go section by section and get an explanation of what all this does. Before we do that let me give you a hint. The NewPerson and Person case classes do all the translation between the form and the application. The Person object is responsible for CRUD.

  • The Form functions used to create personForm and newPersonForm in our Registration controller operate via these Person and NewPerson case classes which is why we import models._ at the top of the controller.
  • The parser does just as its name implies. It parses each field of the data we’ll get from SQL data store and uses it to create a Person object.
  • The create function takes firstname, lastname and email and returns a Person object using the parser.
  • The find function takes an id (specifically the auto-incrementing, primary key generated by our data store and returns the corresponding Person object.

Before we can create or return anything we need to create our database and tables. I use pgAdmin3 to manage my PostGres systems but use whatever tool you wish and create a database called my-playful-prelaunch-development. With our database created open your conf/application.conf, navigate to the Database configuration section (4 sections down) and enter the following:


We’ve now told my-playful-prelaunch about our database. Now we need to tell it to create our Person table. We’ll be using Evolutions to do this. Create a new folder under /conf called evolutions. Under this folder create a new folder called default. This new folder name must match the database name we used earlier in application.conf. The first database must be called default.

Let’s provide Play the SQL it will need to generate our person table. Create a new text file under conf/evolutions/default and name it 1.sql. Enter the following text into 1.sql

# --- Person schema

# --- !Ups

    id bigserial NOT NULL,
    firstname varchar(255),
    lastname varchar(255),
    email varchar(255),
    CONSTRAINT person_pkey PRIMARY KEY (id)


# --- !Downs

DROP TABLE person;

As always let’s take our code section by section:

  • # — Person schema indicates what schema or schemas are modified in our script
  • # — !Ups indicates the transformations that need to occur. This delimiter must be here otherwise Play will not know what it should do with your script.
  • CREATE TABLE person … is the SQL we want Play to run to create our person table with fields matching the attributes of our case classes.
  • # — !Downs indicates how to reverse the !Ups transformations
  • DROP TABLE person; is the SQL we want Play to run to reverse our changes should we experience a problem.

I suggest you read the Play documentation on Evolutions to get a better understanding on how they work and how to control them. Pay special attention to the section on DOWN evolutions.

Now that we have a mechanism for creating our tables let’s update our Person object’s create and find functions.

  def create(firstName: String, lastName: String, email: String): Person = {
    DB.withConnection { implicit c =>
      val id: Long = SQL("INSERT INTO person(firstname, lastname, email) VALUES({firstname}, {lastname}, " +
        "{email})").on('firstname -> firstName, 'lastname -> lastName, 'email -> email)
        .executeInsert(scalar[Long] single)

      return Person.find(id)

  def find(id: Long): Person = {
    DB.withConnection{ implicit c =>
      SQL("SELECT id, firstname, lastname, email FROM person WHERE id = {id}").on('id -> id).using(Person.parser).single()

As before we will take each section and explain it. First, the create function:

  • DB is a helper provided by the import play.api.db._ and it gives us a connection to our PostGres database.
  • val id: Long uses the SQL function to insert a person into our person table.
  • The on function takes the arguments from the create function and puts into our placeholder braces.
  • executeInsert executes our SQL statement, returns our new Id from PostGres.
  • Finally, Person.find(id) is used to return the new person to our controller which uses it to greet our recently registered visitor.

Now for the find function:

  • As we might expect the DB helper with its connection makes another appearance.
  • As does the SQL and on function but with a SELECT statement to retrieve a person and the id from the find function arguments.
  • The function using is called with the Person.parser value so that we return an easily consumed Person object.
  • Finally, the single function only returns a single row.

We have two more things to complete to finish part 2 of the tutorial. We need a form to accept the visitor’s name and email address and we need to update our unit and functional tests. Let’s start by creating our registration form and our signup success forms. Create a folder in app/views called registration and inside of it create two new files called newReg.scala.html and registrationSuccess.scala.html. In the newReg.scala.html type the following:

@import helper._

@(newPersonForm: Form[NewPerson])

@main(Messages("global.welcomeToThe") + " " + Messages("global.appName") + " " + Messages("global.exampleapp")) {
    <div class="container">
        <div class="row">
            <div class="col-md-offset-1 col-lg-offset-1 col-md-4 col-lg-4">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        <div class="row">
            <div class="col-md-offset-1 col-md-10 col-lg-offset-1 col-lg-10">
                @helper.form(action = routes.Registration.create) {

                            newPersonForm("firstName"), '_label -> Messages("person.firstname"),
                                'placeholder -> Messages("person.enterfirstname"), '_showErrors -> true, '_showConstraints -> true

                            newPersonForm("lastName"), '_label -> Messages("person.lastname"),
                            'placeholder -> Messages("person.enterlastname"), '_showErrors -> true,
                            '_showConstraints -> true
                            newPersonForm("email"), '_label -> Messages("email.email"),
                            'placeholder -> Messages("email.enteremail"), '_showErrors -> true,
                            '_help -> Messages("email.enteremail")

                    <div class="actions">
                        <input type="submit" class="btn btn-primary" value=@Messages("signup.register")>

As we’ve done before we will take each section and I will explain what it does, what it provides and why we need it (assuming I know. :D).

  • Let’s start with the @ sign. Scala templates borrow heavily from ASP.NET Razor and the @ indicates that the following text is Scala code.
  • @helper package contains the template helpers for Scala.
  • Scala templates are compiled as Scala functions. Functions have arguments and our newReg template requires a Form with a NewPerson case class. We can refresh our memory by looking at the val and newReg action in the Registration controller. We’ve now completed the circle.
  • If you recall app/views/main.scala.html is our template for the entire app. At the top it also defines a function that takes a title argument as a string and a content argument as html. Our @main(){} call is providing these two arguments.
  • Messages() is the function call for i18n that is pulling our strings from conf/messages.
  • @helper.form() is the appearance of our Scala forms helper that on compilation will be replaced with an HTML form.
  • @inputText is another Scala function that generates an HTML input tag.
  • _label -> Messages(“person.lastname”) assigns the HTML label Last Name to the input tag.
  • ‘placeholder -> Messages(“person.enterfirstname”) assigns the HTML placeholder attribute to the input tag.
  • ‘_showErrors -> true creates a dd tag for every violation of our field’s constraints and assigns each one a CSS class “error”.
  • ‘_showConstraints -> true creates additional dd tags for each our field’s constraints and assigns it a CSS class called “info”
  • ‘_help -> Messages(“address.enterzipcode”) creates a dd tag with the matching text and assigns it a CSS class called “info”

One thing to note. ‘_showConstraints -> true (or false) is mutually exclusive with ‘_help -> “Some help text” on a particular input tag. You can have one or the other but not both. And ‘_help is higher on the priority list so if you forget and use both then you will only see ‘_help.

Our newReg.scala.html can handle errors but what happens if everything goes to plan and our visitor enters the data we need in the format we need it? Right now we left our registration controllers create action as a todo. We will need to update this action to accept our person’s data and persist it to our database. Let’s open our registration controller and change our create action:

  def create = Action { implicit request =>
      errors => BadRequest(views.html.registration.newReg(errors)),
      person => {
        val newPerson = Person.create(person.firstName, person.lastName,
          newPerson.firstName, newPerson.lastName, newPerson.email))

As always we’re going to dissect each section of our code.

  • def create = Action changes our create action to return an action of the todo message
  • implicit request =>. By default Play Actions receive a request and return a result. The request is the data we receive from our client. The implicit keyword allows us to pass the request on to other API functions without explicitly adding it to the argument list.
  • newPersonForm.bindFromRequest.fold() function handles pulling data from our request form and managing binding failures or binding success
  • errors => BadRequest(views.html.registration.newReg(errors)) is an example of a function with a function (views.html.registration.newReg) as an argument. In this particular case if bindFromRequest.fold fails to bind the request it calls BadRequest and passes the errors it received back to newReg. You should also be aware that BadRequest returns an HTTP status of 400.
  • person => … – is a multiline function so we have to wrap it in {} unlike errors which is not. The first line creates the value newPerson using the Person object’s create function. The next

successfully receive and persist our visitor’s information? We need some way to tell the person we have saved her information. Let’s build that now. Create a new form in app/views/registration called registrationSuccess.scala.html and enter the following code:

@(firstName: String, lastName: String, email: String)

@import helper._

@main(Messages("global.welcomeToThe") + " " + Messages("global.appName") + " " +
Messages("global.exampleapp")) {

    <div style="padding:50px">

        <p>Hello @firstName,</p>
        <p>Thank you for signing up to hear more about @Messages("global.appName").
          Once we launch we will email you at
            @email. </p>
        <p>Best regards,</p>

We’ve seen all of this before.

  • The first line contains the arguments our form function will receive. We will only need the person’s first name and their email address.
  • As we’ve discussed before we imported the helper package for our templates
  • We’re calling the @main form function with two arguments: The page title as a string and the page body as html.

You may have noticed that we used the i18n Messages function quite a bit but we didn’t update our messages file. We will correct that now. Open conf/messages and add the following lines.

signup.signupHere = Sign up here
signup.hearaboutlaunch = Be the first to hear about our launch
signup.register = Register
signup.accountCreated = Your account has been created

person.firstname = First Name
person.lastname = Last Name
person.enterfirstname = Enter first name
person.enterlastname = Enter last name

contact.contactus = Contact us
contact.sendmessage = Send message
contact.comments = Comments

email.email = Email
email.enteremail = Enter email

address.zipcode = Zip Code
address.enterzipcode = Enter zip code

phone.phone = Phone number
phone.enterphone = Enter phone number

We are feature complete for step 2 of the tutorial but we have one 2 more functional test to write and 2 more for you to write on your own. If you recall we already adjusted our GET / route to point to Registration.newReg and we also updated our index unit test to account for adding the collection of a visitor’s first name, last name and email. What we have not done is test the functionality to make sure when someone enters the information correctly that it is persisted and we see the registrationSuccess form so let’s do that now. Open test/IntegrationSpec.scala and add the following section.

    "allow you to register your first name, last name and email and take you to registrationSuccess page" in new WithBrowser {
      browser.goTo("http://localhost:" + port)

      val firstName: String = "Jane"
      val lastName: String = "Smith"
      val email: String = "jane@hawkinsunlimited.com"


      browser.pageSource must contain("Hello " + firstName + ",")
      browser.pageSource must contain("Thank you for signing up to hear more")
      browser.pageSource must contain("Once we launch we will email you at " + email)

As we have done before let’s go through our code section by section:

  • “allow you to register your first name, last name and email and take you to registrationSuccess page” in new WithBrowser { As before the quoted text is for us and describes what we’re testing. The new WithBrowser creates a new browser object.
  • browser.goTo(“http://localhost:” + port) uses our browser to navigate to our index.
  • val firstName: String, val lastName: String, and val email: String create the values we’re going to pass into our HTML inputs. Note they all end with : String so we know they are of String type.
  • browser.$(“#firstName”).text(firstName) uses the browser object we created at the outset to enter the firstName value from the previous section to the input with CSS id firstName. The same is true for #lastName and #email.
  • browser.$(“.btn-primary”).click() uses the browser object to call the click function on the object with CSS class btn-primary
  • The next three lines confirm that the registrationSuccess view is shown and that it has “Hello Jane”, “Thank you for signing up…” and the “Once we launch text…”. Notice that used our values again to make sure that our arguments are found in the new view.

Now if open your terminal and go to the root of my-playful-prelaunch and type

$ sbt test

you should get all green tests.

The last test we’re going to write together will confirm that if a visitor doesn’t enter a first name that our validation works. Add the following to the end of test/IntegrationSpec.scala:

    "fail to register you without your first name and prompt you with the missing information" in new WithBrowser {
      browser.goTo("http://localhost:" + port)

      val lastName: String = "Smith"
      val email: String = "jane@hawkinsunlimited.com"


      browser.pageSource must contain("This field is required")

And again go to the terminal and run

$ sbt test

You should get all greens. This time you’ll notice we did not create a firstName value and more importantly we did not pass any value to browser.$(“#firstName”).text(firstName) and as a result our validation prevented the registration and told the visitor why.

If you’re using Heroku we have one final change to make. Open your Procfile and update it to look like so:

web: target/universal/stage/bin/my-playful-prelaunch -Dhttp.port=${PORT} -DapplyEvolutions.default=true -Ddb.default.url=${DATABASE_URL} -Ddb.default.driver=org.postgresql.Driver

Let’s break this down as before:

  • The applyEvolutions.default=true allows an environment perceived to be production like Heroku to run our evolutions and create our person table.
  • db.default.url=${DATABASE.URL} points our default database to Heroku’s DATABASE_URL environment variable.
  • db.default.driver defines the driver for our default database to be org.postgresql.Driver.

Let’s commit our code, merge it into master and then upgrade Heroku. Go to your terminal and type the following:

$ git status
$ git add --all
$ git commit -a -m "finish Playful Prelaunch part 2"
$ git push -u github registration-pages
$ git checkout master
$ git merge registration-pages
$ git push github master
$ git push heroku master
$ heroku open

Let’s do a quick rundown just in case you’ve forgotten Git or Heroku.

  • git status tells us the status of our local repository
  • git add –all tells git to add all files that are not in our git index (monitored and managed by git) to our git index and ready them (stage them) for a commit except those files that are in our .gitignore file
  • git commit -a -m “finish Playful Prelaunch part 2” commits our staged files whether new or modified
  • git push -u github registration-pages creates a remote “registration-pages” branch on GitHub that mirrors our local branch
  • git checkout master switches to our master branch where the only changes should be part 1 of our tutorial
  • git merge registration-pages merges our changes from the registration-pages branch (part 2) into the master branch (part 1). Consider master to be version 1.0 of our product and registration-pages to be version 2.0.
  • git push github master pushes our updated local master branch to its mirror on GitHub
  • git push heroku master pushes our updated local master branch to Heroku which unpacks it and installs it rather than storing it
  • heroku open launches your default browser and navigates to your instance of Playful Prelaunch

We’re done with part 2 of the Playful Prelaunch tutorial! I don’t know about you but I feel we accomplished a lot in this section. Next time we will add email and RESTful calls to the mix.

As always if you find an error, whether it’s a typo or an error in my understanding of Scala, Play or something else please let me know. You can reach me at info hawkinsunlimited [dot] com.

This is part 1 of a tutorial that will introduce the Play Framework version 2.3, an open source model-viewer-controller web framework, by walking through the development of a very simple prelaunch or “coming soon” web app. The code can be found at github here. The Play Framework can be used by Scala or Java developers but this tutorial will focus on Scala. If you’re new to Scala I suggest you start here or here. Before we begin I’d like to give credit to a few people and organizations who influenced what you will read here.

  • Michael Hartl  is the author of the Rails Tutorial and I learned a lot about Rails and tutorials from him. More than anyone else this tutorial reflects the Rails Tutorial and I want to make sure I give credit where credit is due
  • Martin Odersky is the original author of Scala
  • Guillaume Bort is the original developer of the Play Framework
  • The Typesafe team has done an awesome job shepherding Play, Akka and the entire Typesafe stack from the early releases to the mature product it is today
  • The Play/Scala/Akka community who have written tutorials on all of the above and more

We’ll develop the following features:

  • A home page with text and images describing the app or company to be launched in the future with the ability to take a potentially interested party’s first name, last name, email and zip code (I originally wrote this code for a location dependent web app).
  • Nearly static about and privacy policy page
  • Upon submitting this information the user will be taken to a new page thanking them for their interest and will receive an email with similar information. You will be accessing MailChimp‘s Mandrill REST service.
  • A contact us page if an individual wants to speak to the company regarding career opportunities, product questions or investment.

Before we get started you will need to setup your development environment by installing the following.

  • Typesafe Activator – 1.2.3 – You can download it from Typesafe or use your preferred package manager. I use Homebrew on OSX Mavericks.
  • PostgreSQL – 9.3.4 is the most recent version
  • Git – 2.0.1.
  • Heroku toolbelt if you want to deploy your app

As of this writing I am using Typesafe 1.2.3 and PostgreSQL 9.3.4. All the help you will need for PostgreSQL install on anything and everything is already out there so go do that and then come back here when you’re ready.

We’ll begin by creating the home page, an about page and associated unit and integration tests. Eventually, we will collect data, email interested parties, access RESTful services but I think it’s best to start small and work our way towards a more complex and full solution. We’ll start by creating our application using the activator new command. We will use Activator to create a skeleton Play application but it can also be used to develop new applications from templates. I suggest you spend some time and look through templates and remember that new ones are added quite often. As I said we will start from the CLI by creating a new Play project, called my-playful-prelaunch:

$ cd ~/play-apps
$ activator new my-playful-prelaunch

If you’re connected to the internet Activator will go out and get the latest list of templates. This won’t matter for us since we’ll be selecting a very simple template. Select #4, the play-scala template. Hit enter and activator will create your skeleton. It will also give you instruction on how to run tests on “my-playful-prelaunch” from the CLI or how to run the Activator UI for “my-playful-prelaunch” from the command line. We’re not going to do this just yet so next:

$ cd my-playful-prelaunch

From the my-playful-prelaunch directory you are presented with the following files and directories:

  • activator – This is the main activator bash script
  • activator-launch-1.2.2.jar – This is the jar file for the activator launcher
  • app – This is the core Play application source code including controllers and views
    • controllers – Application controllers
      • Application.scala – Default controller (remember Play is an MVC framework)
    • views – Templates
      • index.scala.html – The default home page
      • main.scala.html – The site layout file
  • build.sbt – Application build script
  • conf  – Configuration files and other resources
    • application.conf – Main configuration file
    • routes – Routes definition (MVC remember?)
  • LICENSE – Typesafe templates are licensed under Apache. Make sure you’re comfortable with this before you proceed especially if you’re doing something commercial
  • project – sbt configuration files
    • build.properties – market for sbt project
    • plugins.sbt – sbt plugins including the declaration for Play itself
  • public – Public assets like favicon.png
    • images – Image files
      • favicon.png – You know this one otherwise you should read this
    • javascripts – Javascript files
      • hello.js – If the console is available it will output a Hello message
    • stylesheets
      • main.css – blank css file
  • README – A starter README
  • test – source code for unit or integration tests
    • ApplicationSpec.scala – Unit test script
    • IntegrationSpec.scala – Integration test script

If you want more details please visit the Play anatomy page. To start we’re going to update the build.sbt with the libraries we will need for the project. You can use whatever text editor or IDE with which you are comfortable. Depending on the project I use Vim, Sublime Text or IntelliJ. SBT stands for Software Build Tool and is the mechanism by which Scala and Play apps are usually built though you can also use traditional building and deployment tools like WARs. Update your build.sbt to look like so:

name := """my-playful-prelaunch"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.0"

val playVersion = "2.3.0"

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play" % playVersion,
  "org.webjars" %% "webjars-play" % playVersion,
  "org.postgresql" % "postgresql" % "9.3-1101-jdbc41",
  "org.seleniumhq.selenium" % "selenium-java" % "2.42.2",
  "org.webjars" % "bootstrap" % "3.1.1-2"

scalacOptions ++= Seq(
    "-language:postfixOps" //This allows the postfix operator * to be enabled

Open your command line interface (Command Line Interface), navigate to the root of your project and type the following and press enter:

$ sbt compile

SBT just downloaded and installed all the libraries you requested via your build.sbt and placed them in the project directory. You now have a working project. In the same directory type the following and press enter:

$ activator run

Now open your web browser and navigate to http://localhost:9000 and you should see the following: play_framework_initial_window

Let’s examine what Play has created for us so far. Earlier I mentioned that the Play Framework is a Model-View-Controller framework. As such a full Play Framework has directories titled models, views and controllers. In the case of a Play application where the user is a person, the browser sends a request to the web server which directs the request to a Play controller which is in charge of what to do with the request. The controller can render a view which is converted back to HTML and sent back to the browser. The controller may call a model which is responsible for all operations with the database. Any data the model returns may be used by the controller to determine what view to send to the browser and potentially be used by view to change what it displays. This may seem very confusing if you’re not already familiar with the MVC pattern but it will get clearer as we develop the Prelaunch app. Let’s start by looking at the controller Play created for us. Open my-playful-prelaunch/app/controllers/Application.scala in your preferred text editor. You should see the following:

package controllers

import play.api._
import play.api.mvc._
import play.api.i18n._

object Application extends Controller {

  def index = Action {


The first line indicates this controller is located in the controllers directory. Lines through 3 and 4 show that we’re using all of the objects in the play.api and play.api.mvc namespaces. Line 6 shows that the Application object inherits from the Controller class which is a part of the play.api.mvc namespace. Line 8 is where the first action is defined. The action name is index and it returns an Action object.  The Action object that is returned contains several pieces of data. The Ok function indicates the Action result is returning Http return status 200 meaning the Http request was successful. Passed to the Ok function is the index view which is in turn passed a string parameter: “Your new application is ready.” Now let’s go to the views directory and open index.scala.html. You should see the following:

@(message: String) @main("Welcome to Play") {



The first line defines the parameter message of type String that we passed from the controller. The @ symbol you see indicates that the code following is Scala. This is a template so it mixes HTML and Scala.  The third line also begins with @ and passes the main object the string “Welcome to Play”. The fifth line also begins with an @ and passes the play20 object the message parameter. The main object refers to the main template in the views folder which acts as the layout for the entire application. Open main.scala.html in your text editor. You should see:

@(title: String)(content: Html)

<!DOCTYPE html>

        <title>@title | @Messages("global.appName")</title>
        <link rel="stylesheet" media="screen" href="@routes.WebJarAssets.at(WebJarAssets.locate("bootstrap.min.css"))">
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
        <script src="@routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))"></script>
        <script src="@routes.WebJarAssets.at(WebJarAssets.locate("js/bootstrap.min.js"))"></script>

The first line has a similar function to the first line of index.scala.html but it has two parameters. The first parameter is the title of the page. The second parameter is the content parameter and it is of type html. In this case, the content is the index page. The remainder of the main.scala.html looks like a regular html except for a few of those @tags scattered throughout. If you look at them you can probably guess what they are for but let’s review them anyway.

  • The @title in the title tag puts the contents of the title parameter from the first line into the title so index.scala.html tells main.scala.html what the complete page’s title should be.
  • The link and script tags all share a call to @routes.Assets.at. In all 3 cases they are making use of Play’s built in Assets controller which routes to the public folder the Activator created in the root of our my-playful-prelaunch folder. Activator was also kind enough to include these three assets in the public folder. Let’s open the routes file so we can see the code that makes this work.

# Map static resources from the /public folder to the /assets URL path

GET /assets/*file    controllers.Assets.at(path="/public", file)

The route GET /assets/*file is looking for any HTTP GET calls to the directory /assets/ with a file name *file which will match to the REGEX expression .*. The router will invoke the at action of the Assets controller passing it the path /public and the file name. Learn more here. Finally, the @content references the second parameter in the first line of main.scala.html. The index.scala.html is passing itself to main.scala.html and main is displaying between it’s body tags. Activator has given a fully functioning application. We are at a good place to use Git to save our progress to date. First you will need to put a gitignore file in the my-play-prelaunch directory. You can download one from my GitHub repository here. The gitignore file tells Git which files it should not add to its repository. In your command line interface go to the my-playful-prelaunch root directory and rename the typesafe-activator.gitignore to .gitignore. The period in front of gitignore is not a typo. Git and many other version control systems (VCS) often hide their files from normal view to avoid being accidentally deleted. In most operating systems hidden is accomplished by starting the folder or file name with a period. Now that you’ve prepared the directory with a .gitignore from the CLI type the following:

$ git init
$ git add -A
$ git commit -a -m "initial commit"
$ git status

git init creates an empty Git repository in the current directory. “git add -A” stages all of the folders and files in the repository including deletions but excepting those excluded by gitignore to be committed to git. “git commit -m “initial commit”” commits the current staged files to the git repository. Finally, “git status” let’s you know the status of your repository. It will tell you if the directory you are in is a repository, whether it has any unstaged folders and files or any staged but uncommitted folders and files.You have now committed your code to git and if you needed to you could go back and retrieve this snapshot of your data. You could also easily share it with another person or system. Next you are going to modify the framework Activator created for you but before you do that you are going to use git to create a branch of your code. Branching is a very powerful tool and critical to any size development team from 1 person to 1,000. You can learn more about Git and Git branching here. From your CLI type the following:

$ git checkout -b marketing-pages

You now have a branch separate from the master branch. If you recall one of the features of my-playful-prelaunch is an about page. You’re going to create the controller and view and bring the about page to life. Before you start creating the controllers and views you need for your marketing pages you’re going to create your functional tests so that as you build the rest of the application if you break something you will know without having to hit all of the prior pages manually. Create a new file in the /test directory called MarketingSpec.scala. In this Scala file type the following and save:

import org.junit.runner.RunWith

import org.specs2.mutable.Specification

import org.specs2.runner.JUnitRunner

import play.api.test._

import play.api.test.Helpers._

import play.api.i18n.Messages @RunWith(classOf[JUnitRunner])

class MarketingSpec extends Specification { "should display certain elements on the marketing pages" in new WithBrowser {

// about page browser.goTo("http://localhost:" + port + "/about") browser.$("h1").first.getText must equalTo("About us") }


The import statements give us access to the JUnit, the specs2, and the Play test libraries as well as the Play internationalization Messages library. The next line starts with “should display certain elements on the marketing pages”. The string in the quotes explains in English what the code you are testing should accomplish. The new WithBrowser creates a new browser object as provided by play.api.test. The browser.goTo navigates to http://localhost:9000/about. browser.$(h1).first.getText must equalTo(“About us”) looks to see if the first h1 tag contains the text “About us”. Now you want to run your test. In the root of my-playful-prelaunch type:

$ sbt test

Your results should be as follows:

[info] Application should

[info] x display certain elements on the about page [error] 'Action not found' is not equal to 'About us' (MarketingSpec.scala:25)

Let’s confirm the results of the test. Open a browser and navigate to http://localhost:9000/about.

About Action Not Found

About Action Not Found

Your browser should return a page similar to the above. As we would expect the Play Framework could not find a route to satisfy /about. So let’s resolve this issue first. Open the routes file which you will find in the conf folder and enter the following after the first GET   /:

GET    /about    controllers.Marketing.about

Now let’s rerun sbt test. I received two errors:

[error] /Users/mike/code/mytuts/play/my-playful-prelaunch/conf/routes:9: object Marketing is not a member of package controllers

[error] GET /about controllers.Marketing.about

[error] /Users/mike/code/mytuts/play/my-playful-prelaunch/conf/routes:9: object Marketing is not a member of package controllers

[error] GET /about controllers.Marketing.about

[error] two errors found

[error] (compile:compile) Compilation failed

[error] Total time: 3 s, completed Jul 5, 2014 7:47:01 PM

Why are we getting two errors instead of just one? SBT and Play are doing a little bit of magic behind the scenes with routing calling reverse routing. We will discuss this magic a little later on but let’s discuss a more efficient way of running our tests. In the CLI type:

$ sbt ~test

You should now see output similar to the above with one addition:

1. Waiting for source changes... (press enter to interrupt)

SBT is now in continuous test mode. Each time we modify our application or test code SBT will rerun our tests. Let’s now work to get our tests back to green. We’ll start by creating a new file in the controllers directory called Marketing.scala. This controller will manage your marketing pages responsible for explaining the product and collecting the names and contact information for people who wish to be contacted about your product. Enter the following into Marketing.scala:

package controllers

import play.api._

import play.api.mvc._

object Marketing extends Controller {
   def about = Action {
   Ok(views.html.marketing.about("About us"))

The first line indicates the Marketing controller is found in the controllers package. The next two lines give us access to all objects in the play.api and play.api.mvc packages. Now we create the Marketing controller object and inherit from the Play controller. Next we’ve created the about action which returns an Action type which if everything goes well will be Http 200 (that’s what the Ok function returns). Additionally, we’ve called the views.html.marketing.about() function which will launch the about view located in app/views/marketing. We’re passing the function the string “About us” and the view will in turn pass the string to main.scala.html as part of the title. If we go back to our CLI we will see that we now have a different set of errors.

[info] Compiling 6 Scala sources and 1 Java source to /Users/mike/code/mytuts/play/my-playful-prelaunch/target/scala-2.10/classes...

[error] /Users/mike/code/mytuts/play/my-playful-prelaunch/app/controllers/Marketing.scala:10: object marketing is not a member of package views.html

[error] Ok(views.html.marketing.about("About us")) [error] ^

[error] one error found

[error] (compile:compile) Compilation failed

[error] Total time: 1 s, completed Jul 6, 2014 1:26:49 PM 4. Waiting for source changes... (press enter to interrupt)

We now need to create the about view. Create a new file about.scala.html inside the directory /app/views/marketing. In this file type the following:

@(title: String)

@main(@title ) {
  <div class="container">
  <div class="row">
  <h1>About us</h1>
  <p>This is the <a href="http://github.com/michaelhawkins/playful-prelaunch"   target="_blank">
  Playful Prelaunch</a> Play Framework sample application.
  You can find a working version of this app at
  <a href="http://playful-prelaunch.herokuapp.com" target="_blank">Heroku</a>.

Let’s go back to our test. We can see that all of our tests are now running successfully. Let’s open our browsers and navigate to http://localhost:9000/about. As expected we see:


In this first post we have only two remaining things to do. First, we’re going to use Twitter Bootstrap to improve the look of our application and second we’re going to deploy our application to Heroku. Before we do this let’s commit our changes to Git. Type the following (I suggest you read what Git tells you after each command):

$ git status
$ git add .
$ git commit -a -m "All of our tests are working"

In similar platforms like Rails there is a built in concept for partials. There are special functions to call partials and special names to use for them. In Play in this particular there is less convention and more configuration. We could start the names of our partials with an underscore and we could put all of them in a folder layout under /app/views but in order to avoid any confusion especially for those of you who are Rails developers we’re not going to use the Rails conventions. Of course, I highly recommend you develop conventions for your team even if you are a team of one. You will find this extremely helpful especially if you set a project aside for some time.

Let’s start by improving the look of our application. The first thing we’re going to do is give our application a standard header. We could add the header code to our main.scala.html view but if we separate them it gives us a main function and a header function that do one and only thing (See the first S in SOLID). First, we’re going to create a new directory under views called partials. In this directory we’re going to create a new text file called header.scala.html. In the file type the following:

<nav class="navbar navbar-default" role="navigation">
 <div class="container-fluid">
   <div class="navbar-header">
     <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
       <span class="sr-only">Toggle navigation</span>
       <span class="icon-bar"></span>
       <span class="icon-bar"></span>
       <span class="icon-bar"></span>
    <a class="navbar-brand" href="/">Playful Prelaunch</a>
   <div class="nav-collapse">
     <ul class="nav navbar-nav">
       <li><a href=@routes.Marketing.about>About us</a></li>
       <li><a href="">How it works</a></li>

If we navigate to http://localhost:9000/about we see our About us screen now looks like this:


So we now have a header but it is quite ugly. Let’s fix that with Bootstrap and CSS. First, we need to add WebJars routing to our application. Open conf/routes and add following at the end of the routes file:

GET    /webjars/*file    controllers.WebJarAssets.at(file)

We had SBT add the WebJarAssets controller via the statement “org.webjars” %% “webjars-play” % playVersion. Now we are making use of it. Now let’s use the Bootstrap assets by adding the following code at the top of the head tag of app/views/main.scala.html:

<link rel="stylesheet" media="screen" href="@routes.WebJarAssets.at(WebJarAssets.locate("bootstrap.min.css"))">

We’ll also reference JQuery and Bootstrap’s JS lib by adding the following to the bottom of the head tag:

<script src="@routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))"></script>

<script src="@routes.WebJarAssets.at(WebJarAssets.locate("js/bootstrap.min.js"))"></script>

Let’s also take this opportunity to remove the reference to hello.js and then delete it from /public/javascripts. Now let’s update our header.scala.html with the following Bootstrap classes and attributes.

<nav class="navbar navbar-default" role="navigation">

  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      <a class="navbar-brand" href="/">Playful Prelaunch</a>
    <div class="nav-collapse">
      <ul class="nav navbar-nav">
        <li><a href=@routes.Marketing.about>About us</a></li>
        <li><a href="">How it works</a></li>

Now http://localhost:9000/about looks like this.


It’s not going to win us any design awards but but it gives us a start towards more style. Before we turn our attention to deploying our app to Heroku let’s update index.scala.html so it stops displaying the default Play message. This will make the app totally ours. Change index.scala.html as follows or add any text you want just make it different from what Play gave us:

@(message: String)


     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
     vehicula tellus ut orci auctor dictum. Sed ipsum ipsum, posuere ut eros
     eu, ornare bibendum massa. Donec eu rhoncus magna. Vivamus mauris quam,
     dictum in vestibulum et, auctor malesuada purus. Proin iaculis nibh et
     semper pretium. Sed sit amet libero et felis luctus dignissim. Duis quis
     rhoncus turpis. Praesent eu interdum est, quis feugiat mi. Suspendisse
     fringilla molestie turpis convallis lobortis. Sed cursus odio nec tortor
     pharetra viverra. Nulla lacinia a sapien id condimentum. Integer urna
     sapien, molestie a turpis sed, cursus adipiscing nisl.

     Praesent porta placerat nulla, a vulputate tortor auctor et. Suspendisse
     vitae ligula arcu. Proin fermentum sem vel enim eleifend, fermentum
     lobortis tortor aliquet. Sed eleifend tristique mauris quis egestas. Sed
     eleifend vestibulum ipsum ac sagittis. Sed varius, est sit amet lobortis
     vehicula, risus leo laoreet est, eget faucibus magna massa vel neque. 
     Aenean vehicula nisi vitae elit ultricies, quis suscipit massa 
     convallis. Phasellus mauris sapien, elementum vitae scelerisque eget, 
     fermentum sit amet sapien. Etiam eget consequat urna. Suspendisse id 
     semper nunc. Pellentesque et bibendum diam. Integer porttitor neque nec 
     nunc ultrices convallis. Vestibulum ante ipsum primis in faucibus orci 
     luctus et ultrices posuere cubilia Curae; Maecenas dignissim adipiscing 
     feugiat. Mauris a tincidunt enim, id fringilla elit. Lorem ipsum dolor 
     sit amet, consectetur adipiscing elit.


Let’s also change our index action in our Application controller to pass the text “Home” to index.scala.html instead of “Your application is ready.” Open /app/controllers/Application.scala and change “Your application is ready” in line 9 to “Home”. Finally, before we commit all of our changes to git let’s make sure all of our tests still work. From the command line type the following:

$ sbt test

Our MarketingSpec tests are still all green but our ApplicationSpec and IntegrationSpec tests are returning errors:

[error]    ' doesn't contain 'Your new application is ready.' (IntegrationSpec.scala:20)

ApplicationSpec.scala is returning a similar error. specs2 was nice enough to tell us where our problem is in the spec files. Open your IntegrationSpec.scala and go down to line 20. Replace “Your new application is ready.” with:

Playful Prelaunch App

Now open your ApplicationSpec.scala, go down to line 27 and make the same change here. Save your changes and let’s rerun our test. Our tests should all be green again. Ok, now let’s commit to git. Type the following on the CLI:

$ git status
$ git add -A
$ git commit -a -m "add Bootstrap, WebJarAssets routing and header partial"

We’ve committed all of our changes to our marketing-pages branch but let’s merge them into our master branch. Type:

$ git checkout master
$ git merge marketing-pages

To deploy to Heroku we will need to add a Procfile and a system.properties file to the root of our project. Go ahead and do that now. Make sure you spell each file exactly as I have written them here. In the Procfile type the following:

web: target/universal/stage/bin/my-playful-prelaunch -Dhttp.port=${PORT}

I encourage you to read this page on Heroku but let me give you a quick synopsis on what you see above:

  • web – The process type. Heroku has two process types: web and worker. Web is a web application and worker is basically a background process. My Playful Prelaunch requires a web process.
  • target/universal/stage/bin/my-playful-prelaunch – Defines the application to start. The name in build.sbt and Procfile must match otherwise you will get an app error on deployment to Heroku

In the system.properties file you will want to add the following:


By default Heroku will try to use JRE 1.6 when it detects Java Virtual Machine apps like Scala and Play. We need to tell it that we are dependent on JRE 1.7. The next step is to commit both of these changes to Git because the deployment to Heroku is based on Git so anything that is not committed to the Git database WILL NOT be pushed to Heroku. So let’s commit:

$ git add -A
$ git commit -a -m "add Procfile and system.properties to app for Heroku support"

Now let’s provision our app on Git. If you have installed the Heroku toolbelt then go to your CLI and type:

$ heroku create

Heroku provisioned my app with the name cryptic-tor-9385 with the URL http://cryptic-tor-9385.herokuapp.com. It also added a git remote repository called heroku. In order to deploy I need to type the following:

$ git push heroku master

During the deployment process you will see that Heroku uses our build.sbt to retrieve all of our dependencies so that our remote application has the same libraries as we used locally. Once the deployment finishes we can either navigate to the URL of our Heroku app or we can go to the CLI and type the Heroku Toolbelt will open our default browser and navigate to our app:

$ heroku open

http://cryptic-tor-9385.herokuapp.com looks like this:


and http://cryptic-tor-9385.herokuapp.com/about looks like this:


Ok that’s it! You have finished part 1 of the Playful Prelaunch tutorial. Stay tuned for part 2 of this tutorial where we will investigate the following aspects of Play! development:

  • Evolutions where we will create and modify tables
  • CRUD with ScalaAnorm
  • specs2 testing of components and web pages
  • Scala/Play internationalization (i18n)
  • Email through Mandrill API with and without templates

If you have any questions about this tutorial feel free to email me at hello {at} hawkinsunlimited {dot} com.

I open sourced my Playful Coming Soon Playful Prelaunch app. You can find it at Github. A running version is located on Heroku.

Update: I changed the name from Playful Coming Soon to Playful Prelaunch because alliterations are good and Playful Coming Soon is just a mouthful.

I’d also like to give a little more detail about the app. It is intended to be the source code for a tutorial on using the Play Framework. It uses the following tech which is enough to get someone new to the Play Framework and Scala off and running.

  • Play Framework 2.3.0
  • Scala 2.10.4
  • Twitter Bootstrap 3.1.1
  • JQuery 1.9.1
  • PostgreSQL 9.1-901.jdbc4
  • Heroku
  • sbt 0.13.5
  • webjars (for Bootstrap and JQuery)

It also demonstrates Play Framework concepts like:

  • Evolutions:
    • Create and alter table
  • The CR part of CRUD using ScalaAnorm
  • Scala/Play localization
  • Partials
  • Scala templates / Play forms
  • Testing via specs2 including static pages, dynamic pages and routes

Contact me at info hawkinsunlimited.com if you need some help.

I’ve been leaning towards using build.sbt because those were the examples I used early on but I’m thinking that Build.scala may be the best way to exercise my scala knowledge at the same time. Otherwise I have found no real advantage to using one over the other.

In building the new app I tried to avoid learning anything about building Scala with sbt because it was tl;dr. That didn’t work so I’m going through the sbt tutorial. I like what I see so far. I’m sure I will complain later but right now I’m ok.

I’m building a new app and concurrent with that app I’m learning and using Play Framework with Scala and Slick. Some elements of the app will be SPA but I’m not going to choose an MV* framework right now.

Right now I’m working on the object model for this app. A couple of issues already. I believe based on the Typesafe Play Slick app that Slick requires way more boilerplate than I’m used to coming from Rails and ASP.NET MVC 5 w/ EF6. And I’m pretty sure I’m wrong so I have more research to do / questions to ask.

UPDATE: I was doing it wrong and I am so glad. Check this out.