{join:delimiter:val1:val2:...}

Description

Concatenates an unlimited number of values into a single string, separated by the first parameter (the delimiter). Values that are empty or contain only whitespace are dropped before joining, so the delimiter never appears next to a gap - handy for optional fields like a second address line. As a special case, a delimiter of the literal word json returns a JSON array of the non-empty values instead of a joined string. Parameters are not trimmed, so the delimiter may be a single space and values keep any leading or trailing spaces.

Parameters

delimiter required default (required - no default)

The separator placed between the joined values. It is inserted only between kept (non-empty) values, never at the start or end and never next to a dropped value. It is used verbatim and is not trimmed, so a single space is a valid delimiter. The literal word json is a special case: instead of joining, it returns a JSON array of the non-empty values.

value1, value2, ... optional default (empty - dropped)

One or more values to join, given after the delimiter. There is no fixed limit on how many you pass. Each value that is empty or contains only whitespace is dropped, so optional fields collapse cleanly and the delimiter is never doubled. Values are not trimmed - any leading or trailing spaces you include are kept in the output.

Examples

test{join:, :Brno:Czechia}
ExpectedBrno, Czechia
ActualBrno, Czechia
The first parameter is the delimiter; the rest are values. Here two values are joined with a comma and a space.
test{join:, :Brno::Czechia}
ExpectedBrno, Czechia
ActualBrno, Czechia
The middle value is empty, so it is skipped and the delimiter is not doubled.
test{join: - ::Prague:}
ExpectedPrague
ActualPrague
When all but one value are empty, you get just that value - no leading or trailing delimiter.
test{join::abc:def}
Expectedabcdef
Actualabcdef
An empty first parameter (nothing between the first two colons) joins the values with no separator.
test{join: :one:two:three}
Expectedone two three
Actualone two three
Parameters are not trimmed, so a single space is a valid delimiter.
test{join:,: :Prague}
ExpectedPrague
ActualPrague
A value that contains only spaces counts as empty and is dropped, just like a fully empty one.
test{join:json:Brno::Czechia}
Expected["Brno","Czechia"]
Actual["Brno","Czechia"]
The literal delimiter json is a special case: it returns the non-empty values as a JSON array instead of a joined string.
virtual{join:<br>:Apex Org:Apex Street:apex.example}
ExpectedApex Org
Apex Street
apex.example
ActualApex Org
Apex Street
apex.example
A common real-world pattern: stack optional fields (organization, address, web) with a line break, so blank fields leave no empty rows. Marked illustrative because the output is HTML the browser renders.