Change Template Same URL?


#1

This seems like a really simple question but I’ve spent the last 3 hours trying to figure it out with the docs and available articles with no success. Any help for this noob is much appreciated.

I need to switch which template is rendered without changing the url based on a user action. This has multiple applications in my app. The primary one is to render the login template or the register template within my welcome page template without changing urls.

So essentially, on the register form I have a link to login instead, and on the login form, a link to register instead, and when I click these links, I want the appropriate template to render within the welcome template while staying at the same url.

Is this possible? I’ve read a lot about Template.dynamic but I’m not sure how I’d use this in my case or if it is even the correct solution.


#2

which router are you using?


#3

I am using flow router


#4

Use Template.dynamic
Or
Smt like this:

FlowRouter.route('/authenticate',{
   name : 'authenticate',
   action : function(p, q){
     BlazeLayout.render('defaultLayout', {top : 'header', main : 'login'});
   }
});

Template.login.events({
   'click .btn-register' : function(e, t){
      BlazeLayout.render('defaultLayout', {top : 'header', main : 'register'});
   }
})

#5

As @nxcong pointed out, this is pretty much doable using dynamic templates and BlazeLayout.

I also noticed that there are some edge cases where FlowRouter won’t load the correct template if there is a race condition at startup between the automatic user login and FlowRouter itself. This caused the wrong template to be displayed if a hot code push took place or I refreshed the browser window completely (it showed the login dialog although the user was already logged in; only a FlowRouter.reload() in the console showed the right template).

I was able to fix these issues by calling FlowRouter.wait() in the global code block (i.e. outside any functions) and FlowRouter.initialize() in a Meteor.startup() block. This made sure that user auto-login had been finished before FlowRouter / BlazeLayout rendered the page. Maybe I am just too dumb to do things right, but I assume this is a side-effect of FlowRouter not being reactive.


#6

You can use Template.dynamic, but if you only have 3 templates (login + register + route main template), why don’t you use {{#if ... }} to select which one to display?


#7

@nxcong thanks, that is exactly what I was looking for! I was unaware that I could call the render function from within a template event.

@Steve in some cases that will be my approach, however in others I will need to switch between many different templates at the same URL. I provided the welcome page case as it was the simplest to describe.