public
Description: A beautiful template engine for PHP in Django style
Home | Edit | New

Tags and Filters references

Tags

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

Testing data type


{% if variable is boolean|string|integer|true|false|float|real|number|numeric|array|object|null] %}

{% endif %}

Limitation

  • if tag 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

Recommendations

  • It is recommended to use if statement to branch out the display content, but keep the logic simple and atomic
  • If you are seeing the if statement is scattered all over the document then it is time think about:
  • Simplifying some of the logic into smaller and manageable chunk;
  • Are you abusing display logic to do your business logic;
  • Split them into a separate and reusable template file, “one template file role them all is very very very wrong”

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 => arary( 'name' => 'Peter White', 'age' => 16 ),
  2 => arary( '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.

Summery

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 [unqiue_name]%} 
...
{% endblock %}

optional syntax, give you the ability to identify a end block, it could help you to read through a clustered template.

{% block [unqiue_name] }}}

{% endblock [unqiue_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 }


{
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

{{{
#!text/html
{% 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)
{{{
#!text/html
{% block person }

My name is Peter Wacko


this is coming from {{ block.name }}


{ endblock %}

{% block address %}


18, St Peter Road, NSW 2007, Australia

{% endblock %}
}}}

child template(child.html)
{{{
#!text/html
{% extends “base.html” %}

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

I have wide range of hobbies such as swimming, watching tv and shopping…

{% 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 ==
{{{
#!text/html
{% with [a_very_long_variable_name] as short_name }
{{ shortcut }}
{
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
{{{
#!text/x-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
{{{
#!text/html
{% with galleries.first.Picture as picture }
{{ picture.name }}
{
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
{{{
#!text/html
{% 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.
{{{
#!text/html


{% for person in persons

{% endfor %}

}}}


== 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
{{{
#!text/html
{% debug %}
}}}

if you are not sure the data structure

{{{
#!text/html
{% 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.
{{{
#!text/html
{% comment %}


….

{% endcomment %}
}}}
-

== now ==
Syntax : {% 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


= Filter =

List of build-in filters.


== lower ==
convert variable to lower case.

{{{
#!text/html
{{ ’Upper CASE ’ | lower }}
// outputs “upper case”
}}}


== upper ==
convert variable to upper case.
{{{
#!text/html
{{ ‘lower case’ | upper }}
// outputs “UPPER CASE
}}}


== capitalize ==
Capitalize a value. The first character will be uppercase, all others lowercase.

{{{
#!text/html
{{ ‘page title’ | capitalize }}
// outputs “Page Title”
}}}


== capfirst ==
capitalize the first character of the string


== trim ==
remove leading and trailing spaces.

{{{
#!text/html
{{ ’ example text ’ | trim }}
// outputs “example text”
}}}
-

== length ==
the number of item in a collection or the length of a string.

String
{{{
#!text/html
{{ ‘good morning’ | length }}
//outputs “12”
}}}

Object or Array
(list of page comments)
{{{
#!text/html
/*
$page = array(‘comments’=> array(‘good thinking’, ‘i can do better’));

*/

{{ page.comments | length }}
// outputs “2”
}}}
-

== wordwrap ==
returns string wrapped after 75 characters


== default ==
set default value if variable is undefined

{{{
#!text/html
// let’s say we haven’t define $page[‘description’] yet
{{ page.description | default “page has no description” }}

// outputs “page has no description”
}}}


== escape ==
syntax: escape [boolean]
Convert special characters to HTML entities.

if second parameter is set true, it will also convert single and double quotes ("), (’) to HTML entities.


== e ==
alias to [#escape]
-

== truncate ==

return the truncated version of the string, first parameter will be the length (default:50), second parameter is string to be append at the end other than ellipsis ( default: “…”)


== strip_tags ==

remove all html or markup tags such as script, style, comments and return the readable text content. PHP’s strip_tags is only doing half.


== limitwords ==
syntax: limitwords [limit = 50] [ending = “…”]

return only [limit] (default:50) number of words and append with a ellipsis[ending] (default: “…”)


== linebreaks ==
syntax : linebreaks [format = “p”]
parameter:
format – “p” or “br”

convert linebreaks in windows, macintosh and unix/linux ("

?
“) into [format] tag,


== nl2br ==
convert newline to

alias to [#linebreaks]

== nl2pbr ==
convert newline to

alias to [#linebreaks]

== numberformat ==
syntax:
numberformat [decimals], [decimal_point_string], [thausands_seperator]

alias to PHP number_format() function.
( float $number [, int $decimals [, string $dec_point, string $thousands_sep]] )
{{{
#!text/html
{{ 125 | numberformat 3 }}
// ouputs “125.000”
}}}
-

== moneyformat ==
depreciated : use currency instead
-

== currency ==
syntax:
currency [currency = “USD”] [decimal] [parenthesis_for_negative]

format a numeric value to currency


== date ==
syntax: date “[datetime_format]”
Returns a string formatted according to the given format string using the given integer timestamp or the current time if no timestamp is given.

[datetime_format] is the same as PHP date() function http://www.php.net/date

== relative_date ==

if timestamp is within 7 days. this will format timestamp to relative date in words, eg: today, yesterday, 2 days ago. otherwise this will return to [#date]

== relative_time ==
syntax: relative_time

if timstamp is today, this will format timestamp to relative time in words. eg: 10 minutes ago, 5 hours ago otherwise this will return to [#date]

== relative_datetime ==
if timestamp is today return [#relative_time]

if timestamp is within 7 days return [#relative_date] otherwise return [#date]

== filesize ==
filesize will format numeric number of bytes into “human-readable” file size (eg: KB, MB, GB, TB … )


== first ==
return the first element of a array/list/dictionary
{{{
#!text/html
/*
$lucky_numbers = array( 12, 25, 33, 45);
*/
{{ lucky_numbers | first }}

//outputs 12

}}}
-

== last ==
return the last element of a array/list/dictionary
{{{
#!text/html
/*
$lucky_numbers = array( 12, 25, 33, 45);
*/
{{ lucky_numbers | last }}

//outputs 45

}}}
-

== join ==
syntax: join ", "

join a array/list variable with [delimitor]

{{{
#!text/html
/*
$sports = array(‘swimming’, ‘football’, ‘running’);
*/
{{ sports | join }}

//outputs “swimming, football, running”
}}}
-

== urlencode ==
encode string or associative array into url friendly string or query string.

String
{{{
#!text/html
{{ ‘peter chan’ | urlencode }}
//outputs “peter%20chan”
}}}

Associative array or Dictionary
{{{
#!text/html
/*
$search_params = array(‘name’=>’peter chan’, ‘mode’=>’person_search’);
*/

{{ search_params | urlencode }}
// outputs “name=peter%20chan&mode=person_search”
}}}


== hyphenize ==

format string into URL and SEO friendly URLS, convert white space and non-alphanumeric character into hyphen, all lower cased

{{{
#!text/html
{{ “blog post : Search Engine Optimist offers free service !” | hyphenize }}
// outputs “blog-post-search-engine-optimist-offers-free-service”
}}}
-

== urlize ==
syntax: urlize [truncate = false]

parameter:
truncate – optional interger to truncate the link
Converts URLs in plain text into clickable links.

{{{
#!text/html
{{ “http://www.yahoo.com” | urlize }}
// outputs “http://www.yahoo.com

{{ “http://www.google.com/webmaster/guidline.html” | urlize 30 }}
// outputs “http://www.google.com/webmaste…
}}}


Last edited by speedmax, Tue May 13 21:04:08 -0700 2008
Home | Edit | New
Versions: