Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Guard plugin for smart, automatic compilation of your Javascript templates.
JavaScript Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib Added support for external templates system
spec
.gitignore
Gemfile
LICENSE
README.md
Rakefile
guard-templates.gemspec

README.md

Guard::Templates

Guard::Templates is a Guard plugin that pre-compiles or translates your project's JS-language templates into include-ready Javascript files.

Installation

If using Bundler, just add guard-templates to your Gemfile

group :development do
  gem 'guard-templates'
end

Alternatively, install it system-wide with

gem install guard-templates

Guard::Templates uses ExecJS for intermediary-stage compilation. You can install one of several JS engines and JSON libraries that it will use - see the ExecJS documentation for details. Presently, this is only necessary if you want to transform your Jade templates into precompiled functions.

Usage

Once guard-templates is installed you can add a sample Guardfile with:

guard init templates

This will look something like:

guard 'templates', :output => 'public/javascript/templates.js', :namespace => 'MyApp' do
  watch(/app\/javascripts\/templates\/(.*)\.jade$/)
end

Change the watch and output paths to match your application, and run

guard&

Options

namespace Set to your application's namespace, defaults to 'this'. Use this to keep your templates out of the global scope like a good Javascript citizen. output Path relative to Guard where the compiled Javascript files will be output. If this is a filename ending in .js, all of the templates will be attached to a single object, as above.

Template Languages Without Precompiling Support

Presently, aside from Jade, this means all of them. :-) See adding new languages below if you'd like support precompilation for your favorite Javascript templating language.

With a templates directory that looks like:

templates/
├── foo
│   └── bar.handlebars
└── index.handlebars

Then :output => 'public/javascripts will produce a public/javascripts that looks like:

public/
└── javascripts
    ├── foo
    │   └── bar.js
    └── index.js

Each file contains the stringified template contents of the handlebars file:

MyApp['index'] = "<div>{{index}}</div>\n"

If output is a path ending in .js, the templates will be compiled to an object in that file. Using the example above with :output => 'public/javascripts/templates.js', we get a single file result:

public/
└── javascripts
    └── templates.js

that looks like:

MyApp.templates = {
  "index": "<div>{{index}}</div>\n",
  "foo/bar": "<p>{{example}}</p>\n"
}

With Precompiling Jade

Templates with a .jade extension will be precompiled with Jade's compiler and turned into anonymous functions. The only difference between precompiled and unprecompiled templates is the precompiled ones get turned into functions rather than strings in the resulting Javascript.

With this filesystem structure, and a watch pattern like watch(/templates\/(.*)\.jade$/)

templates/
├── foo
│   └── other.jade
└── index.jade

:output => 'public/javascripts/templates.js' will produce a templates.js that looks like:

MyApp.templates = {
  "foo/other": function anonymous(locals, attrs, escape, rethrow) {
    //function contents
  },
  "index": function anonymous(locals, attrs, escape, rethrow) {
    // function contents
  }
}

You can then include templates.js in your application and render the templates by calling the functions in question. I.e:

MyApp.templates['foo/other']()

With :output => 'public/javascripts', each .jade file will be compiled to an individual .js file, like so:

├── public
│   └── javascripts
│       ├── foo
│       │   └── other.js
│       └── index.js
├── templates
│   ├── foo
│   │   └── other.jade
│   └── index.jade

With the contents of each compiled js file looking like:

MyApp['index'] = function anonymous(locals, attrs, escape, rethrow) {
  //function contents
}

Precompilation

Currently, Jade is the only language natively supported. If you want to use an other language, you have to install plugins.

Here are some available plugins :

Language Extension Gem name Maintainer
Jade .jade Native Thomas Mayfield
JSHaml .jshaml guard-templates-jshaml Sébastien Drouyer

Never the less, an up-to-date list of guard-templates plugins can be found on rubygems.

If there is no installed plugin supporting your template type, it falls back to being inlined as string literals.

Adding Precompilation Support For Other Languages

Adding precompilation support for your favorite language is simple. There are currently two ways :

  • you can add a single class method to Guard::Templates::Compilers. When checking for precompilation support for a particular file extension, guard-templates looks for a class method named compile_<extension> in that module. It should accept a string (representing the template source) and return a stringified Javascript function. See compile_jade in Guard::Templates::Compilers for an example.
  • or you can create an external gem and share your implementation with others. There is only 2 requirements :
    • It is recommended you name your gem guard-templates-<extension> in order to let users find it on rubygems.
    • You have to create lib/guard/templates/<extension>/compiler.rb in which you create a Guard::Templates::<extension>::Compiler class implementing the compile static function.
      • The function takes 2 parameters
        • str, which is the content of the template source
        • target, which is a hash containing information about the target
          • name, path (without extension) of the input template file
          • type, file's extension
          • path, path of the output js file
      • The function must return a stringified Javascript function.
Something went wrong with that request. Please try again.