Over a million developers have joined DZone.
Platinum Partner

Trying to make CoffeeScript work with Scalate and Play

· Java Zone

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.

A few weeks ago, I wrote about integrating Scalate with Play.

The next steps in my Play Scala adventure will be trying to get the CoffeeScript module to work. I also hope to integrate HTML5 Boilerplate with Jade and Scalate Layouts.

Since my last writing, the Scalate Team has created a new branch for Scala 2.8.x (that's compatible with Play) and released 1.5.2. To upgrade my Play application to use this version, I changed my dependencies.yml to have the following:

  - org.fusesource.scalate -> scalate-core 1.5.2-scala_2.8.1:
      transitive: false
  - org.fusesource.scalate -> scalate-util 1.5.2-scala_2.8.1:
      transitive: false

Unfortunately, this release breaks Scalate's CoffeeScript support because it wraps the code with illegal comments. This has been fixed in the latest snapshot, but no new release has been cut. However, even if it did work, it's not quite what I'm looking for. The 1.5.2 release allows for compiling inline CoffeeScript on-the-fly, but I'd rather store my .coffee files external to the page.

To try and figure out how to do this, I sent a message to the Scalate Google Group asking Does Scalate allow for referencing (and compiling) CoffeeScript files like the plugin for Play? My email prompted the Scalate Team to do some modifications that seemed to do exactly what I was looking for.

FWIW I've just checked in a couple of coffeescript examples. To run it, grab the code & do a local build...


then run this...
cd samples/scalate-example 
mvn jetty:run
then open http://localhost:8080/coffee/index

there are 2 sample jade files which use embedded coffee or a separate coffee file (using the .js extension in the <script src attribute>


e.g. here's a jade file references a separate .js file for a coffee script which gets converted to .js on the server...


To try out the improved CoffeeScript support, I checked out the source and fumbled with Git branches for a bit before I got latest version of Scalate to build. Unfortunately, it didn't work because Play doesn't know how to process the .js and .css files.

Application.foo.js action not found 
Action not found 
Action Application.foo.js could not be found. Error raised is 
Controller controllers.Application.foo not found 
play.exceptions.ActionNotFoundException: Action Application.foo.js not 
        at play.mvc.ActionInvoker.getActionMethod(ActionInvoker.java: 
        at play.mvc.ActionInvoker.resolve(ActionInvoker.java:85) 
        at Invocation.HTTP Request(Play!) 
Caused by: java.lang.Exception: Controller controllers.Application.foo 
not found 
        ... 3 more 
08:20:21,133 ERROR ~

Based on this error, I assumed I needed a Controller to do receive the .js and .css requests and compile them accordingly with Scalate. I changed my Jade template to have the following:

script(src="/assets/foo.js" type="text/javascript") 

Then I added a new route to my Play application:

  GET     /                           Application.index
  GET     /assets/{template}          ScalateResource.process

My ScalateResource.scala class is as follows:

package controllers 

import play.mvc._ 

object ScalateResource extends Controller { 

  def process(args: (Symbol, Any)*) = { 
    var template = params.get("template") 
    // replace .js with .coffee 
    template = template.replace(".js", ".coffee") 
    // replace .css with .scss 
    template = template.replace(".css", ".scss") 

Unfortunately, when I tried to access http://localhost:9000/assets/foo.js, I received the following error:

TemplateException occured : Not a template file extension (md | markdown | ssp | scaml | mustache | jade), you requested: coffee

At this point, I still haven't figured out how to solve this. I can only assume that the reason this works in the example application is because it uses a TemplateEngineFilter that's mapped to /*.

As I see it, I have a few choices if I want to continue using CoffeeScript and Scalate in my application:

  1. Revert to an older build of Scalate that uses the in-browser CoffeeScript compiler.
  2. Try to get a new version released that fixes the comment bug and use inline CoffeeScript.
  3. Keep trying to figure out how to get external files compiled by Scalate.

Obviously, I'd like to do #3 the most, but with the lack of responses from the Scalate group, this seems like the most challenging. Since #1 is the easiest (and I can complete without anyone's help), I'll be going that route for now. With any luck, the 2nd and third solutions will surface as options before my talk in November.

Update Oct 4, 2011: I was able to get external CoffeeScript files working! It was rather simple actually. I just tried the Play CoffeeScript module again, using Scalate's {uri("/path")} helper. For example, in a Jade template:

script(type="text/javascript" src={uri("/public/javascripts/script.coffee")})

This compiles the CoffeeScript file on the server and returns JavaScript. Sweet!

From http://raibledesigns.com/rd/entry/trying_to_make_coffeescript_work

The Java Zone is brought to you in partnership with ZeroTurnaround. Discover how you can skip the build and redeploy process by using JRebel by ZeroTurnaround.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}