h1. Your first Play Scala application

A very simple tutorial, that will just help you to discover Play Scala with the famous 'Hello World' example.

h2. <a>Prerequisites</a>

First of all, make sure that you have a working Play installation, with the Scala module correctly enabled. 

As we will use the command line a lot, it's better to use a Unix-like OS. If you run a Windows system, it will also work fine; you'll just have to type a few commands in the command prompt.

You will of course need a text editor. As in Java, Play Scala manages the compilation and the deployment process itself. 

h2. <a>Project creation</a>

Now that Play is correctly installed, it's time to create the hello world 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:

bc. $ play new helloworld --with scala

It will prompt you for the application full name. Type **Hello world**.

bc. $ play new helloworld --with scala
~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   
~
~ play! 1.2.2, http://www.playframework.org
~
~ The new application will be created in ~/myScalaApp
~ What is the application name? [helloworld] Hello world
~
~ Resolving dependencies using ~/helloworld/conf/dependencies.yml,
~
~ 	play->scala 0.9.1 (from playLocalModules)
~
~ Installing resolved dependencies,
~
~ 	modules/scala-0.9.1 -> ~/play/1.2.2/modules/scala-0.9.1
~
~ OK, the application is created.
~ Start it with : play run helloworld
~ Have fun!
~

The **play new** command creates a new directory **helloworld/** and populates it with a series of files and directories, the most important being:

**app/** contains the application’s core. It contains all the application ***.scala files**. You see that the default is a single **controllers.scala** file. You can of course use more files and organize them in several folders for more complex applications. Also the **app/views** directory is where template files live. A template file is generally a simple text, xml or html file with dynamic placeholders.

**conf/** contains all the application’s configuration files, especially the main **application.conf** file, the **routes** definition files and the **messages** files used for internationalization.

**lib/** contains all optional Scala libraries packaged as standard .jar files.

**public/** contains all the publicly available resources, which includes JavaScript, stylesheets and images directories.

**test/** contains all the application tests. Tests are either written either as ScalaTest tests or as Selenium tests.

p(note). 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 but 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 error occurs, Play will create better error reports showing you the exact source code.

h2. <a>Running the application</a>

We can now test the newly-created application. Just return to the command line, go to the newly-created **helloworld/** 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":http://localhost:9000. A new application has a standard welcome page that just tells you that it was successfully created.

!images/welcome!

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 of the application’s accessible URLs. If you open the generated routes file you will see this first ‘route’:

bc. 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** Scala 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 create a singleton object with a single entry point defined by a method such as:

bc. object MyScalaApp {
    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 several objects that we call **controllers**.

Let’s see how the **controllers.Application** controller looks like. Open the **helloworld/app/controllers.scala** source file:

bc. package controllers
 
import play._
import play.mvc._
 
object Application extends Controller {
    
    import views.Application._
    
    def index = {
        html.index("Your new Scala application is ready!")
    }
    
}


You see that controller objects extend the **play.mvc.Controller** class. This class provides all useful methods for controllers. Also we have imported the @play.mvc._@ package that contain everything needed to write controllers.

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 is interpreted by the framework as the response value.  

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:

bc. @(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:

bc. @(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@

h2. <a>Creating the form</a>

We will start the ‘Hello World’ application with a form where you can enter your name.

Edit the **helloworld/app/views/Application/index.scala.html** template:

bc. @main(title = "Home") {
    <form action="@action(controllers.Application.sayHello)" method="GET">
        <input type="text" name="myName" /> 
        <input type="submit" value="Say hello!" />
    </form>
}

p(note). Note that we use GET as form submission method, because the form submission does not have any side effect and is idempotent.

We use the **@action(…)** helper to ask Play to automatically generate the URL able to invoke the **Application.sayHello** action. 

Also, let’s adapt our controller in the **helloworld/app/controllers.scala** file:

bc. package controllers
 
import play._
import play.mvc._
 
object Application extends Controller {
    
    import views.Application._
    
    def index = html.index()  
    def sayHello = html.sayHello(params.get("myName"))
    
}

In the @index@ action, we remove the parameter of the @html.index@ template as our new template doesn't need any parameter anymore. In the @sayHello@ action we retrieve the @myName@ parameter value coming from the form submission, and we pass it to the @html.sayHello@ template.

Now try to refresh the page in the browser, and oops, you will get an error:

!images/hello-1!

This is the way Play works! It will automatically compile your changes at each page refresh, and show you compilation and execution errors right into your browser.

The error is pretty clear. We haven't defined the @html.sayHello@ template. Let’s create it in the file **helloworld/app/views/Application/sayHello.scala.html**:

bc. @(name:String)
 
@main(title = "Hello") {
    
    <h1>Hello @(name ?: "Guest")!</h1>
    
    <a href="@action(controllers.Application.index)">Back to form</a>
    
}

You can refresh the page.

!images/guide1-page2!

Look how we have used the **?:** operator in the template. It switches to a default value if the **name** value is empty. So if you try to submit the form without entering any name, it will display ‘Hello guest’.

h2. <a>Providing a better URL</a>

Well, if you look at the submission URL, you will see something like:

bc. http://localhost:9000/application/sayhello?myName=guillaume

It is not very pretty. This is because Play used the default ‘catch all’ route.

bc. *       /{controller}/{action}                  {controller}.{action}

We can have a better URL by specifying a custom path for the **Application.sayHello** action. Edit the **helloworld/conf/routes** file and add this route after the first one:

bc. GET     /hello                                  Application.sayHello

Now go back to the form and submit it again to check that it uses the new URL pattern.

h2. <a>Customizing the layout</a>

As both templates that the application use so far inherit from the same **main.html** template, you can easily add a custom layout. Edit the **helloworld/app/views/main.html** file:

bc. ...
<body>
    The Hello world app.
    <hr/>
    @body
</body>
...

Now we have a common header for both pages.

!images/guide1-page3!

h2. <a>Adding validation</a>

We will add a little validation to the form, to make the name field required. We can use the Play validation framework to do that.

Edit the **helloworld/app/controllers.scala** file, and the **sayHello** action:

bc. ...
def sayHello = {
    val myName = params.get("myName")
    if(myName == "") {
        flash += ("error" -> "Oops, please enter your name!")
        Action(index)
    } else {
        html.sayHello(params.get("myName"))
    }
}
...

Now our **sayHello** can return 2 distincts values. A @Html@ value in the case of there is a name provided by the form, or an @Action@ value if there is an error. An @Action@ value is used to redirect to another existing action method. Here we specify that we want to redirect to the @index@ action.

Play will automatically check that the myName field is filled or will add an error object to the **errors** scope. Then if there is any error, we add a message to the **flash** scope and redirect to the **index** action.

The flash scope allows to keep messages during action redirection.

Now you just have to display the **error** message if any. Edit the **helloworld/app/views/Application/index.html**:

bc. @()(implicit flash:play.mvc.Scope.Flash)
 
@if(flash.get("error")) {
    <p style="color:#c00">
        @flash.get("error")
    </p>
}
 
@main(title = "Home") {
    <form action="@action(controllers.Application.sayHello)" method="GET">
        <input type="text" name="myName" /> 
        <input type="submit" value="Say hello!" />
    </form>
}

And check that it works:

!images/guide1-page4!

See how we take implicitely the flash parameter from the controller scope.

h2. <a>Writing an automated test suite</a>

We will finish by writing a test for the application. As there is no Java logic to test, we need to test the Web application itself. So we will write a Selenium test.

First, you need to run your application in **test mode**. Stop the application and restart it with the **test** command:

bc. $ play test

The **play test** command is almost the same as **play run**, except that it loads a test runner module that allows to run test suite directly from a browser. 

Open a browser to the "http://localhost:9000/@tests":http://localhost:9000/@tests URL to see the test runner. Try to select all the default tests and run them; all should be green… But these default tests don’t really test anything.

!images/guide1-test!

A selenium test suite is typically written as an HTML file. The HTML syntax required by selenium is a little tedious (formatted using an HTML table element) to write. The good news is that Play will help you to generate it using the Play template engine and a set of tags that support a simplified syntax for selenium scenarios. 

The default test suite of a newly created Play application already contains a selenium test. Open the **helloworld/test/Application.test.html** file:

bc. *{ You can use plain selenium command using the selenium tag }*
 
#{selenium}
    // Open the home page, and check that no error occurred
    open('/')
    assertNotTitle('Application error')
#{/selenium}

This test should run without any problem with the application for now. It just open the home page and check that the page content does not contain the ‘Application error’ text.

Let’s write a test for our application. Edit the test content:

bc. #{selenium}
    // Open the home page, and check that no error occurred
    open('/')
    assertNotTitle('Application error')
    
    // Check that it is the form
    assertTextPresent('The Hello world app.')
    
    // Submit the form
    clickAndWait('css=input[type=submit]')
    
    // Check the error
    assertTextPresent('Oops, please enter your name!')
    
    // Type the name and submit
    type('css=input[type=text]', 'bob')
    clickAndWait('css=input[type=submit]')
    
    // Check the result
    assertTextPresent('Hello bob!')
    assertTextPresent('The Hello world app.')
    
    // Check the back link
    clickAndWait('link=Back to form')
    
    // Home page?
    assertTextNotPresent('Hello bob!')
#{/selenium}

We have fully tested the application. Just select this test in the test runner and click ‘Start’. Everything should be green!

!images/guide1-test2!


h2. <a>Learn more</a>

This was a very simple tutorial about a very dumb application. 

If you want to learn more about Scala, you can use our interactive  %(next)"Play with Scala":learnscala% application. 
