BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.67k stars 339 forks source link

Node + jsRender: allow absolute paths, (and also passing context to renderFile) #357

Closed wowczarek closed 4 years ago

wowczarek commented 4 years ago

Dealing with a scenario where using relative paths is not possible because the app is packaged with pkg and all assets packaged into the executable are accessible using a virtual FS path "/snapshot". As such, these cannot be passed to templates(). The pkg shim layer only reacts to paths starting with /snapshot it seems, and no tricks with a relative path such as ./../../../../snapshot/some/file.html work. Included templates ({{include}})use the same mechanism anyway so there is no easy or sane way out without modifying jsRender.

My current workaround is to precompile all templates before the app starts up by recursing over the template directory and registering named templates where name is the relative path without ./, i.e. ./templates/email/hello.txt is compiled under the name "email/hello.txt" and the absolute path is readFileSync'd, and including using the same names, so that every included template is already compiled before including. But this requires me to read every.single.template at once.

renderFile() does not cut it, because it does not pass the context/helpers object to render() - and also because there is no control over relative paths when using {{include}}.

I agree that this may be a narrow use case, but is there a technical reason for the decision that only paths starting with dotslash are recognised as paths, and not also slash?

BorisMoore commented 4 years ago

I didn't manage to get to this yet, but I hope to respond in a few days...

BorisMoore commented 4 years ago

Thanks for bringing up these scenarios/features.

I have been looking at the current implementation, and I believe it is possible to allow absolute paths.

Here is an update: jsrender_jsviews.zip

Can you test it in your environment?

(A simple way to do to that would be to replace the jsrender-node.js file in your node-modules/jsrender folder with the one in the zip above. If relevant you can also replace the jsrender. js and/or jsviews.js that you are running in the browser (if you are using them there) with the corresponding updates above...

With the new version you can use paths starting with slash, both in templates() and renderFile(). With renderFile you can also pass file paths like "C:\\my\\template.html."

In addition I have added support for passing a context object as well as a data object to renderFile, just like with tmpl.render(myData, myHelpers).

The following signatures are supported: renderFile(filepath, data) renderFile(filepath, data, context) renderFile(filepath, data, callback) renderFile(filepath, data, context, callback)

(So both context and the callback: callback(error, html) are optional)

Let me know your take on this...

BorisMoore commented 4 years ago

@wowczarek: Did you take a look at the update attached above, to verify whether it addresses your needs/requests?

wowczarek commented 4 years ago

@BorisMoore not yet but will be able to test over the next few days. Thanks!

BorisMoore commented 4 years ago

OK great, thanks...

BorisMoore commented 4 years ago

@wowczarek: Still waiting on whether this fix is good for you. Let me know, as soon as you are able to test it. (I will release it in an update as soon as I am ready...)

Thanks.

BorisMoore commented 4 years ago

@wowczarek - I'd appreciate if you could test whether the proposed update does address your issues/needs. If I don't hear back I'll publish it as is, and resolve this issue. Thanks...

BorisMoore commented 4 years ago

This has been included as a new feature in release v1.0.7: