Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change layoutTemplate depending on some expression? Iron-router

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?

like image 237
Vitalii Del Vorobioff Avatar asked Feb 26 '14 09:02

Vitalii Del Vorobioff


2 Answers

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.

like image 199
Dsyko Avatar answered Oct 23 '22 13:10

Dsyko


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.

like image 29
Tomasz Lenarcik Avatar answered Oct 23 '22 11:10

Tomasz Lenarcik