Skip to main content

Custom Helpers Reference

Collate provides 22 custom helpers to format and manipulate event data. These are in addition to standard Handlebars features. Use these helpers to transform data in your notification templates.
Combine multiple helpers to create powerful template logic. For example, use filter to show only failed tests, then limit to display only the first 5 items.

Data Extraction

pluck - Extract properties from objects

Extracts a specific property from each object in an array. Syntax:
{{#each (pluck array 'propertyName')}}
  {{this}}
{{/each}}
Example:
{{#each (pluck entity.tags 'tagFQN')}}
  <li>{{this}}</li>
{{/each}}
Extracts the tagFQN property from each tag object, resulting in a simple list of tag names.

filter - Filter lists by property value

Filters array items based on property values. Syntax:
{{#with (filter array propertyName="value") as |filtered|}}
  {{#each filtered}}
    {{this}}
  {{/each}}
{{/with}}
Example:
{{#with (filter entity.testCaseResultSummary status="Failed") as |failedTests|}}
  <p>Failed tests: {{length failedTests}}</p>
  <ul>
    {{#each failedTests}}
      <li>{{testCaseName}}</li>
    {{/each}}
  </ul>
{{/with}}
Filters test results to show only failed items.

split - Split strings into arrays

Splits a string by a delimiter into an array of parts. Syntax:
{{#each (split string "delimiter")}}
  {{this}}
{{/each}}
Example:
{{#each (split entity.fullyQualifiedName ".")}}
  <span class="breadcrumb">{{this}}</span>
{{/each}}
Splits a qualified name like database.schema.table into individual parts for display. Advanced Example - Nested Field Parsing: When parsing hierarchical field names like columns.columnName.tags, combine with lookup:
{{#with (split name '.') as |parts|}}
  {{#if (endsWith name '.tags')}}
    Tags for column {{lookup parts 1}}
  {{else}}
    Property {{lookup parts 2}} of column {{lookup parts 1}}
  {{/if}}
{{/with}}

limit - Limit array items

Limits the number of items displayed from an array. Syntax:
{{#each (limit array maxItems)}}
  {{this}}
{{/each}}
Example:
{{#each (limit failedTests 5)}}
  <li>{{testCaseName}}</li>
{{/each}}
{{#if (gt (length failedTests) 5)}}
  <li>... and {{math (length failedTests) '-' 5}} more</li>
{{/if}}
Shows first 5 items and mentions count of remaining items.
Combine limit with other helpers to prevent large notifications:
{{#each (limit (filter testResults status="Failed") 10)}}
  {{name}}
{{/each}}

lookup - Access array element by index

Accesses a specific element in an array by its index (0-based). Syntax:
{{lookup array index}}
Example:
{{#with (split entity.fullyQualifiedName ".") as |parts|}}
  Database: {{lookup parts 0}}
  Schema: {{lookup parts 1}}
  Table: {{lookup parts 2}}
{{/with}}
Useful for accessing specific parts after using split helper to parse hierarchical names.

String Operations

camelCaseToTitle - Convert camelCase to Title Case

Converts camelCase strings to Title Case format. Syntax:
{{camelCaseToTitle string}}
Example:
Type: {{camelCaseToTitle event.entityType}}
Converts testCase to Test Case, dataAsset to Data Asset.

startsWith - Check string prefix

Checks if a string starts with a specific prefix. Syntax:
{{#if (startsWith string "prefix")}}
  Content shown if true
{{/if}}
Example:
{{#if (startsWith name "columns.")}}
  <p>Column property changed</p>
{{/if}}
Useful for identifying specific field types in change descriptions.

endsWith - Check string suffix

Checks if a string ends with a specific suffix. Syntax:
{{#if (endsWith string "suffix")}}
  Content shown if true
{{/if}}
Example:
{{#if (endsWith name ".tags")}}
  <p>Tags were modified</p>
{{/if}}
Useful for identifying specific field types in change descriptions.

textDiff - Show text differences

Displays the difference between old and new text with strikethrough and highlighting. Syntax:
{{textDiff oldText newText}}
Example:
{{#each changes.updates}}
  {{#if (eq name 'description')}}
    Description change: {{textDiff oldValue newValue}}
  {{/if}}
{{/each}}
Renders old text with strikethrough and new text highlighted, making changes easy to spot. Optional Parameters: You can customize the HTML tags used for insertions and deletions:
{{textDiff oldValue newValue insTag="mark" delTag="del"}}
  • insTag: HTML tag for inserted text (default: "b")
  • delTag: HTML tag for deleted text (default: "s")

Comparison & Logic

eq - Equality check

Checks if two values are equal. Syntax:
{{#if (eq value1 value2)}}
  Content shown if equal
{{/if}}
Example:
{{#if (eq event.entityType "testCase")}}
  <p>This is a test case</p>
{{/if}}

gt - Greater than

Checks if first value is greater than the second. Syntax:
{{#if (gt value1 value2)}}
  Content shown if greater
{{/if}}
Example:
{{#if (gt (length failedTests) 0)}}
  <p>Some tests failed</p>
{{/if}}

and - Logical AND

Combines multiple conditions with logical AND. Syntax:
{{#if (and condition1 condition2)}}
  Content shown if all conditions true
{{/if}}
Example:
{{#if (and (eq event.entityType "table") changes.updates)}}
  <p>Table was updated</p>
{{/if}}
Shows content only if both conditions are true.

or - Logical OR

Combines multiple conditions with logical OR. Syntax:
{{#if (or condition1 condition2)}}
  Content shown if any condition true
{{/if}}
Example:
{{#if (or (eq status "Failed") (eq status "Aborted"))}}
  <p>Execution had issues</p>
{{/if}}
Shows content if any condition is true.

not - Logical NOT

Inverts a condition. Syntax:
{{#if (not condition)}}
  Content shown if condition false
{{/if}}
Example:
{{#if (not entity.owner)}}
  <p>This entity has no owner assigned</p>
{{/if}}

Collection Operations

groupEventChanges - Group changes into categories

Organizes field changes into separate categories: updates, additions, and deletions. Syntax:
{{#with (groupEventChanges event.changeDescription) as |changes|}}
  {{#each changes.updates}}...{{/each}}
  {{#each changes.adds}}...{{/each}}
  {{#each changes.deletes}}...{{/each}}
{{/with}}
Example:
  {{#with (groupEventChanges event.changeDescription) as |changes|}}
    {{#if changes.updates}}
      <h3>Updated Fields:</h3>
      {{#each changes.updates}}
        {{#if (eq name 'description')}}
          <li><strong>Description:</strong> {{oldValue}}{{newValue}}</li>
        {{else if (eq name 'tags')}}
          <li><strong>Tags:</strong> {{#each oldValue}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}{{#each newValue}}{{this}}{{#unless @last}},
  {{/unless}}{{/each}}</li>
        {{else if (eq name 'owner')}}
          <li><strong>Owner:</strong> {{oldValue.displayName}}{{newValue.displayName}}</li>
        {{else if (eq name 'owners')}}
          <li><strong>Owners:</strong> {{#each oldValue}}{{displayName}}{{#unless @last}}, {{/unless}}{{/each}}{{#each newValue}}{{displayName}}{{#unless @last}},
  {{/unless}}{{/each}}</li>
        {{else if (startsWith name 'columns.')}}
          {{#with (split name '.') as |parts|}}
          <li><strong>Column {{lookup parts 1}}:</strong> Updated {{lookup parts 2}}</li>
          {{/with}}
        {{else if (startsWith name 'extension.')}}
          {{#with (split name '.') as |parts|}}
          <li><strong>Custom Property '{{lookup parts 1}}':</strong> {{oldValue}}{{newValue}}</li>
          {{/with}}
        {{else}}
          <li><strong>{{name}}:</strong> {{oldValue}}{{newValue}}</li>
        {{/if}}
      {{/each}}
    {{/if}}

    {{#if changes.adds}}
      <h3>Added Fields:</h3>
      {{#each changes.adds}}
        {{#if (eq name 'tags')}}
          <li><strong>Tags:</strong> {{#each newValue}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}</li>
        {{else if (eq name 'owner')}}
          <li><strong>Owner:</strong> {{newValue.displayName}}</li>
        {{else if (eq name 'owners')}}
          <li><strong>Owners:</strong> {{#each newValue}}{{displayName}}{{#unless @last}}, {{/unless}}{{/each}}</li>
        {{else if (startsWith name 'extension.')}}
          {{#with (split name '.') as |parts|}}
          <li><strong>Custom Property '{{lookup parts 1}}':</strong> {{newValue}}</li>
          {{/with}}
        {{else}}
          <li><strong>{{name}}:</strong> {{newValue}}</li>
        {{/if}}
      {{/each}}
    {{/if}}

    {{#if changes.deletes}}
      <h3>Deleted Fields:</h3>
      {{#each changes.deletes}}
        {{#if (eq name 'tags')}}
          <li><strong>Tags:</strong> <del>{{#each oldValue}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}</del></li>
        {{else if (eq name 'owner')}}
          <li><strong>Owner:</strong> <del>{{oldValue.displayName}}</del></li>
        {{else if (eq name 'owners')}}
          <li><strong>Owners:</strong> <del>{{#each oldValue}}{{displayName}}{{#unless @last}}, {{/unless}}{{/each}}</del></li>
        {{else if (startsWith name 'extension.')}}
          {{#with (split name '.') as |parts|}}
          <li><strong>Custom Property '{{lookup parts 1}}':</strong> <del>{{oldValue}}</del></li>
          {{/with}}
        {{else}}
          <li><strong>{{name}}:</strong> <del>{{oldValue}}</del></li>
        {{/if}}
      {{/each}}
    {{/if}}
  {{/with}}

hasFieldInChanges - Check if field was modified

Checks if a specific field was modified in the change description. Syntax:
{{#if (hasFieldInChanges changes "fieldName")}}
  Content shown if field changed
{{/if}}
Example:
{{#with (groupEventChanges event.changeDescription) as |changes|}}
  {{#if (hasFieldInChanges changes "testCaseResult")}}
    <p>Test results changed</p>
  {{/if}}
{{/with}}
Must be used with changes from groupEventChanges

length - Get array/string length

Returns the number of items in an array or characters in a string. Syntax:
{{length array}}
Example:
{{#if (gt (length entity.tags) 0)}}
  <p>Tags count: {{length entity.tags}}</p>
{{/if}}

Formatting

formatDate - Format timestamps

Converts timestamps to human-readable date and time format. Syntax:
{{formatDate timestamp}}
Example:
<p>Test executed at {{formatDate entity.testCaseResult.timestamp}}</p>
Converts timestamps to format like: 2025-11-13 14:30:00 Creates a clickable URL that opens the entity in Collate UI. Syntax:
{{buildEntityUrl entityType entity}}
Example:
<a href="{{buildEntityUrl event.entityType entity}}">
  {{entity.fullyQualifiedName}}
</a>
Generates a link like: https://your-Collate/entity/table/database.schema.table Extracts entity information from entity link strings. Syntax:
{{#with (parseEntityLink linkString) as |entity|}}
  {{entity.name}}
{{/with}}
Example:
{{#with (parseEntityLink entity.relatedEntity) as |related|}}
  Related to: {{related.name}}
{{/with}}
Converts @mention syntax to clickable user profile links. Typically used with user-entered descriptions or comments that may contain @mentions to team members. Syntax:
{{{processMentions text}}}
Example:
<p>{{{processMentions entity.description}}}</p>
Converts @john.doe in text to a link to that user’s profile.
Use three curly braces {{{ to render HTML output without escaping.

resolveDomain - Resolve domain references

Displays domain names even when passed as object references. Syntax:
{{resolveDomain domainReference}}
Example:
{{#each entity.domains}}
  <li>Domain: {{resolveDomain this}}</li>
{{/each}}
This helper gracefully handles multiple input types:
  • Domain object references: {{resolveDomain domain}}
  • Already-resolved domain strings: {{resolveDomain "domain-name"}}
  • Null/undefined values: Returns empty string

Math Operations

math - Perform calculations

Performs mathematical operations on numbers. Syntax:
{{math value1 "operator" value2 "round" decimalPlaces}}
Supported Operators:
  • + - Addition
  • - - Subtraction
  • * - Multiplication
  • / - Division
  • round - Round to decimal places
Example:
Success rate: {{math (math passedTests "/" totalTests) "*" 100 "round" 2}}%
Calculates: (passedTests ÷ totalTests) × 100, rounded to 2 decimal places. More Examples:
{{math 10 '+' 5}}              <!-- 15 -->
{{math 100 '-' 30}}            <!-- 70 -->
{{math 5 '*' 3}}               <!-- 15 -->
{{math 20 '/' 4}}              <!-- 5 -->
{{math 3.14159 'round' 2}}     <!-- 3.14 -->

Next Steps