As the title says, this.render does not render a template it's provided with. This is the code in router.js:
Router.configure({
layoutTemplate: 'main'
});
Router.route('/', function(){
this.render('postsList');
});
The file containing the layout template, main.html:
<template name='main'>
<div class='container'>
<header class='navbar'>
<div class='navbar-inner'>
<a class='brand' href='/'>MyApp</a>
</div>
</header>
<div id='main' class='row-fluid'>
{{> yield}}
</div>
</div>
</template>
And the file containing the postsList template which is passed to this.render() function
<template name='postsList'>
<div class='posts'>
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
So when I go to localhost:3000/ the page displays only the main template and not the postsList template. However, there is no error, unless I completely remove Router.route(...), at which point it will display the standard 'route not found' error.
Also, I tried not using the global template, but a route template, by removing Router.configure(...) and adding this.layout('main') to Router.route(...). The browser then displays nothing.
Your code is perfectly fine. I also came across this issue. The iron:router package seems to be missing the ejson dependancy.
Add the ejson to your app and it should work.
meteor add ejson
I'm sure when iron:router is updated this will be resolved.
Related
I'm trying to implement my own login buttons on meteor via:
<template name="login">
<div id="login-buttons">
{{#if currentUser}}
Hello, {{currentUser.profile.name}}
<button id='logout-button' class='small'>Sign Out</button>
{{else}}
<div class="service-login-buttons">
{{#each services}}
{{> _loginButtonsLoggedOutSingleLoginButton}}
{{/each}}
</div>
{{/if}}
</div>
</template>
main.js:
Template.login.helpers({
services: function() {
return getLoginServices();
}
})
Problem is, getLoginServices() doesn't seem to work, I also tried Accounts._loginButtons.getLoginServices() , doesn't exist either.
Any ideas (accounts-ui version 1.15 if it helps) ?
I just worked on the same issue and was able to get the login buttons working.
I performed this with the packages accounts-password 1.1.1 and ian:accounts-ui-bootstrap-3 1.2.71 installed.
My HTML looks similar to yours, but note that difference in the template that I'm calling. I browsed through the Accounts._loginButtons object and looked through the meteor github to find a template I wanted to use Meteor Github re: login buttons
<template name = "intro">
<div class = "container-fluid black">
<div class="service-login-buttons">
{{#each service}}
{{> _loginButtonsLoggedOutAllServices}}
{{/each}}
</div>
</div>
</template>
For my meteor version I found that Accounts._loginButtons.getLoginServices() worked for returning the login services available. If this doesn't work can you take a look at the Accounts._loginButtons object to see what is available?
Template.intro.helpers({
service:function(){
return Accounts._loginButtons.getLoginServices();
}
})
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
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.
I'm trying to get the following behavior for a certain template:
<body onload="someInitFunction();">
Let's say i have the following markup (i'm using mrt router, not iron-router, for {{renderPage}}):
// Main Template
<head>
<title>meteorite-knowviz</title>
</head>
<body>
{{> header}}
<div class="container-fluid">
<div class="row">
{{renderPage}}
</div>
</div>
{{> footer}}
</body>
That renderPage is the secondTemplate:
<template name="secondTemplate">
{{#if currentUser}}
<div class="col-md-2">
<div class="list-group">
<a class="list-group-item" href="{{render thirdTemplate please...}}">Third Template</a>
<a class="list-group-item" href="{{render fourthTemplate please...}}">Fourth Template</a>
</div>
</div>
// In this case let's say thirdTemplate gets rendered
{{render the choice taken above please...}}
{{/if}}
</template>
And within this template, depending on which link was clicked on, (in this case the third) there will finally be a thirdTemplate, which will show a data visualization with some help by a javascript framework, which will be in need of a <body onload="initFunction();">in order to display the data:
<template name="thirdTemplate">
<div class="col-md-5">
<h2>THIS!! section needs a "<body onload="initFunction();"> in order to work" ></h2>
</div>
<div class="col-sm-5">
<h2>Some other related content here</h2>
</div>
</template>
To sum up i have three questions:
1a. How could i get the third template to get a <body onload="initFunction();">
2a. In which way can i render different templates within the secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this template is the renderedPage in the main template or should i do it in some other way?
In order to get the <body onload="initFunction();"> i had to do the following:
First add the following function to a .js file in the client folder:
Template.thirdTemplate.rendered = function() { // Template.thirdTemplate.created - also worked.
$('body').attr({
onload: 'init();'
});
}
This however got me an error saying that initFunction is not defined. In an standard html page my could work just fine, but in meteor i had to change my function from:
function initFunction(){
//what ever i wished to do
}
To:
init = function() {
//what ever i wished to do
}
Regarding the rendering of pages, iron-routing is the way to go since the router add on is not under development any more.
1a. How could i get the third template to get a <body
onload="initFunction();">
You probably want to call initFunction when the third template has been rendered, so just put your call to it in the rendered callback.
Template['thirsTemplate'].rendered = function(){
initFunction()
}
2a. In which way can i render different templates within the
secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this
template is the renderedPage in the main template or should i do it in
some other way?
Listen for clicks on the links, and when one happen you manually render the desired template (possible with Meteor.render, if you need reactivity) and add it to the right node in the document. See this question.
It may be possibly to achieve with router (I don't know that package).
I think that what you want to use is the created callback, that will be called each time your template is created, and not the rendered callback, that would be called each time a change has caused the template to re-render.
Template.thirdTemplate.created = function(){
initFunction()
}
See the documentation for templates for other types of callbacks: http://docs.meteor.com/#templates_api
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}}