My app have multiple layouts for different needs, and I want to choose it dynamically. For example depending of GET params, or if user logged in.
How can i do this?
My app have multiple layouts for different needs, and I want to choose it dynamically. For example depending of GET params, or if user logged in.
How can i do this?
EDIT Since the author edited the question here, and also the specs of iron:router
has changed over time, I decided to refresh this answer a little to prevent confusion.
The documentation on using iron:router
package can be found here.
There are a few possible answers to the question depending on what type of the "parameters".
Typically the main source of knowledge will be the path
, because the user does not necessarily expect the page layout to be changed if the path
remains the same. In this case the thing is pretty simple, because the only thing you need is to define appropriate routes:
Router.route('/some/path/', {
layoutTemplate: 'myFirstLayoutTemplate'
});
Router.route('/another/path/', {
layoutTemplate: 'mySecondLayoutTemplate'
});
If you ever need more refined control you can always choose the layout manually in the action
hook assigned to the give route:
Router.route('/some/path', {
/* ... */
action: function () {
if (Meteor.user()) { // check if user is logged in
this.layout('loggedInUserLayout');
} else {
this.layout('someDefaultLayout');
}
// you need this because otherwise the router
// will not render your templates
this.render();
}
});
Please note that the action
hook is run within a computation and since Meteor.user()
is a reactive data source your page will be re-rendered every time the user logs-in / logs-out.
More details about layouts can be found here.
this
, this also works: Router.current().layout('loggedInUserLayout')
. Helpful for those using arrow functions for example. –
Apiarist You can actually change the layoutTemplate dynamically using this.router.layout()
from within the before hook(and possibly other hooks). It's a bit hidden, and likely to change but here is how I was able to change the layoutTemplate depending on whether a user is logged in or not:
Router.configure({
layoutTemplate: "defaultLayout",
before: function (pause) {
if(!Meteor.user()) {
// render the login template but keep the url in the browser the same
this.router.layout("loginLayout");
this.render('login');
// pause the rest of the before hooks and the action function
pause();
}else{
//Here we have to change the layoutTemplate back to the default
this.router.layout("defaultLayout");
}
}
});
This might get a bit complicated if you have multiple layoutTemplates since once the route is no longer paused it will retain the new layoutTemplate that you have set unless you change it again.
pause()
with this.next()
, so this code will not work without modification: #26630335 –
Weaponeer Meteor currently does not have the ability to render templates dynamically on the server before serving them to the client. Instead it serves the whole complete bundle together.
So within that bundle, you create templates and use them depending on user actions, url paths, session parameters etc.
Take a look at Iron Router which will get you going.
There is also an ongoing discussion on the meteor-talk google group and an item on meteor roadmap trello board.
I'll just leave this here, it's from 2019 and works after some difficulties...
Router.route('/', function () {
Router.current().layout("applicationLayoutEmpty");
this.render('landing', {to: 'content'});
if(Meteor.userId()){
Router.go("/social");
}
});
The magic is in: Router.current().layout("applicationLayoutEmpty");
It uses the default set in main.js when you're configuring IronRouter, but this can be used even in your browser window -- go try it!
© 2022 - 2024 — McMap. All rights reserved.
template
(using{{#if cond}} ... {{else}} ... {{/if}}
and communicate the condition using thedata
available in iron-router. Is there any reason, apart from keeping templates completely logic-less, that you are not taking this approach? – BangalorelayoutTemplate
doesn't currently work. I tried several permutations of conditionally assigning the template in thebefore
hook in bothRouter.configure
and in a specific route. None of those experiments worked. – Excursus