| Template code | Chunk output | |
|---|---|---|
{#example_1}
<ul>
{% loop in $list as $item %}
<li>{$item}</li>
{% endloop %}
</ul>
{#}
Theme theme = new Theme("examples");
// Fetch template from this file: themes/examples/loop.chtml
// Inside that file there is a template "snippet" named #example_1
Chunk html = theme.makeChunk("loop#example_1");
html.set("list", new String[]{"apples","bananas","carrots","durian"} );
html.render( out );
|
|
<ul> <li>apples</li> <li>bananas</li> <li>carrots</li> <li>durian</li> </ul>
|
| Template code | Chunk output | |
|---|---|---|
{#example_2}
<div id="widget-list">
<h2>Widgets</h2>
{% loop in $widgets %}
<div>
{$widget_id}
{$widget_name}
</div>
{% onEmpty %}
{!-- Always provide an onEmpty block in case $widgets is empty/null --}
<div><i>No widgets found!</i></div>
{% endloop %}
</div>
<div id="wodget-list">
<h2>Wodgets</h2>
{% loop in $wodgets %}
<div>
{$wodget_id}
{$wodget_name}
</div>
{% onEmpty %}
<div><i>No wodgets found!</i></div>
{% endloop %}
</div>
{#}
Theme theme = new Theme("examples");
// Fetch template from this file: themes/examples/loop.chtml
// Inside that file there is a template "snippet" named #example_2
Chunk html = theme.makeChunk("loop#example_2");
// getWidgets() might return an array/list of Map objects
// or an array/list of objects that implement com.x5.util.DataCapsule
// or an object that implements com.x5.util.TableData
//
html.set("widgets", getWidgets());
// Templates are *not* allowed to invoke object methods directly!
// So for example, you can't just place objects directly into the
// chunk with .set() and expect to have access to the public methods
// of the Widget class from the template:
//
// Widget w = new Widget();
// html.set("widget", w);
//
// Widget[] widgetsForSale = getWidgetsForSale();
// html.set("widgets", widgetsForSale);
//
// Why? It violate separation-of-concerns. Your code would get ugly, fast.
//
// Not to worry, gluing your custom object into the template doesn't have
// to be busy work. If your class implements com.x5.util.DataCapsule,
// then you will be able to define a short list of "getter" methods
// that are safe for exposing to the template, and the code above will
// work fine.
//
// See the "Data Capsules (easy MVC)" example or the docs for more info.
html.render( out );
|
|
<div id="widget-list"> <h2>Widgets</h2> <div> 1001 Hoositwhatsit </div> <div> 1002 Thingamajig </div> <div> 1003 Gadget </div> <div> 1004 Bauble </div> <div> 1005 Bangle </div> </div> <div id="wodget-list"> <h2>Wodgets</h2> <div><i>No wodgets found!</i></div> </div> Widgets
1001
Hoositwhatsit
1002
Thingamajig
1003
Gadget
1004
Bauble
1005
Bangle
WodgetsNo wodgets found!
|
| Template code | Chunk output | |
|---|---|---|
{#example_3}
{!-- The {% loop in $list as $x %} syntax is the preferred form.
-- The "as" makes your loop template more readable, especially
-- when looping over a list of objects (aka maps, dictionaries,
-- associative arrays, parameter bags, etc).
--
-- Without the "as" clause, it is not even possible to nest loops
-- over similar data types, since the unprefixed attribute tags
-- from the inner and outer loops would collide. Inner loop
-- scope always takes precedence.
--}
<div id="widget-list">
{% loop in $widgets as $w %}
<div class="widget widg_{$w.widget_id}">
{$w.widget_id}
{$w.widget_name}
{% if ($w.related_widgets|len != 0) %}
<div class="related">
<h2>Related Widgets:</h2>
{% loop in $w.related_widgets as $r %}
<div class="related_widget related_widg_{$r.widget_id}">
{$r.widget_id}
{$r.widget_name}
</div>
{% onEmpty %}
{% endloop %}
</div>
{% endif %}
</div>
{% endloop %}
</div>
{#}
Theme theme = new Theme("examples");
// Fetch template from this file: themes/examples/loop.chtml
// Inside that file there is a template "snippet" named #example_3
Chunk html = theme.makeChunk("loop#example_3");
// {% loop %} is pretty smart.
// It knows how to iterate over several different kinds of input.
//
// getWidgets() might return an array/list of Map objects (think JSON)
// or an array/list of objects that implement com.x5.util.DataCapsule
// or an object that implements com.x5.util.TableData
// or a String with tabular data in InlineTable format:
//
// String inlineTable = "[[heading_1,heading_2,heading_3],"
// + "[data_1,data_2,data_3],"
// + "[data_1,data_2,data_3]]";
//
DataCapsule[] widgets = getWidgets();
html.set("widgets", widgets);
html.render( out );
|
|
<div id="widget-list">
<div class="widget widg_1001">
1001
Hoositwhatsit
<div class="related">
<h2>Related Widgets:</h2>
<div class="related_widget related_widg_1002">
1002
Thingamajig
</div>
<div class="related_widget related_widg_1003">
1003
Gadget
</div>
</div>
</div>
<div class="widget widg_1002">
1002
Thingamajig
</div>
<div class="widget widg_1003">
1003
Gadget
</div>
<div class="widget widg_1004">
1004
Bauble
</div>
<div class="widget widg_1005">
1005
Bangle
</div>
</div>
|
| Template code | Chunk output | |
|---|---|---|
{#example_4}
{!-- Sometimes you need some special css for the first and last
-- items in a list. Set first_last="true" in your .loop options
-- to get three special tags:
--
-- {$first} is defined on the first iteration.
-- {$last} is defined on the final iteration.
-- {$place} is "first" or "" or "last" as appropriate.
--
-- If you prefer other tag names for those flags, set the first_last
-- argument to your preferred tag names:
-- first_last="primero,ultimo,puesto"
--
-- Note the use of the rpad filter (new in 2.6.4) to append
-- a space only when the tag value is non-empty.
--}
<style>
.widgets .first { border-top: 1px solid blue; }
.widgets .last { border-bottom: 2px solid green; }
</style>
<div class="widgets">
{% loop in $widgets first_last="true" %}
<div class="{$place|rpad}widget">
{$widget_id}
{$widget_name}
</div>
{% endloop %}
</div>
{#}
import net.minidev.json.JSONValue;
//...
Theme theme = new Theme("examples");
// Fetch template from this file: themes/examples/loop.chtml
// Inside that file there is a template "snippet" named #example_4
Chunk html = theme.makeChunk("loop#example_4");
// Sometimes a chtml snippet is a cool place to store some data.
String jsonWidgets = theme.fetch("loop#example_7");
html.set("widgets", JSONValue.parse(jsonWidgets).get("widgets"));
html.render( out );
|
|
<style>
.widgets .first { border-top: 1px solid blue; }
.widgets .last { border-bottom: 2px solid green; }
</style>
<div class="widgets">
<div class="first widget">
1001
Hoositwhatsit
</div>
<div class="widget">
1002
Thingamajig
</div>
<div class="widget">
1003
Gadget
</div>
<div class="widget">
1004
Bauble
</div>
<div class="last widget">
1005
Bangle
</div>
</div>
|
| Template code | Chunk output | |
|---|---|---|
{#example_5}
{!-- Customized tags example --}
<style>
.widgets .primero { border-top: 1px solid blue; }
.widgets .ultimo { border-bottom: 2px solid green; }
</style>
<div class="widgets">
{% loop in $widgets first_last="primero,ultimo,puesto" %}
<div class="{$puesto|rpad}widget">
{$widget_id}
{$widget_name}
</div>
{% endloop %}
</div>
{#}
import net.minidev.json.JSONValue;
//...
Theme theme = new Theme("examples");
// Fetch template from this file: themes/examples/loop.chtml
// Inside that file there is a template "snippet" named #example_4
Chunk html = theme.makeChunk("loop#example_4");
// Sometimes a chtml snippet is a cool place to store some data.
String jsonWidgets = theme.fetch("loop#example_7");
html.set("widgets", JSONValue.parse(jsonWidgets).get("widgets"));
html.render( out );
|
|
<style>
.widgets .primero { border-top: 1px solid blue; }
.widgets .ultimo { border-bottom: 2px solid green; }
</style>
<div class="widgets">
<div class="primero widget">
1001
Hoositwhatsit
</div>
<div class="widget">
1002
Thingamajig
</div>
<div class="widget">
1003
Gadget
</div>
<div class="widget">
1004
Bauble
</div>
<div class="ultimo widget">
1005
Bangle
</div>
</div>
|