Meteor: insert template between other templates and transfer data between templates - meteor

I'm using Meteor for creating web application. I have defined my layout is:
<template name="default_layout">
{{> header}}
body code here
{{> footer}}
</template>
And here is my routing file:
Router.configure({ layoutTemplate: 'default_layout'
});
Router.map(function() { this.route('post_list', {path: '/'});
});
So. I have two questions:
How to make template post_list go into body code of default_layout template ?
Base on each layout for mapping page, maybe header and footer change content respectively. So, how to contact between template? For example, post_list template will set some value for header template ...
Thanks :)

Use the {{> yield}} helper. This will insert whatever template your route is serving. So.
<template name="default_layout">
{{> header}}
{{> yield}}
{{> footer}}
</template>
If you want to change what goes into the header, you will be using "yield regions.
<template name="default_layout">
{{> yield "header"}}
{{> yield
{{> yield "footer"}}
</template>
Then, in, say, a route controll you could do this:
PostController = RouteController.extend({
yieldRegions: {
'postHeader': {to: 'header'},
'postFooter': {to: 'footer'}
}
})
Then in your post_list route, do this:
Router.route('post_list', function(){
controller: 'postController'
});
Basically, you are creating a controller that can be re-used for certain routes, and telling the controller to put a template called "postHeader" into the {{> yield "header"}} region and "postFooter" into the {{> yield "footer"}} region.

Related

Router for static site using Meteor

I'm new to Meteor and have limited experience with javascript. I've searched all the stack post and the web for a good tutorial on how to use the Iron Router package to route static pages and just can't seem to figure it this out. I would love to have someone help me understand how to setup a router.js file for Home and About. I've played with my code a lot but this is what I had before posting here. Conseptually I seem to be struggling to grasp how the routing works and all the various features of iron router and then connecting these routes into a nav bar where I can navigate between them. Thank you in advance for any help you can provide.
client/templates/application/layout.html
<template name="layout">
<div class="container">
{{> yield}}
</div>
</template>
lib/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', function () {
this.render('home', {
template: 'home'
});
this.render('about', {
template: 'about'
});
});
templates/home.html
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
The code you have above looks correct.
One quirk is you're rendering two pages for your / route. You should have this:
Router.route('/', function () {
this.render('home', {});
});
Router.route('/about', function() {
this.render('about', {});
});
Remember this.render takes the first param as the template, so there's no need to define it separately anymore.
And a new about.html page:
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
Now you can use the / and /about pages (at least I hope i've not missed anything)
You can have 3 templates on your folder
Client/Views
with the name of
about.html
main.html
admin.html
layout.html
(for example)
So in the about.html you have this
<template name="about">
<h1> hello from about page
</template>
<template name="main">
<h1> hello from about page
</template>
<template name="admin">
<h1> hello from about page
</template>
the Layout.html file need con taints this yield rendered.
<template name="layout">
{{> yield}}
{{admin}}
{{about}}
{{main}}
</template>
So you can use layout template as a master page and calling that 3 templates separates by a route, how to assign a route and telling meteor to use that layouts, well use this js code
JS
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function(){
this.route('admin', {path: '/admin'});
});
Router.map(function(){
this.route('about', {path: '/about'});
});
Router.map(function(){
this.route('main', {path: '/'});
});
At least this works for me bro, hope this work for you

How to render a dynamic layout and a static in the main content

I´m just starting with meteor coming from ember. What i have is a menu and the items get rendered into the maincontent layout. Now i would like to have a second menu in the maincontent layout.
Example: I click on people in the navigation and get a list of people. Now i click on a person and i get the details of that person. The navigation is still visible. This is what i have so working so far.
Now i would like to have another menu in the person template with items like todo, events.
Router.configure({
layoutTemplate: 'layout'
});
<template name="person">
//shows the details of that one person
</template>
<template name="events">
//shows the events of that one person
</template>
<template name="todos">
//shows the todos of that one person
</template>
<template name="personlayout">
persondetails
todos
events
</template>
The 3 links obove should always be visible as long a the person template is shown. Like when navigating to localhost:3000/person/5403789845ef834ed58ae745
So how can i render the person or todos or events template in the personlayout template?
First you need to define yield in personLayout.
<template name="personLayout">
{{yield}}
{{yield "persons"}}
{{yield "todos"}}
{{yield "events"}}
</template>
Now you can use this layout:
Using Routes
Router.route('/post/:_id', function () {
this.layout('personLayut');
// render the Post template into the "main" region
// {{> yield}}
this.render('Post');
// render the person template into the yield region named "person"
// {{> yield "persons"}}
this.render('person', {to: 'person'});
// render the todos template into the yield region named "todos"
// {{> yield "todos"}}
this.render('todos', {to: 'todos'});
});
Using contentFor
<template name="Page">
<p>
EVerything from here is going to `personLayout` {{> yield}}
</p>
{{> contentFor region="person" template="person"}}
{{> contentFor region="todos" template="todos"}}
{{> contentFor region="todos" template="events"}}
</template>
Read IronRouter docs

Meteor: nested templates and a pseudo switch conditional

I'm new with meteor and at the moment i'm testing out nested templates. More specific, i'm trying to get this pseudo switch working.
I have a PARENT template that gets data from a template.helper function where it gets the data for the {{#each}}.
This is the PARENT template
<template name="result">
{{#each Tresult}}
<div class="jow">
<h3>{{name}}</h3>
<p>{{type}}</p>
<div>{{> Tstatus}}</div>
</div>
{{/each}}
</template>
The PARENT also includes another template {{> Tstatus}}
This is the CHILD template
<template name="Tstatus">
{{#status_is "green"}}
{{> Tstatus_green}}
{{/status_is}}
{{#status_is "red"}}
{{> Tstatus__red}}
{{/status_is}}
{{#status_is "orange"}}
{{> Tstatus__orange}}
{{/status_is}}
</template>
<template name="Tstatus_green">
<span>green</span>
</template>
<template name="Tstatus_red">
<span>red</span>
</template>
<template name="Tstatus_orange">
<span>orange {{number}}</span>
</template>
This template can also include 3 other templates:
Tstatus_green
Tstatus_red
Tstatus_orange
But the problem is, how do i get this pseudo switch working. So i only need to include 1 of the 3 templates, based on it's status color.
And this is the helper function for the PARENT template
Template.result.helpers({
Tresult:function(){
return Ttable.find()
}
})
I would do something like this:
Template.Tstatus.helpers({
getStatusColor:function()
{
//"this" will be the current Ttable document
var color = getColorFunction(this)
return Template["Tstatus_"+color]
}
})
<template name="Tstatus">
{{#with getStatusColor}}
{{>.}}
{{/with}}
</template>

Meteor iron-router - Can I have multiple data sources in the route?

I have an application built with Meteor that uses Iron Router. My layout uses multiple yield templates and I'd like to pass through different data to each one.
It successfully passes through tasks to the tasksList template, but doesn't pass through selectedTask to the taskDetail template.
Is it possible to have multiple data sources and is this the right way to go about it? And if yes, then why is it not working?
Thanks in advance! :-)
Router.map(function() {
this.route('tasksList', {
path: '/',
layoutTemplate: 'layout',
template: 'tasksList',
yieldTemplates: {
'taskDetail': {to: 'rightTemplate'}
},
data: {
tasks: function(){ return Tasks.find() },
selectedTask: function() { return Tasks.findOne() }
}
});
});
<template name="layout">
<section class="wrapper">
<div class="left-pane">
{{yield}}
</div>
<div class="right-pane">
{{yield 'rightTemplate'}}
</div>
</section>
</template>
<template name="tasksList">
<ul>
{{#each tasks}}
<li>{{detail}}</li>
{{/each}}
</ul>
</template>
<template name="taskDetail">
{{#each selectedTask}}
<div>{{detail}}</div>
{{/each}}
</template>
You are returning selectedTask as a single object (with findOne), but in the taskDetail template, you use {{#each selectedTask}}{{detail}}{{/each}}. What happens if you simply have {{detail}} as the body of that template?
Sorry, both those methods work for me now. I must have had a wrong template name or something similar.
You can have multiple data sources as shown in the examples above.

How to render a Meteor Template from Collection of Template names?

I have three simple Templates in Meteor, and a Collection on the server with any combination of their names. I want to be able to render these templates dynamically based on which of their names are in the Collection.
Currently I am trying to accomplish this by using the client to subscribe to the Collection, and access the names through a template function. Unfortunately, if I try to run ">" on the names, Meteor attempts to render the variable name instead of the Template pointed to by its value.
So instead of rendering the html in template1, template2, and template3, the output is merely their names on the page: "template1 template2 template3".
Here is the code I've been using, I hope there's a way to solve my issue without having to run Meteor.render manually.
Server js:
TemplatesToRender = new Meteor.Collection("templatesToRender");
TemplatesToRender.insert({templateName: "template3"});
TemplatesToRender.insert({templateName: "template2"});
Client html:
<body>
{{#each templatesToRender}}
{{> templateName}} // meteor trying to render a template
// called "templateName" instead of the
// variable inside templateName.
{{/each}}
</body>
<template name="template1">
<span>Template 1</span>
</template>
<template name="template2">
<span>Template 2</span>
</template>
<template name="template3">
<span>Template 3</span>
</template>
You can make a render helper:
Handlebars.registerHelper('render', function(name, options) {
if (Template[name])
return new Handlebars.SafeString(Template[name]());
});
And use it with
{{render templateName}}
You might want to try this
in your html
<body>
{{> templateToRender}}
</body>
<template name="templateToRender">
{{! use below to detect which template to render}}
{{#if templateName "template1"}}
{{> template1}}
{{/if}}
{{#if templateName "template2"}}
{{> template3}}
{{/if}}
{{#if templateName "template3"}}
{{> template3}}
{{/if}}
</template
<template name="template1">
<p>this is template1</p>
</template>
<template name="template2">
<p>this is template2</p>
</template>
<template name="template3">
<p>this is template3</p>
</template>
in your script
Template.templateToRender.templateName = (which) ->
# if user have a field like templateName you can do things like
tmplName = Meteor.user().templateName
# Session.equals will cause a template render if condition is true.
Session.equals which, tmplName
Meteor 1.0 just came out today, and I just want to update this for 2014 :)
https://docs.meteor.com/#/full/template_dynamic
{{> Template.dynamic template=template [data=data] }}
Sample Usage:
{{#each kitten}}
{{> Template.dynamic template=kitten_type data=this }}
{{/each}}

Resources