Starting up the project
Introduction
In this tutorial you will learn Play Scala by coding a real web application, from start to finish. In this application, we will try to use everything you would need in a real project, while introducing good practices for Play application development.
We have split the tutorial into several independent parts. Each part will introduce more complex features, and provide everything that a real project needs: validation, error handling, a complete security framework, an automated test suite, a shiny web interface, an administration area, etc.
All the code included in this tutorial can be used for your projects. We encourage you to copy and paste snippets of code or steal whole chunks.
The project
We chose to create yet another blog engine. It’s not a very imaginative choice but it will allow us to explore most of the functionality needed by a modern web application.
To make things a bit more interesting, we will manage several users with different roles (editor, admin).
We will call this blog engine project yabe.
This tutorial is also distributed as a sample application. You can find the final code in your Scala module installation’s samples-and-tests/yabe/ directory.
Installing the Play framework
Installation is very simple. Just download the latest binary package from the download page and unzip it to any path. Note that the scala module requires at least Play 1.2.
If you’re using Windows, it is generally a good idea to avoid space characters in the path, so for example c:\play would be a better choice than c:\Documents And Settings\user\play.
To work efficiently, you need to add the Play directory to your working path. It allows you to just type play at the command prompt to use the play utility. To check that the installation worked, just open a new command line and type play; it should show you the play basic usage help.
Installing the Scala module locally
The simpler way to work with Play and Scala is to download and install the Scala module locally. You can use the play install scala
command to do that:
$ play install scala
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.2, http://www.playframework.org
~
~ Will install scala-0.9
~ This module is compatible with: Play 1.2
~ Do you want to install this version (y/n)? y
~ Installing module scala-0.9...
~
~ Fetching http://www.playframework.org/modules/scala-0.9.zip
~ [--------------------------100%-------------------------] 17313.2 KiB/s
~ Unzipping...
~
~ Module scala-0.9 is installed!
Project creation
Now that Play is correctly installed, it’s time to create the blog application. Creating a Play application is pretty easy and fully managed by the play command line utility. That allows for standard project layouts between all Play applications.
Open a new command line and type:
~$ play new yabe --with scala
It will prompt you for the application full name. Type Yet Another Blog Engine.
The play new command creates a new directory yabe/ and populates it with a series of files and directories, the most important being:
- app/ contains the application’s core. This is the directory where .scala source files live.
- conf/ contains all the configuration files for the application, especially the main application.conf file, the routes definition files, the dependencies.yml file, and the messages files used for internationalization.
- lib/ contains all optional Java or Scala libraries packaged as standard .jar files.
- public/ contains all the publicly available resources, which includes JavaScript files, stylesheets and images directories.
- test/ contains all the application tests. Tests are either written either as ScalaTest tests or as Selenium tests.
As you see, the conf/dependencies.yml dependencies configuration file is automatically configured with the Scala dependency:
# Application dependencies
require:
- play
- play -> scala 0.9
Because Play uses UTF-8 as single encoding, it’s very important that all text files hosted in these directories are encoded using this charset. Make sure to configure your text editor accordingly.
Now if you’re a seasoned Scala developer, you may wonder where all the .class files go. The answer is nowhere: Play doesn’t use any class files; instead it reads the Scala source files directly.
That allows two very important things in the development process. The first one is that Play will detect changes you make to any Scala source file and automatically reload them at runtime. The second is that when an exception occurs, Play will create better error reports showing you the exact source code.
In fact Play keeps a bytecode cache in the application’s tmp/ directory, but only to speed things up between restart on large applications. You can discard this cache using the play clean command if needed.
Running the application
We can now test the newly-created application. Just return to the command line, go to the newly-created yabe/ directory and type play run. Play will now load the application and start a web server on port 9000.
You can see the new application by opening a browser to http://localhost:9000. A new application has a standard welcome page that just tells you that it was successfully created.
Let’s see how the new application can display this page.
The main entry point of your application is the conf/routes file. This file defines all accessible URLs for the application. If you open the generated routes file you will see this first ‘route’:
GET / Application.index
That simply tells Play that when the web server receives a GET request for the / path, it must call the Application.index
action method. In this case, Application.index
is a shortcut for controllers.Application.index
, because the controllers package is implicit.
When you create standalone Scala applications you generally use a single object with an entry point defined by a main
method such as:
object Main {
def main(args: Array[String]) {
…
}
}
A Play application has several entry points, one for each URL. We call these methods action methods. Action methods are defined in special objects that we call controllers.
Let’s see what the controllers.Application
controller looks like. Open the yabe/app/controllers.scala source file:
package controllers
import play._
import play.mvc._
object Application extends Controller {
import views.Application._
def index = {
html.index("Your new Scala application is ready!")
}
}
Notice that controller objects extend the play.mvc.Controller
class.
The index action is defined as a simple method of this object. This is how action methods are defined. They always return a value that will be infered by the framework to generate the proper HTTP response.
The default index action is simple: it invoke the views.Application.html.index template and returns the generated HTML. Using a template is the most common way (but not the only one) to generate the HTTP response.
Templates are special Scala source files that live in the /app/views directory.
To see what the template looks like, open the helloworld/app/views/Application/index.scala.html file:
@(title:String)
@main(title) {
@views.defaults.html.welcome(title)
}
The template content seems pretty light. In fact, this is because it call other templates to generate the welcome page.
The first line defines the template parameters: a template is a function that generates a play.template.Html return value. In this case, the template has a single title
parameter of type String
, so the type of this template is (String) => Html
.
Then this template call another template called main
, that take two parameters: a String
and an Html
block.
Open the helloworld/app/views/main.scala.html file that defines the main
template:
@(title:String = "")(body: => Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" href="@asset("public/stylesheets/main.css")">
<link rel="shortcut icon" href="@asset("public/images/favicon.png")">
<script src="@asset("public/javascripts/jquery-1.5.2.min.js")"></script>
</head>
<body>
@body
</body>
</html>
Again, the first line defines the template parameters. And the type of the main
template is (String) (Html) => Html
We can try to edit the controller file to see how Play automatically reloads it. Open the yabe/app/controllers.scala file in a text editor, and add a mistake:
def index = html.index()
Go to the browser and refresh the page. You can see that Play detected the change and tried to reload the Application controller. But because you made a mistake, you get a compilation error.
Ok, let’s correct the error, and make a real modification:
def index = {
Logger.info("Index page has been requested")
html.index("Your new Scala application is ready!")
}
This time, Play has correctly reloaded the controller and replaced the old code in the JVM. Each request to the / URL will log the ‘Index page has been requested’ message to the console.
You can remove this useless line, and now edit the yabe/app/views/Application/index.scala.html template to replace the welcome message:
@main("Home") {
<h1>A blog will be there</h1>
}
And because we have remover the parameters of this template, fix the controller:
def index = {
html.index()
}
Setting-up the database
One more thing before starting to code. For the blog engine, we will need a database. For development purposes, Play comes with a stand alone SQL database management system called H2. This is the best way to start a project before switching to a more robust database if needed. You can choose to have either an in-memory database or a filesystem database that will keep your data between application restarts.
At the beginning, we will do a lot of testing and changes in the application model. For that reason, it’s better to use an in-memory database so we always start with a fresh data set.
To set-up the database, open the yabe/conf/application.conf file and uncomment this line:
db=mem
As you can see in the comments, you can easily set-up any JDBC compliant database and even configure the connection pool.
Now, go back to your browser and refresh the welcome page. Play will automatically start the database. Check for this line in the application logs:
INFO ~ Connected to jdbc:h2:mem:play
Go to the A first iteration of the data model.