I’ll admit it; working with AngularJS has left me with a certain sense of entitlement. I expect my front-end framework to be able to let me build distinct elements that can be composed together and placed within each other. After reading about Meteor’s templating system, I was under the impression that content could not be transcluded into a template. After all, where would it go?

{{> myTemplate}}

It wasn’t until I read through Spacebar’s documentation that I found out about the amazingly useful custom block helpers. Custom block helpers let us inject or transclude content (HTML, text, variable interpolations, other templates) into a template. Let’s check it out!

Using Custom Block Helpers

If you read through the Custom Block Helpers section of the Spacebar docs, you’ll notice that Template.contentBlock behaves almost exactly like AngularJS’ ng-transclude directive. It marks the place where content will be injected into the template’s markup. Let’s look at an example:

<template name="myTemplate">
    {{#if this}}
    <h1>{{title}}</h1>
    <div>
        {{> Template.contentBlock}}
    </div>
    {{else}}
        <h1>No content provided</h1>
        <div>
            {{#if Template.elseBlock}}
                {{> Template.elseBlock}}
            {{else}}
                <p>No elseBlock provided</p>
            {{/if}}
        </div>
    {{/if}}
</template>

<body>
    {{#myTemplate title="My Title"}}
        <p>My custom content</p>
    {{else}}
        <p>This is my else block</p>
    {{/myTemplate}}
</body>

There’s a lot going on in this example. Let’s break it down.

Check Your Context

The first thing I do in my template is check the truthiness of the template’s data context (this). If a truthy data context is passed into the template, I render one set of markup (which includes data from the context), otherwise, I render an alternate set of markup.

Inject Your Content

You’ll notice that I’m using Template.contentBlock in the first set of output and Template.elseBlock in the next. Interestingly, when you define a custom block helper, you can also define an “else” block to go along with it. In the second set of output I’m checking if Template.elseBlock is truthy. If it is, I render it, otherwise, I render some markup explaining that an else block was not provided.

Use Your Template

To actually use your new template and inject content into it, you no longer use the inclusion tag syntax. Instead, you reference your template using block tag syntax. You can see this at the bottom of the above example. Within your block tag you include your content to be injected and an optional else block. Note that any arguments you pass into your template becomes that template’s data context.

Final Thoughts

While the above example is completely contrived and mostly useless, I think it shows some really useful functionality. I feel like custom blocks are going to be a big game changer in my Meteor development workflow. There’s a great article over at Discover Meteor that touches on custom blocks with a more practical example. Check it out!