Skip to content

Haanga (en Español)

martinml edited this page Feb 24, 2011 · 7 revisions

Haanga es un motor de templates que implementa la sintaxis de Django. Fue desarrollado para ser utilizado en Menéame, pero fue liberado como proyecto independiente para ser utilizado por cualquier persona :-)

Algunas de las características del proyecto:

  • Legible por humanos
  • Sencillo de utilizar mantener
  • Muy eficiente, ya que el template es “compilado” enteramente a un script PHP equivalente a cada cambio.
  • El código generado está preparado para sacar ventajas a cualquier acelerador/optimizador de PHP (como xcache)

¿Por qué un nuevo motor de template?

  • Lo más importante para Menéame es el rendimiento.
    1. La compilación se hace solo en el peor de los casos (cuando no existe el template, o el template es mas reciente que el generado)
    2. Normalmente, solo una parte pequeña clase de Haanga se carga, que es la encargada de chequear y determinar si se necesita hacer la compilación.
    3. El código generado está optimizado
      1. Se genera una función
      2. Todo es PHP (no hay cambios de contextos entre HTML y PHP)
  • La sintaxis de Django es hermosa :-)

Inicios del proyecto

Todo el proyecto comenzó con un tweet de Ricardo Galli. Unos días más tarde comencé con algunos esbozos para el Lexer, el Parser y rudimentario generador de código (todo el historial de los prototipos está publicado).

El nombre del proyecto viene del Guaraní, dónde Ha’anga significa “dibujo” o “figura”.

Requerimientos

  • PHP 5.2.10 +

Instalación

  • Conseguir el código fuente:

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

  • Copiar el contenido del directorio lib/ al proyecto.
  • Configurar el template:
 <?php
require "Haanga.php";
$config = array(
      'template_dir' => 'templates/',
      /* donde los archivos "compilados" PHP serán almacenados */
      'cache_dir' => '/var/tmp/Haanga/sitio-web',
      /* Por defecto es TRUE, pero debe ser falso si ya se cuenta con un autoloader */ 
      'autoload' => TRUE, 
       /* Opciones que son pasadas al compilador */
      'compiler' => array(), 
);
Haanga::configure($config); 
  • Luego cuando se necesita cargar un template:
 <?php
Haanga::Load("template.html", Array $variables=array(), Bool $return=FALSE);

Sintaxis

La sintaxis soportada por Haanga es básicamente la django (con pequeñas cosas propias). Básicamente un template puede tener 3 tipos de datos, los “tags”, la impresión de variables y el texto en sí.


    <body>
        <head><title>{{ title|default:"Hola mundo"}}</title></head>
        <body>
        {% filter upper %}
            Saludos {{ user.name }}
        {% endfilter %}
        </body>
    </body>

Y el código PHP para cargar el template:

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

o podría ser:

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

Pero jamás ambos, es decir si se desea cambiar el tipo de datos de $user hay que recompilar el template (borrando los compilador). Esto es así porque el tipo de dato de $user es sólo evaluado al momento de compilación (por cuestiones de rendimiento).

  • Variables:
    1. foobar = $foobar
    2. foobar['algo'] = $foobar['algo']
    3. foobar[1] = $foobar[1]
    4. foobar->algo = $foobar->algo (incompatible con django)
    5. foobar.algo
      1. Si la variable foobar al momento de compilación es una objeto sería $foobar->algo, en caso contrario sería $foobar['algo']
      2. Si la variabler foobar no esta definida al momento de compilación sería por defecto $foobar->algo (esto se puede cambiar con la opción del compilador ‘dot_as_object’ => FALSE)
  • Imprimir: {{ variable [|filtro[:parametro]] }}
{{ foobar.algo}} {{ texto|upper }} {{ texto|default:" no hay texto" }}
  • Tags: {% tag [parametro1 [[,] parametro2]] (dónde parametro puede ser literal o variable)
{% tag_1  variable1 "string" 3.55 %}  {% tag_2 variable1, "string", 3.55 %}

Lista de filtros y tags estándares

Tags

  • include:
    • Bloque: No
    • Descripción: incluye a un template
    • Parámetros: requiere un parámetro que puede ser una variable o una cadena.
    • Limitaciones: no puede ser redirigido hacia una variable ya que es una construcción del lenguaje, es decir su definición está en la clase Haanga_Compiler a diferencia de un tag común.
  • inline:
    • Bloque: No
    • Descripción: incluye a un template en tiempo de compilación, es decir el template a incluir es compilado, y su AST es embebido en el template que lo incluye, generando así un sólo compilado.
    • Parámetros: requiere un parámetro que tiene que ser una cadena ya que no podemos (o no debemos) resolver el valor de una variable en tiempo de compilación.
    • Limitaciones: es imposible detectar cambios en un template que es incluido con este tag, la única manera de re-compilar es cuando el template que lo incluye ha cambiado.
  • buffer:
    • Bloque: Sí.
    • Descripción: Guarda todo el contenido del bloque en una variable (similar a la funcion ob_start() y $var = ob_get_clean() de PHP)
    • Parámetros: el nombre de la variable
Ejemplo
{% buffer foobar %}
    <h1>Head line</h1>
    <b>foobar</b>
{% endbuffer %}
{{ foobar }} # imprimimos el contenido del bloque 
Clone this wiki locally