Knowledge Base

Creating Custom Handlebars Helpers

Last Modified:
25 Jun 2026
User Level:
Administrator
Complexity:
Advanced

Out-of-the-Box Helpers

Terminalfour ships with a rich library of built-in Handlebars helpers that cover the most common templating needs. Things like string manipulation, date formatting, conditional logic, and iteration over content. These helpers are available to be used in all your Page layouts and content layouts without any additional configuration.

However, there are times when the built-in helpers simply don't cover what you need. You might want to:

  • Encode or transform data in a way specific to your organisation (e.g. generating a custom format, or applying institution-specific business logic to a string).
  • Manipulate content in non-standard ways.
  • Abstract repeated template logic into a single reusable helper rather than duplicating complex inline expressions across many layouts.
  • Format output in ways the built-in helpers don't support: custom number formats, institution-specific date patterns, or specialized HTML structures.

In all of these cases, Custom Handlebars Helpers give you the power to extend Terminalfour's Handlebars templating with your own JavaScript functions.

A note on the current setup requirements:

Managing Custom Helpers today requires navigating to a specific section in your site structure using a section ID retrieved via a SQL query. We recognize this is not an ideal experience: it requires database access and familiarity with Terminalfour's internals that shouldn't be necessary for what is ultimately a templating task.

This is a temporary requirement. A dedicated UI for creating and managing Custom Helpers is planned, which will make the process straightforward without any need for SQL or manual section navigation. When that UI ships, all existing helpers you have created through the current workflow will automatically appear there. Nothing will need to be migrated or recreated.

In the meantime, the steps below walk you through the current process.

Defining Custom Helpers

Custom Helpers are managed through the Terminalfour interface itself. They live as content items inside a dedicated (hidden) section in your site structure.

Here's how to set one up:

1. Find the Helpers Section

First, you'll need to locate the section in your site structure where helpers are stored. You can find this by running the following SQL query against your Terminalfour database:

SELECT * FROM config_option WHERE config_key='handlebars.helpersSectionId'

This will return the section ID for the section where Custom Helpers should be created and managed. Make a note of the relevant section ID.

If you cannot run SQL against your instance, contact Client Support who can provide you with the Section ID for managing Custom Helpers in your instance.

2. Edit the Section

Navigate to the section identified by the query above in Site Structure. To do this, open any section from the Site Structure and update the URL in your browser to reference the Section ID you found step 1.

E.g https://your-instance.terminalfour.net/terminalfour/page/section#edit/<YOUR_SECTION_ID>

3. Create a Content Item

Inside the helpers section, create a new content item. Only one Content Type is enabled in this section but if you see an option to select a Content Type, ensure you select the one named "Handlebars Helpers".

The content item has two elements:

  • Name
    • This is the name by which you will call the helper inside your Handlebars templates. For example, if you set this to formatPostcode, you would invoke it as {{formatPostcode someValue}} in your layouts. Ensure you use a camelCase naming convention to avoid issues.
      Custom Helpers that share a name with a built-in Helper will take precedence when a layout is being processed.
      Avoid using a Custom Helper name that clashes with a built-in Helper unless you intentionally want to override the behavior.
  • Function Code
    • This is where you write the JavaScript function that defines the helper's behavior.

Once the content is created, your Custom Helper is available to use in your page layouts and content types.

The status of the Content Item defining your Custom helper is ignored. We recommend saving and approving the content to avoid issues.

Writing Your Helper Function

All custom helpers must be defined using the following function signature:

function(context, options) {
  // your logic here
}

  • context is the value passed as the first argument to the helper when it is called in a template (e.g. {{myHelper someValue}}: someValue is the context).
  • options is a Handlebars options object that provides access to hash arguments, and other utilities outlined below
    Method Description
    options.params Returns a List<Object> of all positional parameters
    options.param(int)

    Gets a specific positional parameter by index

    For example: options.param(1)

    options.hash(String)

    Gets a named (hash-style) parameter.

    For example: options.hash('element')

    options.tagType()

    Returns the type of Handlebars expression the helper was called from.

    This is useful if you need to change behavior of your helper depending on whether it's called as a standard expression, triple-stashed expression, or a block level expression.

    Possible tag types returned include:

    • VAR - standard double stashed expressions. E.g. {{example}}
    • TRIPLE_VAR - triple stashed expressions. E.g. {{{example}}}
    • SUB_EXPRESSION - helpers called via a subexpression. E.g. {{abbreviate (example)}}

Example: Replacing instances of a string

A helper named replaceT4 that finds all instances of T4 and replaces it with Terminalfour:

function (context, options) {
  var result = context.replaceAll("\\bT4\\b", "Terminalfour");
  return result;
}

Usage in a layout:

{{{replaceT4 (publish element="Content")}}}

Example: Truncate a string to a given number of words

A helper named truncateWords that takes user provided text from a Plain Text Element and returns the first 10 words.

Unlike the built-in abbreviate Helper, this Helper will return a fixed number of words rather than characters.

function (context, options) {
  var text = context;
  var maxWords = 10;
  var suffix = "...";

  var words = text.trim().split(/\s+/);
  if (words.length <= maxWords) {
    return text;
  }
  var truncated = words.slice(0, maxWords).join(" ") + suffix;
  return truncated;
}

Usage in a layout:

{{truncateWords (publish element="Title")}}

Logging Warnings and Errors

It's strongly recommended that you add error handling to any Custom helpers you create.

This ensures that debugging is easier for developers. Logs can be exposed during Preview using the built-in captureLogs Helper.

An example of throwing different log types:

function (context, options) {
  log.debug("A debug level log has been thrown. Details can be added here.");
  log.info("An info level log has been thrown. Details can be added here.");
  log.warn("A warn level log has been thrown. Details can be added here.");
  log.error("An error level log has been thrown. Details can be added here.");
}

The publishAPI

When writing custom helpers, you have access to a special object called the publishAPI. This is a Terminalfour-provided API that is injected into the helper execution context at publish time, giving your helpers safe, structured access to data within your Terminalfour instance, without needing direct database access or external HTTP calls.

Why Is This Useful?

The publishAPI opens up a wide range of possibilities for powerful, data-driven helpers:

  • Look up content items by ID
    • resolve relationships between content at publish time, for example fetching a related article's metadata from another section.
  • Read section information
    • get details about a section (its name, the content it contains, its metadata) to build dynamic navigation.
  • Traverse the site hierarchy
    • walk up the section tree to build contextual output, such as breadcrumbs.
  • Retrieve data from elsewhere in your system.

Because the publishAPI is provided and managed by Terminalfour, it handles authentication, permissions, and safe read access automatically. You don't need to worry about exposing credentials or accidentally writing to your data.

Example: Fetching a Section Name via publishAPI

There is a built-in helper to get the current section name. But if you need to retrieve it from a Custom Helper it can be done like

function(context, options) {
  var sectionName = apis.getSection().getName();
  return sectionName;
}

Full publishAPI Documentation

For the complete reference (including all available methods, their parameters, and return types) refer to the official Terminalfour publishAPI documentation.

This can be found by visiting the Community Extranet (select the version 7 community site) and navigating to "Documentation > Developer Documentation > Publish API".

Join the community

Consider joining the #handlebars channel in our Slack community where members have been managing a shared collection of useful Custom Helpers.

If you don't already have access to the Community Slack, reach out to your Terminalfour Relationship Manager who can provide an invite.

Back to top