Skip to main content

Working with lists

SHIPM8 extends Handlebars with a set of array helpers. Several are block helpers — they create a new inner context rather than returning a value inline, and must be closed with {{/helperName}}.


Filter a list

arrayFilter is a block helper that filters an array down to only the elements matching a given term.

arrayFilter array filterTerm property partialSearch
ArgumentTypeDescription
arrayarrayThe array to filter.
filterTermstringThe value to filter by.
propertystringThe object property to check (only needed for arrays of objects).
partialSearchbooleanOptional: true allows partial matches.

Example — exact match

{{#arrayFilter portCalls 'Rotterdam' 'port'}}
{{#each this}}{{eta}} {{/each}}
{{/arrayFilter}}

Data:

{
"portCalls": [
{ "port": "Rotterdam", "eta": "2024-03-10" },
{ "port": "Antwerp", "eta": "2024-03-13" },
{ "port": "Rotterdam", "eta": "2024-03-18" }
]
}

Result: 2024-03-10 2024-03-18

Example — partial match

{{#arrayFilter portCalls 'dam' 'port' 'true'}}
{{#each this}}{{port}} {{/each}}
{{/arrayFilter}}

Result: Rotterdam Amsterdam


Find an item

arrayFind is a block helper that works exactly like arrayFilter but returns only the first matching element.

arrayFind array filterTerm property partialSearch
ArgumentTypeDescription
arrayarrayThe array to search.
filterTermstringThe value to find.
propertystringThe object property to check (only needed for arrays of objects).
partialSearchbooleanOptional: true allows partial matches.

Example

{{#arrayFind portCalls 'Hamburg' 'port'}}
{{eta}}
{{/arrayFind}}

Data: same port-calls array as above, with Hamburg added → Result: the ETA for Hamburg only.


Group items

groupBy is a block helper that groups an array by one or more properties. It supports three output modes: items (default), count, and sum.

groupBy array property action actionField decimalSeparator isPropertyJsonPath
ArgumentTypeDescription
arrayarrayThe array to group.
propertystringProperty (or comma-separated list) to group by. Keys are joined with _ for multi-property groups.
actionstringOptional: items (default), count, or sum.
actionFieldstringOptional: field to sum (required for sum).
decimalSeparatorstringOptional: decimal separator used when parsing sum values.
isPropertyJsonPathbooleanOptional: treat property as a JSON path expression (e.g. vessel.type).

Output shapes:

items  →  [{ "key": string, "items": any[] }]
count → [{ "key": string, "count": number }]
sum → [{ "key": string, "sum": number }]

Example — group by port (items)

{{#groupBy portCalls 'port'}}
{{#each this}}
{{key}}: {{#each items}}{{eta}} {{/each}}
{{/each}}
{{/groupBy}}

Result:

Rotterdam: 2024-03-10 2024-03-18
Antwerp: 2024-03-13
Hamburg: 2024-03-15

Example — count calls per port

{{#groupBy portCalls 'port' 'count'}}
{{#each this}}{{key}}: {{count}}
{{/each}}
{{/groupBy}}

Result:

Rotterdam: 2
Antwerp: 1
Hamburg: 1

Example — sum tonnage by cargo type

{{#groupBy shipments 'cargoType' 'sum' 'tonnage'}}
{{#each this}}{{key}}: {{sum}} MT
{{/each}}
{{/groupBy}}

Data:

{
"shipments": [
{ "cargoType": "Crude Oil", "tonnage": 50000 },
{ "cargoType": "Crude Oil", "tonnage": 30000 },
{ "cargoType": "Iron Ore", "tonnage": 75000 },
{ "cargoType": "LNG", "tonnage": 20000 }
]
}

Result:

Crude Oil: 80000 MT
Iron Ore: 75000 MT
LNG: 20000 MT

Example — group by multiple properties

{{#groupBy shipments 'cargoType,vessel' 'sum' 'tonnage'}}
{{#each this}}{{key}}: {{sum}} MT
{{/each}}
{{/groupBy}}

Result: Crude Oil_Ocean Star: 50000 MT etc. (key is values joined by _).

Example — group by nested property (JSON path)

{{#groupBy shipments 'vessel.type' '' '' '' 'true'}}
{{#each this}}{{key}}: {{items.length}} shipment(s)
{{/each}}
{{/groupBy}}

Data:

{
"shipments": [
{ "vessel": { "type": "Tanker" }, "cargo": "Crude Oil" },
{ "vessel": { "type": "Tanker" }, "cargo": "LNG" },
{ "vessel": { "type": "Bulker" }, "cargo": "Iron Ore" }
]
}

Result:

Tanker: 2 shipment(s)
Bulker: 1 shipment(s)

Sort a list

sortedArray is a block helper that sorts an array. You always need an inner #each to print the result.

sortedArray array sortField sortNumeric formats
ArgumentTypeDescription
arrayarrayThe array to sort.
sortFieldstringField(s) to sort by, comma-separated. Prefix a field with ! to sort descending.
sortNumericbooleanOptional: true for numeric sort (default is string sort).
formatsstringOptional: comma-separated .NET format strings (one per sort field) applied before comparison.

Example — single sort

{{#sortedArray portCalls 'eta'}}
{{#each this}}
- {{port}} {{eta}}
{{/each}}
{{/sortedArray}}

Result (ascending ETA):

- Amsterdam 2024-03-08
- Rotterdam 2024-03-10
- Hamburg 2024-03-15
- Antwerp 2024-03-18

Example — multiple sort fields

{{#sortedArray shipments 'cargoType,!tonnage'}}
{{#each this}}{{cargoType}} {{tonnage}} | {{/each}}
{{/sortedArray}}

Sorts by cargoType ascending, then tonnage descending within each group.

Example — numeric sort

By default the sort is string-based ("9" sorts after "10"). Pass 'true' as the third argument for a numeric sort.

{{#sortedArray shipments 'tonnage' 'true'}}
{{#each this}}{{vessel}}: {{tonnage}} | {{/each}}
{{/sortedArray}}

Join into text

Concatenates array elements into a single string with a separator. Optionally extracts a named field from each object.

join array separator fieldName
ArgumentTypeDescription
arrayarrayThe array to join.
separatorstringString placed between each element.
fieldNamestringOptional: field to extract from each object. Lookup is case-insensitive.

Example

{{join ports ', '}}                    => Amsterdam, Rotterdam, Antwerp
{{join portCalls ' → ' 'port'}} => Amsterdam → Rotterdam → Antwerp

Count items (length)

Returns the number of elements in an array.

arrayLength array
ArgumentTypeDescription
arrayarrayThe array to count.

Example

{{arrayLength portCalls}}    => 4
{{arrayLength shipments}} => 3

Combine lists (concat)

arrayConcat is a block helper that merges two or more arrays into a single array in the inner context.

arrayConcat array1 array2 ...
ArgumentTypeDescription
array1arrayThe first array.
array2arrayThe second (and any further) array to merge.

Example

{{#arrayConcat northSeaCalls atlanticCalls}}
{{#each this}}{{port}} {{/each}}
{{/arrayConcat}}

Data:

{
"northSeaCalls": [
{ "port": "Rotterdam" },
{ "port": "Hamburg" }
],
"atlanticCalls": [
{ "port": "Antwerp" },
{ "port": "Amsterdam" }
]
}

Result: Rotterdam Hamburg Antwerp Amsterdam


Repeat an object (from object)

arrayFromObject is a block helper that creates an array of N copies of the same object — useful when you need to repeat a template element based on a numeric field value.

arrayFromObject object occurrences
ArgumentTypeDescription
occurrencesnumberNumber of times the object is repeated in the output array.

Example

{{#arrayFromObject cargo cargo.containerCount}}
{{#each this}}
- Container ({{type}})
{{/each}}
{{/arrayFromObject}}

Data: { "cargo": { "type": "Containers", "containerCount": 3 } } → produces 3 identical rows.


Split text into a list

split is a block helper that splits a string into an array using one or more delimiter characters.

split value delimiters keepEmpty
ArgumentTypeDescription
valuestringThe string to split.
delimitersstringA string whose individual characters are each treated as a delimiter.
keepEmptybooleanOptional: true keeps empty entries. Default: false.

Example

{{#split 'Amsterdam,Rotterdam,Antwerp' ','}}
{{#each this}}{{this}} {{/each}}
{{/split}}

Result: Amsterdam Rotterdam Antwerp

{{#split 'Crude Oil;LNG|Iron Ore' ';|'}}
{{#each this}} {{this}}{{/each}}
{{/split}}

Result: Crude Oil LNG Iron Ore