iron:router's yieldTemplates not working - meteor

I'm trying to use iron:router's yieldTemplatesproperty to render multiple templates on the same layout.
According to this tutorial, we should be abble to do something like this:
template.html
<template name="complexLayout">
<div class="left">
{{> yield region="menu"}}
</div>
<div class="main">
{{> yield}}
</div>
<div class="bottom">
{{> yield region="footer"}}
</div>
</template>
route.js
this.route('home', {
path: '/',
layoutTemplate: 'complexLayout',
yieldTemplates: {
'myMenu': {to: 'menu'},
'myFooter': {to: 'footer'}
}
});
I tried to do it, but the yieldTemplates part doesn't work.
Here is the relevant code:
Router.js
Router.map(function() {
this.route('home', {
path: '/home',
controller: 'homeController'
});
});
Controllers.js
baseController = RouteController.extend({
layoutTemplate: 'baseLayout'
});
homeController = baseController.extend({
yieldTemplates: {
'homeNavTop': {to: 'top'}
}
});
Templates.html
<template name="baseLayout">
<main>
<!-- NAV TOP -->
<div id="nav-top" class="hide-on-large-only light-blue darken-3 white-text">
<div class="row nomargin valign-wrapper hide-on-large-only">
{{> yield region='top'}}
</div>
</div>
<!-- / NAV TOP -->
<!-- BODY -->
<div class="row nomargin">
<div class="col s12">
{{> yield}}
</div>
</div>
<!-- / BODY -->
</main>
</template>
<template name="homeNavTop">
<a href="#" data-activates="slide-out" class="menu button-collapse btn-flat waves-effect">
<i class="material-icons">menu</i>
</a>
</template>
As explained, the BODY part works fine. The top region remains empty.
I have no console errors at all.
Do you have any clue of what is wrong in my code?

Perhaps the syntax has changed since that tutorial was written, but according to the IronRouter guide you should be doing this:
{{> yield 'top'}}
rather than this
{{> yield region='top'}}

Related

BlazeLayout+FlowRouter+Bootstrap not rendering where told to

I've tried half a dozen different ways to do this but i'm not sure what the issue is.
To start, here is a quick drawing of what im trying to accomplish:
What I want:
http://prntscr.com/br8xh6
whats happening:
http://prntscr.com/br8z8p
What seems to be happening is that my .row .full-row is being rendered twice, and the dynamic template is not being loaded into my <div class="col-md-10> as defined. Why would this be?
Heres my current code:
<body>
<div class="container full-container">
{{> navbar}}
{{> middle}}
</div>
</body>
<template name="navbar">
...
</template>
<template name="middle">
<div class="row full-row">
<div class="col-md-2 left-bar" style="background:#800000;">
{{> Template.dynamic template=sidebar}}
</div>
<div class="col-md-10">
{{> Template.dynamic template=content}}
</div>
</div>
<!-- </div> -->
</template>
<template name="leftbar">
<div class="row">
<div class="col-md-12">
{{> avatar size="large" shape="circle"}}
</div>
</div>
</template>
<template name="usercard">
<div class="col-md-4">
<div class="thumbnail thumb-dark">
<img src="default.png" alt="...">
<div class="caption">
<h3>Player name</h3>
<p>...</p>
Join
</div>
</div>
</div>
</template>
<template name="home">
<div class="row">
{{#each playerslooking}}
{{> usercard}}
{{/each}}
</div>
</template>
<template name="find_page">
<div style="height:150px;width:150px;background:blue;">hello</div>
</template>
JS:
FlowRouter.route('/', {
action: function() {
BlazeLayout.render("middle", {sidebar: 'leftbar', content: "home"});
}
});
FlowRouter.route('/find/:_id', {
name: 'postfind.show',
action: function() {
BlazeLayout.render('middle', {sidebar: 'leftbar', content: "find_page"});
}
});
I've refactored my code several times trying to debug this, as I'm not sure how BlazeLayout is suppose to work with nested templates.
All input appreciated, thanks.
Just in case, did you have a try at Blaze Layout root modification?
See: https://github.com/kadirahq/blaze-layout#set-different-root-node

A simple meteor template and routing does not work

I am a beginner trying to get around things with meteor.
I have a program written in meteor which does not render the templates completely.
The main.html file contain the template definitions as below.
<head>
<title>simple</title>
</head>
<template name='ApplicationLayout'>
<header>
<h1>{{title}}</h1>
</header>
<aside>
{{> yield "postAside"}}
</aside>
<article>
{{> yield "main"}}
</article>
<hr />
<footer>
{{> yield "postFooter"}}
</footer>
</template>
<template name='post'>
<p>Hello!!! This is Main Post Template.</p>
</template>
<template name='postAside'>
<p>Side Menu</p>
</template>
<template name='postFooter'>
<p>This is the footer.</p>
</template>
The routes file contains the below code.
Router.route('/', function() {
this.layout('ApplicationLayout');
this.render('post', {to: 'main'});
this.render('postAside', {to: 'aside'});
this.render('postFooter', {to: 'footer'});
});
This is what renders in the browser. What you see in the browser is that only the post template is rendered and not the aside and footer templates.
View the Actual Result Page
View Expected Result Page
When I use {{#contentFor }} directive, then the result is as expected but as in above code, the result is as shown in actual result.
Can anyone help me to find what is going wrong?
Thanks for your help.
Declare the route as below:
Router.map(function () {
this.route('home', {
path: '/',
template: 'post',
layoutTemplate: 'ApplicationLayout',
yieldTemplates: {
'postAside': {to: 'aside'},
'postFooter': {to: 'footer'}
}
});
Change the html to have the below
<head>
<title>simple</title>
</head>
<template name='ApplicationLayout'>
<header>
<h1>{{title}}</h1>
</header>
<aside>
{{> yield region='aside'}}
</aside>
<article>
{{> yield "main"}}
</article>
<hr />
<footer>
{{> yield region='footer'}}
</footer>
</template>
<template name='post'>
<p>Hello!!! This is Main Post Template.</p>
</template>
<template name='postAside'>
<p>Side Menu</p>
</template>
<template name='postFooter'>
<p>This is the footer.</p>
</template>
Thanks. This works perfectly. But. I just identified the problem in my original code.
The problem is with the html file where I gave the wrong name for the regions.
The code snippet should have been like this.
<aside>
{{> yield "aside"}}
</aside>
<article>
{{> yield "main"}}
</article>
<hr />
<footer>
{{> yield "footer"}}
</footer>

Meter: embedding templates in Blaze

Using Bootstrap and Meteor / Blaze, I am trying to dynamically control the size of a template using a template helper. I'd like to have a button to switch between col-md-4 and col-md-12. The hard-coded column sizing looks like this:
<div class="panel-body">
<div class="row">
{{#each articles}}
<div class="col-md-4">
{{> article this}}
</div>
{{/each}}
</div>
I have a template helper that returns the div and found I needed a closing helper call, or Meteor could complain about an unbalanced <\div>. This seems a bit hacky.
Template.articles.helpers({
format: function() {
return '<div class="col-md-4">';
// return '<div class="col-md-12">';
},
end_format: function() {
return '</div>'
}
});
The markup is:
<div class="panel-body">
<div class="row">
{{#each articles}}
{{{format}}}
{{> article this}}
{{{end_format}}}
{{/each}}
</div>
</div>
But the div tags are returned closed and empty, with the markup I'd like enclosed underneath, as can be seen in this screen shot:
Don't return HTML from template helpers, there is usually a better way.
Why don't you return a dynamic class name from a template helper ?
HTML
<div class="panel-body">
<div class="row">
{{#each articles}}
<div class="{{columnSize}}">
{{> article this}}
</div>
{{/each}}
</div>
<button type="button" class="btn btn-primary js-toggle-column-size">Toggle column size</button>
</div>
ES2015
Template.articles.onCreated(function(){
this.largeColumns = new ReactiveVar(false);
});
Template.articles.helpers({
columnSize(){
const largeColumns = Template.instance().largeColumns.get();
return largeColumns ? 'col-md-12' : 'col-md-4';
}
});
Template.articles.events({
'click .js-toggle-column-size'(event, template){
const largeColumns = template.largeColumns.get();
template.largeColumns.set(!largeColumns);
}
});

meteor: getting error "No Iron.Layout found so you can't use yield"

just getting started with meteor
following this autoform tutorial:
http://www.webtempest.com/meteor-js-autoform-tutorial
have these simple files: main.html:
<head>
<title></title>
</head>
<body>
<div class="container">
<h1>Posts</h1>
{{> quickForm collection="Posts" id="insertPostForm" type="insert"}}
</div>
<template name="main">
<div class="container">
{{> yield}}
</div>
</template>
</body>
post.html:
<template name="post">
<h1>Edit Post</h1>
{{> quickForm collection="Posts" id="updatePostForm" type="update" doc=this}}
<a class="btn" href="/">Back</a>
</template>
posts.html:
<template name="posts">
<h1>Add Post</h1>
{{> quickForm collection="Posts" id="insertPostForm" type="insert"}}
<ul>
{{#each posts}}
<li>{{title}} - {{content}}</li>
{{/each}}
</ul>
</template>
and the router:
Router.configure({
layoutTemplate: 'main'
});
Router.route('/', 'posts');
Router.route('/posts/:_id', function () {
var item = Posts.findOne({_id: this.params._id});
this.render('post', {data: item});
}, {
name: 'post.show'
});
When I run this, I get this error:
Error: No Iron.Layout found so you can't use yield! iron_layout.js:410
What can I do to fix this, please?
What you have in your main.html is invalid. The </body> tag should not be after your layout definition. Change it to:
<head>
<title></title>
</head>
<body>
<div class="container">
<h1>Posts</h1>
{{> quickForm collection="Posts" id="insertPostForm" type="insert"}}
</div>
</body>
<template name="main">
<div class="container">
{{> yield}}
</div>
</template>

Meteor 0.80 new template displaying only [object Object] on my app

This is all I see as rendered result: [object Object]
What do I have to modify?
My files:
layout.html
<template name="layout">
<div class="container">
<div class="row">
{{yield}}
</div>
</div>
</template>
post_page.html
<template name="postPage">
<div class="sidebar col-md-4">
{{#each posts}}
{{> postItem}}
{{/each}}
<a class="save-all" href="javascript:;"><span class="glyphicon glyphicon glyphicon-save"></span></a>
</div>
<div class="mainbar col-md-12">
{{> postSubmit}}
</div>
</template>
post_page.coffee
Template.postPage.helpers posts: ->
Posts.find {},
sort:
position: 1
routes.coffee
Router.configure layoutTemplate: "layout"
Router.map ->
#route "home",
path: "/"
template: "home"
#route "postPage",
path: "/posts/:_id"
data: ->
Posts.findOne #params._id
post.coffee
#Posts = new Meteor.Collection "posts"
With 0.8 you need to do: {{> yield}} instead of {{yield}}.
Yes, as of Blaze, as describe here and here you need to change the syntax of your template slightly:
layout.html
<template name="layout">
<div class="container">
<div class="row">
{{> yield}}
</div>
</div>
</template>
Router has been deprecated. Use Iron-Router from meteorite, refer to the docs
Router.map(function() {
this.route('postslist', {path: '/'})
//read the docs for your next routing needs
});
This is a similar post to this question

Resources