meteor template: parse html content - javascript

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>

Related

Meteor: Using variable in child template

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.

How to use an array to render dynamically multiple templates in Meteor?

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.

Meteor: How to make two views - listing and article

What would be the best way in meteor for creating a template for using two different views? Let's call the template 'article' and by default there should be a list of all articles with an input field to create/add new elements. When selecting an article, the selected one should be displayed.
So right now what I am trying is this:
package.js:
Package.onUse(function(api){
api.versionsFrom("METEOR#1.1.0.3");
api.addFiles([
'lib/client/templates/article.html',
], ['client']);
});
router.js:
Router.route('/article/:_id?', {
name: 'article'
})
templates/article.html:
<template name="article">
<form><input name="createNewArticle" type="text"></form>
<ul><li>List of articles</li></ul>
</template>
<template name="article_detail">
<p>Content of article</p>
</template>
If you wish to redirect to a new page, make sure you have two separate routes (one for the list of all articles and another for the the single article or article detail)
lib/router.js
Router.route('/articles', {
name: 'articles',
waitOn: function () {
return [
Meteor.subscribe('articles'),
];
},
data: function() {
return {
articles: Articles.find({})
}
}
});
Router.route('/article/:_id', {
name: 'article',
template: 'article',
waitOn: function () {
return [
Meteor.subscribe('article', this.params._id),
];
},
data: function () {
return {
article: Articles.findOne({
_id: this.params._id
})
};
}
});
client/templates/article.html:
<template name="articles">
<form><input name="createNewArticle" type="text"></form>
<ul>
{{#each articles}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
<template name="article">
<p>{{title}}</p>
</template>
Make sure you setup your publications too in server/publications.js

How render a route relevant subheader with meteor blaze?

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.

How to access another collection by ID in Meteor template?

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}});
}
});

Categories