How to route html pages on clicks in meteor? - meteor

I am a newbie in Meteor. I am developing an app having a login page that must redirect to certain pages as per the login id.There are certain click events which opens up html pages.I have the hard code data in the pages to check the flow now.I have the html pages as well designed, but I am not able to link them for click events and login. Please help.

Here is one way to do it:
In your HTML file, something like this:
<head>
<title>Duckbilled Platypus</title>
</head>
<template name='layout'>
{{> banner}}
{{> yield}}
</template>
<template name="banner">
<h1 class="chocolatefont">Platypi of the World Unite! (Duckbilled, that is)</h1>
<hr/>
</template>
<template name="main">
<div id="templateMain" name="templateMain">
<h2>RAVES</h2>
<p>No Raves yet</p>
<h2>RANTS</h2>
<p>No Rants yet</p>
<h2>RANDOM</h2>
The Legend of NFN Oscar
<br/><br/>
NFN Oscar's donut
<br/><br/>
Alliteration Station ("Ben's Bizarre Bazaar")
<br/><br/>
Boomeranging Telescopic and Kaleidoscopic Phrase Mazes
<br/><br/>
Acrostics
<br/><br/>
Homonym Homie
</div>
</template>
...and then add whichever templates you want for the pages you want to route to; in my case, it's one for each "href" referenced in the anchor tags (nfnoscar, nfnoscarsdout. etc.)
The "yield" (which means, "insert here whatever the router says corresponds to the URL") requires Iron:Router, which you say you already have.
In your JS file, something like this:
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {
name: 'main',
template: 'main'
});
Router.route('/nfnoscar', {
name: 'nfnoscar',
template: 'nfnoscar'
});
Router.route('/nfnoscarsdonut', {
name: 'nfnoscarsdonut',
template: 'nfnoscarsdonut'
});
Router.route('/alliterationstation', {
name: 'alliterationstation',
template: 'alliterationstation'
});
Router.route('/btakpm', {
name: 'btakpm',
template: 'btakpm'
});
Router.route('/homonyms', {
name: 'homonyms',
template: 'homonyms'
});
Router.route('/acrostics', {
name: 'acrostics',
template: 'acrostics'
});
Now, whichever link is clicked, the corresponding page is loaded by means of the "yield" and the Iron Router routing.
You can see this particular app and how it works when you click the links, etc., at my "sandbox" Meteorsite here.

Related

Router for static site using Meteor

I'm new to Meteor and have limited experience with javascript. I've searched all the stack post and the web for a good tutorial on how to use the Iron Router package to route static pages and just can't seem to figure it this out. I would love to have someone help me understand how to setup a router.js file for Home and About. I've played with my code a lot but this is what I had before posting here. Conseptually I seem to be struggling to grasp how the routing works and all the various features of iron router and then connecting these routes into a nav bar where I can navigate between them. Thank you in advance for any help you can provide.
client/templates/application/layout.html
<template name="layout">
<div class="container">
{{> yield}}
</div>
</template>
lib/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', function () {
this.render('home', {
template: 'home'
});
this.render('about', {
template: 'about'
});
});
templates/home.html
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
The code you have above looks correct.
One quirk is you're rendering two pages for your / route. You should have this:
Router.route('/', function () {
this.render('home', {});
});
Router.route('/about', function() {
this.render('about', {});
});
Remember this.render takes the first param as the template, so there's no need to define it separately anymore.
And a new about.html page:
<template name="home">
<div class="container">
<h2>Home</h2>
</div>
</template>
Now you can use the / and /about pages (at least I hope i've not missed anything)
You can have 3 templates on your folder
Client/Views
with the name of
about.html
main.html
admin.html
layout.html
(for example)
So in the about.html you have this
<template name="about">
<h1> hello from about page
</template>
<template name="main">
<h1> hello from about page
</template>
<template name="admin">
<h1> hello from about page
</template>
the Layout.html file need con taints this yield rendered.
<template name="layout">
{{> yield}}
{{admin}}
{{about}}
{{main}}
</template>
So you can use layout template as a master page and calling that 3 templates separates by a route, how to assign a route and telling meteor to use that layouts, well use this js code
JS
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function(){
this.route('admin', {path: '/admin'});
});
Router.map(function(){
this.route('about', {path: '/about'});
});
Router.map(function(){
this.route('main', {path: '/'});
});
At least this works for me bro, hope this work for you

Meteor: make layout.html WaitOn a subscription?

I'm trying to make a chat (Template.chatlist) feature that sticks to the bottom of the page (similar to the chat function on Facebook, where the chat box is persistent while the page in the background changes as the user browses to other parts of the site). So I put the chat box in a handlebars template on the layout page (so it's not rendering from the {{>yield}} template). The problem is, it's not waiting on the subscriptions before it loads (there is no route to the layout.html, so I couldn't set a waitOn on it in the router), so it's not able to pull information from my users collection.
I need to know, how can I make the layout.html page wait to load after the subscriptions are properly finished? Of course, I can put the chat template inside every page's yield template to have it wait properly, but is there a way where I don't have to do it this way?
<main class="main container" id="central">
{{> yield}}
{{> chatlist}}
</main>
This is sort of what the layout.html looks like right now. The chatlist template is not waiting on any data subscriptions because it's not in the yield section (and thus not controlled by the router)
I also did Template.chatlist.helpers and registered the user data into a helper, but for some reason when I tested it by console logging Users.count the console returns with zero.
Use a region:
<template name="layout">
<aside>
{{> yield region='aside'}}
</aside>
<div>
{{> yield}}
</div>
<footer>
{{> yield region='footer'}}
</footer>
</template>
Router.map(function () {
this.route('home', {
path: '/',
template: 'myHomeTemplate',
layoutTemplate: 'layout',
yieldTemplates: {
'myAsideTemplate': {to: 'aside'},
'myFooter': {to: 'footer'}
},
waitOn: function() {
// ...
}
});
});
See the Iron Router docs.

Path works on desktop, but not mobile

I've a tab bar on a responsive app I'm building:
<template name="tabNav">
<nav class="bar bar-tab">
<a class="tab-item" id="groups-nav" href="{{pathFor 'groupsList'}}">
<span class="icon icon-star-filled"></span>
<span class="tab-label">Groups</span>
</a>
<a class="tab-item active" id="games-nav" href="{{pathFor 'locationSet'}}">
<span class="icon icon-list"></span>
<span class="tab-label">Games</span>
</a>
<!-- more code -->
</template>
The pathFor 'groupsList' works on desktop, but not on mobile. You can try it out here: pp-groups.meteor.com.
This is a prototype only and doesn't use any real data. All of my views code is available here: https://github.com/stewartmccoy/pp-groups/tree/master/groups/client/views
These are my defined routes:
Router.map(function() {
this.route('layout', {
path: '/',
template: 'getLocation',
layoutTemplate: 'getLocation',
yieldTemplates: {
'tabNav': {to: 'footer'}
}
});
this.route('locationSet', {
path: '/locationSet',
template: 'locationSet',
layoutTemplate: 'locationSet'
});
this.route('groupsList', {
path: '/groupsList',
template: 'groupsList',
layoutTemplate: 'groupsList'
});
});
Why doesn't the pathFor work on mobile? (It at least doesn't work in Xcode iOS simulator or on iPhone Mobile Safari or Chrome).
The push.js component is causing the issue. You can still use Rachet with Iron Router by disabling push.js. Per rachet's documention you can disable push by adding a data-ignore tag to your HTML link.
<!-- Use data-ignore="push" to prevent the push.js interception -->
<a href="http://www.google.com" data-ignore="push">Google<a>
Routing issue:
Removing the ratchet package fixed it for me. Looks like ratchet uses it's own way of linking between templates which is incompatible with iron-router. Removing ratchet removes the UI elements, but the routing works on mobile: http://pp-groups-fixed.meteor.com. You could use a strictly UI library, like bootstrap to make the UI elements, or maybe even just the ratchet's UI components. If you want to fully use ratchet, you will most likely have to forgo IronRouter.
Other things to fix:
Layout Templates
When using meteor and iron-router, a layout template is a template with common elements, with a {{> yield}} placed where you want the regular templates to show up.
You actually only have one real layout template in your code, in groups.html there is a layout template named layout, and it is unused.
In your code, regular templates are being misused as layout templates, because they don't have {{> yield}} in them. Also, the tabNav template is being placed using iron-router, yet you have already included it in each template with {{> tabNav}}.
So, you can simply get rid of the layout template code in your iron router, and your app will still function:
Router.map(function() {
this.route('layout', {
path: '/',
template: 'getLocation',
// layoutTemplate: 'getLocation',
// yieldTemplates: {
// 'tabNav': {to: 'footer'}
// }
});
this.route('locationSet', {
path: '/locationSet',
template: 'locationSet',
// layoutTemplate: 'locationSet'
});
this.route('groupsList', {
path: '/groupsList',
template: 'groupsList',
// layoutTemplate: 'groupsList'
});
});
A better way is to take out all the common code, the header, general structure of the page, tab bar, and put it in a layout template. Add a {{> yield}} where you want the page template to render. Refer to this layout template in your router as layoutTemplate.
Another sidenote, iron-router automatically looks for the template with the same name as the route, if no template is defined. So if you are writing this.route('groupsList', ... you don't need to write template: 'groupsList' as well.
Data
Your past-game.js file should be named get-location.js. Yes, the name itself doesn't matter, but that is getLocation's complimentary code, not postGame's. Same with scheduled-games.js and locationSet. Look at the Template.templateName.helpers to see how the code corresponds.
Of course, ideally this data should be in a collection. For now, instead of creating the data as arrays with var, you could create a seperate file with your data as global variables. Simply define as PastGames = [...], then use the template helpers to return the data you need.

How can I use two Iron Router controllers in one layout in Meteor 0.8.0?

In my Meteor app, I have two yield blocks: one for my global navbar and the other for my main content:
<template name="layout">
<div>
{{> yield region='navRegion'}}
</div>
<div>
{{> yield}}
</div>
</template>
How can I add an Iron Router Controller into my routes so that I can pass data into my global navbar (since it doesn't have a route)? Is it possible to run the two controllers at the same time? Or do I have to rely on helpers for the global nav?
Let's say the template that you were trying to render in the main {{> yield}} was named home. The following would work.
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function () {
this.route('home', {
path: '/',
template: 'home',
yieldTemplates: {
'navRegion': {
to: 'navRegion'
}
}
});
});
Here's the answer from #cmather, which he answered on my other post:
How do I activate an Iron Router route without changing the path?
There is a one-to-one between a route and a route controller. You'll
only ever have one controller running at a time, based on the route
you're on. If you want to set a global value from a controller, and it
doesn't make sense to do it in the global data context, you can always
set a session value. For example: Session.set('currentId',
this.params._id) - #cmather

Router only render certain templates

I have a layout with 2 containers 1)productView and 2)calendarView. My Router is configured as follows:
this.route('productDetail', {
layout: 'main',
path: '/products/:_id',
waitnOn: function(){...},
data: function(){...},
yieldTemplates: {
'calendarView: { to: calendar }
}
});
I now want to achieve that whenever the route changes (e.g. from 'products/1' to 'products/2') only the productView is re-rendered and that calendarView does nothing. As for now every time the 'productDetail/:id' route is called the 'calendarView' function 'Template.calendarView.rendered' gets called and re-renders the template. My 'main' template looks like this:
<template name="main">
<div>
{{yield}}
</div>
<div>
{{yield 'calendar'}}
</div>
</template>
Is there a way to tell the router to only render certain templates? Or is there a better solution?
Any help is much appreciated.
Is there a reason why you use the router for the calendar view ?
I think one solution may be not to use the router for the calendar view
<template name="main">
<div>
{{yield}}
</div>
<div>
{{>calendar}}
</div>
</template>

Resources