Skip to content
Pabl3ras edited this page Sep 14, 2010 · 1 revision

Haanga is a template engine that uses Django syntax. In the beginning it was developed for Menéame, but we decided to release it as an independent project so it can be used by anyone :-)

Some Hangaa’s features

  • Human readable
  • Easy to use and mantain.
  • Highly efficient because every template is “compiled” into a PHP script
  • The generated code is ready to take advantage from any PHP optimizer (like xcache).

Why a new template engine?

  • At Meneame performance is prioritary.
    1. The compilation is only made in the worst case (when there is no template or the template is newer than the generated)
    2. Usually, only a small piece of Haanga is loaded –the one that checks and determinates if it’s necessary a compilation.
    3. Generated code is optimized.
      1. One function is generated.
      2. Everything is PHP (no context changes between HTML and PHP)
  • Django’s syntax is beautiful :-)

Beginnings of the project

It all started with a Ricardo Galli’s tweet. A few days later I began with some outlines for the lexter, the parser and the rudimentary code generator (all the prototype record is public)

The name of the project it’s from a Guarani word –Ha’anga- which means “draw” or “shape”

Requirements

  • PHP 5.2.10 +

Setup

  • Get the source code:

git clone git://github.com/crodas/Haanga.git

  • Copy the content inside /lib to the project.
  • Configure the template.:
 <?php
require "Haanga.php";
$config = array(
     'template_dir' => 'templates/',
     /* where the “compiled” PHP will be saved */
     'cache_dir' => '/var/tmp/Haanga/website',
     /* by default TRUE, but it must be false if you have an autoloader already */
     'autoload' => TRUE,
     /* Compilator options */
     'compiler' => array(),
);
Haanga::configure($config);
  • Load a template:
 <?php
Haanga::Load("template.html", Array $variables=array(), Bool $return=FALSE);

Syntax

Haanga syntax is just the Django one -with a few of particular things. Basically a template can include 3 sort of data: the tags, variable printing and the text itself.


<body>
     <head><title>{{ title|default:"Hello World"}}</title></head>
     <body>
     {% filter upper %}
           Greetings {{ user.name }}
     {% endfilter %}
</body>

The PHP code for loading the template::

<?php
$user = array('name' => 'crodas');
$title = 'Title';
$vars = compact('user', 'title');
Haanga::Load('template.html', $vars);

Or it could be:

<?php
$user->name = 'crodas';
$title = 'Title';
$vars = compact('user', 'title');
Haanga::Load('template.html', $vars);

But NEVER both. This means that if you want to change the kind of data from $user you should recompile the template (erasing the compiled). For performance matters the type of data from $user is only checked once during the compilation.
h3.

  • Variables:
    1. foobar = $foobar
    2. foobar['something'] = $foobar['something']
    3. foobar[1] = $foobar[1]
    4. foobar->something = $foobar->something (incompatible with django)
    5. foobar.something
      1. If the foobar var is an object variable at the compilation time, it will be $foobar->something, otherwise it will be $foobar['something']
      2. If foobar is not defined when compilation, by default it will be $foobar->something (this can be changed with de compiler option ‘dot_as_object’ => FALSE)
  • Print: {{ variable [|filter[:parameter]] }}
{{ foobar.something}} {{ text|upper }} {{ text|default:" no text" }}
  • Tags: {% tag [parameter [[,] parameter]] (the parameter can be literal or variable)
{% tag_1 variable1 "string" 3.55 %} {% tag_2 variable1, "string", 3.55 %}

Filter list and standard tags

Tags

  • include:
    • Block: No
    • Description: includes a template
    • Parameters: Requires a parameter that can be a variable or a chain.
    • Limitations: Cannot be redirected to a variable because it’s a language construction, I.E. its definition is inside the class Haanga_Compiler unlike a common tag.
  • inline:
    • Block: No
    • Description: Includes a template in the compile time, I.E. the template to include is compiled and its AST is embedded in the template that includes it, generating just one compilation.
    • Parameters: Requires a parameter that must be a chain – because whe can’t (or we shouldn’t) solve the value of a variable during the compile-time.
    • Limitations: It’s impossible to detect changes in a template that is included with this tag. The only way to recompile is when the template that includes it has changed.
  • buffer:
    • Block: Sí.
    • Description: Saves all the block’s content into a variable (like the function ob_start() and $var = ob_get_clean() in PHP)
    • Parameters: the name of the var
Example
{% buffer foobar %}
    <h1>Head line</h1>
    <b>foobar</b>
{% endbuffer %}
{{ foobar }} # we print the block content