Archive

Play Framework – Scala TodoList

I’ve just finished going through the Scala TodoList sample application in the Play Framework:

http://www.playframework.com/documentation/2.1.0/ScalaTodoList

It’s not exactly the most straightforward written tutorial I’ve come across from a framework so I thought I’d post the full sources here along with an archive of everything:

Download

for people to refer to if they get stuck.

One other thing, it doesn’t tell you to enable database evolutions by default in the application.conf file so make sure you do, it’s not a showstopper by any means, but it’s handy to know.

The application consists of the following sources:

* app/controllers/Application.scala – Main Controller
* app/models/Task.scala – Task Companion Object
* app/views/index.scala.html – Index Template
* conf/application.conf – Configuration
* conf/routes – Routes
* conf/evolutions/default/1.sql – Database Evolution/Migration

Application.scala

 Scala |  copy |? 
package controllers
 
import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import models.Task
 
// Controller
object Application extends Controller {
 
	val taskForm = Form(
		"label" -> nonEmptyText
	)
 
	def index = Action { 
		Redirect(routes.Application.tasks) 
	}
 
	def newTask = Action { implicit request =>
	  taskForm.bindFromRequest.fold(
	    errors => BadRequest(views.html.index(Task.all(), errors)),
	    label => {
	      Task.create(label)
	      Redirect(routes.Application.tasks)
	    }
	  )
	}
 
	def tasks = Action {
	  Ok(views.html.index(Task.all(), taskForm))
    }
 
	def deleteTask(id: Long) = Action { 
		Task.delete(id)
  		Redirect(routes.Application.tasks)
	} 
}

Task.scala

 Scala |  copy |? 
package models
 
import anorm._
import anorm.SqlParser._
import play.api.db._
import play.api.Play.current
 
case class Task(id: Long, label: String)
 
// Task companion object
object Task {
 
	val task = {
	  get[Long]("id") ~ 
	  get[String]("label") map {
	    case id~label => Task(id, label)
	  }
	}
 
	def all(): List[Task] = DB.withConnection { implicit c =>
  		SQL("select * from task").as(task *)
	}
 
	def create(label: String) {
	  DB.withConnection { implicit c =>
	    SQL("insert into task (label) values ({label})").on(
	      'label -> label
	    ).executeUpdate()
	  }
	}
 
	def delete(id: Long) {
	  DB.withConnection { implicit c =>
	    SQL("delete from task where id = {id}").on(
	      'id -> id
	    ).executeUpdate()
	  }
	}
}

index.scala.html

 Scala |  copy |? 
 
@(tasks: List[Task], taskForm: Form[String])
@import helper._
@main("Todo list") {
 
    <h1>@tasks.size task(s)</h1>
 
    <ul>
        @tasks.map { task =>
            <li>
                @task.label
 
                @form(routes.Application.deleteTask(task.id)) {
                    <input type="submit" value="Delete">
                }
            </li>
        }
    </ul>
 
    <h2>Add a new task</h2>
 
    @form(routes.Application.newTask) {
 
        @inputText(taskForm("label")) 
 
        <input type="submit" value="Create">
 
    }   
}

conf/routes

 Text |  copy |? 
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
 
# Home page
GET     /                           controllers.Application.index
 
# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)
 
# Tasks          
GET     /tasks                  controllers.Application.tasks
POST    /tasks                  controllers.Application.newTask
POST    /tasks/:id/delete       controllers.Application.deleteTask(id: Long)

application.conf

 Text |  copy |? 
...
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
...

conf/evolutions/default/1.sql

 SQL |  copy |? 
# Tasks schema 
# --- !Ups
 
CREATE SEQUENCE task_id_seq;
CREATE TABLE task (
    id INTEGER NOT NULL DEFAULT NEXTVAL('task_id_seq'),
    label VARCHAR(255)
);
 
# --- !Downs
 
DROP TABLE task;
DROP SEQUENCE task_id_seq;

Hope that helps !

Javascript Visualisation and Graphing

Javascript data visualisation and graphing is becoming a big deal these days. When I started with web development it was on IE5/6 with Javascript and I can’t remember the experience as being pleasurable. Nowadays, our modern browsers, Chrome, Firefox and Opera have HTML5 canvas implementations that provide a mechanism for doing 2D graphics that are ...

Subversion Pre-Commit Hook

Rename the pre-commit.tmpl template to drop the .tmpl off the end. The pre-commit script has to be executable as well by the relevant user.  Bash |  copy |? cd /usr/local/subversioncp pre-commit.tmpl pre-commitchown apache:apache pre-commitchmod +x pre-commit Pre-commit hooks generally call out to other programs to do their work. It’s a Bash script by default, but people tend to write ...

Parsing Kickstarter Information With PHP5, Curl and XPath

I had a simple lightweight task to complete tonight, namely to pull Kickstarter information from the awesome Elite: Dangerous project on Kickstarter. To do it I used a simple PHP5 script with the curl dependency installed with:  Bash |  copy |? sudo apt-get install php5-curl along with a bit of XPath, which can be customised whatever way, script is ...

Chippenham Tech Chat

There’s a new meetup group in the South West called Chippenham Tech Chat: http://www.meetup.com/Chippenham-Tech-Chat/ It takes place at the office of Mango Solutions, the company I work for here: View Larger Map The first meetup is on the 18th September 2012, come along if you want to find out more, topic still to be decided.