5 Handlebars Helpers BigCommerce Developers Should Know

Kyle O’Brien
BigCommerce Developer Blog
5 min readDec 5, 2019

The Stencil theme platform enables developers to control store data flow from the BigCommerce back-end to the front-end. Developers can direct the presentation of each page using Handlebars Helpers. There are various examples of this throughout the Cornerstone theme: where product fields are assembled, templates/components/products/product-view.html, the account page’s list of previous orders, templates/components/account/order-contents.html.

In this blog post, we’re going to focus on five underutilized Handlebars Helpers that might be helpful for everyday programming tasks. Starting with the string helpers {{json}} and {{concat}}, these offer string access or modification when developers would commonly need to make a tedious change with scripting. Building on that with the {{moment}} helper, we’ll learn how to cache-bust an image using the current moment as a parameter. Afterward, we invoke {{filter}} to display a custom component. Finally, we wrap up with {{jsContext}} and its broad appeal for various applications. As an example, we’ll inject related product IDs into the jsContext and console log the results.

It’s important to note that Handlebars should only be used in .html files, if found elsewhere the code will display unchanged or possibly invite unexpected errors into the codebase. To check which objects are available in a page’s context, add the parameter ?debug=bar to the localhost URL when running the Stencil CLI.

{{json}}

We can see what {{json blog}} returns on the home page of a sandbox store.
We can see what {{json blog}} returns on the home page.

This is a custom helper added with our built-in paper-handlebars plugin that converts a JavaScript object into a json string. I’ve seen {{json}}commonly used when working with Stencil objects to quickly test what is returned in a given context, which is where the json Handlebars Helper shines.

If you’re trying to add blog posts to the home page, you can quickly see what the blog object returns on /templates/pages/home.html by adding {{json blog}} to that file.

Find more examples of objects available for use with the json helper on our developer documentation here.

{{concat}}

Concat, shorthand for concatenate, might be familiar for terminal users and is used to join strings end-to-end from a page’s context. {{concat}} could be used to link to interchangeable URLs, or as we’ll see later to dynamically display custom components. In the example below, I made an addition to templates/components/products/product-view.html where {{concat}} is invoked to join the current product page’s title and SKU. This illustrates the difference between concat and join, which includes separators.

<h1 class=”productView-title” {{#if schema}}itemprop=”name”{{/if}}>{{concat product.title product.sku}}</h1>

We can see the result in the following screenshot. Note the SKU “CLC” is placed immediately after the product title “Canvas Laundry Cart”, without space between.

A screenshot of our {{concat}} example in action on a product page.
Our {{concat}} example in action on a product page.

{{moment}}

This helper is a necessity when working with time. By exposing helper-date with the moment helper, developers can reference the exact moment in time wherever this helper is invoked. In an example found on StackOverflow, the following solution was shared with a developer when looking to re-cache their image assets on our CDN:

<img src=”/content/home-hero.jpg?{{moment}}”/>

Our CDN will use that asset’s first chronological upload, which can cause problems when testing and replacing files in real-time. By using {{moment}}as a parameter, the latest version is retrieved instead. This is called cache-busting. To retain benefits gained from using our CDN, developers should focus on specific, frequently-updated resources such as an advertising banner. In contrast, developers would not cache-bust a store logo that is rarely updated.

Any resource served this way will lose the benefits of our CDN, discretion should be exercised with the moment helper.

{{filter}}

The filter Handlebars Helper returns an array of values when they’re available in a given Stencil context. On the product page, {{filter}} can be used to determine if custom components should be displayed as shown below (within the description), or with other product details such as the warranty. I replaced {{product.description}} with the following in the templates/components/products/description-tabs.html file:

{{#filter product.custom_fields ‘Bulk Shipping Dimensions’ property=’name’ }}{{> (concat ‘components/bulk-dim/’ value) }}{{else}}Bulk Shipping not available.{{/filter}}

This also uses the concat helper we learned earlier. The joined strings here are the product’s value for the custom field ‘Bulk Shipping Dimensions’, expecting a component with the same value in the ‘components/bulk-dim’ directory of the theme. Excluded from this example, I created an .html file with the same value as the product’s Bulk Shipping Dimensions. If the matching value exists, the component will be displayed as a partial. Otherwise, the message below {{else}} appears.

Screenshot of the product edit page on BigCommerce, a custom field matching the code has been added.
A value of ‘small’ has been added to the custom field “Bulk Shipping Dimensions”. This product will expect a small.html to be found in components/bulk-dim when loaded on the storefront because of our changes.
What our component looks like on a sandbox store, as well as description-tabs.html.
What our component looks like on a sandbox store, compared to our changes to description-tabs.html.

{{jsContext}}

The {{jsContext}} Handlebars Helper paired with the {{inject}} helper bridges information to an app from a page’s context, which developers can use to access resources through JavaScript. The resource being accessed will first need to be “injected” from the context of the page using key/value pairs and {{inject}}, which can then be referenced later in a script. As such, to use {{jsContext}}, {{inject}} needs to be instantiated first. As an example, I used the code below to inject and log related product IDs:

{{inject “productIds” (pluck product.related_products “id”)}}<script>const pageContext = JSON.parse({{jsContext}});console.log(pageContext[‘productIds’]);</script>

This console logs the product IDs within the current context. It’s worth noting in this example when using {{inject}} the pluck helper is also invoked. This is to return the corresponding value, in this example being the related_products’ IDs.

{{jsContext}} returns values specified with {{inject}} for requested attributes, but without an injection we can see what the default jsContext is above.

Conclusion

Handlebars Helpers expedite development time by removing the need for verbose coding, and can quickly impact any Stencil developers’ effectiveness. After reviewing the functionalities and examples, I hope that everyone has thought of their own uses for these Handlebars Helpers!

I’m curious how others would use these helpers creatively. Share your ideas below and let us know how you’ve applied Handlebars Helpers to your Stencil themes lately.

--

--