While HTML itself does not support conditionally displaying elements or repeating elements, it is a critical part of building any web application. In Marko, this functionality is provided by the <if>
and <for>
tags.
The <if>
tag recieves an argument which is used to determine if its body content should be present.
<ifuser.loggedOut><a href="/login">Log in</a></if>
ifuser.loggedOuta href="/login" -- Log in
As you might expect, there are also <else>
and <else-if>
tags as well:
<ifuser.loggedOut><a href="/login">Log in</a></if><else-if!user.trappedForever><a href="/logout">Log out</a></else-if><else>Hey !</else>
ifuser.loggedOuta href="/login" -- Log inelse-if!user.trappedForevera href="/logout" -- Log outelse -- Hey !
If you have a list of data and need to represent it in the UI, the <for>
tag is probably what you're looking for. The <for>
tag passes each item and its index to its body as parameters.
<ul><forcolor, index of=colors><li>: </li></for></ul>
ulforcolor, index of=colorsli -- :
The <for>
tag actually support 3 different flavors:
<for|item, index, array| of=array>
renders its body for each item of an array. It's similar to the JavaScript for...of
loop.<for|key, value| in=object>
renders its body for each property in an object. It's similar to the JavaScript for...in
loop.<for|value| from=first to=last step=increment>
renders its body for each value in between and including from
and to
.key
Marko automatically keeps your UI in sync with the state behind it, but one place where it needs a little extra help is repeated content. Specifying keys gives Marko a way to identify items in a list and keep track of which items have been changed, added, or removed.
A key should be a string or number that uniquely identifies an item in the list and differentiates it from its siblings. The same key value should never be used twice! Often, you will use something like an id
property.
<foruser of=users><user-card key=user.id data=user/></for>
foruser of=usersuser-card key=user.id data=user
ProTip: If you have multiple tags underneath
<for>
, you can key only the first tag and that is enough to properly identify its sibilings as well<dl><forentry of=entries><!-- only the first tag needs a key --><dt key=entry.id></dt><!-- This key can be omitted --><dd></dd></for></dl>dlforentry of=entries// only the first tag needs a keydt key=entry.id --// This key can be omitteddd --
EDITNote: If a key is not set, Marko will use the index of an item as its key. However this only works perfectly if items are only ever added or removed at the end of a list. Here's an example where things break down: if we have a list of
["A", "B", "C"]
and reverse the order, index keys would cause "A" to be transformed into "C" (and "C" into "A"), rather than just swapping them. Additionally if these components contained state, the new "C" would contain the state from the old "A" (and vice-versa). Be aware, stateful components include tags like the native<input>
element. For this reason it is always recommended to set akey
on tags in a<for>
.
Helpful? You can thank these awesome people! You can also edit this doc if you see any issues or want to improve it.