Skip to content

Conformance Examples 0.1.0 — Render: each-block

each-array-iterates-in-order

A {{#each X }} block over a JsonArray iterates elements in order with {{this}}.

Template

{{#each items }}({{ this }}){{/each}}

Context

{
    "items": [
        1,
        2,
        3
    ]
}

Output

(1)(2)(3)

each-array-of-objects-pushes-object-context

Iterating an array of objects lets the body resolve fields on each element.

Template

{{#each items }}<{{ name }}>{{/each}}

Context

{
    "items": [
        {
            "name": "a"
        },
        {
            "name": "b"
        }
    ]
}

Output

<a><b>

each-object-iterates-in-insertion-key-order

A {{#each X }} block over a JsonObject iterates its entries in insertion order, pushing each value.

Template

{{#each scores }}[{{ this }}]{{/each}}

Context

{
    "scores": {
        "c": 3,
        "a": 1,
        "b": 2
    }
}

Output

[3][1][2]

each-empty-array-no-else-emits-nothing

Empty array, no else arm: emits nothing.

Template

before {{#each items }}({{ this }}){{/each}} after

Context

{
    "items": []
}

Output

before  after

each-empty-array-with-else-renders-else

Empty array, else arm present: renders the else arm.

Template

{{#each items }}({{ this }}){{else}}none{{/each}}

Context

{
    "items": []
}

Output

none

each-empty-object-with-else-renders-else

Empty object, else arm present: renders the else arm.

Template

{{#each scores }}{{ this }}{{else}}empty{{/each}}

Context

{
    "scores": {}
}

Output

empty

each-missing-key-no-else-emits-nothing

Identifier resolves to nothing (missing key), no else: emits nothing.

Template

[{{#each absent }}x{{/each}}]

Context

{
    "items": [
        1,
        2
    ]
}

Output

[]

each-missing-key-with-else-renders-else

Identifier resolves to nothing (missing key), else arm present: renders the else arm.

Template

{{#each absent }}x{{else}}fallback{{/each}}

Context

{
    "items": [
        1,
        2
    ]
}

Output

fallback

each-primitive-no-else-emits-nothing

Identifier resolves to a JsonPrimitive, no else: emits nothing.

Template

[{{#each name }}x{{/each}}]

Context

{
    "name": "Alice"
}

Output

[]

each-primitive-with-else-renders-else

Identifier resolves to a JsonPrimitive, else arm present: renders the else arm.

Template

{{#each name }}x{{else}}not iterable{{/each}}

Context

{
    "name": "Alice"
}

Output

not iterable

each-root-context-as-object-iterates-values

{{#each this}} with no nesting iterates the root context object's entries in insertion order, pushing each value.

Template

{{#each this }}[{{ this }}]{{/each}}

Context

{
    "c": 3,
    "a": 1,
    "b": 2
}

Output

[3][1][2]

each-nested-blocks

Each blocks can be nested; inner {{this}} sees the inner element, outer context is restored after.

Template

{{#each rows }}{{#each this }}({{ this }}){{/each}};{{/each}}

Context

{
    "rows": [
        [
            1,
            2
        ],
        [
            3
        ]
    ]
}

Output

(1)(2);(3);

each-parent-pointer-from-body

Inside an each body, ../X resolves against the outer (pre-iteration) context.

Template

{{#each items }}{{ this }}-{{ ../label }}|{{/each}}

Context

{
    "label": "L",
    "items": [
        1,
        2
    ]
}

Output

1-L|2-L|

each-pop-restores-outer-context

After an each block ends, the outer context is restored for following interpolations.

Template

{{ /label }}|{{#each items }}{{ this }}{{/each}}|{{ /label }}

Context

{
    "label": "outer",
    "items": [
        1,
        2
    ]
}

Output

outer|12|outer

each-peer-blocks

Two each blocks at the same level each push and pop correctly.

Template

{{#each a }}{{ this }}{{/each}}-{{#each b }}{{ this }}{{/each}}

Context

{
    "a": [
        1,
        2
    ],
    "b": [
        3,
        4
    ]
}

Output

12-34

each-non-this-on-primitive-element-is-null

When the array element pushed onto the stack is a primitive, any non-this identifier soft-fails and resolves to null.

Template

{{#each items }}{{ x }}{{/each}}

Context

{
    "items": [
        "a",
        "b"
    ]
}

Output

nullnull

each-object-non-this-on-primitive-value-is-null

Object iteration pushes each value; if the value is a primitive, non-this identifiers soft-fail and resolve to null.

Template

{{#each scores }}{{ x }}{{/each}}

Context

{
    "scores": {
        "a": 1
    }
}

Output

null

each-with-block-inside-each

A {{#with}} nested inside an {{#each}} body works and pops correctly back to the iteration element.

Template

{{#each users }}{{#with profile }}{{ name }}{{/with}}|{{/each}}

Context

{
    "users": [
        {
            "profile": {
                "name": "A"
            }
        },
        {
            "profile": {
                "name": "B"
            }
        }
    ]
}

Output

A|B|

each-empty-array-with-empty-else-emits-nothing

Empty array with present-but-empty else arm emits nothing (else is rendered, but it has no content).

Template

[{{#each items }}x{{else}}{{/each}}]

Context

{
    "items": []
}

Output

[]

each-object-non-sorted-keys-preserve-insertion-order

Struct iteration order is insertion order, not alphabetical: keys 'z', 'a', 'm' (already out of sorted order) render in that exact insertion sequence. A HashMap-backed port would fail this fixture.

Template

{{#each letters }}{{ @key }}{{/each}}

Context

{
    "letters": {
        "z": 1,
        "a": 2,
        "m": 3
    }
}

Output

zam

each-doubled-adjacent-each-same-key

Two adjacent {{#each}} blocks over the same key iterate independently; the second is unaffected by the first.

Template

{{#each xs }}({{ this }}){{/each}}{{#each xs }}[{{ this }}]{{/each}}

Context

{
    "xs": [
        1,
        2
    ]
}

Output

(1)(2)[1][2]

Source fixture: render/each-block.json