Module for Play framework

77 views
Skip to first unread message

Gp P

unread,
Dec 16, 2011, 10:35:10 PM12/16/11
to cambridge...@googlegroups.com
Hi List ,

I think biggest user for CT (Cambridge templates is just too many key strokes , can we use CT or CAM  as abbreviation ?  ) is play users (including me), doesn't it make sense to release current or  next version of CT as module for play ? 

And add it in official Module repository , it would really boost its usage among play users and in general 

Thanks ,
Gp


Rakesh Waghela

unread,
Dec 17, 2011, 9:09:20 AM12/17/11
to cambridge...@googlegroups.com
I have been following cambridge for the similar reason , but one of the guy who has contributed quite a bit... is not using Play !
i guess he is a building a web app using cambridge .. his name is Jon Stvens   http://lookfirst.com/
 fingers crossed for Play ! + Cambridge marriage.

Tom Carchrae

unread,
Dec 17, 2011, 10:05:27 AM12/17/11
to cambridge...@googlegroups.com
you should file an issue on github now! ;) 

i agree.  a full working example as a play module would be good.  the current example does not run.

when i get a minute, i'll look into it.  my minutes are scarce at the moment.

tom

Jeff Schnitzer

unread,
Dec 17, 2011, 10:23:53 AM12/17/11
to cambridge...@googlegroups.com
Jon and I use Cambridge+Jexl in our non-Play appengine project. We
render templates with Htmleasy + Resteasy, although a lot of content
is rendered in javascript via Handlebars.js after we write json into
the page. Play! may be great but we would hate to see a full
dependency.

I suspect another source of fresh faces is the appengine community,
although that probably overlaps with the Play community.

Jeff

Tom Carchrae

unread,
Dec 17, 2011, 10:37:35 AM12/17/11
to cambridge...@googlegroups.com
I don't think he's suggesting a full dependency (and I agree it would be bad).  

Play! is best taken as a relatively loose integration of many useful parts of a web app.  I'm also a fan of some of their java anti-patterns.

Tom

Jon Stevens

unread,
Dec 17, 2011, 1:38:07 PM12/17/11
to cambridge...@googlegroups.com
The app that we've developed has all of the benefits of Play... namely the edit/save/reload cycle for Java code. We aren't concerned with the ability to create new applications quickly since we already have our single app. ;-) We don't have a 'build' step since Eclipse pretty much just takes care of that for us and the Google Eclipse plugin just runs stuff out of our web-inf folder.

We've accomplished the Java code cycling feature by just using jrebel, which works most of the time, but not all, there are some edge cases where it doesn't seem to work. That said, a full restart of the container is two clicks in eclipse and only about 3 seconds, so it isn't that big of a deal to do when you need it.

I recently documented how we are serving up our JS in a super efficient way. Again, it takes advantage of the use of Cambridge/JEXL. http://lookfirst.com/2011/12/optimizing-your-javascript-delivery.html

In the end, I think you can get the benefits of Play without too much work. I'm not sure why there is such a big landrush for it. I also think that their new focus on Scala will be their downfall.

cheers,

jon

Tom Carchrae

unread,
Dec 18, 2011, 2:05:47 PM12/18/11
to cambridge...@googlegroups.com
I agree about the Play Scala move - the fact that they will be using SBT instead of Python scares me.  I'm not a fan of Python either mind, but it's clearer what it is doing.  I haven't touched Play 2.0 yet. That said, Play devs say that the Java 1.x will live on, so who knows.  There are a few things that bug me about their approach, but such is using any framework.  Personally, I like simple and being able to get my head around the stack so I can understand how to use/fix/abuse it.

Jon/Jeff - I'm curious to see what your cambridge files looks like.  Any chance you could post a small one?

Tom

Jon Stevens

unread,
Dec 18, 2011, 2:25:47 PM12/18/11
to cambridge...@googlegroups.com
We are all developers here, don't kid yourself about 1.x living on. As soon as the next big thing comes, we love to jump to it like rabid monkeys. ;-)

I'm happy to show whatever you want. What would you like to see? A template file or some Java code? For the templates, there really is not much there other than a whole bunch of html. At this point, most of the dynamic rendering is done with CoffeeScript + Handlebars. Sometimes I'll render first with cambridge and then when I have the design looking good, I'll move the code into Handlebars.

Sometimes I'll do little stuff like this (JEXL based):
<!--$set tabindex=1 -->
<td><input id="name" name="name" type="text" tabindex="${tabindex = tabindex + 1}" /></td>

We use the cambridge $extends a fair bit which is nice and a must have feature of any template system.

jon

Tom Carchrae

unread,
Dec 18, 2011, 3:17:41 PM12/18/11
to cambridge...@googlegroups.com
On Sun, Dec 18, 2011 at 11:25 AM, Jon Stevens <latc...@gmail.com> wrote:
We are all developers here, don't kid yourself about 1.x living on. As soon as the next big thing comes, we love to jump to it like rabid monkeys. ;-)

Haha...  well, I've been holding my horses about jumping on Scala.  Things like 2.9 not being backward compatible give me the willies.  Coda Hale's mail, while generally useful, his scorn on SBT was the worst part for my fear about Play 2.0....  and I used to code Haskell for several years.  I don't doubt there is a tasty subset of Scala features that would make my Java code nicer.  I've been eyeing Scala for some time, primarily because Generics in Java don't cut it for writing reusable/abstract code.


I'm happy to show whatever you want. What would you like to see? A template file or some Java code? For the templates, there really is not much there other than a whole bunch of html. At this point, most of the dynamic rendering is done with CoffeeScript + Handlebars. Sometimes I'll render first with cambridge and then when I have the design looking good, I'll move the code into Handlebars.

Makes a lot of sense....   but why not jump straight in with Handlebars at the start? 

I recall starting an email on porting Cambridge to javascript (probably via GWT), but I think I got distracted or slapped my self for procrastinating and dreaming.  

Sometimes I'll do little stuff like this (JEXL based):
<!--$set tabindex=1 -->
<td><input id="name" name="name" type="text" tabindex="${tabindex = tabindex + 1}" /></td>

We use the cambridge $extends a fair bit which is nice and a must have feature of any template system.

Seem nice and clean.  

Tom

 

Jeff Schnitzer

unread,
Dec 18, 2011, 3:29:30 PM12/18/11
to cambridge...@googlegroups.com
On Sun, Dec 18, 2011 at 3:05 PM, Tom Carchrae <t...@carchrae.net> wrote:
>
> Jon/Jeff - I'm curious to see what your cambridge files looks like.  Any
> chance you could post a small one?

It's really hard to pick out "just one" because (as Jon mentioned) we
use template inheritance a lot, plus a significant part of the app is
rendered in javascript (coffeescript) with handlebars.js. Cambridge
provides the structure of the page + we use it more heavily for pages
with a significant SEO footprint.

FWIW, here's the page about an event (event_about.html):

-----

<!--$extends _event.html -->
<!--$set page="about" -->

<div id="eventContent">
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var regTimeline = %{tool.jsonify(model.event.regTimeline)};
var pagecode = function(lab) {
lab.script(socialRefs['google']).script(socialRefs['twitter'])
.script('${tool.jsbuilder(['gen/event_about'])}');
}
</script>

<div class="startmain"></div>
<div class="main">
<div class="inner_main second_block">
<div class="container_alpha_nogradients">
<!--$ Here we show the categories -->
<div class="gs_9 products">
<div class="productGroup" a:foreach="model.event.productGroups"
a:as="group">
<div a:if="!empty(group.products)">
<h3 a:if="!empty(group.name)">${group.name}</h3>

<table class="bootstrap bordered-table">
<thead>
<tr>
<th class="categoryField">Category</th>
<th>Distance</th>
<th>Start</th>
<th>Prizes</th>
<th>Registered</th>
<th>Fee</th>
</tr>
</thead>
<tbody>
<tr a:foreach="group.products" a:as="prod">
<td class="categoryField">${prod.name}</td>
<td>${prod.distance}</td>
<td>${prod.start}</td>
<td>${prod.prizes}</td>
<td>${prod.count}${if (prod.limit != null) " / " + prod.limit}</td>
<td>${prod.pricePretty}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="gs_3 omega">
<div class="top_sidebar_mask"></div>
<div class="sidebar">
<div class="widget">

<div id="regDetails">
<p class="confirmation" a:if="!empty(model.you.ticketGroup)">
Congratulations, you are signed up for this event.
<br/>
<a href="/event/${model.event.shortKey}/you">details</a>
</p>

<div id="regOpen" style="display:none;">
<a href="/event/${model.event.shortKey}/register" class="btn
orange xlarge">Register</a>
<p>Closes in</p>
<div id="countDownCloses" class="countDown"></div>
</div>

<div id="regFuture" class="information" style="display: none;">
<p>Registration opens in</p>
<div id="countDownOpens" class="countDown"></div>
</div>

<p id="notFutureOrOpen" class="error" style="display: none;">
Sorry, registration<br />has closed.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="endmain png_bg"></div>

<div class="startmain"></div>
<div class="main">
<div class="inner_main second_block">
<div class="container_alpha_nogradients">
<span id="description">%{model.event.descriptionHtml}</span>
</div>
</div>
</div>
<div class="endmain"></div>

<div class="startmain"></div>
<div class="main">
<div class="inner_main second_block">
<div class="container_alpha_nogradients">
<h3>${model.event.location.full}</h3>
<div id="directionsMap" class="gs_12 omega">
<a href="http://maps.google.com/maps?q=${model.event.location.full}"
target="_blank">
<img src="%{model.event.location.fullWidthMap}" alt="Map of location"/>
</a>
</div>
<div id="mapLink">
<a href="http://maps.google.com/maps?q=${model.event.location.full}"
target="_blank">Click to view full-size map</a>
</div>
<div id="directions">%{model.event.directionsHtml}</div>
</div>
</div>
</div>
<div class="endmain"></div>
</div>

Jon Stevens

unread,
Dec 18, 2011, 3:34:46 PM12/18/11
to cambridge...@googlegroups.com
Makes a lot of sense....   but why not jump straight in with Handlebars at the start? 

Just because it requires a bit more boilerplate. I have to build out the CS code around displaying the data within an element. At this point, I've abstracted most of that out to a 'class' that I extend, but it is still a bit of typing.
 
Seem nice and clean.  

One thing you'll note is that I'm not generating the input statements so that I can do all sorts of fancy CS/JS controller library nonsense. I've found all of that to be too much typing and more code == more mistakes. 

Instead, I'm keeping as much in html as I can and using relatively simple tools like form2js/js2form [1] to pull/push data between form elements and a json blob (which is serialized to the page through cambridge/jexl.. note the tool.jsonify at the top of the template Jeff just posted). I'm then using dirty_form [2] to watch for changes in a form so that I can enable/disable a Save button as necessary. I've had to make some bug fixes and enhancements to those tools, but this model is working really well. Most importantly, it is nice and clean. A designer or jr. engineer can come in and work on these templates and figure out what is going on relatively easily.

jon

Tom Carchrae

unread,
Dec 18, 2011, 4:08:55 PM12/18/11
to cambridge...@googlegroups.com
Looks great.  Thanks for posting more Jeff.  

Jon - cool, not just DRY, but remove code/complexity.  Thanks for posting the links to the form2js code.  

I still don't have a happy answer for the client side logic in general.  I'm currently working on two projects; one is a GWT  fat client and the other is a Play + scraps of jQuery.  I certainly prefer working with jQuery - the GWT refresh/compile times are brutal... but GWT logic is much nicer.  And sure, backbone/etc, but really, is JS really the right tool for anything reasonably complex.  

I've been working on an app that grabs JSON from several places and stuffs it into templates.  I'm writing templates (with Play's Groovy template) to directly access these elements without converting them into Java classes (at the moment via GSON's JsonElement).  I'm not particularly happy with the current approach and am looking at extending the template markup to make it simpler to access the Json elements - I'm sure some kind of JsonPath + template engine should exist for this.  This approach makes more sense to me than de-serializing JSON into java then turning it back into text for the template.  

Very much agree with how clean and designer friendly it is... and how valuable that is to reducing 'tech support' of a developer's time.  

Thanks again for sharing.  

Tom

Erdinc Yilmazel

unread,
Dec 20, 2011, 1:06:21 AM12/20/11
to cambridge...@googlegroups.com
Hi all,

I wanted to let you know that I have started the work to create a Play Framework module. I have a working module now which was fairly easy to build. I just copied the existing code in the cambridge-playframework directory into this new play module folder and I didn't even need to write any new code. I need more experienced Play programmers to give me ideas about how to make this something really useful.

The way existing code works is documented on this twiki page: http://code.google.com/p/cambridge/wiki/UsingWithPlayFramework . Instead of extending Controller, you need to extend CambridgeController if you want to use a cambridge template. Please tell me if this would or would not work in general. 

I know that some of the existing Play Template features don't have exact counterparts on Cambridge. Can you guys list the top must-have features for play framework support ordered by importance? I think the ability to create custom tags easily is one of the main issues. I will address this issue not only for Play but in general so any input is appreciated.

I will update the cambridge-playframework folder with the new Play framework module code, replacing the old integration code soon. Once all the missing points are implemented, I will email play google groups and ask for the module to be put in play's official repository.

Thanks,

Erdinc

Tom Carchrae

unread,
Dec 20, 2011, 2:11:56 PM12/20/11
to cambridge...@googlegroups.com
Hi Erdinc,

I had a quick look at your example and I think we could improve it.  In particular, instead of using renderArgs.put it is nicer if you use render(arg, arg, arg);

It would be nice to not have to change code to use the Cambridge template.  I believe this is possible by registering the Template rendering engine as a Plugin, but I am not quite sure how to do this.  I just spent some time looking at how plugins are registered.  If you trace into the render() method you'll see it ends up checking plugins as well.  

If the plugin can render a template it returns an instance of Template. https://github.com/playframework/play/blob/master/framework/src/play/PlayPlugin.java#L155


Tom
Reply all
Reply to author
Forward
0 new messages