1
votes

I'm relatively new to this, so please excuse if I'm missing some obvious point...

I'd like to create a reusable widget using Handlebars, for simplicity let's consider a Users table:

<script type="text/x-handlebars-template" id="temp1">
       <table>
         {{#users}} 
            <tr><td>{{name}}</td><td>{{email}}</td></tr> 
         {{/users}} 
       </table>
</script>

<script>
   var template=Handlebars.compile($("#temp1").html());    
   function renderUsersTable(users, divId){
       $("#"+divId).html(template(users:users));
   }
<script>

This works, but I only got it to work with the template script (text/x-handlebars-template) embedded into my business page. That's not reusable: if I need it on another page, I'll need to copy-paste. I considered quoting the template into a javascript string variable, but that's ugly especially since my real html is pretty large.

Are there any better practices, that allow to separate the handlebars template into a dedicated file, to be included into different pages as needed?

Thanks very much

1
you can use Handlebars' Partial feature - riyadhalnur
thanks, that's not exactly what I was shooting for but this Partial is an excellent feature I wasn't aware of, so thanks very much! - Pelit Mamani

1 Answers

0
votes

Yes. One way is to use a gulp task to compile all your templates. The example below takes all the individual handlebars files from a directory and puts them in one javascript file hb_templates.js as templates. Each template is given the name of the file it came from. For your example you could put your template into users.handlebars. Then include the generated hb_templates.js after Handlebars.js in your production webpage.

gulp.task('handlebars', function() {
  gulp.src('./app/views/*.handlebars')
  .pipe(htmlmin({
    collapseWhitespace: true
  }))
  .pipe(handlebars())
  .pipe(wrap(function(data) {
    var filename = data.file.history[0].split('\\').pop().split('.')[0];
    return "Handlebars.templates." + filename + "=Handlebars.template(<%= contents %>)";
  }))
  .pipe(concat('hb_templates.js'))
  .pipe(gulp.dest('./app/scripts/'));
});

You use the template like this;

$("#"+divId).html(Handlebars.templates.user(users:users));

Since partials in Handlebars are just templates you can use these templates inside other template files like so

<div>
{{> user}}
</div>

Just register them as partials once you have loaded hb_templates.js like this;

handlebars.registerPartial('user', handlebars.templates.user);

The example used the following dependencies in nodejs for gulp

{
    "gulp": "3.9.0",
    "gulp-concat": "2.6.0",
    "gulp-handlebars": "4.0.0",
    "gulp-htmlmin": "1.1.3",
    "gulp-wrap": "0.11.0",
    "handlebars": "3.0.3",
}