Structural tags

MX’s structural core is a small set of tags that render exactly the way Marko renders them, on every host. A host may forbid one of these tags outright, but it may never change what one means.

<try> is implemented as a core-owned custom tag: the core validates one portable call shape, then requests the active host’s try primitive. Projects cannot shadow its name.

<if> / <else if> / <else>

<if=user.loggedIn>
  <p>Welcome back, ${user.name}.</p>
</if>
<else if=user.isGuest>
  <p>Browsing as a guest.</p>
</else>
<else>
  <p>Please sign in.</p>
</else>

The html target lowers this to a plain JS if/else if/else chain around the corresponding output. SolidMX lowers the same tag to Solid’s <Show> for two or fewer conditioned branches, or <Switch>/<Match> for three or more, matching what a hand-written Solid component would use for a branch.

<for>

<for> covers four distinct iteration shapes, chosen by which attribute you write.

of= — iterate a list

<for|item, i| of=items>
  <li>${i}: ${item.name}</li>
</for>

Add by= to key each row for reconciliation:

<for|item| of=items by="id">
  <li>${item.name}</li>
</for>

On the html target this is a plain for/.map loop. On SolidMX, of= lowers to Solid’s <For each={...} keyed={...}>, and by="id" becomes the keyed key function.

by= is evaluated once, outside the loop body, so the loop param is not in scope there. Key with a property-name string (by="id") or a function (by=(item) => item.id); by=item.id is a compile error pointing at item, as in Marko.

in= — iterate an object’s entries

<for|key, value| in=config>
  <dt>${key}</dt><dd>${value}</dd>
</for>

Lowers over Object.entries(...).

from= / to= / until= / step= — iterate a numeric range

<for|i| from=0 to=9>
  <span>${i}</span>
</for>

to= is inclusive, until= is exclusive; add step= for a stride other than 1. On SolidMX this lowers to Solid’s <Repeat> rather than <For>, since there is no list to key against — only a count. When from/to/step are all literals the row count is folded at compile time; when any is dynamic, the count is computed at render time and clamped to zero rather than ever producing an infinite range (a step=0 you write directly is a parse error; a step that evaluates to 0 at runtime clamps to zero rows).

What’s next

Tag params and attribute tags apply to <for>'s own |item, i| binding too — see Attribute tags and tag params.

To define project-specific tags that expand before a host sees them, continue with Custom tags.