I'm using template-level subscriptions, but I have some problems to use the results in a child template:
As I'm loading the template example, the template exampleChild will be displayed (just take this as an basic example - I know this doesn't make sense right now).
On creating the main template, the subscription is done and the data gets stored in a helper:
Template
<template name="example">
{{> Template.dynamic template=switch}}
</template>
<template name="exampleChild">
<h1>{{result}}</h1>
</template>
Helper
Template.example.helpers({
switch: function() { return 'exampleChild'; },
result: function() { return Template.instance().result(); },
});
Event
Template.example.onCreated(function() {
var instance = this;
instance.autorun(function () {
var subscription = instance.subscribe('posts');
});
instance.result = function() {
return Collection.findOne({ _id: Session.get('id') });
}
});
If I would put the {{result}} in the example-Template, everything is working. But I need to use the variable in the child template.
Did you try:
<template name="example">
{{#with result}}
{{> Template.dynamic template=switch}}
{{/with}}
</template>
<template name="exampleChild">
<h1>{{this}}</h1>
</template>
With doc
When doing that, I prefer wrap the data context result into an object, to have something proper on the child like:
Template.example.helpers({
switch: function() { return 'exampleChild'; },
data: function() { return {result: Template.instance().result()} },
});
<template name="example">
{{#with data}}
{{> Template.dynamic template=switch}}
{{/with}}
</template>
<template name="exampleChild">
<h1>{{result}}</h1>
</template>
Hope it's help
You could store the result in a session variable, and then add another helper to exampleChild that waits for the session variable.
Related
I saved some HTML-content in my collection. By using IronRouter data() will be used to set the cursor/array. In this example I just show an example array.
Now the HTML-content isn't shown correctly, as it doesn't get parsed. The user would see the HTML-tags. What do I have to do to get the content displayed correctly?
IronRouter
Router.route('/article/:_id', {
name: 'article',
data: function () {
var articles = [{ title: 'title', content: '<strong>content</strong>'}];
return { articles: articles };
}
});
template
<template name="article">
{{#each articles}}
<h1>{{title}}</h1>
<section>{{content}}</section>
{{/each}}
</template>
Use Handlebars triple-stash:
<template name="article">
{{#each articles}}
<h1>{{title}}</h1>
<section>{{{description}}}</section>
{{/each}}
</template>
I am having problems with rendering templates using the data from the helper.
Template.bonus.helpers({
Userform: function(){
return UserForms.find({owner:Meteor.userId()});
},
warehouse: function(){
return Warehouse.find({});
},
DisplayForm: [
{ formname: "SW - Picking" },
{ formname: "SW - Packing" },
{ formname: "SW - Putaway" }
]
});
Basically I just want to achieve something like this:
<div id="placeholder" class="col-md-8">
{{#each DisplayForm}}
{{> {{formname}} }} //Render 3 templates "SW - Picking","SW - ....
{{/each}}
</div>
I am sure it is fairly easy but I just need the correct syntax so I can use data from helper as a name of a template to be rendered.
You can include a template dynamically in Meteor by using {{> Template.dynamic template=template [data=data] }}.
For example:
<body>
{{> bonus}}
</body>
<template name="bonus">
{{#each displayForm}}
{{> Template.dynamic template=formname }}
<br />
{{/each}}
</template>
<template name="picking">
Picking Template
</template>
<template name="packing">
Packing Template
</template>
<template name="putaway">
Putaway Template
</template>
if (Meteor.isClient) {
Template.bonus.helpers({
displayForm: [{
formname: "picking"
}, {
formname: "packing"
}, {
formname: "putaway"
}]
});
}
Here is a MeteorPad.
I need to check in a child template the value of a reactive dict variable, which was created in the parent template.
<template name="parent">
{{ > child }}
</template>
<template name="child">
{{#if something}}
checked
{{/if}}
</template>
This is how I initialize a reactive dict variable to the parent template:
Template.parent.onCreated(function() {
this.blabla = new ReactiveDict();
});
So for the parent template this helper is working:
Template.parent.helpers({
anything: function(type) { return (Template.instance().blabla.get('foo') === 'bar') ? true : false; }
});
But it won't work for the child:
Template.child.helpers({
something: function() { return (Template.instance().blabla.get('foo') === 'bar') ? true : false; }
});
So how can I check the value of the variable in the child helper?
At its core, this question is about how to find a template's parent instance. I'd recommend reading all of the answers here.
I'll build on the idea presented by Sacha, with this example:
html
<template name="parent">
{{ > child parentHelper=parentHelper}}
</template>
<template name="child">
{{#if parentHelper}}
<h1>pass</h1>
{{else}}
<h1>fail</h1>
{{/if}}
</template>
js
Template.parent.onCreated(function() {
this.dict = new ReactiveDict();
this.dict.set('foo', 'bar');
});
Template.parent.helpers({
parentHelper: function() {
return Template.instance().dict.equals('foo', 'bar');
}
});
If that exact pattern doesn't work in your code, you can try one of the others from the linked question above.
The end result of all of what I am about to go over is the subheader is not rendering on screen like i want it to.
Currently there is a mongo collection subheader with a category field and a texth field.
Subheader = new Mongo.Collection('subheader');
Meteor.methods({
subheaderInsert: function(subheaderIdAttributes) {
check(String);
check(subheaderIdAttributes, {
texth: String,
category: String
});
var subheaderId = _.extend(postAttributes, {
submitted: new Date()
});
var subheaderId = SubheaderId.insert(subheader);
return {
_id: subheaderId
};
}
});
There is a route that subscribes to the subheader and other page data.
Router.route('/', {
name: 'home',
controller: MissionstatementpostController,
waitOn:function () {
return Meteor.subscribe('subheader', 'home');
}
});
The publish function appears to work fine.
Meteor.publish('subheader', function(cat) {
return Subheader.find({category: cat});
});
The correct doc from the mongodb collection is reaching the client. this can be seen by
Subheader.findOne(); output Object {_id: "NPo5cwqgjYY6i9rtx", texth: "ex text", category: "home"}
The problem starts here
The template loaded by the Controller in this case MissionstatementpostController is postlist
<template name="postsList">
<div class="posts page">
{{> subheader}}
<div class="wrapper">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{else}}
{{#unless ready}}
{{> spinner}}
{{/unless}}
{{/if}}
</div>
</template>
Here is the subheader template
<template name="subheader">
<div class="container">
<p>{{{texth}}}</p>
</div>
</template>
So what did I mess-up?
thanks
you must create a template helper for your subheader template. To return just the texth field, the helper will be like this.
Template.subheader.helpers({
texth: function() {
var sh = Subheader.findOne();
return sh && sh.texth;
}
});
You can return the whole document and use the #with helper inside the template.
Template.subheader.helpers({
subh: function() {
return Subheader.findOne();
}
});
<template name="subheader">
{{#with subh}}
<div class="container">
<p>{{{texth}}}</p>
</div>
{{/with}}
</template>
You can find more info about template helpers on Meteor Docs.
Let's say I have a Posts collection, the data for which looks like this:
var post1 = {
title: "First post",
post: "Post content",
comments: [<comment id>, <another comment id>, <etc>]
};
And I have a corresponding Comments collection. I've published and subscribed to both collections and want to display a post with it's comments.
How do I go about displaying the comments for that specific post?
<template name="post">
<h1>{{title}}</h1>
<p>{{post}}</p>
{{#each comments}}
// Only have access to the ID
{{/each}}
</template>
I could create a helper like this:
Template.post.helpers({
displayComment: function(id) {
return Comments.findOne(id).fetch().comment;
}
});
and do:
<template name="post">
<h1>{{title}}</h1>
<p>{{post}}</p>
{{#each comments}}
{{displayComment #index}}
{{/each}}
</template>
But then I'd have to create a helper for each of the comment object's properties, etc.
What's the clean way to do it? I don't want to populate the comments field on the post object, since that would mean calling .fetch(), and posts would no longer be reactive.
A couple of suggestions:
<template name="post">
<h1>{{title}}</h1>
<p>{{post}}</p>
{{#each comments}}
{{#with commentDetails}}
{{userName}} //
{{content}} // These are properties of a comment document
{{upvotes}} //
{{/with}}
{{/each}}
</template>
Template.post.helpers({
commentDetails: function() {
return Comments.findOne(this);
}
});
That will set the data context within each with block to be the comment object returned by looking up the current _id (which is the value of this in the commentDetails helper within the each block).
An alternative would be to just use an each block on its own, but have it iterate over a cursor:
<template name="post">
<h1>{{title}}</h1>
<p>{{post}}</p>
{{#each commentCursor}}
{{content}}
... // other properties
{{/each}}
</template>
Template.post.helpers({
commentCursor: function() {
return Comments.find({_id: {$in: this.comments}});
}
});