How to find current template in meteor? - meteor

Is there any function to find current templates?
<template name="Login">
<h1>{{template}}</h1> //Should display Login
</template>
or
<template name="Login">
<h1>{{showtemplate}}</h1>
</template>
Helperjs:
showtemplate: function(){
return Template;
}

If you want the name of the template, you can get it like this:
showtemplate: function(){
return Template.instance().view.name;
}
This will return the string "Template.yourTemplateName"

Related

Meteor stopped running template `rendered` functions

Im trying to run some jquery code after the template renders. But it's not working. When I run the code in the console manually, it works. Here's the js :
Template.PanelLayout.helpers({
restricted: function() {
return !Meteor.user();
},
authInProcess: function() {
return Meteor.loggingIn();
},
canShow: function() {
return !!Meteor.user();
}
});
Template.PanelLayout.rendered = function() {
$(document).ready(function() { // This is the code I want to run
$(".button-collapse").sideNav();
$('.collapsible').collapsible();
});
}
Template code :
<template name="PanelLayout">
{{#if restricted}}
{{> NotFound}}
{{else}}
{{#if authInProcess}}
{{> spinner}}
{{else}}
{{#if canShow}}
<header>
{{> PanelMainNav}}
</header>
<main id="panel-content">
{{> Template.dynamic template=content }}
</main>
{{/if}}
{{/if}}
{{/if}}
</template>
Im not sure but I think it's because I have added the if else statements to load the content only when the user is logged in? How can I fix this?
Probably it's because rendered function is called after document is ready, therefore your hook document.ready won't work, you should remove it, so it will look like this(also rendered function is deprecated, use onRendered instead):
Template.PanelLayout.onRendered(function() {
$(".button-collapse").sideNav();
$('.collapsible').collapsible();
});

pass the current path as argument in a meteor template

How can I pass the current path in a meteor template as in
{{> sometemplate somearg="{{currentpath}}" }}
Where current path is basically what would be returned by window.location.pathname
You can use a simple helper for this:
Template.parentTemplate.helpers({
currentPath: function() {
return window.location.pathname;
}
});
And call it in your template using:
<template name="parentTemplate>
{{!-- ... --}}
{{> sometemplate somearg=currentPath }}
</template>

Rendering Template in Meteor and Iron Router depending on value in document

I am trying to render a template depending on a value of a field in a document.
I tried using a switch case in a helper but the return value comes out incorrect.
units_list.html
<template name="unitsList">
{{#each units}}
{{> unitItem}}
{{/each}}
</template>
units_list.js
Template.unitsList.helpers({
units: function() {
return Units.find({}, {sort: {name: 1}});
}
});
unit_item.html
<template name="unitItem">
{{name}}
</template>
unit_item.js
Template.unitItem.helpers({
unitType: function() {
var unitType = this.unitType;
switch(unitType){
case 'first': return "{{pathFor 'unitPageFirst'}}";
case 'second': return "{{pathFor 'unitPageSecond'}}";
}
}
});
I'm either going about this the wrong way or missing something elementary...
I've cut out a lot of code to focus on the problem.
Any ideas on how to get this working, or any suggestions on how to do it better?
You can't return uncompiled Spacebars strings from JS at execution time.
You can either use Router.path to get the path for your routes within your template helper :
Template.unitItem.helpers({
unitType: function() {
var unitType = this.unitType;
switch(unitType){
case 'first':
return Router.path('unitPageFirst', this);
case 'second':
return Router.path('unitPageSecond', this);
}
}
});
Or you can use plain Spacebars by declaring template helpers to check against the unitType.
HTML
<template name="unitItem">
{{#if unitTypeIs 'unitTypeFirst'}}
{{name}}
{{/if}}
{{#if unitTypeIs 'unitTypeSecond'}}
{{name}}
{{/if}}
</template>
JS
Template.unitItem.helpers({
unitTypeIs: function(unitType){
return this.unitType == unitType;
}
});
Have a look at Rendering Templates in the Iron-router guide, specifically the this.render('xyz'); statement
https://github.com/iron-meteor/iron-router/blob/devel/Guide.md#rendering-templates

Iron Router / Meteor - Post details with username in URL

I'm relatively new to Meteor (especially Iron Router), and have been stuck on the following issue...
I have a route which displays details about a single post:
this.route('singlePost',{
path:'/posts/:_id',
data:function(){
return Posts.findOne(this.params._id);
}
});
This works fine, but I'd like to be able to show the post owner's username in the URL, rather than the static "/posts/" path, ex:
this.route('singlePost',{
path:'/:username/:_id',
data:function(){
return Posts.findOne(this.params._id);
}
});
The post object includes the user Id of the owner, but not the username (username is in the Meteor.users collection).
When I try to set the route with 2 dynamic values (username, post Id), the pathFor link disappears (I assume because it cannot find "username" in the post object that is returned).
How can I get the route to recognize the username? I assume some lookup function to the Users collection but I'm not sure when/where. Also, how would I be able to validate the route to make sure the post is owned by the correct username?
Edit - here is the code:
router.js
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
waitOn:function(){
return Meteor.subscribe('posts') && Meteor.subscribe('users');
}
});
Router.map(function() {
this.route('home', {
path: '/',
data:function(){
Session.set('pageView','list');
return Posts.find();
}
});
this.route('singlePost',{
path:'/:username/:_id',
data:function(){
Session.set('pageView','single');
return Posts.findOne(this.params._id);
}
});
});
Router.onBeforeAction('loading');
home.html
<template name="home">
{{> postsList}}
</template>
posts_list.html
<template name="postsList">
<ul>
{{#each posts}}
{{> postBlock}}
{{/each}}
</ul>
</template>
single_post.html
<template name="singlePost">
{{> postBlock}}
</template>
post_block.html
<template name="postBlock">
{{#if pageView "list"}}
<li>
{{title}}<br/>
Author: {{username}}
</li>
{{/if}}
{{#if pageView "single"}}
<h1>{{title}}</h1>
<p>{{description}}</p>
<p>Author: {{username}}</p>
{{/if}}
</template>
post_block.js
Template.postBlock.helpers({
username:function(){
var user = getUserInfo(this.owner);
return user.username;
},
pageView:function(type){
return Session.get('pageView') == type;
}
});
functions.js
getUserInfo = function(id){
return Meteor.users.findOne(id);
}
The username outputs correctly on both the list and the details views, however I cannot get the pathFor link to include the username.
Looking at your template, you appear to be not passing username or id in {{pathFor 'singlePost'}}.
It should be {{pathFor 'singlePost' username=username _id=yourId}}
Your route should work then.

Can Meteor child templates access parent template helpers?

Say we have a parent template and a child template:
<template name="parent">
{{> child }}
</template>
<template name="child">
{{#if show}}
//Do something
{{/if}}
</template>
If we assign 'show' to the parent template:
if (Meteor.isClient){
Template.parent.show = function(){
return Session.get('isShowing');
}
}
Is there any way for the child template to have access to it?
Edit
You could make a universal handlebars helper so you could use Sessions values anywhere in your html:
Client js
Handlebars.registerHelper('session', function(key) {
return Session.get(key);
});
Client HTML
<template name="child">
{{#if session "show"}}
//Do something
{{/if}}
</template>
Similarly, you could also use {{session "show"}} / {{#if session "show"}} in your parent template and not have to use the Template.parent.show helper anymore.
Regarding the use of ../ notation. There are certain scenarios it may not work: https://github.com/meteor/meteor/issues/563. Basically it works within {{#block helpers}} but not with templates, but it would work in a block helper if it contains a subtemplate.
<template name="child">
{{#if ../show}}
Do something
{{/if}}
</template>
You can also register a common helper :
Template.registerHelper('isTrue', function(boolean) {
return boolean == "true";
});
And call it just like that in your html:
<input type="checkbox" checked="{{isTrue attr}}"/>

Resources