Flowrouter - dynamic templates from mongo


#1

I would like to dynamically load template using flow router from database but unfortunately flowrouter does not have any waiton helper. What is the best way to accomplish it. I prefer not to name templates after my slugs.

contractRoutes.route('/:slug', {
  name: 'createContractRoute',
  subscriptions: () => {
    Meteor.subscribe('allContractTemplates');
  },
  action: (params) => {
    let contractTemplate = Collections.ContractTemplates.findOne({slug: params.slug});

    BlazeLayout.render('layout', {main: 'createContract', contract: contractTemplate.template});
  }
});

Completly dynamic site
#2

The best way to accomplish the same thing is to install the flow-router-helpers package and then use {{#if subsReady}}Template display logic{{/if}}


#3

You are still rendering “Layout” and passing arguments to it. So you can handle waiting and all these data tasks in that layout template. Or 1 layer lower in kinda data loading templates.
And than have separate sets of user facing templates.
Differentiating on these template levels is pure convention, but can improve reusability a lot.


#4

I think you’re doing the subscription part wrong

subscriptions: function () {
  this.register('contracts', Meteor.subscribe('allContractTemplates'));
}

Then you can wait on that particular subscription to do something pretty easily by making your own helper or using flow-router-helpers.

Template.contracts.helpers({
  contractsReady: function () {
    return FlowRouter.subsReady('contracts');
  }
});

Then in template

{{#if contractsReady}}
  // contract stuff here
{{else}}
  {{>loading}}
{{/if}}

#5

Thank you guys. Especially to you corvid. Your solution worked well. Here is the complete source code for those interested.

Template

    <template name="createContract">
      <div class="col-md-4 col-md-offset-4">
        {{#if subsReady 'allContractTemplates'}}
          {{> Template.dynamic template=getContractTemplate}}
        {{/if}}
      </div>
    </template>

Helpers

Template.createContract.helpers({
  getContractTemplate: () => {
    let slug = FlowRouter.getParam('slug');
    let contractTemplate = Collections.ContractTemplates.findOne({slug: slug});
    return contractTemplate.objectName;
  }
});

Flow Router

contractRoutes.route('/:slug', {
  name: 'createContractRoute',
  subscriptions: function() {
    this.register('allContractTemplates', Meteor.subscribe('allContractTemplates'));
  },
  action: () => {
    BlazeLayout.render('layout', {main: 'createContract'});
  }
});