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.68k stars 340 forks source link

Jsrender Browserify nested templates #298

Closed ViktorHofer closed 8 years ago

ViktorHofer commented 8 years ago

Hey Boris it's me again ;)

When I want to make use of the nested template browserify bundling feature I get an error "cannot find module './../../../template.html' ...".

My template structure looks like this: template-structure

And the template which is the root template and includes all the others looks like this:

<div id="productlist">
    <ul>
        <li><a href="#general">Allgemein</a></li>
        <li><a href="#roles">Rollenmodell</a></li>
        <li><a href="#service">Service Desk</a></li>
        <li><a href="#privacy">Datenschutz</a></li>
        <li><a href="#weakpointanalysis">Schutzbedarfsanalyse</a></li>
    </ul>
    {{include tmpl="./productlist-general.html"/}}
    {{include tmpl="./productlist-roles.html"/}}
    {{include tmpl="./productlist-service.html"/}}
    {{include tmpl="./productlist-privacy.html"/}}
    {{include tmpl="./productlist-weakpointanalysis.html"/}}
</div>

It seems like the jsrender/tmplify transform does not handle the paths correctly.

One of the includes in more detail: {{include tmpl="./productlist-general.html" /}} current directory (./) => /src/modules/productlist/ the transformed path => ./../../../productlist-general.html

Thanks for your time :+1:

BorisMoore commented 8 years ago

When using Browserify, the relative paths are relative to your calling script. It is mentioned here: http://www.jsviews.com/#node/filetmpls:

Note: The ./... paths are always interpreted as relative paths relative to the location of your calling script. Declaring a templates folder for Express or Hapi does not change the origin of these relative paths.

I'll try to call it out more clearly also in the Browserify topic. http://www.jsviews.com/#node/browserify

See also the examples in https://github.com/BorisMoore/jsrender-node-starter.

In your case you probably need to write {{include tmpl="./src/modules/productlist/productlist-general.html" /}} - it looks like you are running your browserify transform script from the the parent folder of src?

Let me know if that works for you...

ViktorHofer commented 8 years ago

Hey Boris,

yeah thanks, it worked perfectly!! This was indeed the solution. Just for interest, why hast the path to be absolute? normally when you do require/import in js it's always the realtive path, so this seems a bit uncommon. (But it's not such a big issue!)

Thanks a lot! 👍

BorisMoore commented 8 years ago

It's a relative path, from the current folder (i.e. the folder with the calling script that does require('jsrender') - in this case Browserify that is creating the bundle).

It is not relative to the layout template. That's because the nested templates are registered and cached based on the path ./path/relative/to/current/folder/mytemplate.html. Different templates in different folders might invoke the same nested template. But the registered path needs to be the same. And that path is used by the calling template to load the template.

BorisMoore commented 8 years ago

In the last update I added a note on relative paths, here: http://www.jsviews.com/#node/browserify:

Note on relative paths...

ViktorHofer commented 8 years ago

Great improvement! Thank you for that :+1: