Programmatically defining and using handlebars templates


#1

Does anyone know of any good examples or straightforward documentation that talks about the programatic creation of templates (and by extension components) without explicitly writing out handlebars template code and markup? In either script tags or separate handlebars file.

Perhaps a hello world or ember starter kit example that is pure javascript and does not have any HTML script tags defined.

Is this possible?


#2

Why would you want to do this? Even ApplicationView uses a string template when setting a default template for ApplicationView. It’s just “{{outlet}}”, why would you not do the same?


#3

I guess I was just curious if it was possible. Perhaps the use case is that I might want to create an array of component instances and then programmatically push them to DOM.

But mostly just curious if it was possible.


#4

Curiosity is an attribute of a great mind :slight_smile:

I’ve actually seen something similar done before. Checkout the Customer Rendering section on Evil Trout’s blog post about Custom Views.


#5

Try looking here:

https://github.com/emberjs/ember.js/blob/master/packages/ember-handlebars/lib/controls/select.js#L21

You can override template or defaultTemplate to possibly achieve what you’re trying to do, if you reaaaally need/want to do it (though it seems unnecessary).

You could feasibly do something like

  defaultTemplate: function(context, options) {
    options = { data: options.data, hash: {} };
    Ember.Handlebars.helpers.view.call(context, SomeViewOrComponentClass, options);
    Ember.Handlebars.helpers.view.call(context, SomeViewOrComponentClass, options);
    Ember.Handlebars.helpers.view.call(context, SomeViewOrComponentClass, options);
    Ember.Handlebars.helpers.view.call(context, SomeViewOrComponentClass, options);
    Ember.Handlebars.helpers.view.call(context, SomeViewOrComponentClass, options);
  },

I haven’t actually tried this out but should probably work without too much crazy hacking.


#6

Thanks @tarasm and @machty for the links and info. I think I just learn best when I try to understand it from the inside out. Trying to get to the point where I have to refer to the documentation less, because I just know how the underlying code actually works.

And @machty perfect! I didn’t think to go look at how the built in views like select are implemented. Good info there. And helps me understand handlebars a little better too!


#7

I’m the same way. Sorry if I came across sarcastic, I didn’t mean it that way.


#8

No not at all. It is all good. Didn’t take anything personal. And by the way great work on the EmberSherpa. I like where that is going.


#9

Thanks :slight_smile: I’m working on CRUD without Ember Data Part 2 right now.


#10

That is a worthy topic. It seems there is still not a lot of info around creating, modifying and committing data and models. Look forward to it.

If you find time, also might be useful to briefly touch about the backend side of that. Basically what should happen when you push data over the wire via PUT and when manipulating with DELETE.


#11

If all permits, I’ll go down the stack and probably into PHP and Node.js side of things because Rails is well covered by EVERYone else :slight_smile:


#12

Makes sense. On php are you going to use Symfony? Or vanilla PHP? There is also Yii, which might be of interest.


#13

I actually haven’t written anything in Symphony or Yii before. I’d love to get a contribution from someone who has.

I haven’t actually seen a good implementation of an API server for PHP. If you know of one, I’d like to look at it.

Rolling one from scratch is not difficult, but I wouldn’t encourage anyone to do it. I’m still unsure about how to handle those scenarios.


#14

I haven’t done Symfony work since the 1.0 days. But my impression was that it was very rails like. You have a CLI, some generators, actions, ORM (propel, doctrine) and a general MVC architecture. I think Symfony has evolved a bit but haven’t kept up with the 2.0 stuff.

This might have some promise.

If you do get started on this and have any specific questions ping me, I might be able to answer a few things.


#15

On second thought, I don’t think that people who use Symfony would need help setting up APIs, or at least not the majority of them. Without solid statistics, its difficult to tell but my sense is that there are more people who’re coming from other frameworks than Symfony.

But I really don’t know. I’ll think about it some more when I get to it. I’ll keep you posted.


#16

Makes sense. Probably best to just focus on a ember example that does all the CRUD stuff. And then theoretically it could talk to any specific backend implementation. It would be cool if people could run with your example and build discrete backends to support the CRUD defined in your example.

In my mind a Create and Delete operation are not truly complete until something happens at the persistence DB layer. So what happens on the server matters. That is all I meant by touching on the topic of backends.

Obviously local storage is one case where server is not necessarily involved.


#17

I’m working it downwards. First, I want to get to a point where its clear how persistence in browser happens. From there, I’ll work down to interacting with the backends and covering different kinds of backend implementations.


#18

I like this idea. I haven’t thought out it, but I think you’re right.


#19

I tried what @machty proposed because I needed something similar. Unfortunately it works only with a single view. As soon as you instantiate more than one like this, you end up with:

Uncaught TypeError: Cannot read property 'templateData' of undefined 

#20

Inside of a view or component:

var viewClass = Ember.View.extend({ templateName: "path/to/template" });
var view = this.createChildView(viewClass);
var html = view.renderToBuffer().buffer;
```

### UPDATE:

This code works slightly better:

var viewClass = Ember.View.extend({ templateName: this.get(‘contentTemplate’) }); var view = this.createChildView(viewClass); var html = view.renderToBuffer().buffer; view.removeFromParent();