Calling external template from a loop in meteor - meteor

From the Meteor templates tutorial here: (https://www.meteor.com/tutorials/blaze/templates)
We see that we can call a template {{> task}} inside the loop over tasks. However, when I try to get the task template in its own file - it no longer has access to the data. What is the correct way to do this?
<body>
<div class="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
</div>
</body>
<template name="task">
<li>{{text}}</li>
</template>

Figured it out. Basically, I was importing the task.html in the main.js, but not the accompanying task.js. So all the conditional helpers I had were not loaded and hence not working.

We need to pass value to the template which we are calling. And I assume tasks helper is implemented. Here I'm passing current value using 'this'.
<body>
<div class="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{{#each tasks}}
{{> task this}}
{{/each}}
</ul>
</div>
</body>
<template name="task">
<li>{{this}}</li>
</template>

Related

Creating UI comment component with blaze

I'm trying to create a comments component with Blaze but i don't know how to handle the replies.
This is the schema for the 'comment' element:
_id, authorId, message, replies (those are comment ids), isReply (boolean).
Then I created a template with html
{{#each message}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{#each replies}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{/each}}
{{/each}}
Well, how do I handle the replies of the replies? Any Idea?
You need to use the templates recursively! An example
In your case, something like the following:
{{#each message}}
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
</div>
{{#each replies}}
{{> reply}}
{{/each}}
{{/each}}
<template name="reply">
<div class="message">
<h2>{{author}}</h2>
<p>{{message</p>
<a class="button">Reply</a>
{{#each replies}}
{{> reply}}
{{/each}}
</div>
</template>
You'll need a replies helper for the reply template that gets the replies to that reply.

Access template parameter when already in an {{#each}}

I'd like to access a parameter template while I'm on a {{#each}} already. Something like:
<template name="overview">
{{> userList users=users level=0}}
</template>
<template name="userList">
{{#each users}}
<div class="level{{../something}}">
<!-- not working, how can i access {{something}} here ? -->
{{>userList users=users level=subLevel}}
{{name}}
{{/each}}
</template>
Template.userList.helpers({
subLevel: function() {
return this + 1;
}
});
but it's not working, do you have any idea ?
Technically, I'm calling recursively a template, and I'd like to know at what level my template is.
I'm not sure what you're trying to do but this doesn't look right. A template calling itself leads to an infinite loop. For example, create a new meteor project and try to call {{> hello}} inside "hello" template. It doesn't work.
<head>
<title>test</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
<template name="hello">
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
{{> hello}}
</template>
There must be another way to do what you're trying to do...
<template name="overview">
{{> userList users=users level=0}}
</template>
<template name="userList">
{{#each users}}
<div class=level>
{{>userList users=users level=subLevel}}
{{name}}
{{/each}}
</template>
Because you have enclosed level variable in double quotes that will not be evaluated.
Ok, I finally found that the best way to achieve that was to add a level key in my array of users instead of passing it with a parameter. Spacebars seems to no be able to achieve what I wanted initially.

How to do recursive templates in Meteor?

rather a theoretical question - how can I render recursive templates in Meteor? For example, displaying a comment on comment with unlimited number of comment sub-levels so that HTML would be diplayed as the following?
<section>
some text
<section>
nested text
<section>
further nested text and sections
.....
</section>
</section>
</section>
In my case I pass to the "tree" template a mongoDB document and this document can have unlimited number of sub-content levels. My example below doesn't work the way I want.
<template name="tree">
<div class="wrapper" style="border:1px solid red">
<ul>
{{#each getStructure}}
<li>
{{#each content}}
<ul>
<li>
<a class="item">{{text}}</a>
<!-- TODO: this stuff needs to be recursive.
{{#if sub_content}}
<ul>
{{#each sub_content}}
<li>
<a class="item">{{text}}</a>
{{#if sub_content}}
....
{{/if}}
</li>
{{/each}}
</ul>
{{/if}}
</li>
</ul>
{{/each}}
</li>
{{/each}}
</ul>
</div>
</template>
A simplified example of recirsuve, say you had a post sample template of:
<template name="post">
{{post_text}}
{{#each comments}}
{{>comment}}
{{/each}}
</template>
and a post helper of:
Template.post.helpers({
comments: function() {
return CommentCollection.find({post_id: this._id, parent_id: {$exists: 0}});
}
});
I would create a template for the comment layout and provide a helper in that for sub-comments, depending on your data structure something like the following:
<template name="comment">
{{comment_text}}
{{#each sub_comment}}
{{> comment}}
{{/each}}
</template>
and then the helper along the lines of:
Template.comment.helpers({
sub_comments: function() {
return CommentCollection.find({parent_id: this._id});
}
});
This would recursively produce the comments template for each sub-comment then roll back up the tree to the next #each and then print that comment and all of its sub-comments etc.

Meteor js not responding

I have been working with meteor.js and have been practicing using examples from getting started with meteor.js Javascript framework. The book is 2 years old and I have been running across some snags. For instance the book tells you to use var to define a variable, but after searching on stack I read that you didn't have to use it and now it works. I'm new so I write programs, run them, debug them and start from scratch to help me learn. For some reason this program that I have done 4 times before today is not running and I cant figure out why.
I keep getting this message :
While building the application:
LendLib.html:37: Expected "template" end tag
...  </div>
after inputting the following code:
<head>
<title>LendLib</title>
</head>
<body>
{{> hello}}
<div id="categories-container">
{{> categories}}
</div>
</body>
<template name="hello">
<h1>Lending Library</h1>{{greeting}}
<input type="button" value="Click" />
<template name="categories">
<div class="title">my stuff</div>
<div id="categories">{{#each lists}}
<div class="category">{{Category}}</div>{{/each}} </div>
</template>
</template>
any advice will be appreciated
dont define templates inside another template.
try like this.
<template name="hello">
<h1>Lending Library</h1>
{{greeting}}
<input type="button" value="Click" />
</template>
<template name="categories">
<div class="title">my stuff</div>
<div id="categories">
{{#each lists}}
<div class="category">
{{Category}}
</div>
{{/each}} 
</div>
</template>
Like pahan said, you cannot define a template within another template. They each have to be separate and un-nested. You CAN, however, call a template from within another template.
<template name="myOtherTemplate">
<h1> Lalalala </h1>
</template>
<template name="myTemplate">
{{> myOtherTemplate}} //injects the contents of myOtherTemplate
</template>
On another note, you also cannot nest Template instances within other Template instances.
Say that you want to register a helper function only after a certain template has been rendered.
Template.myTemplate.rendered = function({
Template.myTemplate.helpers({
key: "value",
anotherKey: "anotherValue"
});
});
^^ This also won't work.

Rendering a template when value in Mongo equals certain value

So I want to render a template that will hold an image when the value of the score in my Players collection equals 500, it right now doesn't render at all even when a player score equals 500, do I need an if statement in my handlebars or something else?
Relevant code I made so far
client
foo.html
<body>
<div class="container">
{{> header}}
<div class="row-fluid">
<div class="span8">
{{> leaderboard}}
</div>
<div class="span4">
{{> champion}}
</div>
</div>
</div>
</body>
<template name="champion">
{{#each winners}}
{{> winner}}
{{/each}}
</template>
<template name="winner">
<img src="gold.jpg" alt="winner">
</template>
foo.js
Template.champion.winners = function () {
return Players.find({score: 500});
};
You marked the Template code as being on the server in your question, but the code with Template.winner.winners should be on the client, not the server. This is most likely the problem. Also, you have two templates named winner, although Meteor should throw an error on the command line if you have duplicate template names.
Finally, this isn't what you asked, but it may come handy for debugging too. You can detect whether the cursor is empty in your templates using Handlebars {{else}}:
{{#each winners}}
{{> winner}}
{{else}}
no winners!
{{/each}}

Resources