yield with region in Meteor.js - meteor

In my meteor.js application, some pages have side menu, some pages do not have. This is my layout.html
<template name="layout">
<div class="container">
{{> header}}
<div id="main" class="col-md-3">
{{> yield region="sidenavigation"}}
</div>
<div id="main" class="col-md-9">
{{> yield}}
</div>
</div>
</template>
Let's say I have x template which has side menu, and y template which does not have side menu. When I render x template, everything is good. But when I render y template, because it does not have side menu, the content is pushed to the right expectedly. How can I solve this? Thank you.

Use {{#contentFor region=''}} in the template or page that you want to show the side menu in
eg.
<template name="yourtemplatename">
{{#contentFor region="sidenavigation"}}
..
...
....
{{/contentFor}}
</template>
example https://github.com/EventedMind/meteor-building-an-application-with-meteor-and-iron-router

Related

If/Else logic in Blaze causing authenticated user page flickers when navigating between pages in Meteor

I have this main layout
<!-- Wrapper-->
<div id="wrapper">
{{#if currentUser }}
<!-- Page wrapper -->
{{> topNavbar }}
<!-- Navigation -->
{{> navigation }}
<!-- Page wraper -->
<div id="page-wrapper" class="gray-bg">
<!-- Main view -->
{{> yield}}
</div>
<!-- End page wrapper-->
<!--{{> rightSidebar }}-->
{{else}}
{{> loginPage }}
{{/if}}
</div>
<!-- End wrapper-->
With the obvious purpose of displaying the login page if users are not logged-in. An unintended effect is when users navigate between certain pages/routes it can occasionally show the loginpage for a half second or two.
I am sure there is a way to do this with subscriptions, but just haven't gotten their in Meteor yet... was wondering if one of the ninjas out there that will look at this and scoff can pass a quick hint.
Thanks!
I have seen How to get rid of Meteor template flickers but I am hoping that there is a way to solve this without routing -- can I add the code to the main templates javascript file?
The problem is, there are not two states of logged in and not. There is also the in between state where the client is logging in. To account for that, there is a {{loggingIn}} helper which you could use as:
<!-- Wrapper-->
<div id="wrapper">
{{#if currentUser }}
<!-- Page wrapper -->
{{> topNavbar }}
<!-- Navigation -->
{{> navigation }}
<!-- Page wraper -->
<div id="page-wrapper" class="gray-bg">
<!-- Main view -->
{{> yield}}
</div>
<!-- End page wrapper-->
<!--{{> rightSidebar }}-->
{{else}}
{{#if loggingIn}}
loading...
{{else}}
{{> loginPage }}
{{/if}}
{{/if}}
</div>
<!-- End wrapper-->
Also on an unrelated note, you can use
{{!-- Spacebars comments do not get into the DOM --}}
instead of
<!-- This still gets into the DOM, but not rendered by the browser -->

how to render several templates in the same place several times?

I have several templates:
<template name='mamals'>
<div id={{id}} class="mamals-container">
{{> UI.contentBlock}}
</div>
</template>
<template name='dog'>
{{#mamals}}
<div class="dog">
<p>I'm a dog</p>
</div>
{{#mamals}}
</template>
<template name='cat'>
{{#mamals}}
<div class="cat">
<p>I'm a cat</p>
</div>
{{#mamals}}
</template>
<template name='pig'>
{{#mamals}}
<div class="pig">
<p>I'm a pig</p>
</div>
{{#mamals}}
</template>
so in the main page I have a where user can drag and drop as many animal as they want into the farm. What I need to accomplish is every time a user drag an animal I would like to render that template and add it to farm (NO replacing, just add it). How may I implement this???
thanks in advance!
with Blaze you can render any template dynamically using JS http://docs.meteor.com/#/full/blaze_render

How to write Iron-router nested template?

I have 2 templates:
1) mainLayout.html -> general layout which must be used by all pages. (e.g. page title, navbar, footer)
Router.configure({
layoutTemplate: 'mainLayout'
})
<template name="mainLayout">
{{> header}}
<div class="container-fluid">
{{> yield}}
</div>
</template>
2) specialLayout.html -> custom layout which is inheriting main-layout.html but with additional template (e.g. side/tab menu)
How should I define specialLayout? Note that specialLayout should have the title, navbar, and footer defined in mainLayout.
If I have route X which want to use specialLayout, how should I write it?
I don't know any simple method at this moment, but most things can be achieved by several less elegant ways:
Copy your common parts into separate templates and use them in both layouts, i.e.:
<template name="mainLayout">
{{> navbar}}
<div>
{{> content}}
</div>
{{> footer}}
</template>
<template name="specialLayout">
{{> navbar}}
<div>
{{> content}}
{{> sidebar}}
</div>
{{> footer}}
</template>
Make your special part an option in the main layout instead of a separate one:
<template name="mainLayout">
...
<div>
{{#if layout.renderSidebar}}
<div class="col-2">>
{{> yield 'sidebar'}}
</div>
{{/if}}
<div class="{{#if layout.renderSidebar}} col-10 {{else}} col-12 {{/if}}">
{{> yield}}
</div>
</div>
...
</template>
Then in the appropriate routes enable sidebar in the data:
this.map('pathName', {
...
data: function() {
return {
layout: {renderSidebar: true},
...
};
},
});

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