Tutorial : Create your first application
This tutorial show how to create a very simple photo management application. It's a simple demonstration of how Play! works. You don't need to read the full manual to try this; just follow the tutorial step by step.
Be sure to have a functional installation. You can work with your preferred IDE or you can work with a simple text editor.
Create the application
Open a shell and create the new application :
# play new photos
The application is created. Start it :
# play run photos
The application is now ready. The created application contains a default Controller Application, and the associate html template.
The object model
Our application object model is very simple : a single Photo class. Model objects are defined in the models package.
So let's create the Photo class in the app/models/Photo.java file :
package models;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import play.Play;
import play.libs.Files;
public class Photo {
public File file;
public Photo(File file) {
this.file = file;
}
public String getName() {
return file.getName();
}
public Long getSize() {
return file.length();
}
public static List<Photo> findAll() {
List<Photo> all = new ArrayList<Photo>();
for (File file : Play.getFile("data").listFiles()) {
all.add(new Photo(file));
}
return all;
}
public static Photo findByName(String name) {
return new Photo(Play.getFile("data/" + name));
}
public static Photo create(File file) {
File to = Play.getFile("data/" + file.getName());
Files.copy(file, to);
return new Photo(to);
}
}
This class stores files under the /data directory of the application. No need to use a database here. Just create a /data directory in your photos application.
The first screen
The first screen of the application display all photos. Edit the index action of the Application controller to add the functionality :
package controllers;
import java.util.List;
import models.Photo;
import play.mvc.Controller;
public class Application extends Controller {
public static void index() {
List<Photo> photos = Photo.findAll();
render(photos);
}
}
The render(…) method at the end of the action, display by convention the app/views/Application/index.html template.
Let's edit this template to display the photos :
#{extends 'main.html' /}
#{set title:'All photos' /}
<h1>${photos.size() ?: 'No'} photo(s) found</h1>
#{list items:photos, as:'photo'}
<div class="photo">
<img src="@{Application.photoContent(photo.name)}" height="100" />
<div>
<span class="name">${photo.name}</span>
<span class="size">${photo.size}</span>
</div>
</div>
#{/list}
Note that the src=”…“ attribute use a Play! action to retrieve the image content. So we need to define the photoContent action in the Application controller :
public static void photoContent(String name) {
Photo photo = Photo.findByName(name);
renderBinary(photo.file);
}
Finally we have to declare 2 routes to bind these 2 actions to corresponding HTTP events. Routes are defined in the conf/routes files :
GET / Application.index
GET /{name}/content Application.photoContent
You can now test the first screen. Open http://localhost:9000/ in your browser and see the result.
The second screen : upload photos
For this second screen, we need to implement two actions to :
- Display the upload form
- Handle form submission
Let's code these actions in the Application controller :
public static void newPhoto() {
render();
}
public static void upload(File photo) {
Photo.create(photo);
index();
}
The newPhoto action displays the app/views/Application/newPhoto.html template, again guessing the template name from the action name. Here is the template:
#{extends 'main.html' /}
#{set title:'Add a photo' /}
<h1>New photo</h1>
<form action="@{Application.upload}" method="POST" enctype="multipart/form-data">
<label for="photo">Choose a file to send : </label>
<input type="file" id="photo" name="photo" />
<p>
<input type="submit" value="Send it ..." />
</p>
</form>
And we also need a link on the first screen too … Add this line to index.html :
<a class="new" href="@{Application.newPhoto}">New photo</a>
Finally we declare the new routes to handle HTTP events :
GET /new Application.newPhoto POST / Application.upload
Just reload the page and test your form.
Styling
Now we can apply a CSS to make the screen look better. In public/stylesheets/default.css add these rules :
.photo {
border: 1px solid #aaa;
padding: 4px;
float: left;
height: 150px;
width: 150px;
text-align: center;
margin: 0 10px 10px 0;
}
.photo img {
margin-bottom: 5px;
}
.photo .name {
display: block;
white-space: nowrap;
width: 142px;
overflow: hidden;
}
.photo .size {
font-weight: bold;
white-space: nowrap;
display: block;
}
.new {
clear: both;
margin-top: 1em;
display: block;
}
And a last thing : we can easily display the image size in a better way. Edit the index.html template to format the size number like this :
<span class="size">${(photo.size/1000).format('# ###')} kb.</span>
Creating application with Play! is really easy, isn't it ?



