18

Is it possible to store a jsRender template in a separate file?

I want to store it in a separate file and make a reference of it in my page.

something like this

<script id="templateName" type="text/x-jsrender" src="thisIsTheTemplate.js"></script>

I will apreciate any commemnts or suggestions.

Thanks

profanis
  • 2,741
  • 3
  • 39
  • 49
  • You can also use require as the mentioned on www.jsviews.com: https://www.jsviews.com/#search?s=load%20templates&l=node/browserify@0 – ceasaro Dec 28 '18 at 18:51

5 Answers5

21

Yes, you can accomplish this (I use this every time).

let's assume that you have your templates in a template folder and it is called, for example _productDetails.tmpl.html

in your page you use jQuery $.get() to pull it and load into the template, like:

var renderExternalTmpl = function(item) {

    var file = '../templates/_' + item.name + '.tmpl.html';
    $.when($.get(file))
     .done(function(tmplData) {
         $.templates({ tmpl: tmplData });
         $(item.selector).html($.render.tmpl(item.data));
     });    
}

and you pass an object item witch will contain all 3 properties, like:

renderExternalTmpl({ name: 'productDetails', selector: '#items', data: {} })

You can have a nice utilities class to hold all this:

var my = my || {};
my.utils = (function() {
    var getPath = function(name) {
        return '../templates/_' + name + '.tmpl.html';
    },
    renderExtTemplate = function(item) {

        var file = getPath( item.name );
        $.when($.get(file))
         .done(function(tmplData) {
             $.templates({ tmpl: tmplData });
             $(item.selector).html($.render.tmpl(item.data));
         });    
    };

    return {
        getPath: getPath,
        renderExtTemplate: renderExtTemplate
    };
});

and you can easily call my.utils.renderExtTemplate(item);

balexandre
  • 73,608
  • 45
  • 233
  • 342
  • Is it a good idea to send a http request every time i want to render a template? – Stefan Aug 08 '12 at 07:45
  • 2
    @Stefan I do that, just use `cache: true` if you want the browser to cache the template so you don't need to send it every single request. – balexandre Aug 08 '12 at 08:40
  • 8
    How come simply setting the `src` attribute of the template's ``)? That would be so clean, beautiful, and intuitive. – Maxy-B Dec 18 '12 at 21:25
2

I recently ran into this problem myself. After looking through the jsRender code, and studying other javascript libraries, I decided to write my own library that would simplify loading external templates so that one could attach templates to a html page using the <link> tag and render them by simply including the .js file. If you would like to check it out, I have posted the code on github with examples:

https://github.com/stevenmhunt/tmpl.loader

This library works with jsRender, as well as any code capable of processing a template.

Enjoy!

Steven Hunt
  • 2,321
  • 19
  • 18
  • @Maxy-B: Thanks for the message, I changed my github username recently. I forgot this post was sitting out there, thanks for the heads up! If you have any difficulties with the library, let me know. – Steven Hunt Dec 18 '12 at 21:37
2

Here is a function I wrote to load one or more external templates at once. It also caches the templates so if one is already loaded it won't load again.

function loadTemplates() {
    var toLoad = [],
        loadAll = $.Deferred();

    $.each(arguments, function(i, templateName) {
        var filepath = '/path/to/templates/' + templateName + '.html',
            loadTemplate = $.Deferred();

        toLoad.push(loadTemplate);

        if ($.templates[templateName]) {
            loadTemplate.resolve();
        } else {
            $.get(filepath , function(html) {
                var newTemplate = {};
                newTemplate[templateName] = html;
                $.templates(newTemplate);
            }).fail(function() {
                throw 'Could not load template at '+filepath;
            }).done(function() {
                loadTemplate.resolve();
            });
        }
    })

    $.when.apply($, toLoad).done(function() {
        loadAll.resolve();
    });

    return loadAll;
}

Use it like so:

loadTemplates('modal','itemDetail', 'itemsList').done(function() {
    // do stuff when all templates are loaded
    $('#viewItemDetail').on('click',function() {
        $.render.itemDetail({
            id:'123',
            name:'Cool Thing',
            description:'This thing is really cool.'
        });
    });
});
johnpolacek
  • 2,599
  • 2
  • 23
  • 16
  • You can set cache to false in the get. https://stackoverflow.com/questions/8841425/how-to-set-cache-false-in-jquery-get-call – johnpolacek Nov 23 '17 at 18:15
1

In case you're trying to load external templates from a local file, like I was, let me save you some frustration. Don't use the jQuery $.get() as recommended in balexandre's answer.

Use $.ajax(), and set async: true and dataType: text, otherwise it gives you an error: elem.getAttribute is not a function. See my answer to Error when loading jsrender templates through AJAX for details.

Community
  • 1
  • 1
Dmitri Zagidulin
  • 1,117
  • 9
  • 23
0

in my experience, you don't need to work with that trouble, you just need to append the template to the page before you using it. see below code.

<div id="all_template"></div>
<script>
var file = '/tmpl/all.tmpl.html';
$.ajax({
    url: file,
    async: false,
    type : "GET",
    dataType: 'text',
    cache: true,
    success: function(contents) 
    {
    $("#all_template").append(contents);//append all your template to the div
    }
});
</script>
<script>
var data = {};
$('#js-template').render(data);//use it as the same old way
</script>

in this way, you don't need to request a ajax file everytime you want to render a js template

X.Cen
  • 1