Skip to content

Scoped Variables ({{= }})

{{= target = exprChain }} evaluates exprChain once and binds the result to target, in one of two namespaces. The target must be a bare @env/name or @local/name — a sub-pointer target such as @env/a/b is a parse-time error.

@env — render-global

{{= @env/total = 0 }}
{{#each items}}
  {{= @env/total = @env/total | plus: price }}
{{/each}}
Total: {{ @env/total }}

{{= @env/name = … }} binds in the render-global @env namespace. The binding survives {{#with}} / {{#each}} boundaries — so it can accumulate across a loop, as in the example above — and shadows a registered environment property of the same name for the rest of that render. It never mutates the environment itself; the shadow is local to the single render call.

@local — frame-scoped

{{#with user}}
  {{= @local/greeting = "Hi" }}
  {{#with address}}
    {{ @local/greeting }}, {{ city }}!    {{! reads the binding from the enclosing frame }}
  {{/with}}
{{/with}}
{{ @local/greeting }}    {{! renders empty — the binding was dropped when the outer {{#with}} ended }}

{{= @local/name = … }} binds in the frame-scoped @local namespace, read with {{ @local/name }}. A read walks outward through enclosing frames the same way ../ does (see Interpolation) — visible to the frame it was bound in and every ancestor frame, but the binding is discarded when its {{#with}} block or {{#each}} iteration ends. An unbound @local read renders empty.

Where to next

  • Environment Properties — the @env namespace this tag can shadow.
  • Blocks — the {{#with}}/{{#each}} boundaries that scope an @local binding's lifetime.