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> |