Nunjucks Helpers for Skeleton Entities
Skeleton Entities are rendered with Nunjucks using the ${{ ... }} syntax.
Standard Nunjucks syntax is available in skeleton rendering, including conditions, loops, and built-in filters. This page documents the Witboost-specific helpers available in Skeleton Entities, plus dump because it is the built-in filter used most often in Witboost skeletons.
The helpers documented here are available when Witboost renders:
catalog-info.yamlparameters.yamlexpressions in theparameters,values,readonly, andenvironmentParameterssectionsrefs.<name>.configinparameters.yaml
The variables available in each phase differ. For example, refs are available only when rendering catalog-info.yaml, while refs.<name>.config can use parameters, values, and readonly.
dump
dump is a built-in Nunjucks filter commonly used in Skeleton Entities to serialize a value while preserving its type.
Use it when you want a string, object, array, boolean, number, or map to be emitted as valid YAML.
Input:
- any scalar value, array, or object
Output:
- a serialized representation of that value, suitable for insertion into YAML
Example input:
parameters:
owner: group:finance-data
tags:
- pii
- finance
Example usage:
%SKELETON
kind: Component
spec:
owner: ${{ parameters.owner | dump }}
tags: ${{ parameters.tags | dump }}
Example output:
kind: Component
spec:
owner: group:finance-data
tags:
- pii
- finance
parseEntityRef
parseEntityRef is a filter that parses an entity reference into its structured parts.
Use it when you need to extract the kind, namespace, or name from a Witboost entity reference.
Input:
- a Witboost entity reference string
Output:
- an object with the parsed entity reference parts, including
kind,namespace, andname
Example input:
group:default/finance-data
Example output:
kind: group
namespace: default
name: finance-data
Example usage:
%SKELETON
kind: Component
metadata:
description: Owned by team ${{ (parameters.owner | parseEntityRef).name }}
pick
pick is a filter that extracts a nested field from an object using a dot-separated path.
Use it when an object contains nested data and you want a single field.
Input:
- first argument: an object or array
- second argument: a dot-separated path string such as
spec.owneror@graph.0.@id
Output:
- the value found at that path
nullorundefinedif the path does not resolve to a value in the input object
Example input:
spec:
owner: group:finance-data
mesh:
maturity: strategic
Example output with pick('spec.owner'):
group:finance-data
Example usage:
%SKELETON
kind: Component
spec:
mesh:
maturity: ${{ parameters.metadata | pick('mesh.maturity') }}
parseRdf(...)
parseRdf is a global helper that parses RDF content and returns an object value that can be used in Nunjucks and that follows JSON-LD syntax.
Use it when the skeleton needs to inspect RDF data available in the rendering context.
Input:
- the RDF content as a string
- an optional format string
Supported format strings:
autoturtlen3trigntriplesnquadsrdfxmljsonld
If the format is omitted, the parser tries to auto-detect it from the input content and the optional parsing metadata.
Output:
nullif the input content isnull,undefined, or an empty string- otherwise, an object using JSON-LD syntax, typically containing
@contextand@graph
Example input in Turtle format:
@prefix ex: <http://example.com/> .
ex:Tom a ex:Person ;
ex:name "Tom" .
Example output for Turtle input:
'@context':
ex: http://example.com/
'@graph':
- '@id': ex:Tom
'@type': ex:Person
ex:name: Tom
Example input in RDF/XML format:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.com/">
<rdf:Description rdf:about="http://example.com/Tom">
<rdf:type rdf:resource="http://example.com/Person" />
<ex:name>Tom</ex:name>
</rdf:Description>
</rdf:RDF>
Example output for RDF/XML input:
'@context':
ex: http://example.com/
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
'@graph':
- '@id': ex:Tom
'@type': ex:Person
ex:name: Tom
Example input already written with JSON-LD syntax:
{
"@context": {
"ex": "http://example.com/"
},
"@id": "ex:Tom",
"@type": "ex:Person",
"ex:name": "Tom"
}
Example output for JSON-LD input:
'@context':
ex: http://example.com/
'@graph':
- '@id': ex:Tom
'@type': ex:Person
ex:name: Tom
Example usage in a skeleton:
%SKELETON
kind: Component
metadata:
annotations:
ontology-subject: ${{ parseRdf(parameters.ontology, 'turtle') | pick('@graph.0.@id') }}
Rendered catalog-info.yaml:
metadata:
annotations:
ontology-subject: ex:Tom
slugify
slugify is a helper, available as both a Nunjucks function and a filter, that normalizes free text into a lowercase, separator-joined string.
Use it when you need to turn free text (for example, a display name typed by the user) into a value safe for identifiers, URLs, or labels, without writing a manual replace/split/join/lower filter chain.
Unlike the other helpers on this page, slugify is also available in Legacy fetch:template scaffolder steps. See Custom functions for that context.
Input:
value(required): the free-text string to sanitizeseparator(optional): the character(s) used in place of illegal or whitespace characters; defaults to-. Pass""to concatenate without a separator
Output:
- a lowercase string with diacritics removed, illegal/whitespace characters replaced by
separator, consecutive separators collapsed, and leading/trailing separators trimmed ""if the sanitized value has no characters left — this is a valid result, not an error
Errors: fails with a descriptive error if value is not a string (or is an empty string), or if separator is not a string, or contains whitespace, a comma, a semicolon, a colon, or diacritics.
Example input:
parameters:
name: "Domain: Finance / Transactions!"
Example usage:
%SKELETON
kind: Component
metadata:
name: ${{ slugify(parameters.name) }}
labels:
team: ${{ parameters.name | slugify("_") }}
Example output:
kind: Component
metadata:
name: domain-finance-transactions
labels:
team: domain_finance_transactions
parseWitboostId
parseWitboostId is a helper, available as both a Nunjucks function and a filter, that parses a Witboost URN or a Builder entity reference into its structured parts.
Use it when you need to extract the domain, system, component, or subcomponent segments out of a Witboost identifier.
Unlike the other helpers on this page, parseWitboostId is also available in Legacy fetch:template scaffolder steps. See Custom functions for that context.
Input:
- a Witboost URN (
urn:dmb:..., including domain URNs such asurn:dmb:dmn:<domain>) or a Builder entity ref (for exampledomain:default/finance,system:default/finance.transactions.0,component:default/finance.transactions.0.workload)
Output: an object with the parsed identifier parts. The available fields depend on the kind of the parsed identifier:
kind | Available fields |
|---|---|
domain | kind, raw, type, domain |
system | kind, raw, type, domain, systemName, majorVersion |
component | kind, raw, type, domain, systemName, majorVersion, componentName, parentSystem |
subcomponent | kind, raw, type, domain, systemName, majorVersion, componentName, subcomponentName, parentComponent |
| Field | Description |
|---|---|
kind | domain, system, component, or subcomponent |
raw | the parsed urn:dmb:... value |
type | the raw URN type code, e.g. dmn, dp, cmp |
domain | the domain segment |
systemName | the system segment; present for system/component/subcomponent identifiers |
majorVersion | the system's major version; present for system/component/subcomponent identifiers |
componentName | the component segment; present for component/subcomponent identifiers |
subcomponentName | the subcomponent segment; present for subcomponent identifiers |
parentSystem | the parsed parent system identifier (same shape as a system result); present for component identifiers |
parentComponent | the parsed parent component identifier (same shape as a component result, including its own parentSystem); present for subcomponent identifiers |
Errors: fails with a descriptive error if the input is neither a well-formed urn:dmb:... value nor a Builder entity ref that can be resolved to one.
Example input:
component:default/finance.transactions.0.workload
Example output:
kind: component
raw: urn:dmb:cmp:finance:transactions:0:workload
type: cmp
domain: finance
systemName: transactions
majorVersion: 0
componentName: workload
parentSystem:
kind: system
raw: urn:dmb:dp:finance:transactions:0
type: dp
domain: finance
systemName: transactions
majorVersion: 0
Example input for a subcomponent:
urn:dmb:cmp:finance:transactions:0:workload:task
Example output:
kind: subcomponent
raw: urn:dmb:cmp:finance:transactions:0:workload:task
type: cmp
domain: finance
systemName: transactions
majorVersion: 0
componentName: workload
subcomponentName: task
parentComponent:
kind: component
raw: urn:dmb:cmp:finance:transactions:0:workload
type: cmp
domain: finance
systemName: transactions
majorVersion: 0
componentName: workload
parentSystem:
kind: system
raw: urn:dmb:dp:finance:transactions:0
type: dp
domain: finance
systemName: transactions
majorVersion: 0
Example usage:
%SKELETON
kind: Component
metadata:
annotations:
domain: ${{ parseWitboostId(parameters.outputPortRef).domain }}
component: ${{ (parameters.outputPortRef | parseWitboostId).componentName }}
# component identifiers expose their parent system
componentSystemUrn: ${{ parseWitboostId(parameters.outputPortRef).parentSystem.raw }}
# subcomponent identifiers expose their parent component, which in turn exposes its own parent system
subcomponentParentUrn: ${{ parseWitboostId(parameters.subcomponentUrn).parentComponent.raw }}
subcomponentSystemUrn: ${{ parseWitboostId(parameters.subcomponentUrn).parentComponent.parentSystem.raw }}
Practical Notes
- Use
dumpwhenever you inject arrays, maps, or nested objects into YAML. parseEntityRefandpickare filters, so they are used with the|syntax.parseRdfis a global helper, so it is called like a function.slugifyandparseWitboostIdare registered as both functions and filters, and are also usable in Legacyfetch:templatescaffolder steps.