You can compile a handlebars string using the code below.
1 2 |
var template = Handlebars.compile("Hello <em>{{name}}</em>!"); var html = template({ name: 'World' }); |
But what if you wanted to load the string from an existing .hbs template? You can create a utility function like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
//utils/template-to-string'; import Ember from 'ember'; export default function(container, template, context) { let resolvedTemplate = container.lookup('template:' + template); context = context || {}; return new Ember.RSVP.Promise((resolve) => { var component = Ember.Component.extend(Ember.merge({ style: 'display:none;', layout: resolvedTemplate, container, init() { this._super.apply(this, arguments); Ember.setOwner(this, container); }, didRender() { resolve(this.$().html()); this.destroy(); } }, context)); var instance = component.create(); instance.append(); }); } |
Then use it in your code like this:
1 2 3 4 5 6 7 8 9 |
import templateToString from '../utils/template-to-string'; ... var myTemplateContext = { firstName:'Emad' }; templateToString(Ember.getOwner(this), 'demo', myTemplateContext) .then((html) => { this.set('templateString', html); }); |
This will load and compile the template demo.hbs and also pass it a context, here is an example demo.hbs.
1 |
<h3>Hello Template: {{firstName}}</h3> |
This will generate the string:
1 |
<h3>Hello Template: Emad</h3> |
Explanation
The helper function does the following:
- Load the template using the lookup method
- Define a component and merges the context object with it
- Instantiate the component
- Append it to DOM (to force a render) – nothing gets displayed because of the display:none
Credits
Thanks to Matt Roberts for suggesting this tip and pointing me to http://stackoverflow.com/questions/27950413/render-ember-js-hbs-template-to-a-string/35625858