jinja-js icon indicating copy to clipboard operation
jinja-js copied to clipboard

Precompliation Questions

Open aldendaniels opened this issue 11 years ago • 16 comments

Hello, thanks for this sweet library.

I'm considering writing a Browserify transform for JinjaJS that pre-compiles templates server-side (NodeJS). The compiled templates only will then be used in the browser.

For my project, I have a couple of requirements:

  1. The compiled templates need to be very concise.
  2. The compiled templates need to be compatible with IE8 and above (preferably no shim required)
  3. The runtime component (if any) needs to be small and not duplicated across components. In other words, if I have three templates that I pre-compile server-side, they should all be able to share the same client-side runtime code.

Looks like JinjaJS does 1 really well. Can it do 2 and 3 as well?

Cheers -Alden

aldendaniels avatar Dec 12 '14 03:12 aldendaniels

I am pretty sure it satisfies 2 also. The compiler requires ES5, but the compiled templates will run on IE8 if I recall correctly.

As for 3, it should be easy to factor out the runtime and include it alongside the templates. The runtime itself is very small. If I have some time, I'll make an option to save it to a separate file.

sstur avatar Dec 12 '14 05:12 sstur

Edit: that's not exactly true. The runtime relies on Object.keys, array.forEach, Array.isArray and Object.create. It should be pretty easy to remove this dependency. I'll see if I can get this taken care of.

sstur avatar Dec 12 '14 06:12 sstur

@sstur - Thanks, man. This is great.

About 3 - I need to be able to include the runtime component in source and then use it like this:

var jinjaJSRuntime  = require('jinjaJSRuntime');
var compiledTemplate = require('myTemplateFile.tmpl.html'); // Compiled by my browserify transform
var data = {...};
var renderedHTML = compiledTemplate(jinjaJSRuntime, data);

Make sense?

BTW - I intend to open source the Browserify Transform once we get this working.

aldendaniels avatar Dec 12 '14 15:12 aldendaniels

Or an alternative API:

jinjaJSRuntime.render(compiledTemplate, data)

aldendaniels avatar Dec 12 '14 15:12 aldendaniels

So I've pushed a commit to take care of 2. I think 3 is totally doable. Let me have a think about it and see what needs to be changed.

sstur avatar Dec 13 '14 04:12 sstur

Thanks, sounds good. Looking forward to seeing what you come up with.

aldendaniels avatar Dec 13 '14 04:12 aldendaniels

@sstur - Any headway on this?

aldendaniels avatar Dec 19 '14 19:12 aldendaniels

I'll take a look at it this weekend when I have some spare time. Check back Monday

sstur avatar Dec 19 '14 19:12 sstur

Cool - will do.

aldendaniels avatar Dec 19 '14 20:12 aldendaniels

@sstur - Checking back in. :)

FYI - I think this approach of providing a separate, runtime-only build is pretty standard. Handlebars, for example, does this:

  • http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v2.0.0.js
  • http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars.runtime-v2.0.0.js

aldendaniels avatar Dec 28 '14 03:12 aldendaniels

@sstur - totally understand if this isn't something you can get to soon. Please just let me know so I can decide if I should wait on this or find something else that will work for me. Thanks again!

aldendaniels avatar Dec 30 '14 21:12 aldendaniels

@aldendaniels - I've started on this in a separate branch, but it will be a few days before we get this tested and working. Not too long now...

sstur avatar Jan 06 '15 18:01 sstur

@sstur - thanks for the heads-up! That sounds great.

aldendaniels avatar Jan 06 '15 20:01 aldendaniels

So I've pushed up some changes to the runtime branch. Try this to see if it helps in your use-case:

npm uninstall -g jinja-js #just to be sure
git clone [email protected]:sstur/jinja-js.git
cd jinja-js
git checkout runtime
npm link

Then you should be able to go to your project's directory and run the command:

jinjajs path/to/template/directory -o combined-output.js

This will compile the runtime and all the template files into one file which is not exactly what you asked for but it might be helpful. Then from within a browser, after including the file, you can call jinja.render('path/to/template.html', data, options) in which the path is relative to the working/project directory that you were in when you called the compiler step above. The data and options are both optional. You can require the jinja using requirejs or as a global, depending on your setup.

I'm planning on refactoring it so you can do something like this:

jinjajs --runtime-only -o runtime.js
jinjajs path/to/template/file.html -o template1.js

Then ideally you can include them in any order you like and require/call jinja.render() as above.

sstur avatar Jan 09 '15 03:01 sstur

Actually, on second thought, I'm going to refactor it to be more like the handlebars example. So disregard the part about jinja.render('path/to/template.html', data, options)

sstur avatar Jan 09 '15 18:01 sstur

Hey @sstur - sorry for my delayed reply.

For my use-case, this isn't quite right. For streaming build systems like Browserify and Gulp, reading and writing the actual files is handled by the framework. All a plugin need do is handle strings.

Compile Time

var jinjajs = require('jinjajs');
var compiledTemplate = jinjajs.complile('My name is {{ name }}');

Requirements:

  1. compiledTemplate does not include the runtime.
  2. compiledTemplate.toString() results in functional code

Runtime

var jinjajsRuntime = require('jinjajs/runtime');
compiledTemplate.render({name: 'John Smith'}, jinjajsRuntime});

Make sense?

aldendaniels avatar Jan 15 '15 18:01 aldendaniels