Way to organize client-side templates into individual files?

1.8k views Asked by At

I'm using Handlebars.js, and currently all my templates live inside script tags which live inside .html files housing dozens of other templates, also inside script tags.

<script type="text/template" id="template-1">
  <div>{{variable}}</div>
</script>

<script type="text/template" id="template-2">
  <div>{{variable}}</div>
</script>

<script type="text/template" id="template-3">
  <div>{{variable}}</div>
</script>

...

Then I include this file on the server-side as a partial.

This has the following disadvantages:

  1. A bunch of templates are crammed into HTML files.
  2. Finding a given template is tedious.

I'm looking for a better way to organize my templates. I'd like each each template to live in its own file. For example:

/public/views/my_controller/my_action/some_template.html
/public/views/my_controller/my_action/some_other_template.html
/public/views/my_controller/my_other_action/another_template.html
/public/views/my_controller/my_other_action/yet_another_template.html
/public/views/shared/my_shared_template.html

Then at the top of my view, in the backend code, I can include these templates when the page loads, like this:

SomeTemplateLibrary.require(
    "/public/views/my_controller/my_action/*",
    "/public/views/shared/my_shared_template.html"
)

This would include all templates in /public/views/my_controller/my_action/ and also include /public/views/shared/my_shared_template.html.

My question: Are there any libraries out there that provide this or similar functionality? Or, does anyone have any alternative organizational suggestions?

4

There are 4 answers

0
Chad Johnson On BEST ANSWER

I ended up using RequireJS, which pretty much let me do this. See http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/.

0
Hasith On

RequireJS is really good library for AMD style dependency management. You can actually use the 'text' plugin of requireJS to load the template file in to your UI component. Once the template is attached to the DOM, you may use any MVVM, MVC library for bindings OR just use jQuery events for your logic.

I'm the author of BoilerplateJS. BoilerplateJS reference architecture uses requireJS for dependency management. It also provides a reference implementations to show how a self contained UI Components should be created. Self contained in the sense to handle its own view template, code behind, css, localization files, etc.

Files in a BoilerplateJS UI Component

There is some more information available on the boilerplateJS homepage, under "UI components".

http://boilerplatejs.org/

1
user1267362 On

there's this handy little jquery plugin I wrote for exactly this purpose.

https://github.com/cultofmetatron/handlebar-helper

0
ivan loire On

I use a template loader that loads the template using ajax the first time it is needed, and caches it locally for future requests. I also use a debug variable to make sure the template is not cached when I am in development:

var template_loader = {
    templates_cache : {},
    load_template : function load_template (params, callback) {
        var template;
        if (this.templates_cache[params.url]){
            callback(this.templates_cache[params.url]);
        }
        else{
            if (debug){
                params.url = params.url + '?t=' + new Date().getTime(), //add timestamp for dev (avoid caching)
                console.log('avoid caching url in template loader...');
            }
            $.ajax({
                url: params.url,
                success: function(data) {
                    template  = Handlebars.compile(data);
                    if (params.cache){
                        this.templates_cache[params.url] =  template;
                    }
                    callback(template);
                }
            });
        }
    }
};

The template is loaded like this:

template_loader.load_template({url: '/templates/mytemplate.handlebars'}, function (template){
  var template_data = {}; //get your data
  $('#holder').html(template(template_data)); //render
})