24

I love the HAML-like syntax of Jade's templating engine in Node.js, and I would love to use it client-side within Backbone.js.

I've seen Backbone commonly using Underscore.js templating in the following style.

/* Tunes.js */
window.AlbumView = Backbone.View.extend({
  initialize: function() {
    this.template = _.template($('#album-template').html());
  },

  // ...
});

/* Index.html */
<script type="text/template" id="album-template">
  <span class="album-title"><%= title %></span>
  <span class="artist-name"><%= artist %></span>
  <ol class="tracks">
    <% _.each(tracks, function(track) { %>
      <li><%= track.title %></li>
    <% }); %>
  </ol>
</script>

What I'd like to see is a way to use AJAX (or some other method) to fetch Jade templates and render them within the current HTML.

Josh Smith
  • 14,674
  • 18
  • 72
  • 118
  • https://github.com/gruntjs/grunt-contrib-jade compiles jade to js template functions with `{client: true}`. It's not AJAX fetching but it sounds like it could do what you need. – sam Apr 18 '13 at 04:42
  • The native `jade` compiler can compile templates to client-side JS with the `--client` option. However, you must include the Jade runtime before you can render these templates. There's another project, [clientjade](http://projects.jga.me/clientjade/), that makes this even easier. – mpen Dec 12 '13 at 22:29

5 Answers5

23

I was able to run Jade client-side using jade-browser project.

Integration with Backbone is then simple: Instead of _template() I'm using jade.compile().

HTML (scripts and template):

<script class="jsbin" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://raw.github.com/weepy/jade-browser/master/jade.js"></script>
<script src="https://raw.github.com/weepy/jade-browser/master/jade-shim.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>

<script type="template" id="test">
div.class1
  div#id
    | inner
  div#nav
    ul(style='color:red')
      li #{item}
      li #{item}
      li #{item}
      li #{item}
script
  $('body').append('i am from script in jade')
</script>

JavaScript (integration with Backbone.View):

var jade = require("jade");

var TestView = Backbone.View.extend({

  initialize: function() {
    this.template = jade.compile($("#test").text());
  },

  render: function() {
    var html = this.template({ item: 'hello, world'});
    $('body').append(html);
  }
});

var test = new TestView();
test.render();

HERE is the code.

kubetz
  • 8,485
  • 1
  • 22
  • 27
  • Was looking for this to use Jade in client side. I am using Backbone, requirejs in Express. I am confused on how to use Jade browser project. Do i need to npm install anything or just link to js files. And how to configure it in require config files? – Sami Dec 11 '13 at 15:17
  • Your example says: "ReferenceError: require is not defined at http://null.jsbin.com/runner:1:771" – Phil Nov 18 '14 at 23:34
14

As @dzejkej mentioned above, one of the best known ways to use Jade templates on the client is to use jade-browser; however, I've always had a few issues with Jade in the browser.

  • Compiling Jade templates is slow - which is okay, but really, all templates should be cached, and if you cache them on the client, anytime they load a new page, the cache disappears (unless using HTML5 persistent storage, for example).
  • File includes can be a pain and can create excess bloat. If you are compiling Jade templates on the browser and the template contains include statements, you may have to do some extra work to get them to compile properly. In addition, if you decide to compile on the server and send JavaScript to the client, you still have issues. Whenever Jade templates use file includes, your compiled Jade templates can get rather large because they contain the same code over and over. For example, if you include the same file again and again, that file's contents will be downloaded to the browser several times, which is wasting bandwidth.
  • Lack of support - Jade provides little support for client-side templates out of the box. Yes, you can use the {client: true} compiler option, but the compiled templates are really not optimized for the client, and in addition, there is no mechanism for serving compiled Jade templates to the browser.

These are among some of the reasons why I created the Blade project. Blade is a Jade-like templating language that supports client-side templates right out of the box. It even ships with Express middleware designed for serving compiled templates to the browser. If you are okay with a Jade-like alternative for your projects, check it out!

BMiner
  • 16,669
  • 12
  • 53
  • 53
4

I just open sourced a nodejs project, called "asset-rack", that can can precompile jade templates and offer them in the browser as javascript functions.

This means that rendering is blazingly fast, even faster then micro-templates because there is no compilation step in the browser.

The architecture is a little different then what you mention, just one js file for all templates called "templates.js" or whatever you want.

You can check it out here, https://github.com/techpines/asset-rack#jadeasset

First you set it up on the server as follows:

new JadeAsset({
    url: '/templates.js',
    dirname: __dirname + '/templates'
});

If you template directory looked like this:

templates/
  navbar.jade
  user.jade
  footer.jade

Then all your templates come into the browser under the variable "Templates":

$('body').append(Templates.navbar());
$('body').append(Templates.user({name: 'mike', occupation: 'sailor'});
$('body').append(Templates.footer());

Anyway, hope that helps.

Brad C
  • 720
  • 8
  • 14
  • Great, we need JST for Node ! – Maxence De Rous Mar 03 '13 at 14:47
  • @Maks I recommend using [jade-browser-middleware](https://github.com/JoeChapman/jade-browser-middleware), the code is fairly simple so you might want to just copy the raw `index.js` from the repo and add it to your lib. – Cole Lawrence Jul 23 '14 at 13:39
  • I'm totally not sure how to use this. Could you update this with a synopsis? What is JadeAsset? Is that was asset-rack exports? – Evan Carroll Nov 17 '14 at 11:39
  • **NOTE:** Asset-Rack support **neither** Express 4 (latest), nor Jade 1.x (latest). It's has not been worked on in a year. – Evan Carroll Nov 17 '14 at 11:46
0

You might also checkout my new library for jade inside browser. It is as simple as < jade>...< /jade>. https://github.com/charlieamer/jade-query

0

You won't get the full power of Jade templates, but you can hack it a bit to get jade to properly output underscore templates, the key is preventing jade from escaping the <%> tags with the ! operator, like so:

script#dieTemplate(type='text/template')
    .die(class!='value-<%= value %>')
        i.fa.fa-circle
        i.fa.fa-circle
        i.fa.fa-circle
        i.fa.fa-circle
        i.fa.fa-circle
        i.fa.fa-circle
        i.fa.fa-star
DigitalDesignDj
  • 1,725
  • 15
  • 16