Widgets/Transformer
Template String Widget
Template String Widget
A "Transformer" type widget. Template String Widget allows you to create dynamic strings by replacing placeholders (using JavaScript expression syntax with {{expression}}) in a template with values from an input object, pre-defined date/time variables, and global variables.
Inputs
- input (DataType: Anything)
This port accepts any data type. The data received will be available in the template under the
inputvariable. If the input is a primitive type (e.g., string, number, boolean), it will be wrapped in an object like{ value: your_input }.
Outputs
- text (DataType: String) This port outputs the processed string with all placeholders replaced by their corresponding values.
Custom Settings
The Template String Widget has a text area where you define the template string. You can use JavaScript expression syntax (e.g., {{input.value}}, {{date.year}}, {{$vars.myVariable}}) to insert dynamic content. For complex operations, use the $fn() helper to execute JavaScript code (e.g., {{$fn("input.map(item => item.name).join(', ')")}}).
It also includes a "Format" drop down list with the following options:
- Text — Trims the template string (default)
- JSON — Formats the template string as a JSON. If the content is not valid JSON, it remains unchanged
- HTML — Formats the template string as HTML
Important Note: The format options only improve the editing experience and don't change the final output when the template is actually rendered. The output will be exactly as you write it in the template editor — HTML won't be rendered automatically, and JSON won't be converted to objects.

Available Template Variables
When crafting your template, you have access to the following variables and helpers:
input
This object contains the data passed to the input port.
- If the input is an object, you can access its properties directly (e.g.,
{{input.propertyName}}) - If the input is a primitive type (e.g., a string "Hello"), it will be available as
{{input.value}} - Bracket notation: Use bracket notation to access properties with special characters or spaces:
{{input['key with spaces']}}- Access properties with spaces using single quotes{{input["key with spaces"]}}- Access properties with spaces using double quotes{{input[0]}}- Access array elements by numeric index
date
This object provides various date and time properties:
year: Full year (e.g., 2025)month: Month of the year (1-12)day: Day of the month (1-31)hours: Hour of the day (0-23)minutes: Minutes of the hour (0-59)seconds: Seconds of the minute (0-59)milliseconds: Milliseconds of the second (0-999)time: Milliseconds since epochdayOfWeek: Day of the week (0 for Sunday, 1 for Monday, etc.)dayName: Full name of the day (e.g., "Monday")shortDayName: Short name of the day (e.g., "Mon")date: Alias fordayfullYear: Alias foryeartimezoneOffset: Timezone offset in minutesUTCDate: Day of the month in UTC (1-31)UTCDay: Day of the week in UTC (0 for Sunday, 1 for Monday, etc.)UTCFullYear: Full year in UTCUTCHours: Hour of the day in UTC (0-23)UTCMilliseconds: Milliseconds of the second in UTC (0-999)UTCMonth: Month of the year in UTC (1-12)UTCMinutes: Minutes of the hour in UTC (0-59)UTCSeconds: Seconds of the minute in UTC (0-59)isoString: ISO 8601 string representation of the date(e.g., "2025-05-24T10:30:00.000Z")localeString: Locale-specific string representation of the date
$vars
This object provides access to global variables defined in your workspace:
- Dot notation:
{{$vars.variableName}}- Access a global variable by name - Bracket notation (static):
{{$vars["variableName"]}}- Access using string literal - Bracket notation (dynamic):
{{$vars[input.fieldName]}}- Access using dynamic key from context - Returns the current value of the global variable
- Returns
undefinedif the variable doesn't exist - Note: Nested bracket notation like
$vars[$vars["key"]]is not currently supported
$secrets
This object provides access to secrets mapped to the recipe:
- Dot notation:
{{$secrets.secretName}}- Access a secret by name - Example:
{{$secrets.apiKey}}retrieves the secret named "apiKey" - Returns the decrypted secret value if it exists and is mapped to the recipe
- Returns an empty string if the secret doesn't exist or is not mapped
- Security note: Bracket notation (
$secrets["key"]) is not currently supported
$fn() Helper
This helper allows you to execute JavaScript code within your template for complex operations:
- Syntax:
{{$fn("javascript_code_here")}} - Array operations:
{{$fn("input.map(item => item.name).join(', ')")}} - Filtering:
{{$fn("input.filter(item => item.active).length")}} - Calculations:
{{$fn("input.reduce((sum, item) => sum + item.price, 0)")}} - Conditionals:
{{$fn("input.length > 0 ? 'Items available' : 'No items'")}} - String methods:
{{$fn("input.name.toUpperCase()")}} - Complex Math:
{{$fn("Math.sin(PI / 4)")}} - All variables from your template context (
input,date,$vars) are available within$fn()
Math Functions (Available Directly)
These Math functions can be used directly in expressions without $fn():
- Basic:
round(),floor(),ceil(),abs() - Min/Max:
min(),max() - Powers:
sqrt(),pow() - Constants:
PI,E - Example:
{{round(input.price)}},{{max(a, b, c)}},{{PI * radius * radius}}
Array Operations
When working with arrays in your templates, use the $fn() helper with JavaScript array methods for powerful data manipulation:
Basic Array Access
- Direct indexing:
{{input[0]}}for the first element - Array length:
{{input.length}}for the total number of elements (only wheninputis directly an array; for nested arrays likeinput.tasks.length, use{{$fn("input.tasks.length")}}) - Property access:
{{input[0].name}}for object properties within arrays
Array Iteration with $fn()
- Simple mapping:
{{$fn("input.map(item => item.name).join(', ')")}} - With indexing:
{{$fn("input.map((item, index) => (index + 1) + '. ' + item).join('\\n')")}} - Conditional formatting:
{{$fn("input.map((item, index) => (index === 0 ? '[FIRST] ' : '') + item).join(', ')")}} - First/last detection:
{{$fn("input.map((item, index, arr) => item + (index === arr.length - 1 ? ' [LAST]' : '')).join(', ')")}}
Advanced Array Operations
- Filtering:
{{$fn("input.filter(item => item.active).map(item => item.name).join(', ')")}} - Sorting:
{{$fn("input.sort((a, b) => a.name.localeCompare(b.name)).map(item => item.name).join(', ')")}} - Calculations:
{{$fn("input.reduce((sum, item) => sum + item.price, 0)")}}
Examples
Basic Usage with Date Variables
This example demonstrates how to create a personalized meeting schedule message by combining a name input with formatted date and time information.
Drag the example onto the workspace to explore and experiment!
In this example
- The Text widget provides the name "John Doe" as a primitive
Stringvalue - The Template String widget receives the name and combines it with a formatted message using:
- The input name via
{{input.value}} - The current date and time using various date helpers:
{{date.dayName}}for the day of the week{{date.month}}/{{date.day}}/{{date.year}}for the date{{date.hours}}:{{date.minutes}}for the time
- The input name via
- The resulting formatted message is displayed in another Text widget, showing a personalized greeting with the current date and time
Using Object Input
This example demonstrates how to create a personalized user account summary by accessing nested properties from a JSON object input.
Drag the example onto the workspace to explore and experiment!
In this example
- A JSON object containing user information is provided as input, with nested properties for user details and location
- The Template String widget accesses the nested properties using dot notation:
{{input.user.firstName}}for the user's first name{{input.user.email}}for the email address{{input.user.location.city}}and{{input.user.location.country}}for the location{{input.user.lastLogin}}for the last login timestamp
- The resulting formatted message displays a personalized account summary with all the user's information neatly organized
Using Global Variables ($vars)
This example demonstrates how to access global variables using all three notation styles: dot notation, static bracket notation, and dynamic bracket notation.
Drag the example onto the workspace to explore and experiment!
Setting up Global Variables
To use this example, you'll need to create the following Global Variables in the Global Variables Panel:
- Group variable named
usercontaining:- Group variable named
profilecontaining:- Text variable named
country(e.g., value: "Spain")
- Text variable named
- Group variable named
- Text variable named
greeting(defines the greeting message) - Text variable named
team(displays the team name)
In this example
- The Button Widget triggers the Text Widget to output a JSON string containing
nameandvariableKeyfields - The JSON Parse Widget converts the text string into a JSON object
- The Template String Widget builds the message using Global Variables (created and managed in the Global Variables Panel) combined with the parsed input object. The template accesses global variables using all three notation styles:
- Dynamic bracket notation:
{{$vars[input.variableKey]}}- Access using a dynamic key from the input context (thevariableKeyfield contains "greeting", so it accesses$vars.greeting) - Dot notation:
{{$vars.team}}- Direct access by variable name - Static bracket notation:
{{$vars["user.profile.country"]}}- Access using string literals (useful for keys with special characters or dots)
- Dynamic bracket notation:
- The Text Widget displays the final formatted message output
Using Secrets in Template Strings
This example demonstrates how to access secrets mapped to the recipe using the $secrets object in a template string.
Drag the example onto the workspace to explore and experiment!
Prerequisites / Setup
To use this example, you'll need to set up secret mapping:
- Create (or ensure you already have) a Hub Secret available in the workspace (e.g.,
TOKEN) - Add a Secret Widget to the recipe and select/declare the secret name used by the workflow (e.g.,
TOKEN). The widget is used for mapping and does not need to be connected - Open Recipe Secrets (Secret Mapping) and map the required secret to an environment variable:
- Confirm the required secret name appears (e.g.,
TOKEN) - Select the Context (e.g.,
develop) - Select the matching Environment Variable (e.g.,
TOKEN) - Click Save
- Confirm the required secret name appears (e.g.,
- After mapping, the secret can be referenced in Template String using dot notation (e.g.,
{{$secrets.TOKEN}})
In this example
- The Secret Widget declares the
TOKENsecret used in the recipe and prompts mapping it to an environment variable via the Secret modal - The Button Widget triggers the Template String Widget to process the template
- The Template String Widget retrieves the mapped secret value using
{{$secrets.TOKEN}}and injects it into the formatted output - The Text Widget displays the final rendered message containing the decrypted secret value
Creating a Numbered Task List with $fn()
This example demonstrates how to create a numbered task list using JavaScript array methods within the $fn() helper for formatting each item with proper numbering and conditional formatting.
Drag the example onto the workspace to explore and experiment!
In this example
- A JSON object containing user information with
nameproperty, adatefield, and an array oftaskswhere each task has atitleproperty is provided as input - The Template String widget uses JavaScript array methods within
$fn()to create a personalized task summary:{{input.user.name}}and{{input.date}}for personalized greeting{{$fn("input.tasks.map((task, i, arr) => (i === 0 ? 'First Task 👇\\n' : '') + '✅ Task #' + (i + 1) + ': ' + task.title + (i === arr.length - 1 ? '\\nLast Task ☝️' : '')).join('\\n')")}}to iterate over tasks with numbering and conditional formatting- Array methods like
map()withi(index) andarr(array) parameters for 1-based numbering and first/last detection - Conditional logic within the
$fn()usingi === 0for the first task andi === arr.length - 1for the last task {{$fn("input.tasks.length")}}to display the total number of tasks
- The resulting output shows a personalized message with a numbered task list, demonstrating how JavaScript array methods within
$fn()can be used to create rich, structured content from array data with full programming flexibility
📌 Additional Notes
- The Template String widget uses JavaScript expression syntax with
expr-evalfor variable substitution and calculations - When using the
Textformat (default), special characters in the output are HTML-encoded (e.g.,/becomes/) - To prevent HTML escaping: Use triple curly braces
{{{variable}}}instead of double curly braces{{variable}}when you need unescaped output (useful for file paths, URLs, or when you want literal characters) - The
JSONformat is useful when you need to generate structured data - Date and time values are always in the local timezone unless explicitly using UTC helpers (e.g.,
{{date.UTCHours}}) - For primitive input types (string, number, boolean), use
{{input.value}}to access the value - Nested object properties can be accessed using dot notation (e.g.,
{{input.user.profile.name}}) - Array values can be accessed using JavaScript array syntax (e.g.,
{{input.user.pets[0]}}) - Bracket notation supports quoted strings for properties with spaces or special characters (e.g.,
{{input['full name']}},{{input["user age"]}}) - The Template String widget automatically handles undefined or null values by replacing them with empty strings
- Template variables are case-sensitive (e.g.,
{{input.user.firstName}}is different from{{input.user.firstname}}) - Use
$fn()helper for complex array operations, calculations, and conditional logic with full JavaScript capabilities - Global variables are accessible via
{{$vars.variableName}}or{{$vars["variableName"]}}syntax, with support for dynamic keys like{{$vars[input.key]}} - Basic operators and Math functions are available within expressions (e.g.,
{{input.length > 0}},{{round(input.price)}}) - The
$fn()helper provides access to the full JavaScript runtime for advanced operations
Expression Syntax Support
✅ Supported directly in {{}} expressions:
- Basic arithmetic:
{{5 + 3}},{{input.price * 1.2}} - Comparisons:
{{input.length > 0}},{{price >= 100}} - Logical operators:
{{true and false}},{{not isEmpty}} - Math functions:
{{round(3.7)}},{{max(1, 5, 3)}},{{sqrt(16)}} - Math constants:
{{PI}},{{E}} - Simple property access:
{{input.name}},{{user.age}} - Ternary operator:
{{input.isTrue ? 'yes' : 'no')}}
❌ Requires $fn() helper:
- JavaScript logical operators:
{{$fn("true && false")}} - String methods:
{{$fn("input.name.toUpperCase()")}} - Array methods:
{{$fn("items.join(', ')")}} - Array property access on nested arrays:
{{$fn("input.tasks.length")}}(for arrays, use$fn(); object properties like{{input.user.profile.settings.theme}}work directly)
Glossary
-
ISO 8601
An international standard for representing dates and times in a consistent format
(YYYY-MM-DDTHH:mm:ss.sssZ). -
UTC
Coordinated Universal Time, the primary time standard by which the world regulates clocks and time. UTC is independent of time zones and provides a consistent reference point for global time coordination.
-
Global Variables Panel
A centralized interface component in Kemu that provides a single location to create, configure, and manage Global Variables used throughout recipes. Global Variables are values that persist during recipe execution and can be accessed and modified from any widget in the workflow or directly from the panel interface. The panel enables centralized variable management, runtime control, configuration sharing across workflows, and hierarchical organization of related variables. Variables created in the panel are immediately available to widgets, expressions, and services throughout the recipe. Users can open the Platform Help from the left sidebar (question mark icon) to find more information about the Global Variables Panel