[SOLVED] How to properly use dynamic templates?

I need to include a template only on the homepage. I already am adding a homepage specific class to the body element so here’s what I tried. The template is a drawer that is supposed to be included in my header.

<template name="header">
    <header class=".header>
        <div class=".wrap">    
            {{> nav }}
            {{> Template.dynamic template=isHome }}
         </div>
    </header>
</template>

The isHome helper:

Template.header.helpers({
    'isHome': function(){
        if($('body').hasClass('page-index')
            return Blaze.render('bottomDrawer',Template.instance().find('.wrap'));
    }
});

The error I get is that I can’t render the template ( bottomDrawer ) on a template with no DOM. So I’m assuming that the helper is firing before the actual DOM has rendered for the header template?

How can I dynamically include this template if Blaze.render() expects a parent node to which the parent hasn’t even rendered yet?

It seems like you don’t understand Blaze and reactivity. Read docs http://docs.meteor.com/#/full/


Don’t do this in helper: if($('body').hasClass('page-index').

You need some reactive source which will track if it’s a home page or not. jQuery’s hasClass method is not reactive. You can use Session or ReactiveVar: http://docs.meteor.com/#/full/session, http://docs.meteor.com/#/full/reactivevar.


Blaze.render('bottomDrawer',Template.instance().find('.wrap'));

This is really wrong. Avoid manual DOM manipulation. Try not to use Blaze's methods in JavaScript at all.


Template.dynamic expects string, e.g. {{> Template.dynamic template='bottowDrawer'}}


This is how what you want can be achieved:

<template name="header">
    <header class="header">
        <div class="wrap">    
            {{> nav }}
            {{#if isHome}}
                {{> bottomDrawer}}
            {{/if}}
         </div>
    </header>
</template>
Template.header.helpers({
    isHome: function(){
        return Session.get('isHome');
    }
});

Session.set('isHome', true) should be called when you go to home page and Session.set('isHome', false) should be called when you leave home page.

Template attribute of the Template.dynamic helper should be a string the is the name of a template that you have defined in your app.

Try this instead:

<template name="header">
    <header class=".header>
        <div class=".wrap">    
            {{> nav }}
            {{> Template.dynamic template=isHome }}
         </div>
    </header>
</template>
Template.header.helpers({
    'isHome': function(){
        if($('body').hasClass('page-index'){
            return "bottomDrawer";
        }
    }
});

As a side note you can accomplish this easier using the features of a router… With iron:router you can use the yieldTemplates feature and with kadira:flow-router you can use BlazeLayout in the action to to render templates into Template.dynamic

Thanks for the walk-through and yes, I’m just still pretty new at meteor and getting into the components specifically. Thanks again.

I hate to admit this but I actually am using Flow Router and Blaze Layout but I completely spaced on doing this with the two. For whatever reason I had it in my head to do it the other way. Thanks for the wake up!

1 Like