External CoffeeScript Files

349 views
Skip to first unread message

Matt Raible

unread,
Sep 11, 2011, 8:10:41 PM9/11/11
to sca...@googlegroups.com
Does Scalate allow for referencing (and compiling) CoffeeScript files like the plugin for Play? From its documentation:

<quote>
You can also write your Coffee in a separate file, including it via a script tag.

For example (Java),

<script type="text/javascript" href="@{'/public/javascripts/sample.coffee'}"></script>

or (Scala),

<script type="text/javascript" href="@asset("/public/javascripts/sample.coffee")"></script>

The module handles the request and compiles the coffee on the fly.
</quote>

https://github.com/robfig/play-coffee

James Strachan

unread,
Sep 12, 2011, 12:20:09 AM9/12/11
to sca...@googlegroups.com
So you can refer to templates/resources/files/images/css relative to your web applications context using the uri scala function. e.g. in jade

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

though that just does relative or absolute URI resolving (adding the web app context stuff too etc). It doesn't do anything magical with coffee script.

If you want to keep the generated JS file as a separate resource in your app you might want to do something like...

  script(type="text/javascript" href={uri("/public/javascripts/sample.js")})

then either have a servlet for converting the coffee -> js or use the coffeescript/cake watcher thingy. We don't as I type have a default coffee -> js servlet filter in Scalate (though it'd be pretty trivial to hack one in to be honest). But if play has that already you could just reuse it I guess.


Though if you want to include the content of the coffee file inside a page you can use the include function - so something like...

h1 hello world
:&coffeescript
  #{include("/public/javascripts/sample.coffee")}

Which would include the generated JS inside your page. (using & on a filter turns on interpolation so you can use #{expression} inside the filter block
http://scalate.fusesource.org/documentation/jade-syntax.html#Filter_Interpolation

Though the above isn't terribly DRY; it'd probably be better to create a function to include a chunk of coffee using the filter. e.g. something like

h1 hello world
= includeCoffee("/public/javascripts/sample.coffee")


There's so many ways to slice and dice this stuff ;-). did you want the JS to be a separate browser request right? If so did you want the URI to include "sample.coffee" (but return JS) or did you want to use a URI with "sample.js" and so have the server side realise "sample.js" should be generated from "sample.coffee"?

--
James
-------
FuseSource
Email: ja...@fusesource.com
Web: http://fusesource.com
Twitter: jstrachan, fusenews
Blog: http://macstrac.blogspot.com/

Open Source Integration and Messaging

Matt Raible

unread,
Sep 12, 2011, 12:26:06 PM9/12/11
to Scalate


On Sep 11, 10:20 pm, James Strachan <ja...@fusesource.com> wrote:
> turns on interpolation so you can use #{expression} inside the filter blockhttp://scalate.fusesource.org/documentation/jade-syntax.html#Filter_I...
>
> Though the above isn't terribly DRY; it'd probably be better to create a
> function to include a chunk of coffee using the filter. e.g. something like
>
> h1 hello world
> = includeCoffee("/public/javascripts/sample.coffee")
>
> There's so many ways to slice and dice this stuff ;-). did you want the JS
> to be a separate browser request right? If so did you want the URI to
> include "sample.coffee" (but return JS) or did you want to use a URI with
> "sample.js" and so have the server side realise "sample.js" should be
> generated from "sample.coffee"?
>

Yes, I want the JS to be a separate browser request. Or rather, I'd
like to see something like the Play CoffeeScript plugin in Scala -
where a link to a CoffeeScript file is compiled on-the-fly and
returned as CSS. This is done by using @asset like the following
example.

<script type="text/javascript" href="@asset("/public/javascripts/
sample.coffee")"></script>

However, even if you add that, I'm not sure it'd give me what I want.
Because as soon as you give me this ability, then I'm going to want
the ability to concatenate and minimize my JS and CSS files. Now that
I think of it, it might be easiest if I figure out how to integrate
wro4j into Play, since it has a CoffeeScript compiler, supports LESS,
etc.

http://code.google.com/p/wro4j/

I'm assuming I can use something like {uri("/wro/my.js")} to write out
a link that can be processed by wro4j's filter.

James Strachan

unread,
Sep 13, 2011, 2:17:27 PM9/13/11
to sca...@googlegroups.com

FWIW I've just checked in a couple of coffeescript examples.

To run it, grab the code & do a local build...
http://scalate.fusesource.org/source.html
http://scalate.fusesource.org/building.html

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>
https://github.com/scalate/scalate/tree/master/samples/scalate-example/src/main/webapp/coffee

e.g. here's a jade file references a separate .js file for a coffee
script which gets converted to .js on the server...
https://github.com/scalate/scalate/blob/master/samples/scalate-example/src/main/webapp/coffee/external.jade


> However, even if you add that, I'm not sure it'd give me what I want.
> Because as soon as you give me this ability, then I'm going to want
> the ability to concatenate and minimize my JS and CSS files.

Yeah, sounds like wro4j can give you that today; then someday soon we
can add something wro4j-like as I described in the separate thread...
http://groups.google.com/group/scalate/browse_thread/thread/2904bbdc8ca9dd46

James Strachan

unread,
Sep 13, 2011, 3:11:50 PM9/13/11
to sca...@googlegroups.com

I just added a sass/scss sample too btw
https://github.com/scalate/scalate/blob/master/samples/scalate-example/src/main/webapp/coffee/external.jade#L1
https://github.com/scalate/scalate/blob/master/samples/scalate-example/src/main/webapp/coffee/mysass.scss

though if you want to minify collections of css/sass/coffee/js today
the best option is wro4j (or some helper scala functions).

Matt Raible

unread,
Sep 21, 2011, 10:09:21 PM9/21/11
to Scalate


On Sep 13, 12:17 pm, James Strachan <ja...@fusesource.com> wrote:
> To run it, grab the code & do a local build...http://scalate.fusesource.org/source.htmlhttp://scalate.fusesource.org/building.html
>
> then run this...
>
> cd samples/scalate-example
> mvn jetty:run
>
> then openhttp://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>https://github.com/scalate/scalate/tree/master/samples/scalate-exampl...
>
> e.g. here's a jade file references a separate .js file for a coffee
> script which gets converted to .js on the server...https://github.com/scalate/scalate/blob/master/samples/scalate-exampl...
>

This looks great. I was able to checkout the source and build locally,
but when I try the scalate-core JAR in my Play application, I get:

NoClassDefFoundError occured : scala/collection/GenTraversableOnce

I'm guessing this is because of Scala 2.9 vs. 2.8. Is this enhancement
available on the 2.8 branch?

Also, can I put my .coffee and .scss files in the "public" folder of
my application or does it have to be in app/templates?

Thanks,

Matt

Matt Raible

unread,
Sep 22, 2011, 10:31:52 AM9/22/11
to Scalate
> > To run it, grab the code & do a local build...http://scalate.fusesource.org/source.htmlhttp://scalate.fusesource.or...
>
> > then run this...
>
> > cd samples/scalate-example
> > mvn jetty:run
>
> > then openhttp://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>https://github.com/scalate/scalate/tree/master/samples/scalate-exampl...
>
> > e.g. here's a jade file references a separate .js file for a coffee
> > script which gets converted to .js on the server...https://github.com/scalate/scalate/blob/master/samples/scalate-exampl...
>
> This looks great. I was able to checkout the source and build locally,
> but when I try the scalate-core JAR in my Play application, I get:
>
> NoClassDefFoundError occured : scala/collection/GenTraversableOnce
>
> I'm guessing this is because of Scala 2.9 vs. 2.8. Is this enhancement
> available on the 2.8 branch?

I tried downloading the latest scala-2.8.x branch snapshot, building
and using those JARs in my application. Play doesn't like it because
it doesn't know how to process the .js and .css files. Here's the
error I get when using the external.jade and foo.coffee/mysass.scss
files in my application:

08:20:21,122 ERROR ~

@67o8fflce
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
found
at play.mvc.ActionInvoker.getActionMethod(ActionInvoker.java:
588)
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 ~

@67o8fflcf
Application.mysass.css action not found

Action not found
Action Application.mysass.css could not be found. Error raised is
Controller controllers.Application.mysass not found

play.exceptions.ActionNotFoundException: Action Application.mysass.css
not found
at play.mvc.ActionInvoker.getActionMethod(ActionInvoker.java:
588)
at play.mvc.ActionInvoker.resolve(ActionInvoker.java:85)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.Exception: Controller
controllers.Application.mysass not found
... 3 more

I'm guessing I need to figure out some sort of way to map .js and .css
requests to Scalate?

Sync Tango contacts

unread,
Sep 22, 2011, 10:37:36 AM9/22/11
to sca...@googlegroups.com

--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

Matt Raible

unread,
Sep 22, 2011, 10:44:01 PM9/22/11
to sca...@googlegroups.com

On Sep 22, 2011, at 8:31 AM, Matt Raible wrote:
</snip>

I was able to work something out. I changed external.jade to have:

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

Then I added a new route to my Play application:

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")
ScalateTemplate(template).render();
}
}

However, when I try to go to http://localhost:9000/assets/foo.js, I get:

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

Any ideas are much appreciated.

Thanks,

Matt

Matt Raible

unread,
Oct 4, 2011, 10:43:51 AM10/4/11
to sca...@googlegroups.com

On Sep 22, 2011, at 8:44 PM, Matt Raible wrote:
<snip/>

>
> I was able to work something out. I changed external.jade to have:
>
> script(src="/assets/foo.js" type="text/javascript")
>
> Then I added a new route to my Play application:
>
> 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")
> ScalateTemplate(template).render();
> }
> }
>
> However, when I try to go to http://localhost:9000/assets/foo.js, I get:
>
> TemplateException occured : Not a template file extension (md | markdown | ssp | scaml | mustache | jade), you requested: coffee

Quick update. I was able to get past this because I discovered the Play CoffeeScript module[1] handles external CoffeeScript files. For example, in a Jade template:

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

Thanks,

Matt

P.S. I was also able to find a Sass module:

http://www.playframework.org/modules/sass

[1] https://github.com/robfig/play-coffee

Reply all
Reply to author
Forward
0 new messages