Gem for using Google Closure Templates with jRuby.
gem install closure-templates
Assuming a simple template:
/** myapp.soy */
{namespace myapp.templates}
/**
* Hello there template
* @param name The name of the person to greet
*/
{template}
Hi {$name}
{/template}
Use it in jRuby:
require 'closure-templates'
ClosureTemplates.config(
:template_directory => '/path/to/soy/templates',
:output_directory => '/path/to/where/generated/javascript/should/go'
)
# render a template
ClosureTemplates.render('myapp.templates.hello', :name => 'Dylan')
# returns 'Hi Dylan'
Use it in JavaScript:
<script type="text/javascript" src="soyutils.js"></script>
<!-- following was generated by ClosureTemplates -->
<script type="text/javascript" src="myapp.templates.js"></script>
<script type="text/javascript">
var output = myapp.templates.hello({ name: 'Dylan' });
</script>
You will need to include either soyutils.js (if you are not also using Google Closure Library) or soyutils_usegoog.js (if you are). Read more here.
Currently I have an initializer that looks like this:
require 'closure-templates'
ClosureTemplates.config(
:template_directory => "#{Rails.root}/app/templates",
:output_directory => "#{Rails.root}/app/assets/javascripts/templates"
)
Then I render the templates where needed (HAML example):
!= ClosureTemplates.render('myapp.posts.index', :posts => @posts)
Google Closure Templates have some requirements for the data passed in, specifically (from SoyData.java):
Note that in order for the conversion process to succeed, the given data structure must correspond to a valid SoyData tree. Some requirements include: (a) all Maps within your data structure must have string keys that are identifiers, (b) all non-leaf nodes must be Maps or Lists, (c) all leaf nodes must be null, boolean, int, double, or String (corresponding to Soy primitive data types null, boolean, integer, float, string).
This gem makes some attempts to meet these requirements by converting hash keys to strings and calling the 'attributes' method (by default) on objects which respond to it. This allows the use of Rails models, for example, to be passed to templates and have their basic attributes accessible. You can customize the method that the gem uses to try to get a hash of attributes by passing the 'attribute_method' option to the config method (see below).
These are all passed to the ClosureTemplates.config method, which must be called before the first ClosureTemplates.render.
default: templates
Where you keep your soy templates. You should specify this.
default: closure_js
Where you want the gem to put the generated JavaScript files. You should specify this.
default: true
The gem maintains a list of the soy template files and can check to see if any of them have been modified when calling render. If one has been modified, then if :recompile is true, it will regenerate the Java object and the JavaScript files from the latest soy templates, which is nice for development. You could turn this off in production to get slightly faster rendering.
default: attributes
This is the method the gem will try to use to get a more Closure Templates friendly representation of Ruby Objects before passing them into the template. It will call this method on objects if they respond to it. If you want to customize which properties (or make methods available) you can customize this method to be one you implement in your classes.
Idea for this gem came from a discussion on the Google Closure Template discuss group:
where Aliaksandr Zahatski pointed me to a gist by Ilya Grigorik which led me to the Closure Sprockets gem also by Ilya. I took code and ideas from both places as starting points for this gem.
(MIT License) - Copyright (c) 2011 Dylan Vaughn