sercrod

*iterate

Aliases: *iterate, n-iterate Category: placement

Summary

*iterate declares a host-owned placement region. It reads an iterable value, selects a registered *template for each item, and keeps the placed children synchronized without clearing and rebuilding the parent host.

The recommended data shape is an array of objects with a type field:

{
  rows: [
    { type: "text", title: "Hello" },
    { type: "image", title: "Photo" }
  ]
}

With that shape, the short form is enough:

<template *iterate="rows"></template>

<template>
  <section *template="'text'">%item.title%</section>
  <figure *template="'image'">%item.title%</figure>
</template>

This is read as:

Forms

Short form

<template *iterate="rows"></template>

This is equivalent to:

{ iterable: "rows", variable: "item", template: "item.type" }

Use this when each item is an object and its type field names the template to render.

JavaScript-like form

<template *iterate="row of rows"></template>

This keeps the default template selector based on the chosen variable:

{ iterable: "rows", variable: "row", template: "row.type" }

Object form

Use the object form when the data shape does not use the default names:

<template *iterate="{ iterable: 'rows', variable: 'row', template: 'row.kind' }"></template>

Fields:

For a constant template, write the template name as the template value:

<template *iterate="{ iterable: 'names', variable: 'name', template: 'name-row' }"></template>
<p *template="'name-row'">%name%</p>

Template Selection

template is evaluated for each item in a scope that includes the parent host data and the current value name.

<template *iterate="{ iterable: 'rows', variable: 'row', template: 'row.kind' }"></template>

<section *template="'note'">%row.title%</section>
<section *template="'task'">%row.title%</section>

If row.kind evaluates to "note", Sercrod renders the template registered as note.

Template sources can be ordinary elements or native template elements:

<section *template="'note'">%item.title%</section>

<template *template="'task'">
  <article>%item.title%</article>
</template>

A plain native <template> can be used only to group template declarations in the HTML source:

<template>
  <section *template="'text'">%item.title%</section>
  <section *template="'image'">%item.title%</section>
</template>

The grouping wrapper is not an iterate warehouse. *iterate still selects the registered *template names directly.

Scope

Normal template elements use the parent host scope plus the current item variable:

<section *template="'text'">%item.title%</section>

A child <serc-rod> without data receives the same local scope for its initial render.

A child <serc-rod data="item"> is handled by the parent placement logic: the parent evaluates item in the local scope, passes that object as the child host data root, and prevents the child from parsing data="item" in the global scope.

<serc-rod *template="'editor'" data="item">
  <p>%title%</p>
  <button @click="count++">%count%</button>
</serc-rod>

Inside that child host, %title% and %count% refer to the item object.

Staged item editing

A data-less child <serc-rod *stage> inside an iterate template can stage the current object item without making that item the child host's data root:

<serc-rod *template="'editor'" *stage>
  <input *input="item.title">
  <p>%item.title%</p>

  <button type="button" *apply>Apply</button>
  <button type="button" *restore>Restore</button>
</serc-rod>

This rule is narrow:

Use <serc-rod data="item"> when the child should be an independent item-root host. Use data-less <serc-rod *stage> when the child should keep the inherited iterate scope while editing the current object item in a confirmable staged buffer.

Identity And Placement

*iterate is not a faster *for. *for repeats one element from scratch during rendering. *iterate owns a placement region and keeps item-to-DOM records for the current browser run.

Rules:

With *dominate

*dominate suppresses the parent host's automatic full redraw, but it does not suppress placement sync. During an automatic update on a dominate host, Sercrod synchronizes registered iterate regions instead of clearing and rebuilding the parent template. The older *dominant spelling remains available as an alias.

This allows large parent hosts to remain stable while item children are added, removed, moved, replaced, or locally updated.

Removed v0.1 placement shape

Sercrod v0.2 removes the older grouped-template placement shape:

{ list: "rows", as: "item", template: "row-tpl", unit: "item.type" }

template no longer names a warehouse, and unit / *unit / *entry are not used for v0.2 *iterate placement. Use iterable, variable, and template instead.

Warnings

Missing template sources, invalid iterate expressions, unsupported legacy place fields, and non-template anchors warn with [Sercrod warn] and continue where possible.