FlowRouter/BlazeLayout: How to set data context for a template on routing?

On the contrary, providing data context to template with an inclusion tag is much better in terms of decoupling. This way that template will not have to be tied to the route. Remember, a route can resolve to a page with multiple templates which require separate data contexts!

So the best approach to achieve portability of templates would be:

<template name="layout">
  <h1>My App</h1>
  {{Template.dynamic template=main}}
</template>

<template name="postContent">
  {{#with postData}}
    {{> postContentFull}}
  {{/with}}
  {{!-- 
    note that we could shortly have done:
    {{> postContentFull postData}}
  --}} 
</template>

<template name="postContentFull">
  <h2>Post Content for {{title}}</h2>
  <div>{{body}}</div>
</template>
FlowRouter.route('/posts/:_id', {
  action: function(params) {
    BlazeLayout.render('layout', {main: 'postContent'})
  }
});

Template.postContent.onCreated(function() {
  var template = this;
  Tracker.autorun(function() {
    template.subscribe('singlePost', FlowRouter.getParam('_id'));
  });
})

Template.postContent.helpers({
  postData: function() {
    var post = Posts.findOne({_id: FlowRouter.getParam('_id')});
    return post;
  }
})

Now this way, we decouple what template the router renders onto the page and what that template renders within that page specifically.

We also now can reuse the inner template.

We could also make a postData(id) helper so that we could get arbitrary posts.