Mr Speaker

CoffeeScript & Less with Play! 2.0

The Play! framework went and made Java development more fun than Ruby development (*ducks*) - and then Martin Odersky went and made Java more fun than Java (*considers ducking, but doesn't*), and then the Play framework went and mashed those fun things together and now there is the Play! 2.0 framework.

Play 2.0 gives a big hug to Scala (the core is all Scala now - though there are still Java APIs for everything if you haven't convinced your bosses to switch yet). One small-yet-nice feature of the new version is built-in CoffeeScript and Less CSS support. Here's how you use it...

After creating a new app, add a app/assets directory to the default structure. Files in here are contenders to be compiled and served as public resources. From here we'll go ahead and add javascripts and stylesheets folders as children.

Adding some CoffeeScript

Next, we'll add a new CoffeeScript file. Create a new file app/assets/javascripts/main.coffee and add some coffee magic (here we're alerting after a jQuery document.ready):

$ ->
    alert "Mmmmm... Coffee...."

To link this from your main template, add a link to where the compiled version should go:

<script type="text/javascript" src="@routes.Assets.at("javascripts/main.js")"></script>

Notice the path is javascripts/main.js (not .coffee). We're pretending that the JS file is a normal-ol' JS resource in the /public/javascripts/ directory (though, internally it's actually compiled to a separate target directory).

Refresh the page, and alerts abound! Anytime you refresh your browser, any changes will be automagically compiled and served. Neato.

And some Less

Adding Less CSS is almost exactly the same: add a file app/assets/stylesheets/main.less:


body {
    background: green;
    color: yellow;
}

And link it as a regular resource (and if you're trying this from a default project, don't forget to delete the main.css in the public stylesheets directory, and the @play20.welcome(message) from the index view - which brings it's own CSS to the party!):

<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">

There's one caveat though: if we have an import statement in our Less file - the compile command will merge the files, but it will also find the import and try to compile it standalone. To avoid this, you need to name the import file with a leading underscore.

Here's our import file, apps/assets/stylesheets/_theme.less:


@mainBackground:        green;
@mainColor:             yellow;
@defaultFont:           13px sans-serif;

And here's our main.less:


@import '_theme.less';

body {
    background: @mainBackground;
    color: @mainColor;
    font: @defaultFont;
}

You can add as many subdirectories as you need to give your project a nice structure (for example, adding all the imports in libs etc.)

And that's it! For the inquisitive of you who are wondering how this works under the hood, check out the code in framework/play/src/main/scala/play/core/coffeescript and less, and Mozilla's Rhino project!

Captcha! Please type 'radical' here: *
How did you find this thingo? *