This chapter will introduce Play! Framework 2 by demonstrating its basic features and overall structure.
We'll cover the bootstrapping tasks, including creating projects and running them. To tackle this, the following list of topics will be put to use:
Set up Play! Framework 2 – installation and configuration
Create projects (Java and Scala)
Set up your IDE for the project
First contact with the build tool
See the projects in action
Review the code within default projects
Experiment by modifying the code
As the first step of using Play! Framework, we'll see how to install it on our machine with minimum requirements as possible. The goal is to have our basic environment set up in a few and simple tasks.
The simplest way to install Play! Framework 2 is to download it from the website http://www.playframework.org/. This is fairly simple. Just go to the Download link in the upper-right-hand side of the website and click on the Latest official version link. This will download a .zip
file to your system. Unzip it to a location of your choice.
This package can seem quite large (almost 150 MB, compressed), but if we have a look inside, we'll see that it contains everything needed to run the framework or for the developer to develop with it. That's because it is composed of documentation, libraries with their dependencies (repository), and the framework itself. This means that even when disconnected, we'll have access to all the information needed.
Let's have a look at the documentation
folder:
Apart from these, we'll find the samples
folder. It is a mine of snippets for common tasks and is split into two parts: java
and scala
. As you can imagine, here we have an access to plenty of simple or advanced Play! 2 projects that have been written in both in Java and Scala. For example, the forms
sample project that introduces some patterns to deal with forms, or the websocket-chat
sample project that goes deeper into the details of using the more advanced Play! 2 features.
At this stage, we're almost done; all we have to do is to update our PATH
environment variable to point to the extracted folder, which contains the command-line tool: play!
.
However, before that, as Play! Framework 2 is a JVM web framework, you must check that Java 6 or a higher version is installed and available for use.
Note
However, for "non-JVM" people, you can get the last version from http://www.oracle.com/technetwork/java/javase/downloads/index.html.
Let's perform the following steps to update our PATH
environment variable:
Press the Windows key.
Type
sys var
.Select Edit the system environment variables.
In the new window, click on the Environment Variables... button.
In the user variables panel, we can now add/edit the
PATH
variable with the path to the Play! installation. The following screenshot summarizes what we just did:
As you may know, Play! Framework is now part of a more general stack provided by Typesafe, which redefines almost all the layers of the modern applications built on top of the JVM: the Typesafe Stack 2.
Roughly, it begins with the language (Scala), continues with a concurrent layer (Akka), and completes with a web layer (Play!).
It's quite helpful to install the stack rather than Play! 2 alone because it will install versions that are validated to work together.
At this stage, we can use the command-line tool embedded with Play! Framework 2. This tool, simply named play!, is the very beginning as it will start the whole machinery. For that, let's open a terminal depending on our OS, as follows:
We're ready to check whether our Play! environment has been correctly set up. Let's enter the following command:
$> play
Once done, you should see the following screenshot:
This means that Play! is correctly installed. Bravo! Don't worry about the message; it only tells you that you weren't in a valid Play! project folder, that's all!
What's interesting at this point is that the play! tool is actually starting an SBT console (http://www.scala-sbt.org/release/docs/index.html).
You can also get some help from the tool by executing:
$> play help
As you may notice, it recommends that you create your first application. Here we go!
Now that your machine is prepared, we can create our first project using the play
command.
As we have just seen, Play! Framework 2 comes with a handy command-line tool, which is the easiest and fastest way to create a new project. The following screenshot shows how to create a project with Java stubs:
Tip
Downloading the example code
You can download the example code files for all the Packt books you have purchased from your account at http://www.packtpub.com. If you have purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
As we can see from the previous screenshot of the console, in order to create a brand new application in a directory, we just have to use the play! command-line tool with a parameter (named new
) followed by the name of the new application (play-jbook
).
The tool will ask us to specify whether our application is a Scala or Java application, or even an empty project. In the first two cases, the structure of the application will be created along with the source files for the chosen language. In the third case, only the structure will be created—without sample code though.
Note
By the way, the last option has been removed in the Play! 2.1 release. Thus only the first two options remain now.
Let's have a very quick overview of the created structure (we'll go into further details later on in this book).
At first, a new directory will be created with the name of the application, that is, play-jbook
. This will be the root of our project, so the whole structure is inside this directory and looks like the following screenshot:
Let's describe each folder briefly:
app
: This is the root of all the server-side source files, whatever type they are (Java, Scala, server-side templates, compiled scripts, and so on). At creation, only two subfolders will be created:controllers
andviews
.conf
: This folder is dedicated to all of the files meant to configure the application itself, external services, or whatever the application could need at runtime.project
: As SBT is used behind the curtains, theproject
folder is meant to contain all of the necessary files to configure this tool.public
: This last folder will simply contain all of the external files that can be accessed by the clients, such as stylesheets, images, and JavaScript source files. A dedicated folder has been created for each type as well.test
: This last folder will contain all all test files with some examples provided.
In the previous section, we installed the framework on our machine, and we even created our first application. The next natural step for any developer would be to open the project in our preferred IDE.
It is good for us that Play! has already configured everything in order to generate the project and module files required by the most popular IDEs.
Let's see how to configure Eclipse and IntelliJ IDEA, and then we'll see how to deal with another editor: Sublime Text 2. But first of all, you will have to enter your application in the terminal:
$> cd play-jbook $> play
While executing, you might see checks for a lot of things (dependencies), but nothing is failing and nothing has been downloaded (if you're disconnected). That's because everything has already been packaged in the Play! 2 .zip
file—especially all of the dependency JARs are provided in Play! 2's dedicated repository.
Being in the console, you now have access to plenty of commands related to your project (this should sound like déjà vu for those who've used Maven plugins); for example, version
, name
, and dependencies
. Just try them, or hit the Tab key twice.
Commands have been created to execute tasks such as generating files based on the project. Among them is the generation of the IDE settings.
Eclipse is probably the most commonly used editor by the Java community, the advantages being: it's free, has a strong community, and provides a powerful extension framework.
That's why this section will have two sections: one for the classical Eclipse Juno and one for the Scala version named Scala IDE (http://scala-ide.org/).
While in the play! console, you can ask it to generate the Eclipse project configuration by simply invoking the eclipse
:
This will generate all the specific files necessary to configure an Eclipse project. Now we can open Eclipse and import the project into it. For that, let's perform the following steps:
The following screenshot is what you should see now:
Looking at the screenshot, we should notice the following points:
Some folders have been marked as sources and test files (
app
andtest
)A bunch of libraries have been mounted on the project (including the Play! library)
The Play! API is recognized along with the generated template sources (
index.render
)
For projects that involve the Scala source code, even though a Play! project can contain both Scala and Java source code, the Scala IDE is probably the best choice. The Scala IDE is actually a customized Eclipse version, which has Scala as the main focus. To set up a Scala project in the Scala IDE, we'll first need to create the project using the play! console in a similar way to how the Java version was created. This is shown as follows:
The very next step is to install the Scala IDE. As it's an Eclipse plugin, all we have to do is to start an Indigo version of Eclipse. Then go to Help | Install New Software....
In the Work with field, we'll enter the path from which the Scala IDE team is distributing their plugin (http://scala-ide.org/download/current.html).
In order to import our project, we can just repeat the same steps that we performed earlier in the Eclipse Juno section. At the end, we will have the following screenshot:
As expected, the features brought by Eclipse for the Java version still remain in this version. So do the features including syntax coloring for the Scala code, code browsing, contextual documentation, and so on.
IDEA is a great and well-known IDE despite the fact that it isn't open source or totally free. At least, we can choose between the free version (Community)—which has less features—and the other one (Ultimate).
Note
At the time of writing this book, a Play! 2 plugin is on its way for the paid version, however we will try to stick with the free only IDE. But for those interested in this plugin, check the link at http://plugins.jetbrains.com/plugin/index?pr=&pluginId=7080.
Let's go back to the play! console. We can now invoke a new task called idea
:
This will create a fully configured project with the related modules for our project.
Now we can simply open the folder itself as a project in IDEA. For that, we need to go to File | Open Project and navigate to the project folder:
The following screenshot shows what we should get after having confirmed our project folder. Hopefully, we will get the same kind of features that we get with Eclipse.
As Play! is fully integrated, we can sometimes feel an IDE to be overkill because of two things:
IDEs support of Play! is very young (obviously) and limited
Play! is so easy that for most of the time we only need the documentation and the Javadoc (or Scaladoc) of the provided API
Having said, that an IDE is helpful for code completion/navigation and maybe sometimes in debugging sessions, but I think their need decreases slightly when used with a simple framework like Play!.
Sublime Text 2 comes with features than an IDE. Actually, it comes with pure editing features, such as multiple selects for batch edition, quick find, embedded console, and macros. Moreover it takes fewer resources (thankfully, when we develop without any power slots available). Another feature is that it has the best support of the Scala template used by Play! 2 including syntax coloration, snippets, and more.
To install it, we can download the installer related to our operating system from http://www.sublimetext.com/2 and execute it. Now that Sublime Text 2 is installed, we can also enable two packages:
The package manager can add and search a package repository directly from the Sublime Text 2 console. See http://wbond.net/sublime_packages/package_control for more details.
The Play! 2 support package installation is very easy and is well explained at https://github.com/guillaumebort/play2-sublimetext2#installation-instructions.
Now with everything set up and a Sublime Text 2 window opened, what we could do is simply add our project folder to it using the console. So press Ctrl + Shift + P and type Add Folder
, and then browse to our project. The following screenshot is what we should have:
Now, we can very often save a few lines of code by simply using the snippets that are available for all components of a Play! 2 application (code, configuration, templates, and so on). Let me introduce some of the most useful ones:
pforeach
: This creates a loop over sequence in a templatebindform
: This binds data from a form using the request contentok
/redirect
: They create the related HTTP resultsessionget
/sessionset
: They retrieve or set a value to the session
Check the following page for an exhaustive list: https://github.com/guillaumebort/play2-sublimetext2#code-snippets
In the earlier sections, we used the play! console a lot to access the tasks related to our project. Actually, this command-line tool is a customization of Simple Build Tool (SBT).
SBT is a powerful and easily extensible build tool like Maven or Ant. But, where the latter rely exclusively on the external DSLs to manage their configuration, SBT uses an internal Scala DSL for that. Of course, this isn't its only advantage.
What is interesting at this point is that SBT doesn't need any specific integration with IDEs because it's simply Scala code. As one isn't required to know Scala in order to create or update an SBT configuration, let's cover how to deal with its common tasks.
Looking into the project
folder, we'll find a Build.scala
file, which contains the basic configuration of our build. It briefly defines play.Project
: an extension of a regular SBT Project
. The following screenshot shows what it contains:
Even if Play! 2 already integrates a lot of libraries that are usually sufficient, it often happens that we need to add new dependencies to our projects to access new features (such as a statistics library) or provided one with a different vision (such as a new logging library).
As an example, we'll add the latest version of Guava (http://code.google.com/p/guava-libraries/) to our project.
As Scala is powerful enough to create DSLs, SBT took the opportunity to provide a DSL to define Ła project. Let's see an example of adding a dependency using this DSL.
For that, the Build.scala
file already defines a sequence (appDependencies
) that can be seen as an immutable java.util.List
in Scala. This sequence is meant to contain all the extra dependencies that we'll need to be added to our project.
As SBT can use the Maven or Ivy repositories, and is configured to check the common public ones, what we'll do is add Guava using its Maven groupId
, artifactId
, and the required version.
Let's see the syntax:
Later on, this sequence will be used in the play.Project
configuration as a parameter.
In the previous section, we saw how to add new dependencies to our projects; but this method will only work for the libraries that have been deployed on public repositories. However, as developers, we'll face two other cases:
Locally built libraries (either open source or owned) that are placed in our local repository
A library that is not available in the common public repositories
The way to go for such cases is to tell the play.Project
configuration to look into the other repositories that we have configured, shown as follows:
A DSL is meant to be code-readable by expressing and using business-specific concepts for a specific field. Let's check if it is, by reviewing the repositories' declaration.
A repository is nothing more than a folder that is accessible using a path, and which has a structure that follows some convention. So, a declaration is composed of three things:
For convenience, we store these definitions in val
(which are immutable variables) in order to use them in the play.Project
declaration. This declaration is done by adding the existing resolvers (or repositories) to our new sequence of repositories (or resolvers) using the ++=
operator.
In the earlier sections we saw how to create a project, import it into our development environment, and we even learned how to attach new libraries to it.
Now it's time to look at what has been created so far. As we've chosen not to create an empty project (which was the third option proposed by the play new
command), we already have a certain amount of things available for our perusal.
Rather than looking at the files, we are going to run the application using a play command to compile everything and start a server that will run our application.
To do this, enter the play! console and type run
:
As we can see, the console tells us that it has started the application and an HTTP server is available on port 9000.
The next logical step is to open our browser and request this brand new server by going to the URL http://localhost:9000/
.
Once done, our page should look like the following screenshot:
What is being shown is the default welcome web page that Play! 2 has made available for us.
As shown in the previous screenshot, this page already contains a lot of information, essentially the basics (that we'll cover next) and some help about the environment (which we've just covered).
Recall that when we installed Play!, the Play! Framework 2 installation directory contained a documentation
folder. Now that we have an application running, we'll see that this documentation wasn't there for no reason.
If we pay more attention to the welcome page, there is a Browse menu on the right side of the page. This menu has two items. Let's have a quick overview of them now.
The first item, Local documentation, is a reference to the manual
folder of our installation. So we can access the current Play! version's documentation directly from our application (at development time only, not in production).
The second item is the API and is discussed in the next section.
Before entering into any details, we must have noted that the menu has the word Java in its name. That's because Play! has detected (we'll see how later) that we're running a Java application.
On entering this menu, we'll see the following web page:
As expected, we obtained the well-known Javadoc website. We won't cover the API here, but the good thing to note is that we'll always have direct access to it without having to generate it, browse the Web to find it, and so on.
In this section, we'll have a good time looking into the files that have been generated while creating our project.
First of all, we should wonder what is responsible for taking a URL and deciding what is to be done with it. That's done through routing.
As discussed earlier, we went to the root path of our running application (http://localhost:9000/
). What we got was an HTML page containing information and links to some documentation—the welcome page.
What happened is that the browser took a URL and sent a GET
request targeting the /
path of our server.
At this stage, Play! Framework 2 enters the game; it will try to find an action somehow related to the received request using two pieces of information: a method (GET
) and a path (/
).
For that, Play! uses a kind of mapping file, routes
, that can be found under the conf
folder. Let's see what it looks like so far:
As we can see, the comments begin with the hash character (#
), and the relevant information is in the lines with three columns, as we can see in the following screenshot:
Indeed, each row defines how to access server-side functionalities using HTTP, and is composed of three columns:
GET
: This is the first column that contains the method used in the request/
: This second column contains a relative path (to the application context, which is void in our case)controllers.Application.index()
: This third column is reserved for the action to be invoked
So, when the Play! application is asked for a route, it looks in its defined mapping to find the perfect match using the method (GET
) and the path (/
). In this case, it will stop at the first line.
Having found a definition, Play! will call the action (third column): controllers.Application.index()
, which calls the index
method in the Application
class that resides in the controllers
package. We'll cover the action part in detail in the next section.
Now let's have a look at the second line of the routes
file:
What it does is map all of the GET
requests on the paths that start with /assets/
. And the next portion, *file
, stands for: all next characters (*
) must be kept in a resulting string that will be named file
. This variable is very important because it can be used in the action part of the mapping to initialize data. Let's read ahead for more.
An example of matching requests would be the one that asks for the jQuery asset (the version 1.7.1 is available by default): http://localhost:9000/assets/javascripts/jquery-1.7.1-min.js
Looking at the mapping, it says that the file
variable will hold the javascripts/jquery-1.7.1.min.js
string. Let's see how this value can be used in the action.
In the second line, the action is the at
method in the controllers.Assets
class; its signature has two parameters:
path
: This is the source folder that will be the rootfile
: This is the path to the wanted file, which is relative to the previously defined root folder
To check which file will be retrieved, let's have a look at the source under public/javascripts
and verify that the jquery-1.7.1.min.js
file is present.
We'll see in the later chapters how we can define a more advanced matching system that involves type checking, conditional data extraction, using HTTP methods other than GET
, defining HTTP query parameters, and so on.
An action in Play! Framework 2 is the business logic that defines an HTTP request. It's a simple method that has a defined route declaring it as the code to be executed when a matching request arrives.
The action methods are declared in a container
(a class in Java) that extends the Controller
type (either in Java or Scala). Such a container is itself usually called a controller. Roughly, a controller is a bunch of methods that respond to the HTTP requests.
Controllers are, by convention at least, defined in the controllers
package under the source root—the app
folder.
If we look back at the first route, its action was controllers.Application.index()
; it leads us to have a look at the code now.
Note
What I'll propose is to review the next listing in both Java and Scala, because they are really simple and can be an intuitive introduction to the Scala syntax. However, in the rest of the book, the code will be mostly presented in Java and sometimes in Scala. In all cases, we can find both versions in the code files of the book.
We'll start by looking at the Java version:
Now lets take a look at the Scala version. We can see that at this stage, both are looking pretty much the same.
Having seen both versions, it'll be interesting to point out where they differ. But first, let's see what's common between them.
A controller is a type that extends a Controller
structure provided in the play.api.mvc
package. Now it would seem obvious that the MVC pattern is implemented by Play! 2, and we're just looking at the C part.
After this, we notice that a method, index
, is defined. It means something similar in both languages and could be phrased as follows: inform the client that the response is OK with an HTML content rendered from something in the views
package named index
and using a string parameter.
The sentence is enough representative information to figure what an action is in Play! 2, but some keywords may require a bit more explanation:
Response: An action is something that always returns an HTTP response, which is represented in Play! 2 by the
Result
type.Ok: The
Result
type must be a valid HTTP response, so it must include a valid HTTP status code. HenceOk
is setting it to 200.Rendered something: This seemingly esoteric portion of the phrase is only referencing what is called a template file in Play! Framework 2. In other words, this is about the V part of the MVC pattern.
String parameter: A template can take parameters to adapt itself to predictable situations. Here we may feel that these template parameters are just like method parameters; perhaps because they are.
Now that we've tackled the similarities, what about the differences? The very first noticeable distinction is the following one:
In Java, a controller is a class
In Scala, a controller is an object
To illustrate this difference, we must know that an object in Scala can be thought of as a classical singleton. And actually, our Java class is a bit special due to this next distinction:
In Java, an action is a static method
In Scala, an action is a function
Strictly, a controller in Java is nothing more than a bunch of static methods, and is a convenient way to force a totally stateless code, which offers common functionalities. We're approaching the notion of a singleton without static reference to an instance (non-static getInstance
method), because the singleton instance will be created and held by the Play! 2 internals.
The Scala action definition is simply defining a new function—an object's method. If we omit the pure syntactical differences (the return type and keyword are missing in Scala), the last interesting difference is that Scala uses an additonal structure: Action
.
Such Action
can be thought of as a block of code executor within an HTTP context that could be synchronous or even asynchronous (this will be covered in Chapter 7, Web Services – At Your Disposal).
So far we have learned how to map a request to some server-side code, and how to define such server-side code as an action in a controller. In this section, we'll learn what a view looks like in Play! Framework 2.
Actually, starting from version 2, templates (or views
) are Scala based (whereas in version 1 they were based on Groovy). That is to say, a template file is HTML mixed with Scala code that can manipulate the server-side data.
As an introduction for those unfamiliar with what we covered earlier, we'll step into the template we saw in the Action section: views.html.index
. This file is located under the app/views/
folder, and is named index.scala.html
.
Here again we'll see that Play! is perfectly well integrated with Java or Scala, showing that the templates are exactly the same in both versions. The following screenshot shows what it looks like in Java:
Next, we can check what the Scala version has defined:
OK, they are not exactly the same (at first glance), but that's where it becomes really interesting. First of all, where is the HTML? We've just learned that a Scala template is a mixture (Scala and HTML), while what we have here seems to be something like Scala prefixed by @
("magic character"). Actually, it's true, the magic character tells the compiler that a Scala instruction is about to be defined in the very next block.
So, before talking about the difference (type = "Java"
), we'll have a quick review of the rest. The template starts with a parameter between the parentheses (
...)
and is prefixed with an @
character. This parameter is defining the signature of the template. Then we have a new expression composed of two parts:
The first part is invoking a certain function named
main
with one string argumentThe second part is a curly brace block (
{
...}
) containing another block of code
In fact, these two parts together compose the invocation of the main
function, which are Scala features:
A function can have several blocks of parameters
A block of parameters can be defined using either parenthesis or curly braces
The last portion to be reviewed is the content of the last parameter block. Since it starts with an @
character, we know that it will be Scala code.
Confused? Actually, in a Scala template, a curly brace is opening a staged box in which we can define a new output. In our case, the output is an HTML page. But the default index page will delegate its content generation to another function named welcome
, located in a self-descriptive play2
object (provided by the framework). As Scala code is not HTML, we must use the magic character. The content rendered by the welcome
function is what we saw while testing http://localhost:9000/
—an HTML page with documentation. But, what the heck are these functions! Still no HTML? Strictly speaking, a Scala template is compiled into a function, that's all. Keeping this in mind, we'd better look at a file named main.scala.html
that should be located in the same folder as index.scala.html
, since no import has been used at all. Indeed, there is (HTML) and it is shown as follows:
As we can see, this new template contains things such as parameters, magic characters, and so on. If we keep aside the link
and script
tags, we have an excerpt of HTML with an almost empty body.
Back to the parameters; we can see two blocks (similar to what we saw in the index.scala.html
template), where the first block is declaring a title and the second one content. They are used to set the HTML title
and the body
content respectively.
Note
The type of content
is Html
, which is the Scala structure that can be written as HTML when invoked by the template. Thus, @content
is a parameter that represents valid HTML to be written in the body of the document.
Both the Java and Scala versions of main.scala.html
are exactly the same.
This leads us to remind ourselves of the difference we saw between the index templates. The Java version is calling the welcome
template with an extra parameter (given by name—another Scala feature) telling the template that the current project is a Java one.
This style
parameter will be used by the welcome
template to show specific links to documentation, depending on the language. For instance, we can recall that earlier we got a direct link to the Java API documentation. The Scala version is not initializing this argument because its default value is Scala
.
Modifying the code and experimenting with the tool is probably the most fun part for developers like us. In the next sections, we'll try to adopt what we have learned so far to see what kind of results we can get very easily.
Let's start with the view part.
We'll first try to slightly modify the index.scala.html
template in order to replace the default welcome page with a bunch of self-coded HTML.
To keep it very simple, that is, without modifying anything else other than the index template itself, we'll try to disPlay! the given message in a header. For that, the first thing to do is to remove the call to welcome
:
That was very simple. Now, to render some HTML, we'll have to fill in an Html
value in the second parameter—the curly braces block:
We've just written the most common HTML body ever, but also asked Play! to echo the content of the message
variable. This message
variable came from the controller with the Your new application is ready.
value. If we check http://localhost:9000
again, the following screenshot is what we should get:
Not pretty, but at least we've made it ourselves. However, did you notice one thing? We don't have to package the template to compile it, or whatever a "classic" Java web application would require. What we have to do is simply save the file and check in the browser because, in Play! 2, everything is compiled or packaged on the fly when developing. And that's awesome!
The actual Application
controller has only one action saying that our application is ready. We'd now like to show in the view the well-known "It works!" message coming from Apache 2.
For that, open the Application
controller and simply change the value of the argument of index
:
Now let's check it in the browser:
Feels nostalgic!
Again, no compilation or action is required to update the running code. Play! 2 does the boring work for us.
There's another easy thing that can be done: changing the HTML title, which is left as an exercise.
Just to show how easy it is to deal with the content type, we'll see how to render a JSON response to the client.
All we have to do is to modify the index
action and nothing else. Tasks such as binding and creating a specific template are handled by Play! 2 for us.
As done earlier, we'll start with the Java version:
Followed by the Scala one:
A quick check in the browser should disPlay! the following screenshot:
As we can see, the browser has rendered the response as JSON because its content type was set by Play! with the application/json
value. This content type has been automatically inferred from the data type given to the OK response (a JSON object). The content-type value can be checked in the browser console, as shown at the bottom of the previous screenshot (see the Type column).
Until now, all our changes have been successfully applied. Unfortunately, we can sometimes make errors or typos.
The good thing is that Play! is well integrated, even for errors. This would be quite disappointing for some, but not much for those coming from the "classical LAMP stack world" for instance.
This integration is another feature that makes Play! 2 different from the other Java frameworks. Everything is compiled code—views, even assets (CoffeeScript, LESS)—and every compile-time error is just disPlay!ed in the browser when reloading the page.
This leads us to launch the application at start from the console and it'll probably be the last time we'll interact with this console. The only tools that a Play! 2 developer needs is an editor and a browser.
It's quite easy to imagine the kind of errors that can be made and how. So, let's see a few screenshots showing the result of applications presenting some of the errors encountered.
So far, we've already taken a big step forward in Play! Framework 2 by covering high-level concepts, and also introduced more advanced ones in some cases.
We tackled a whole and definitive installation of the framework itself, but with all of the other things that make a development environment: machine, IDE, command-line tool, and so on.
We've also covered the basics that are common to all the Play! 2-based web applications: Java and Scala controllers, actions, and even a bit of views.
We took the opportunity to see the whole machinery in action, and made some adaptations showing us the coolest features provided by Play! 2, such as compilation on the fly and errors shown on the browser side.
At this stage, we know that Scala is the core language of the system; moreover, it's also the templating system's language. So in the next chapter, we'll see just enough Scala to write great templates that are easy to create and maintain.