Skip to content
This repository

Tags reference

if

The if tag is very similar to the if statement in computer programming. In h2o you can use the if tag to test either a
variable, string or numbers. It is designed to do simple tests to branch out display content.

Syntax

{% if true %}
  ...
{% else %} 
  ...
{% endif %}

Example
A good usage of branching display content, use white space, comment

<div class="person female"> 

  {% if person.age > 17 %}         {* Adult *} 
    she is a adult lady 
  {% else %}                       {* Too young *} 
    she is a child 
  {% endif %} 

</div> 

Expression can be joined by following keywords

and 
or
not
! – shortcut to not

Comparision

<     – less than 
> – greater than
>= – equal or greater than
<= – equal or less than
== – equal
!= – not equal

Limitation
Does not support

  • expression grouping, ifelse or if else statements, function calls for good reason,
  • it is designed to encourage you to do the right thing :), so keep it simple and tight

for

This is the only loop construct in h2o template.
bq. loop is a sequence of commands that is executed repeatedly – Wikipedia

The for tag is a very powerful construct to iterate or loop through the content of a object, regardless if it is an array, a dictionary(hash, keyword indexed array), or an object.

Syntax

{% for [key], [item] in [list] %}
    ...
{% endfor %} 

You can name key and item anything you like.

Example
Let’s say we have a $person data array in our application

$persons => array(
  1 => array( 'name' => 'Peter White', 'age' => 16 ),
  2 => array( 'name' => 'Dr ABC', 'age' => 56 ),
);
{% for index, person in persons %}
  {{ index}}.   {{ person.name }} - {{ person.age }} years old
{% endfor %}

outputs

1. Peter White – 16 years old
2. Dr ABC – 56 years old

Lets have another try…

<?php
$keywords = array('SEO friendly', 'markets', 'widget king');
?>
<meta name="keywords", value="
  {% for term in keywords %}
     {{ term }} {%if !loop.last %},{% endif %}
  {% endfor %}" />

The “loop” variable will be discussed later.

Outputs

 <meta name="keywords", value="SEO friendly, markets, widget king" />

Magic loop variable

The magic “loop” variable is available inside the scope of any for loop.

Booleans

  • loop.first – is first iteration
  • loop.last – is last iteration
  • loop.odd – the odd iterations (1, 3, 5, 7.. )
  • loop.even – the even iterations (0, 2, 4, 6…)

Counters

  • loop.counter – 1 based iteration count
  • loop.counter0 – 0 based
  • loop.revcounter – reversed 1 based iteration count ( 10, 9, 8 )
  • loop.revcounter0 – reversed 0 based iteration count ( 9, 8, … 0, boom)

More

  • loop.length – number of item in the list
  • loop.parent – point to the parent loop variable, you can check "if loop.parent.first "

This is a blessing if you decide to have a pretty data grid displayed with
the alternative rows, row/column headers, or footer highlighted.
The magic ‘loop’ variable is similar to the [wiki:H2oReference#cycle cycle tag].

Reversed keyword

If you decide to iterate in reverse order, this will be it

Example

 {% for keyword in keywords reversed %}
    // Print out keywords in reversed order
 {% endfor %}

Recommendations

  • Since you can name the [key] and [value] any thing you want, make it short, descriptive and sweet. ( person instead of current_person. )
  • The loop itself is very fast, so let’s keep it like that and avoid nested loop when one loop can perform the task.
  • please don’t introduce any of the nested loop hell, maximum of two level. I didn’t even bother to implement the “loop” variable more than two level anyway.

Limitations

  • This is the only way to loop through a list of data, h2o does not support any of the traditional foreach|for|while|do while|while do in computer programming, again for good reasons.
  • Loop variable only works for two level of nested loop, I won’t implement them. We are making web pages not 3D games.

Summary

It’s a very powerful and easy feature, Just imagine
1. you load a SimpleXML with any xml/rss/atom document, and for tag prints em all.
2. you load a query a database with either object or aray data, and for tag prints em all.

<?php 
 $h2o = new h2o('feed.html');
 $feed = simplexml_load_file('http://www.digg.com/rss/index.xml');
 $h2o->evaluate(compact('feed')); 
?>

H2O template – feed.html

<h1>Feeder : {{ feed.channel.title | capitalized }} </h1>
 {% for entry in feed.channel.item %}
        <h3>{{ entry.title | capitalize}}</h3>
        <p>{{ entry.description }}</p>
 {% endfor %}

may be you can already tell what this 8 liner can do, very nice way to end this, so i will stop right there.


block

Block tag provides you the ability to group your template code such as html into smaller and manageable chunk.

{% block [unique_name] %}
...
{% endblock %}

This optional syntax gives you the ability to identify an end block. It could help you to read through a clustered template.

{% block [unique_name] %}
...
{% endblock [unique_name] %}

Consequently, your child template will inherit all the content of base template, also can override those portion of template.

’’’block variable’’’
A magic variable “block” will be automatically available inside scope of block.

  block.depth          //  depth of current block
  block.name           //  name of block
  block.super          //  content of parent block

Base template

{% block javascripts %}
   <script src="script1.js"></script>
   <script src="script2.js"></script>
{% endblock %}

Child template

{% extends 'base.html' %}

{% block javascripts %}
    {{ block.super }}
    <script src="script3.js"></script>
{% endblock %}

This is a example that you can take advantage of blocks to extend your template on the fly.(include new javascript)

Tips

  1. if you found you have a lot of common element inside the template, it may be a good idea # put that portion of template in side a block in a base template.
  2. block gives you a hook, especially useful when you are doing template inheritance.
  3. When defining a block use a short and distinctive name

extends

{% extends "[path to base template]" %}

extends tag tells h2o template engine current document extends from a base template, so all previously defined block will be inherited and can be override. this is very similar to the principle of object oriented programming, anyone who has OO experience will feel right at home, Otherwise, don’t worry and here is a example.

base template (base.html)

{% block person %}
   <p> My name is Peter Wacko</p>
   <p> this is coming from {{ block.name }} </p>{% endblock %}

{% block address %}   <address>
      <p>18, St Peter Road, NSW 2007, Australia</p>
   </address>
{% endblock %}

child template(child.html)

{% extends "base.html" %}

{% block person %}
 {{ block.super }}

 <p>I have wide range of hobbies such as swimming, watching tv and shopping... </p>
{% endblock %}

Explanation
As you can see, base template defined a block (person), as child template extends parent block all block previously defined
will be inherited.

Deep inheritance
You can have deeper inheritance like following, this is also a good example.

base.html 
section.html ( extends base.html )
page.html ( extends section.html )
  • base.html – define all common elements such as head/body tag, layout information.
  • section.html – define section specific template contains common presentation of a section.
  • page.html – define only page specific elements.

Limitation
When you working deep inheritance more than 2 level, you should be aware following.

1. You can only override, block tag defined inside your direct parent. 1. Therefore, it wouldn’t work, If you trying to override a block only defined in base.html from page.html,

Since it could potentially lead to confusion and unnecessary overhead, so it is still under consideration whether or not to allow direct override your grandparent or grand-grandparent.

with

 {% with [a_very_long_variable_name] as short_name %}
   {{ short_name }}
{% endwith %}
With tag is designed to give you the the ability to create a shortcut variable

Let’s say you have a variable in PHP

$galleries => array( 
    0 => array('Picture' => array('name' => 'name of 1st picture', 'url' => 'http://domain.com/logo.gif'), 
    1 => array('Picture' => array('name' => 'name of 2nd picture', 'url' => 'http://domain.com/peter.jpeg'),
);

With tag give you a nice shortcut

 {% with galleries.first.Picture as picture %}
    <a href="{{ picture.url }}">{{ picture.name }}</a>
 {% endwith %}

Note: List.first, List.last is shortcut provided by H2O engine to access first and last object inside a list.

’’’Benefit’’’
1. Its Faster, doing a very complex lookup can be slow. with tag actually speed things up because you are creating a reference in shortcut variable.
2. Helps you to simplify those Long , complex and ugly variable name.

cycle

Syntax:

 {% cycle [value1], [value2] %}

if value contains non alpha numeric character, it is recommended to put quotes (") outside them

{% cycle "#fffff", "#00000" %} 

cycle tag is usually used inside a loop(for tag) , can cycle through a sequence of values.

Alternative highlighting for table rows couldn’t be easier.

<table>
{% for person in persons %}
    <tr style="background:{% cycle red, black %}>
        <td>{{ person.name }}</td> 
        <td>{{ person.address }}</td>
    </ tr>
{% endfor %}
</ table>

debug

Debug tag is a very handy utility to inspect the content of a variable, unspecified variable then debug tag will print out all variable content.

Syntax: {% debug [optional variable] %}

if you are not sure what variable is in template just do a

{% debug %}

if you are not sure the data structure

{% for person in persons %}
    {% debug person %}
{% endfor %}

comment

When you want to comment out a portion of template. This is a alternative syntax for multi line comments.

{% comment %}
<div id="experimental-stuff"> 
  ....

{% endcomment %}

now

{% now "[optional time_format]" %}

Now tag outputs the current time, you can pass in a time format string to customize time format, time format string is same as date function in PHP, http://www.php.net/date

Something went wrong with that request. Please try again.