Q:

Meteor Iron Router server-side hooks

Using Iron router it's possible to add hooks like so:
// this hook will run on almost all routes
Router.before(mustBeSignedIn, {except: ['login', 'signup', 'forgotPassword']});

// this hook will only run on certain routes
Router.before(mustBeAdmin, {only: ['adminDashboard', 'adminUsers', 'adminUsersEdit']});

See: https://github.com/EventedMind/iron-router#using-hooks
But the documentations does not say how to make these hooks "server side".
The idea is to create a hook which will oversee publishing Collections for all routes, except for one or two specific routes where I want more control over what's published.

A:

Iron Router is just the same both on client and server and the declarations can be done on a directory/file which is available to both client and the server.
By default, the declared routes are for the client. If you want a route to be server side, then you explicitly declare so by including where: 'server'.
Taken from the official docs:

Defining routes and configuring the Router is almost identical on the server and the client. By default, routes are created as client routes. You can specify that a route is intended for the server by providing a where property to the route like this:

Router.map(function () {
  this.route('serverRoute', {
    where: 'server',

    action: function () {
      // some special server side properties are available here
    }
  });
});

Note that where must be placed in Router.map, not on the controller.
Server action functions (RouteControllers) have different properties and methods available. Namely, there is no rendering on the server yet. So the render method is not available. Also, you cannot waitOn subscriptions or call the wait method on the server. Server routes get the bare request, response, and next properties of the Connect request, as well as the params object just like in the client.

Router.map(function () {
  this.route('serverFile', {
    where: 'server',
    path: '/files/:filename',

    action: function () {
      var filename = this.params.filename;

      this.response.writeHead(200, {'Content-Type': 'text/html'});
      this.response.end('hello from server');
    }
  });
});

As you see, there is only one naming convention, therefore you can state something like this:
Router.before(someFilter, {only: ['clientRoute1', 'clientRoute2', 'serverRoute1']});

or
Router.before(someOtherFilter, {except: ['clientRoute3', 'clientRoute4', 'serverRoute2']});

just like you normally would.

