I. Introduction▲
HAML est un langage de template pour Ruby on Rails conçu pour créer des fichiers HTML de manière rapide et élégante. Il se substitue au RHTML et apporte à Rails un vrai langage de template : clair, concis et puissant. De plus, HAML est très facile à prendre en main, car il se base sur des langages déjà connus : HTML, CSS et Ruby. Comme dit son créateur, « HAML paraît bizarre les 20 premières minutes, mais après ça, vous irez plus vite ».
Bien que ce tutoriel soit orienté sur Ruby on Rails, il est intéressant de noter que la portée de HAML dépasse le monde de Ruby et Rails. En effet, un moteur de template utilisant la syntaxe d'HAML existe depuis peu pour PHP, il s'agit de phpHaml.
II. Installation▲
II-A. Installation du plugin pour Ruby on Rails▲
Le plugin HAML pour Ruby on Rails s'installe comme tout autre plugin. Il est téléchargeable à l'adresse http://haml.hamptoncatlin.com/download/.
Si vous débutez avec Ruby on Rails, voici la procédure à suivre pour installer ce plugin :
Placez-vous à la racine de votre application Rails, et entrez la commande suivante :
ruby script/plugin install http://svn.hamptoncatlin.com/haml/tags/stable
Le script se charge alors de télécharger les fichiers nécessaires et les place dans le dossier vendor/plugins/.
Une fois le plugin pour Rails installé, vous pouvez commencer à écrire vos vues avec HAML. Pour l'utiliser à la place de ERB, il vous suffit de nommer votre fichier avec l'extension haml. Par exemple, le template de l'action inscrire du controlleur membres sera app/views/membres/inscrire.haml au lieu de app/views/membres/inscrire.rhtml. De plus, vous pouvez parfaitement écrire certaines vues en HAML et d'autres en RHTML, voire faire un partial en HAML et l'inclure dans une vue en RHTML et vice-versa. La transition entre RHTML et HAML est donc très facile, car elle peut se faire petit à petit. Sachez seulement que si les deux fichiers existent, c'est le fichier HAML qui sera utilisé.
II-B. Configuration de l'éditeur▲
HAML utilise une indentation de deux espaces pour sa mise en forme, il est donc important d'utiliser un éditeur bien configuré pour nous faciliter la tâche. Il existe actuellement des plugins pour les éditeurs suivants :
- TextMate ;
- Aptana/RadRails (Eclipse) ;
- Jedit ;
- (G)Vim ;
- Komodo ;
- Emacs.
Ces plugins ont l'avantage d'ajouter également la coloration syntaxique, et quelques raccourcis qui vous faciliteront la tâche lorsque vous maîtriserez ce langage.
Vous pourrez retrouver les liens vers ces plugins sur http://groups.google.com/group/haml/web/syntax-highlighting. Je me suis intéressé en particulier à TextMate et Aptana/RadRails pour vous proposer une méthode d'installation détaillée. N'hésitez pas à consulter la page des plugins pour installer le support de HAML dans votre éditeur favori.
II-B-1. Installation du plugin pour TextMate▲
Le bundle pour TextMate est disponible sur le repository SVN de l'éditeur. Pour le télécharger, lancez un Terminal, puis entrez les commandes :
mkdir -p /Library/Application Support/TextMate/Bundles
cd /Library/Application Support/TextMate/Bundles
svn co http://macromates.com/svn/Bundles/trunk/Bundles/Haml.tmbundle
Si TextMate est lancé, vous pouvez utiliser la commande Bundle > Bundle Editor > Reload Bundles pour charger le plugin sans avoir besoin de relancer l'éditeur.
II-B-2. Installation du plugin pour Aptana/RadRails▲
Il existe un plugin pour Aptana/RadRails, l'éditeur gratuit basé sur Eclipse. Pour installer ce plugin :
- allez dans le menu « Aide > Mises à jour de logiciels > Rechercher et installer » … ;
- sélectionnez « Rechercher les nouveaux dispositifs à installer » puis cliquez sur « Suivant » ;
- cliquez sur « Nouveau site distant » ;
- saisissez les informations suivantes :
Nom : Plugin pour HAML
Adresse URL : http://haml.lucky-dip.net/ ; - cochez alors la case correspondant à la ligne créée, et cliquez sur Terminer.
Aptana devrait trouver la dernière version du plugin et vous proposer de l'installer.
III. Un premier aperçu de HAML▲
Si vous connaissez déjà relativement bien le HTML, et a fortiori si vous avez déjà travaillé sur des templates RHTML, vous verrez rapidement que HAML est un langage très simple et naturel. C'est d'ailleurs ce qui en fait son succès : son apprentissage peut prendre moins de 20 minutes pour les développeurs web confirmés.
Dans la tradition de Rails « Show don't tell », nous allons commencer par quelques exemples de conversion d'un template RHTML en HAML, tirés d'applications réelles. Ces exemples devraient simplement vous permettre de voir à quoi ressemble un template HAML. Ne vous inquiétez pas de ce que vous ne comprenez pas, nous verrons tous les détails de la syntaxe par la suite.
Pour avoir tout de même une idée de ce qui se passe, dites-vous simplement que :
- HAML reflète la structure du document par son indentation (comme YAML) ;
- il mélange Ruby, HTML et CSS dans un tout cohérent.
Assez parlé, voyez donc par vous-même.
Le premier exemple est une page affichant une News sur un site sur lequel j'ai eu l'occasion de travailler. C'est l'exemple typique d'une page simple qui affiche un modèle provenant d'une base de données.
Ce deuxième exemple est un extrait de Typo, le célèbre moteur de blog. C'est un morceau de code qui affiche les commentaires publiés pour un billet.
Le dernier exemple est un layout typique d'une application Rails, conçu directement en HAML :
Maintenant que vous avez eu un bref aperçu de ce à quoi peut ressembler un template HAML, voyons ensemble plus en détail la syntaxe du langage.
IV. La Syntaxe▲
IV-A. Les éléments principaux : faire du HTML▲
IV-A-1. Les balises▲
Le caractère %, placé en début de ligne, désigne une balise :
%p
%li
%br
Les attributs sont notés sous la forme d'un Hash ruby :
%meta{'content-type' => 'text/html', 'charset' => 'utf8'}
%label{:for => 'user_login'}
%ul{:id => 'menu'}
%p{:class => 'details'}
On retrouve les attributs 'id' et 'class' très souvent, on a donc introduit une syntaxe particulière, qui vient tout simplement de CSS :
IV-A-2. Un peu de CSS▲
Placé après une balise, le # indique la valeur de l'attribut id :
%ul#menu => <ul id="menu">
Placé après une balise, le . indique la valeur de l'attribut class :
%p.details => <p class="details">
Avec la syntaxe # ou . il n'est pas obligatoire de donner le nom de la balise. Si on l'omet, HAML utilisera un 'div' :
#sidebar => <div id="sidebar">
.footer => <div class="footer">
Comme en CSS, on peut mélanger . et # ; On peut également définir plusieurs classes en les séparant par des . :
#colonne.gauche => <div id="colonne" class="gauche">
#messages.colonne.gauche => <div id="messages" class="colonne gauche">
On obtient alors une syntaxe très compacte et proche de celle utilisée en CSS.
IV-B. Interpréter du code Ruby▲
IV-B-1. Afficher du contenu dynamique▲
Le caractère = placé soit en début de ligne, soit après une balise, désigne du code Ruby qui sera évalué et affiché (comme <%= … %> avec RHTML) :
= @article.titre => Introduction au moteur de template HAML
%p= @article.titre => <p>Introduction au moteur de template HAML</p>
Bien évidemment, on n'est pas limité aux simples variables. On peut utiliser n'importe quel code Ruby imaginable, en particulier les Helpers existant dans Rails.
%p= link_to "Accueil", accueil_path => <p><a href="/">Accueil</a></p>
IV-B-2. Tests et boucles▲
Le signe - indique du code Ruby qui sera évalué, mais ne sera pas affiché (comme <% … %> avec RHTML). N'importe quel code Ruby peut être utilisé dans un template, mais on utilise cette syntaxe la plupart du temps pour des boucles ou des tests :
- if logged_in?
Bienvenue dans votre espace personnel
- else
Accès refusé
%ul
- @articles.each do |article|
%li= article.title
Il n'y a jamais de 'end', contrairement à ERb
IV-C. Remarques▲
L'imbrication des balises et des blocs se fait simplement en fonction de l'indentation. Il n'y a pas de 'end' ou de balises fermantes avec HAML. L'indentation en HAML est aussi importante que le code, car elle définit la portée des éléments. Ainsi vous pouvez changer facilement et rapidement l'imbrication des balises, car tous les éditeurs textes ont un moyen d'indenter ou désindenter les lignes sélectionnées. En revanche, cela peut vous jouer des tours si vous n'y faites pas attention.
L'indentation est toujours de deux espaces, il ne faut jamais utiliser de tabulation. Faites bien attention sur ce point, car des erreurs d'indentation peuvent vous donner des messages d'erreur difficiles à interpréter.
C'est pour cette raison que bien configurer votre éditeur est primordial !
<div id
=
"content"
>
<div class
=
"left column"
>
<h2>Bienvenue dans notre site !</h2>
<p>
<%=
print_information %>
</p>
</div>
<div class
=
"right column"
>
<%=
render :
partial
=
>
'sidebar' %>
</div>
</div>
L'équivalent de ce code HTML sera :
#content
.left.column
%h2 Bienvenue dans notre site !
%p= print_information
.right.column= render :partial => "sidebar"
V. Aller plus loin▲
V-A. Exercez-vous !▲
Avant d'aller plus loin, prenez quelques minutes pour convertir un template d'une de vos applications. N'ayez pas d'inquiétude, si vous faites une erreur, il vous suffira de supprimer le fichier .haml que vous avez créé. Convertir quelques-uns de vos templates vous permettra de bien vous familiariser avec le langage. Dans le reste de cet article, vous trouverez quelques conseils et astuces pour vous aider à améliorer encore la lisibilité de vos vues.
V-B. Les balises inline▲
Un des premiers problèmes rencontrés lorsque l'on débute avec HAML est la gestion des balises inline, c'est-à-dire :
« Comment faire si je veux mettre un mot en gras ou en italique au milieu d'une phrase ? »
En HAML, la représentation suivant la structure du document serait :
%p
Ceci est un paragraphe avec un mot en
%strong gras
et en
%em italique
\.
Ce n'est pas très lisible… Cependant dans ce cas, on peut écrire simplement :
%p
Ceci est un paragraphe avec un mot en <strong>gras</strong> et en <em>italique</em>.
Qui sera compilé en :
<p>
Ceci est un paragraphe avec un mot en <strong>gras</strong>
et en <em>italique</em>
.
</p>
De la même manière, pour interpréter des valeurs, plutôt que d'écrire :
%p
Prix :
= #{produit.prix}
?
Il suffit de faire :
%p= "Prix : #{produit.prix}?"
On peut également utiliser un double égal qui évite l'utilisation de guillemets. Ce code ci-dessous est strictement équivalent au code précédent :
%p== Prix : #{produit.prix}?
On peut aussi utiliser les helpers, par exemple link_to pour faire un lien :
%p== Un lien vers la page #{link_to 'contact', contact_url}.
V-C. Écrire une expression sur plusieurs lignes▲
À l'inverse, vous aurez parfois besoin d'insérer du code sur plusieurs lignes. Pour cela, on utilise le caractère | (« pipe ») à la fin de chaque ligne. Par exemple pour un helper particulièrement long :
%p= link_to_remote "Supprimer", |
:url => {:action => 'delete_profile_from_duel', :id => 2}, |
:before => "Element.show('wait_icon')", |
:complete => "Element.hide('wait_icon')" |
Notez que cette syntaxe est un peu lourde, mais peut être très souvent évitée en utilisant les mécanismes de Rails. La vocation d'HAML est également de vous inciter à utiliser au mieux les Helpers et les routes nommées : si votre code n'est pas assez clair, refactorisez !
V-D. Attributs 'class' et 'id' dynamiques▲
Il n'est pas possible d'utiliser les raccourcis # et . pour spécifier dynamiquement un id ou une classe, il faut passer par un Hash dans lequel n'importe quel code Ruby est accepté :
- @items.each do |item|
%tr{ :class => cycle('even', 'odd') }
%td= item.titre
%td= item.description
Si vous êtes adepte du plugin simply_helpful, vous serez heureux d'apprendre qu'il existe une syntaxe spéciale avec HAML pour ce plugin, il s'agit de [] qui remplace div_for :
Contrôleur :
@article = Article.find(3)
Vue :
%p[@article] => <p id="article_3" class="article">
V-E. Autres éléments▲
V-E-1. Doctype▲
Un triple point d'exclamation (!!!) insère un Doctype XHTML. Par défaut, le doctype « XHTML 1.0 Transitional » est utilisé, mais d'autres versions sont également supportées, ainsi que le prologue XML.
!!!
%html
%head
%title Utilisation de !!!
%body
%h1 Exemple de document HAML
Génère le document suivant :
<!
DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<html>
<head>
<title>Utilisation de !!!</title>
</head>
<body>
<h1>Exemple de document HAML</h1>
</body>
</html>
Voici la liste des doctypes disponibles :
!!!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
!!! strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
!!! frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
!!! 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
!!! xml iso-8859-1
<?xml version='1.0' encoding='iso-8859-1' ?>
V-E-2. Commentaires▲
Le / crée un commentaire html : tout le contenu qui suit est englobé dans un commentaire :
/
%p Ceci ne sera pas affiché ...
Sera compilé en :
<!--
<p>Ceci ne sera pas affiché</p>
-->
Les commentaires conditionnels d'Internet Explorer peuvent être utilisés en les rajoutant juste derrière le /. Par exemple, pour inclure une feuille de style spécifique à Internet Explorer :
/[if IE]
= stylesheet_link_tag 'ie'
Sera compilé en :
<!--[if IE]>
<link href="/stylesheets/ie.css" media="screen" rel="Stylesheet" type="text/css" />
<![endif]-->
V-E-3. Échappement▲
Le \ sert de caractère d'échappement : utile pour afficher une ligne qui commence par -, =, % ?
%p
\- Ceci ne sera pas interprété comme du code ...
Sera compilé en :
<p>
- Ceci ne sera pas interprété comme du code ...
</p>
VI. Conclusion▲
Vous devriez maintenant en savoir suffisamment pour créer vos vues avec HAML. Si vous rencontrez des problèmes, n'hésitez pas à poser vos questions sur le forum Ruby on Rails.
Pour ponctuer cet article, voici quelques liens intéressants :
- le site officiel d'HAML : http://haml.hamptoncatlin.com/
- le groupe de discussion sur Google Groups (en anglais uniquement) : http://groups.google.com/group/haml/
Je tiens également à remercier Bestiol et Titoumimi pour leurs conseils avisés et leurs relectures patientes.