I want to give my users the possibility to create document templates (contracts, emails, etc.)
The best option I figured out would be to store these document templates in mongo (maybe I'm wrong...)
I've been searching for a couple of hours now but I can't figure out how to render these document template with their data context.
Example:
Template stored in Mongo: "Dear {{firstname}}"
data context: {firstname: "Tom"}
On Tom's website, He should read: "Dear Tom"
How can I do this?
EDIT
After some researches, I discovered a package called spacebars-compiler that brings the option to compile to the client:
meteor add spacebars-compiler
I then tried something like this:
Template.doctypesList.rendered = ->
content = "<div>" + this.data.content + "</div>"
template = Spacebars.compile content
rendered = UI.dynamic(template,{name:"nicolas"})
UI.insert(rendered, $(this).closest(".widget-body"))
but it doesn't work.
the template gets compiled but then, I don't know how to interpret it with its data context and to send it back to the web page.
EDIT 2
I'm getting closer thanks to Tom.
This is what I did:
Template.doctypesList.rendered = ->
content = this.data.content
console.log content
templateName = "template_#{this.data._id}"
Template.__define__(templateName, () -> content)
rendered = UI.renderWithData(eval("Template.#{templateName}"),{name:"nicolas"})
UI.insert(rendered, $("#content_" + this.data._id).get(0))
This works excepted the fact that the name is not injected into the template. UI.renderWithData renders the template but without the data context...
Use UI.dynamic: https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
It is fairly new and didn't make its way to docs for some reason.
The thing your are missing is the call to (undocumented!)
Template.__define__
which requires the template name (pick something unique and clever) as the first argument and the render function which you get from your space bars compiler. When it is done you can use{{> UI.dynamic}}
as @Slava suggested.There is also another way to do it, by using
UI.Component
API, but I guess it's pretty unstable at the moment, so maybe I will skip this, at least for now.There are few ways to achieve what you want, but I would do it like this:
You're probably already using underscore.js, if not Meteor has core package for it.
You could use underscore templates (http://underscorejs.org/#template) like this:
var templateString = 'Dear <%= firstname %>'
and later compile it using
_.template(templateString, {firstname: "Tom"})
to get
Dear Tom
.Of course you can store
templateString
in MongoDB in the meantime.You can set delimiters to whatever you want,
<%= %>
is just the default.Compiled template is essentially htmljs notation Meteor uses (or so I suppose) and it uses
Template.template_name.lookup
to render correct data. Check in console ifTemplate.template_name.lookup("data_helper")()
returns the correct data.I recently had to solve this exact (or similar) problem of compiling templates client side. You need to make sure the order of things is like this:
Template.template_name.lookup("data_name")()
)To compile the template, as @apendua have suggested, use (this is how I use it and it works for me)
After this you need to make sure the data you want to render in template is available before you actually render the template on page. This is what I use for rendering template on page:
Although my use case for rendering templates client side is somewhat different (my task was to live update the changed template overriding meteor's hot code push), but this worked best among different methods of rendering the template.
You can check my very early stage package which does this here: https://github.com/channikhabra/meteor-live-update/blob/master/js/live-update.js
I am fairly new to real-world programming so my code might be ugly, but may be it'll give you some pointers to solve your problem. (If you find me doing something stupid in there, or see something which is better done some other way, please feel free to drop a comment. That's the only way I get feedback for improvement as I am new and essentially code alone sitting in my dark corner).