Tuesday, November 13, 2012

Hello World! with Scala Web Application using Play 2.0 and Scalate

In this post, we will look at how to make a hello-world web application in scala using the Play 2.0 Web Framework and change the template engine to work with Scalate. We assume your machine is all set up with Java and Scala configured.

Step 1 : DOWNLOAD AND CONFIGURE Play 2.0

Download the Play Framework 2.0 from http://download.playframework.org/releases/play-2.0.4.zip. Then extract the zip file to some location. I put mine at C:\Development\tools\play-2.0.4\. It is usually a good idea to leave the version number intact so as to easily know what version of any tool you are currently having on your machine.

The configuration portion is pretty simple – Update your PATH environment variable to include the root directory of the play-2.0.4 folder which has the “play.bat” (I am running windows).

To verify, launch your command line or powershell and type the command “play”. You should see something like shown below.

image

Step 2 : CREATE A NEW PLAY 2.0 WEB APPLICATION

Using command line (change directory – cd), go to a folder where you wish to place your application. Run the following command

play new helloworld-scalate

Here helloworld-scalate will be my application name.

Then from the command line go into the “helloworld-scalate” folder. And then run the following command.

play run

The first time you run, it takes a few seconds to initialize the project and upon success, you will see on-screen instructions that the application is hosted at 9000 port on localhost.

image

Verify by opening your browser and loading http://localhost:9000

You should see a welcome page.

Step 3 : INTEGRATING SCALATE INT YOUR APPLICATION

I found the proper instructions to do this here. But I will repeat them again.

Go to helloworld-scalate\project\Build.scala

3.a Add the following lines to appDependencies.

"org.fusesource.scalate" % "scalate-core" % "1.5.3"

What did we do? What we are doing is to add a dependency on scalate-core in an SBT friendly style. Play 2.0 takes care of fetching this dependency through its repositories which is listed at helloworld-scalate\project\plugins.sbt


To verify if things are fine, go back to command line and run the command


play run


You should see that SBT updates the dependencies. Just verify if your application can still be browsed from localhost:9000.



3.b Add ScalaIntegration.scala to helloworld-scalate\app\lib


You will need to create a folder “lib” inside helloworld-scalate\app folder. And then from the URL given below copy the content into a new file – ScalaIntegration.scala


https://raw.github.com/janhelwich/Play-2-with-Scala-and-Scalate/master/app/controllers/ScalateIntegration.scala


This does the necessary bootstrapping such that you can now use scalate in the current project.


Run the “play run” command again and reload the page at localhost:9000 to make sure you haven’t made a mistake.



Step 4 : UPDATE VIEWS & ACTION WITH TEMPLATE OF YOUR CHOICE


Scalate supports multiple template engines like Jade, Mustache, Scaml. The documentation indicates that Scaml gives the best performance given the strongly typed nature. But I might have misread the docs so read and check yourself.


To do this, rename your files inside “helloworld-scalate\app\views” folder such that extension is changed from .scala.html to .scaml. Note that you will see two files – the layout file (main) and the view file (index).


In the main.scaml, add the following code.

-@ var body: String
-@ var title: String = "Page"

%html
%head
%title= title
%body
!= body

In the index.scaml, add the following code.

-@ var message: String = "Page"
/Layout template file given here
-attributes("layout") = "main.scaml"

%h1= message

Notice that in the index.scaml, we specified that we want to apply the main.scaml layout using the attributes(“layout”) declaration.


You also need to change the application controller which is inside the helloworld-scala\app\controllers\application.scala


The Application controller has an action called “index” which is the one that gets executed when you were loading the browser. We need to change this action such that it renders using Scalate instead of the default one.

package controllers

import play.api._
import play.api.mvc._

object Application extends Controller {

def index = Action {
//Ok(views.html.index("Your new application is ready."))
Ok(Scalate("index.scaml").render(‘message -> "Hello World"))
}
}

As you can see in the index action, I commented the existing line added this one line.


Ok(Scalate("index.scaml").render(‘message-> "Hello World"))


Please pay attention to the ‘ in front of the title. Here the ‘message is a symbol literal. You can read more about them here. 


Now run the “play run” command again and you should see plain html page that prints “Hello World”.


I hope this step-by-step helped you get started with a new play 2.0 web application in Scala and also made you familiar with integrating the scalate engine. Note that the original url which I mentioned earlier has the same steps but step 4 where default Scalate template type is specified in the <application folder>\conf\application.conf is not performed. I skipped this step and it doesn’t appear that it will cause any problems. But again, after reading this tutorial, if you are a beginner, then you and I are at the same level so please feel free to explore more and learn.


Thanks!

2 comments:

coco said...

hi..when I compile I get this error:

[error] /home/yo/Downloads/play/play-2.2.0/BasicApp1/app/lib/ScalaIntegration.scala:20: not enough arguments for constructor TemplateEngine: (sourceDirectories: Traversable[java.io.File], mode: String)org.fusesource.scalate.TemplateEngine
[error] val engine = new TemplateEngine
[error] ^
[error] /home/yo/Downloads/play/play-2.2.0/BasicApp1/app/lib/ScalaIntegration.scala:47: missing parameter type
[error] Writeable[ScalateContent](scalate => codec.encode(scalate.cont))
[error] ^
[error] two errors found
[error] (compile:compile) Compilation failed
[error] Total time: 3 s, completed Dec 7, 2013 1:09:07 PM


seems than the TemplateEngin receive several parameters (no implicits)

coco said...

HI!...I get this error:

[error] /home/yo/Downloads/play/play-2.2.0/BasicApp1/app/lib/ScalaIntegration.scala:20: not enough arguments for constructor TemplateEngine: (sourceDirectories: Traversable[java.io.File], mode: String)org.fusesource.scalate.TemplateEngine
[error] val engine = new TemplateEngine
[error] ^
[error] /home/yo/Downloads/play/play-2.2.0/BasicApp1/app/lib/ScalaIntegration.scala:47: missing parameter type
[error] Writeable[ScalateContent](scalate => codec.encode(scalate.cont))
[error] ^
[error] two errors found
[error] (compile:compile) Compilation failed
[error] Total time: 3 s, completed Dec 7, 2013 1:09:07 PM

do you know what can I do? thanks!