How to render a template to a string

When looking up a template, e.g:

var template = this.container.lookup('template:greeting');

You can’t do anything useful with it, like render to a string.

It would make sense to be able to do: template({msg: 'hi'});

Because then the precompiled templates could be used with other libraries that utilise templating, for example Typeahead.js

(I’ve looked everywhere for a solution, including all the tests in github - but these all pass the template into a view, insert it into the DOM and then read the html which seems a waste of effort)

var el = document.createElement('div'); 
Ember.View.create({
  context: { msg: 'hi' },
  template: this.container.lookup('template:greeting') 
}).appendTo(el);
// el.innerHTML

Probably not along the lines of an acceptable answer, but hopefully unblocks you in whatever you’re trying to achieve.

@jasonmit’s will definitely work, but if you do not want to render to the DOM, you can render to a Ember.RenderBuffer instance instead.

See:

function templateToString(template) {
  var View = Ember.View.create({ template: template });
  var buffer = new Ember.RenderBuffer();

  view.render(buffer)

  return buffer.string();
}
1 Like

@rwjblue Thank you for your solution, although it’s still a bit convoluted.

IMO you shouldn’t have to instantiate a View just to get the template to render to a string.

@amk - It is absolutely possible to do manually. Please research and let us know the solution (my guess is that it will be much more convoluted).

  • Oh yes it’s possible under the hood - you have to collate some variables and pass them in, but even then the result is pushed to a buffer rather than returning a value.
  • You also can’t create a view on its own like your suggestion, due to this. Which means you have to create an empty and unnecessary view file as well in order for the lookup to work.
  • From your example, I get “You can’t use appendChild outside of the rendering process” or " Container was not found" depending on how I instantiate the view.

    view = @createChildView Ember.View.extend
      controller: Ember.Controller.create name: 'Fred'
      templateName: 'greeting'

    buffer = new Ember.RenderBuffer

    view.render buffer

    buffer.string() # ---> "Hello "

This appears to not work in 1.8.0.beta.1.

ok thanks. I thought I was going mad. Issue created.

@rwjblue I was doing something similar in 1.4, but now we’re moving to 1.9 and that seems to be broken. Any insight on this?

cc: @erik_bryn

Seems like this comment will help: https://github.com/emberjs/ember.js/issues/5534#issuecomment-60527838

I’ll try it later.

@amk That’s actually the topic of our 'Today I Learned" blog post, take a look at our solution at Rendering Templates To Strings In Ember.js. Was it helpful?

Hey, anyone knows how to do this with Ember 2.0?

I am sure there’s a better way, but I’ve just got this working in Ember 2.4: ST answer to ‘Render ember.js .hbs template to a string’

What do people recommend now that we are in a Ember 3x world?

There is GitHub - m-basov/ember-render-to-string: 📎 Render Ember Template to string. add-on, but wondering if there is a more up-to-date solution.