{tree}
Renders a tree of rows: its body for every row, and {recurse} renders it again for the row's children.
Syntax
{tree 'rows'} ... {recurse} ... {/tree}
{tree data='rows', children='items'} ... {branch} ... {recurse} ... {/branch} ... {/tree}
{tree 'rows'} ... @else@ ... {/tree}
Parameters
-
rows -
The name of the rows: a
{data}block, a stored sequence, an array of the page or of an enclosing row, or a_data/file.data=names them as well.
Options
-
children -
The field of a row that holds its children, at every depth. Default
children.
Description
{tree 'menu'} renders its content - the body - once for every top row, like any data tag. The difference is inside the body: {recurse} renders that same body again for the children of the current row, each child a row of its own, and so on down to any depth. Menus, category trees, folder listings and threaded comments are all one body written once.
The children of a row are the array in its children field; the children='items' option names another field, used at every depth. A row without children - the field missing or empty - renders nothing at its {recurse}. {branch} ... {/branch} renders only for a row that has children, so the <ul> around a {recurse} is left out for a leaf, and its @else@ part renders for a leaf instead.
Every list of the tree is a level named as the tree is: depth@tree is 1 for the top rows and one more per level down, and first@tree, current@tree, count@tree speak of the list being rendered. The handling options sort, where and reverse written on the tree apply to every list, the children included. The @else@ part of the tree itself shows when there are no rows at all.
Under the strict syntax check a tree without rows named, a name nothing holds, or a tree without its closing tag is an error.
Examples
A nested menu
One body renders every level; branch leaves the inner list out for a leaf.
{data 'treeMenu'}
[
{ "title": "Home" },
{ "title": "Shop", "children": [
{ "title": "Books" },
{ "title": "Music", "children": [ { "title": "Jazz" }, { "title": "Folk" } ] } ] },
{ "title": "Contact" }
]
{/data}
<ul>
{tree 'treeMenu'}
<li>{$title}{branch}<ul>{recurse}</ul>{/branch}</li>
{/tree}
</ul>
- Home
- Shop
- Books
- Music
- Jazz
- Folk
- Contact
Another children field, sorted, with depth
children= names the field; sort applies at every level; depth@tree counts the levels.
<ul>
{tree data='folders', children='sub', sort='name'}
<li>{$name} <small>(depth {depth@tree}, {current@tree} of {count@tree})</small>{branch}<ul>{recurse}</ul>{/branch}</li>
{/tree}
</ul>
<?php
$folders = [
[ 'name' => 'src', 'sub' => [
[ 'name' => 'views' ],
[ 'name' => 'models', 'sub' => [ [ 'name' => 'user' ], [ 'name' => 'order' ] ] ] ] ],
[ 'name' => 'docs' ] ];
?>
- docs (depth 1, 1 of 2)
- src (depth 1, 2 of 2)
- models (depth 2, 1 of 2)
- order (depth 3, 1 of 2)
- user (depth 3, 2 of 2)
- views (depth 2, 2 of 2)
- models (depth 2, 1 of 2)
See also
- {branch} Inside a {tree}: renders its content only when the current row has children, its @else@ part for a leaf.
- {recurse} Inside a {tree}: renders the tree's body once more for the children of the current row.
- {data} Turns its content - JSON, XML, YAML, CSV, a list or a range - into a named data set for a later tag to iterate.