Iron-Router dynamic templates in layout like in Flow-Router - meteor

How can i render dynamic templates via layout in Iron Router?
For example in Flow-Router in layout i can define some dynamic templates:
newsRoutes.route('/',{
action:function(){
BlazeLayout.render("layout",{top:"digest",left:"post_list",right:"chat"});
}
});
And then i can define another route with another parameters:
adminRoutes.route('/',{
action:function(){
BlazeLayout.render("admin_layout",{top:"admin_user_list"});
}
});
And Flow-Router will not render nothing in left and right positions.And it is good for me.
But with named {{>yield}} regions in Iron:Router i can't do that. Because Iron:Router save {{>yield}} regions from route to route, and it can be only rewriten by redefined regions. How can i prevent rendering {{>yield}} regions if it not defined in current route?

Related

Meteor & Flow Router: Marking Dynamically generated paths as 'active'

Needless to say, my experience with Meteor is lacking. I come from a Rails background, where you can do a lot more logic (and magic) in your views than Meteor.
The situation: I've got some routes that look like /things/:_id, and I've named that route 'thing' because it shows only one thing of a user's many owned things:
FlowRouter.route('/things/:_id', {
name: 'thing',
action() {
BlazeLayout.render('appPage', {app: 'thing', sidebar: "thingsListOnThing", header: 'thingTitle'});
}
});
As you can see, I'm also loading a template I've built to list all of the user's owned things on the sidebar for easy navigation. That template, thingsListOnThing is the target of this question.
Get the gist? I'm able to mark the route that dislays a template with a complete list of a user's things as active using zimme:active-route like so:
// A list of all a user's things
<div class="{{isActiveRoute name='things' class='is-active'}}">
List of Things
</div>
This package is great, but it won't help me with routes that look like /things/:_id because, then every link to each individual thing would be is-active on any thing page, not just the one where the current path's :_id matches the _id of the active thing.
I'm really kind of stuck here. My first guess would be to use template helpers, but I'm confused as to where to get started with that.
If need be, please as me to upload any piece of my code you require. I figured it's such a generic question that you guys probably don't need to see all of my code to understand what I'm trying to accomplish.
Using: zimme:active-route
Template Helpers
Template.listOfThings.helpers({
activeListClass(page) {
const active = ActiveRoute.name('thing') && FlowRouter.getParam('_id') === this._id;
return active && 'active';
},
});
Template HTML:
<a class="{{isActivePath 'thing'}}" href="/things/{{_id}}">
<div class="thingListItem {{activeListClass page}}">
{{title}}
</div>
</a>

Change some html in layout template when on a certain route (with iron-router and meteor.js)

I have a template I have set up as my layout using iron-router:
Router.configure({
layoutTemplate: 'main'
});
Within this layout, I have a line of html that I would like to be changed on certain routes.
My ideas is doing something like:
{{#if landing }}
<div id="page-wrapper">
{{/if}}
However, how do I implement this for a certain route? I want this variable to be true on every route except for 1.
I think that this kind of "change the template based upon what route I'm on" logic fits best into the use of a template for that route (and any others that will make this same change. Depending on the change required, you may be able to call in your base Template into the modified template.
Example:
Router.route('/yourSpecialRoute', function(){
this.layout('OtherLayout');
});
See the Layout docs - I borrowed the syntax of Setting Region Data Contexts
Having said, if you prefer not to switch layouts per route, consider setting a data on your route (something like {data: item} as shown here in the iron:route readme which can then be read by a global helper (Template.registerHelper syntax) - this will at least make it consistent across your routes / templates.

Prevent Iron Router Not Found template showing when using angular-meteor

I have a Meteor application and I'm using a combination of angular-meteor and Iron Router routing.
Angular-meteor client side routing is used for all browser side routing and Iron Router is used for all server side routing. I'm implementing an OAuth2 server in Meteor so I need to be able to hit a URL without using the client side code.
The setup works great, but with one consequence: the Iron Router 'not found' template always shows on the client, because I have no client side routes for Iron Router:
I've also tried adding a blank Iron Router route to the client side code:
Router.route('(.*)', function(){
//Do nothing
});
or
Router.route('(.*)', function(){
//Do nothing
this.ready();
});
But that results in all my angular-meteor templates being duplicated on the client:
I've also tried setting the Iron Router configuration to use a different not-found template I've written in Blaze, and using angular-with-blaze:
> meteor add angular-with-blaze
client & server code:
Router.configure({
notFoundTemplate: "ironrouternotfound"
});
ironrouternotfound_blaze.html:
<template name="ironrouternotfound">
IR Not Found
</template>
ironrouternotfound.html
<blaze-template name="ironrouternotfound"></blaze-template>
But that results in the following text being injected into the bottom on the HTML DOM:
Couldn't find a template named "ironrouternotfound" or "ironrouternotfound". Are you sure you defined it?
This message is injected by IronRouter and it doesn't have an ID on the div or any CSS classes so I can't hide it using JS or CSS. (Well, I might be able to hack a JS to remove the last div on the page, but that could be dangerous)
Any one managed to remove the Iron Router not-found view in this situation?
My temporary CSS hack is:
div[style="margin: 0 auto; color: red;"] {
display: none;
}
This works for me. First declare a blank HTML template in a client folder like this:
<template name="noRoutesTemplate"></template>
Next in a common folder (eg. 'lib') add iron router's noRoutesTemplate to the configuration.
import { Router } from 'meteor/iron:router';
Router.configure({
noRoutesTemplate: 'noRoutesTemplate',
});
See this reference link

Meteor: Images and text do not load after moving to Iron:Router

My site works fine when the data is in a template, but once I try to route to it using iron:router, a background image and most remaining content no longer appear. (Some of the content still appears with working css, JS components so I know that those files are being read. Also, when inspecting the element, all the text, images are still visible in the code, but not the website.
This works fine (index.html):
<body>
{{>home}}
</body>
This adds another {{>home}} section, but the new section is having issues rendering as explained above (router.js):
Router.map(function() {
this.route('home', {path: '/'});
});
Are you on the latest iron:router? I had a similar problem, and inquired about it in this pull request:
https://github.com/iron-meteor/iron-router/issues/1051
Latest response indicates this should be fixed now!
You've followed the wrong tutorial :( There are plenty of tutorials and articles out there explaining to define routes like you did.
However, the Iron Router project page explains how to define routes differently.
For more information on routes, have a look at this article about Iron Router as well.
Fixed: problem was not with iron:router but rather that not all elements were loaded into the page yet. Document.ready() works fine when I directly called template.
Issue is that when iron:router loads the template, the new page elements are being loaded after the JS files were already called (JS that animates the images/text in).
Solution: use rendered instead of document ready:
Template.MyTemplate.rendered = function(){
}

Where does Meteor.subscribe() belong?

I just noticed that my subscription code "Meteor.subscribe('my-publications')" at the top of my JS file affects ALL my templates, not just the template that the JS file is created for.
This was unexpected because all the demos did it this way.
Where is the subscription code suppose to be in if I want it to affect one template only? Inside Template.name.created()?
Don't assume the only data in minimongo is what is relevant to your template. Be specific when selecting your data for the template.
You have several options as far as subscriptions go, the most common by far is adding a subscription to the waitOn section of your routes definitions. Using waitOn will result in the subscription being unsubscribed when the route is no longer in use.
Router.map(function() {
this.route('route', {
waitOn: function(){ return Meteor.subscribe("yourSub"; }
});
});
You can also subscribe per template. A package I've created for this purpose can be added via
meteor add elevatedevdesign:template-subscriptions
This pattern will also be coming soon as a part of blaze, but with some slight differences in how you call it. This will automatically unsubscribe when the template is no longer active. It also allow's subs-manager to be subscribed to on template destruction.

Resources