Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving client side Jade templates

I want to use Jade templates at the client side with Backbone. How can I do that?

For now, I have successfully configured Backbone (Marionette) to compile Jade templates for use in its Views:

Marionette.TemplateCache.prototype.compileTemplate = (tmplStr) ->
    console.log "jade stuff: ", jade.compile(tmplStr)
    return jade.compile(tmplStr)

The "problem" is: I am currently writing templates like:

script(type="text/template", id="tmplMainView")
    | h1= title
    | p= content

Notice the pipes (|) those are to prevent Jade from trying to interpret/parse them on server side. How can I eliminate those?

UPDATE

Perhaps I can use the jade --client flag ... but it gives a single compiled function: for example

h1= title

Becomes

function anonymous(locals, attrs, escape, rethrow, merge) {
attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;
var buf = [];
with (locals || {}) {
var interp;
buf.push('<h1>');
var __val__ = title
buf.push(escape(null == __val__ ? "" : __val__));
buf.push('</h1>');
}
return buf.join("");
}

That means I have to have 1 Jade/compiled JS for each template? How might I use it? Also I think many JS files is a slow way to work? But since template functions are all named anonymous, how can I then concat or somehow work with them effectively?

like image 992
Jiew Meng Avatar asked Feb 19 '23 05:02

Jiew Meng


2 Answers

Check the ClientJade project.

From their site:

clientjade is a command line tool to compile your jade templates into client side templates for use in the browser. It will automatically include everything you need to render the templates, no need to include jade.js or runtime.js.

$ clientjade test1.jade test2.jade > templates.js

And then include template.js file in your html. To render the templates, just make a call like this:

//jade.render(domNode, templateName, data);    
jade.render(document.getElementById('test1'), 'test1', { name: 'Bob' });
like image 115
Felipe Castro Avatar answered Feb 21 '23 09:02

Felipe Castro


After looking at Jadify and ClientJade, and encountering a few problems along the way ... (perhaps its just somethings I missed out), I decided to explore simply compiling the templates on server side.

I defined a Node module (used by ExpressJS) which does the compilation and returns the compiled JS source (which I served with /js/templates.js).

fs = require "fs"
jade = require "jade"
async = require "async"

# done callback will be passed (source, err)
exports.compile = (done, templatesDir) ->
    js = "var Templates = {}; \n\n"

    # get all files in templates directory
    fs.readdir templatesDir, (err, files) ->
        # keep only ".jade" files
        jadeFiles = files.filter (file) -> 
            file.substr(-5) == ".jade"

        # function to compile jade templates (appending to js source)
        compileTmpl = (file, doneCompile) ->
            # "test.jade" becomes "test"
            key = file.substr(0, file.indexOf("."))
            filePath = templatesDir + file
            fs.readFile filePath, (err, src) ->
                # store js function source into Templates.{key}
                js += "Templates." + key + " = " + jade.compile(src, { debug: false, client: true }).toString() + "; \n\n"
                doneCompile(err)

        # foreach jadeFile, compile template, then write templates.js file
        async.forEach jadeFiles, compileTmpl, (err) ->
            done(js, err)

And I use the precompiled templates on client side by including the templates.js and use templates like:

  • Templates.tmpl1()
  • Templates.tmpl2({ something: "Hello world", ... })

More on https://coderwall.com/p/hlojkw

like image 34
Jiew Meng Avatar answered Feb 21 '23 08:02

Jiew Meng