Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
How Sprockets works with JST and EJS templates
// This document distills the magic that happens when you create a file with the ".jst"
// and ".ejs" extensions anywhere on your asset path in Ruby on Rails, courtesy of the
// Sprockets library (https://github.com/sstephenson/sprockets).
//
// For the purpose of this example, imagine that you have created a template for
// messages in `app/assets/javascripts/backbone/templates/messages/message.jst.ejs`
// with the following contents:
//
// <h1><%= user.full_name %></h1>
// <p><%= body %></p>
//
// You will find that a request to `http://localhost:3000/assets/backbone/templates/messages/message.js`
// yields something very different:
//
// (function() {
// this.JST || (this.JST = {});
// this.JST["backbone/templates/messages/message"] = function(obj){var __p= ...
// }).call(this);
//
// This may strike you as "magic", but really it's just clever engineering. Let's
// break it down.
//
// To kick things off, Sprockets' JST preprocessor creates an anonymous function and
// calls it in the right context. While it is not strictly necessary to do that in
// this example, it's considered good practice because it prevents variables from
// leaking into the global scope unless explicitly exported (see
// http://stackoverflow.com/questions/5211638).
(function() {
// Next, Sprockets' JST preprocessor creates a new `JST` object in the global scope
// unless it already exists.
this.JST || (this.JST = {});
// Sprockets' JST preprocessor assigns a key to the `JST` object describing
// the path to this template.
//
// At this point, Sprockets' EJS preprocessor kicks in and assigns the value
// of the aforementioned key to a function that evaluates your template in the
// context of `obj`.
//
// This enables you to call JST["backbone/templates/messages/message"] anywhere in your
// JavaScript code to evaluate the template with a given context.
//
// Example:
//
// var view = {
// template: JST["templates/person"],
// render: function(){
// return this.template({ name: "Elvis Presley" })
// }
// }
//
// Pretty neat.
this.JST["backbone/templates/messages/message"] = function(obj) {
// The `__p` variable will hold a list of strings describing the evaluated template.
var __p = []
// Populate the `__p` array with strings describing the template evaluated
// in the context of `obj`.
with(obj || {}) {
__p.push('<h1>', user.full_name ,'</h1>\n<p>', body ,'</p>\n');
}
// Convert the `__p` array into a string and return it.
return __p.join('');
};
}).call(this);

Thanks for this, nice bit of insight gained

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment