Now that our routes are working we can create a menu:

client/views/layout.html

<template name="layout">
  <h1>Foosboom</h1>
  <ul>
    <li><a href="/">Games</a></li>
    <li><a href="/teams">Teams</a></li>
  </ul>

  {{> loginButtons}}
  {{> yield}}
</template>

However there is a problem with this menu: we can't tell which menu item has been selected.

It's impossible to tell which menu item we are on

To fix this we need to style our "active" menu item differently. But to do that we need to know which menu item is active so we can give it a different CSS class.

Don't reinvent the wheel

Since most apps require this functionality it's highly likely someone has created a package for this. I like to browse packages on Atmosphere, check compiled package lists, as well as looking over well maintained Meteor boilerplate projects (here's one, and another) just to make sure I'm not reinventing the wheel with certain functionality.

In saying this I should warn you that some packages can be poorly maintained - meaning that at some point in the future they might suddenly break after a Meteor update or something. To protect against this you just need to check that the Github project seems to be reasonably active. Are there many commits? Are issues being resolved? Is the package recommended by any blogs or boilerplate projects? The last thing you want is for your app to fail because a third-party package is causing a random bug.

meteor-iron-router-active

Anyway after some searching I found meteor-active-route, which seems perfect for our needs, and is recommended by a popular boilerplate Meteor app (making it trustworthy in my opinion).

Let's add it to our project:

meteor add zimme:active-route

client/views/layout.html

<template name="layout">
  <h1>Foosboom</h1>
  <style>
    .active a {color: black;text-decoration: none;border: 1px solid black}
  </style>
  <ul>
    <li class="{{isActiveRoute regex='games'}}">
      <a href="/">Games</a>
    </li>
    <li class="{{isActiveRoute regex='teams'}}">
      <a href="/teams">Teams</a>
    </li>
  </ul>

  {{> loginButtons}}
  {{> yield}}
</template>

Our routes now appear active when selected. But only for 'teams'.

It appears this is only half working - it works for teams but not for games. The reason for this is that Iron Router allocates a "name" to each route. When we created our teams route with Router.route('/teams', 'teams') it was able to guess the name to be "teams" (/teams => "teams").

But with our games route (Router.route('/', 'games'), Iron Router only had / to obtain a name from (/ => ?), and hence didn't name it anything. We can check the name of the current route (docs) by opening the browser console and typing:

Router.current().route.getName()

Here we see our route name being undefined.

Luckily, it's quite easy to specify a name for our route:

both/router.js

Router.configure({
  layoutTemplate: 'layout'
});

Router.route('/', {name: 'games'});
Router.route('/teams', 'teams');

Here we have named our route games, but not supplied a template. Luckily it still works because if Iron Router has a name for the route then it automatically searches for a template with the same name. So it saw the name was "games" and then searched for a template called "games". With this knowledge we can further simplify our teams route:

both/router.js

Router.configure({
  layoutTemplate: 'layout'
});

Router.route('/', {name: 'games'});
Router.route('/teams');

Our routes are now working nicely

Feel free to style it better.