I am fighting with the common need for redirecting a user to a login page if he is not logged-in (Meteor v0.8.0 on Windows 7).
There are several similar questions on
You can put an if or unless template helper in the layout template.
{{#unless currentUser}}
{{> loginPage}}
{{else}}
{{> yield}}
{{/unless}}
On Meteor 0.8.3 for me works:
Router.onBeforeAction(function () {
if (_.include(['formLogin'], this.route.name)){
return;
}
if (!Meteor.userId()) {
this.redirect('formLogin');
return;
}
});
It looks like this has something to do with waiting on subscriptions in waitOn.
The following solves the layout rendering issues for me:
Router.onBeforeAction(function() {
if (!Meteor.user() && this.ready())
return this.redirect('/login');
}, {except: ['login']});
You just need to return the the result of render()
from your onBeforeAction()
onBeforeAction: function () {
if (_.include(['login'], this.route.name)){
return;
}
if (!Meteor.userId()) {
return this.render('login');
}
}
Also note I changed Meteor.user()
to Meteor.userId()
. This keeps the hook from being rerun every time the current users document chages.
Ok, so it seems that the render function on a route only renders a template into the current layout. To render a template into a different layout you have to call this.setLayout('templateName')
. The one caveat seems to be that you'll need to set the layout back after login.
onBeforeAction: function(pause) {
var routeName = this.route.name;
if (_.include(['login'], routeName))
return;
if (! Meteor.userId()) {
this.setLayout("newLayout");
this.render('login');
//if you have named yields it the login form
this.render('loginForm', {to:"formRegion"});
//and finally call the pause() to prevent further actions from running
pause();
}else{
this.setLayout(this.lookupLayoutTemplate());
}
}
You could also just render the login template as the layout if your login template is all you need by calling this.setLayout('login')