Reputation: 4017
I currently can do the following:
var template = Handlebars.compile("Hello <em>{{name}}</em>!");
var html = template({ name: 'World' });
The html
variable now holds the string "Hello <em>World</em>!"
.
But how can I do the same with a template whose code is in a .hbs
file inside my app/templates
directory?
(I'm using ember-cli with ember 1.9.1)
Upvotes: 4
Views: 1828
Reputation: 6403
In Ember 1.13.15 this will work (UPDATE to work with v2.4 at the bottom):
// template-to-string.js
import Ember from 'ember';
export default function(container, template, context) {
let resolvedTemplate =
typeof template === 'string' ? container.lookup('template:' + template) : template;
context = context || {};
Ember.assert(`Template '${template}' could not be resolved`, !!template);
return new Ember.RSVP.Promise((resolve) => {
Ember.Component.create(Ember.merge({
style: 'display:none;',
layout: resolvedTemplate,
container,
didRender() {
resolve(this.$().html());
this.destroy();
}
}, context)).append();
});
}
It's based on a solution proposed in this post: How to Render an HTMLBars Template to a String in Ember 2.0? where further explanation is offered.
I have extended to support passing in a template context.
Use the function like so:
// my-component.js
import Ember from 'ember';
import templateToString from './template-to-string';
export default Ember.Component.extend({
_appendMyChildTemplate() {
let myTemplateContext = ...;
templateToString(this.container, '<my-template-path>', myTemplateContext)
.then((html) => {
this.$().append(html);
});
}
})
I can't claim to fully understand this or that it is anywhere near the best solution, but it works :)
Not massively different from the function above:
import Ember from 'ember';
export default function(container, template, context) {
let resolvedTemplate =
typeof template === 'string' ? container.lookup('template:' + template) : template;
context = context || {};
Ember.assert(`Template '${template}' could not be resolved`, !!template);
return new Ember.RSVP.Promise((resolve) => {
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))
.create()
.append();
});
}
Upvotes: 4