Scala, come out and Play

Last week I started work on a Play 2.1 Scala project, which is a nice departure from Spring and Hibernate, so it’s a good time to share some first thoughts on the differences between the old traditional Java webapp, Grails, Rails and Play 2.1 with Scala.

First off, installing Play is easy as pie. Most modern frameworks can create a skeleton app quite easily, however the integration with sbt feels a bit awkward but is still much better than good ol’ Maven. Re-compiling scala files can seem to take awhile, but running tests are nice and quick in IntelliJ.

IntelliJ is a great choice for Scala/Play projects, as v12.1 has excellent auto-completion, syntax highlighting and click-through method links and good test integration. The contextual help is quite good at telling you what’s wrong – this seems to be a strength of the Scala compiler. However, for whatever reason we spent some time trying to get IntelliJ to register our Play app as such when importing the project. Possibly because the /app folder wasn’t off the root of the repository, (we have it in /play/app) but even after running play idea to generate the necessary project files, IntelliJ refused to import it as a Play app.

After upgrading the Play plugin, installing a Scala plugin and ensuring Scala, Play and Java were all in the path and had appropriate %_HOME directories set, it still wouldn’t give in. Creating a new Play app from IntelliJ seemed to bootstrap it with the necessary vision it needed, and after doing this, it imported our existing app no worries.

Be careful as lots of documentation on the web is disinformation, since Play 1.0 is different, and Play 2.1 have made some refinements from previous revisions. Also the fact that we are using Specs2 means you have to sanity check all blog posts and stackoverflows before assuming they are correct for you.

Testing in Scala is beautiful and clean, feels natural and all the crazy syntax of Mockito in Java seems to have been repaired. Specs2 reminds me more of RSpec or Jasmine Specs, which make it easier to read and group similiar tests.

Scala as a language feels quite wierd. Ruby and underscore.js already have nice functional methods like reduce, map, filter which are pretty straight-forward. Things I like are the Option class and the case matching aspects. Like any new framework (and language) you can get stumped and need a good reference on how to do things the idiomatic way.

Scala templates have been carefully designed with a set of opinions and good conventions (such as auto-escaping and immutable parameters, and the ability to create templates and helpers which have multiple closures as parameters changes the way you can call templates.

As an example:

To get all the goodness I am used to in other projects, I created a @toggle macro, which takes in a single String parameter, followed by 2 closures (one to render when enabled and, you guess it, the other to render when disabled).

Place the following in the directory views/helpers/toggle.scala.html as a helper template:

@(toggle: String)(enabledContent: Any)(disabledContent: Any)

@import play.api._

@defining(Play.current.configuration.getBoolean("toggles." + toggle)) { toggleValue =>

  @toggleValue match {
    case Some(toggleEnabled) => {

      @if(toggleEnabled) {
          @enabledContent
      } else {
         @disabledContent
      }

    }
    case None => {
      <h1> Error invalid toggle specified: @toggle</h1>
    }
  }
}

Then simply set a value in conf/application.conf ie.

toggles.search_box=true

Where you want to switch the behaviour (in a Scala template), do the following:

  @toggle("search_box") { 
    <label>Search:<input type="text" id="search"></label>
  } {
    <div>Search is currently disabled</div>
  }

Additionally, Play allows you to toggle the value in the application.conf file dynamically, no restart needed =)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s