Haml Coffee est un moteur de template en JavaScript utilisant la syntaxe Haml, tout en comprenant CoffeeScript pour générer une fonction function qui donnera du HTML. Il est possible de l'utiliser dans des applications JavaScript côté client, par exemple avec Backbone.js, Spine.js, JavaScriptMVC, KnockoutJS ou d'autres, ou côté serveur avec des frameworks comme Express.
Vous pouvez essayer Haml Coffee en ligne en visitant Haml Coffee Online.
Haml Coffee est disponible via npm et peut être installé par la commande:
$ npm install haml-coffee
Pensez à vérifier le CHANGELOG lorsque vous mettez à jour votre version d'Haml Coffee avec npm update
.
Il existe différent packages pour intégrer Haml-Coffee dans votre environnement de travail:
- grunt-haml pour les projets utilisants Grunt.
- gulp-haml-coffee pour les projets utilisants Gulp.
- hem-haml-coffee pour les projets utilisants Hem.
- haml_coffee_assets pour les projets utilisants Rails.
- stitch-haml-coffee pour les projets utilisants Stitch.
- guard-haml-coffee pour les projets utilisants Guard.
- Haml Coffee compiler (minified) pour le navigateur.
Veuillez noter que cette dernière version (navigateur) n'inclue pas CoffeeScript, vous devrez vous assurer de l'avoir inclus avant d'inclure haml-coffee.
Vous pouvez compiler un template Haml Coffee à une fonction JavaScript en lui passant les variables locales à utiliser pour générer le HTML. Le code suivant
hamlc = require 'haml-coffee'
tmpl = hamlc.compile '%h1= @title'
html = tmpl title: 'Haml Coffee rocks!'
donnera <h1>Haml Coffee rocks!</h1>
.
La fonction compile
peut prendre les options comme second paramètre pour personnaliser la fonction :
hamlc.compile '%h1= @title'
cleanValue: false
escapeHtml: false
Référez-vous aux options pour avoir des informations plus détaillées sur les options disponibles et n'hésitez pas à naviguer dans le codo généré depuis l'Haml-Coffee API documentation.
Vous pouvez configurer Express pour utiliser Haml Coffee comme moteur de template.
Depuis la version 1.4.0, Haml Coffee supporte Express 3 et peut être enregistré comme moteur de thème comme il suit :
express = require 'express'
app = express()
app.engine 'hamlc', require('haml-coffee').__express
Vous pouvez aussi utiliser consolidate.js pour l'inclure :
express = require 'express'
cons = require 'consolidate'
app = express()
app.engine 'hamlc', cons['haml-coffee']
Depuis la version 0.5.0, Haml Coffee supporte Express 2 et peut être enregistré comme moteur de thème comme il suit :
express = require 'express'
app = express.createServer()
app.register '.hamlc', require('haml-coffee')
Vous pouvez aussi utiliser consolidate.js pour l'inclure :
express = require 'express'
cons = require 'consolidate'
app = express.createServer()
app.register '.hamlc', cons['haml-coffee']
Express 2 utilise un fichier d'agencement layout.hamlc
par défaut, dans lequel vous pouvez insérer la vue de cette manière :
!!!
%head
%title Application Express
%body
!= @body
Maintenant, vous pouvez créer une vue avec Haml Coffee
%h1= "Welcome #{ @name }"
%p You've rendered your first Haml Coffee view.
que vous pouvez exécuter comme ceci :
app.get '/', (req, res) ->
res.render 'index.hamlc', name: 'Express user'
Express 3 a retiré les agencements (layouts), mais vous pouvez installer express-partials et le configurer comme middleware :
partials = require 'express-partials'
app.use partials()
Il est possible d'utiliser Haml Coffee comme moteur de template en modifiant l'option view engine
:
app.configure ->
app.set 'view engine', 'hamlc'
Qui vous permet d'omettre l'extension .hamlc
quand vous exécutez une vue :
app.get '/', (req, res) ->
res.render 'index', name: 'Express user'
Avec Express 3, vous pouvez passer des options au compilateur en utilisant app.locals
:
app.locals.uglify = true
qui équivaut à faire :
res.render view, { uglify: true }
Référez-vous aux options pour avoir des informations plus détaillées sur les options disponibles.
Après l'installation, vous aurez un fichier binaire haml-coffee
que vous pourrez utiliser pour compiler des fichiers templates voire plusieurs fichiers templates dans un seul fichier JavaScript.
$ haml-coffee
Usage: node haml-coffee
Options:
-i, --input Either a file or a directory name to be compiled
-o, --output Set the output filename
-n, --namespace Set a custom template namespace
-t, --template Set a custom template name
-b, --basename Ignore file path when generate the template name
-e, --extend Extend the template scope with the context
La section suivante ne fait que décrire les options qui sont uniques à l'outil en ligne de commande.
Vous pouvez obtenir la liste des options en exécutant haml-coffee --help
et vous référez aux options pour avoir des informations plus détaillées sur les options disponibles
input
et output
sont optionnels et vous pouvez directement rediriger les flux (streams).
Vous pouvez donner un fichier simple ou un nom de dossier avec l'option -i
/--input
.
Si vous passez un dossier, les fichier sont cherchés de manière récursive :
$ haml-coffee -i template.haml
Cette commande générera un fichier avec le même nom que celui donné mais avec .jst
comme extension.
La commande ci-dessus par exemple produirait un fichier template.jst
.
Un fichier Haml Coffee valide a l'une de ces extensions : .haml
, .html.haml
, .hamlc
or
.html.hamlc
.
Vous pouvez spécifier le fichier de sortie (unique) qui sera utilisé plutôt que laisser Haml Coffee le déduire via l'option -o
/--output
:
$ haml-coffee -i template.haml -o t.js
Cette commande générera un fichier nommé t.js
. Vous pouvez aussi vus servir de cette commande et donner un dossier en entrée pour n'avoir qu'un fichier en sortie :
$ haml-coffee -i templates -o all.js
Cela compilera tous les fichiers templates dans le dossier templates
dans un unique fichier all.js
.
Par défaut, chaque template est disponible dans window.HAML
mais vous pouvez changer l'espace de nom avec l'option -n
/--namespace
:
$ haml-coffee -i template.haml -n exports.JST
Chaque template a un nom unique. Le nom est déduit depuis le fichier source en retirant l'extension et tous les caractères illégaux. Les noms des dossiers sont utilisés en plus de l'espace de nom. Par exemple, un template nommé user/show-admin.html.haml
sera compilé dans une fonction accessible via window.HAML['user/show_admin']
.
Via l'option -b
/--basename
, le nom déduit n'incluera pas le chemin vers le thème. Par exemple, un template nommé user/show-admin.html.haml
sera compilé dans une fonction accessible via window.HAML['show_admin']
au lieu de window.HAML['user/show_admin']
.
L'option -t
/--template
vous permet de manuellement changer le nom du template :
$ haml-coffee -i template.haml -n exports.JST -t other
La fonction sera accessible via exports.JST['other']
.
En étandant la portée (scope), vous pouvez accéder directement à vos variables locales sans utiliser @
ou this
:
%h2= title
Ceci est possible grace au with
de JavaScript. Utiliser with
est interdit en Mode Strict (ECMAScript 5).
Vous pouvez utiliser Haml Coffee en ligne de commande pour entrer un template et arrêtez via Ctrl+D :
$ haml-coffee -p amd
%h1 Hello AMD
^D
qui produira un module AMD dans la console. Vous devez utiliser le placement amd
ou donner un nom au template comme par exemple
$ haml-coffee -t name
%p JST rocks!
^D
qui donnera le code source JST. Vous pouvez aussi rediriger les flux (streams) comme il suit :
$ haml-coffee -t name < input.hamlc > output.jst
Haml Coffee implémente la Spécification Haml (EN) pour assurer un degré de compatibilité avec les autres implémentations HAML. Les sections suivantes sont parfaitement compatibles :
- Texte seul
- Multilignes :
|
- Balises :
%
- Attributs :
{}
or()
- Classes et ID :
.
et#
(balisediv
implicite) - Balises auto-fermantes :
/
- Doctype :
!!!
- Commentaires HTML :
/
, commentaires conditionnels :/[]
, commentaires Haml :-#
- Code CoffeeScript:
-
, insertion de CoffeeScript:=
- Interpolation :
#{}
- Préservation d'espaces :
~
- Suppression d'espaces :
>
et<
- Échappement
\
- Échappement HTML :
&=
, dé-échappement HTML :!=
- Filtres :
:plain
,:javascript
,:css
,:cdata
,:escaped
,:preserve
- Conversion des attributs booléens
- Syntaxe de référencement d'objets :
[]
Consultez la Référence Haml (EN) pour plus de détails.
Haml Coffee supporte les attributs style Ruby 1.8 et Ruby 1.9. Les attributs (style Ruby 1.8)
%a{ :href => 'http://haml-lang.com/', :title => 'Haml home' } Haml
peuvent aussi être écrits comme il suit (style Ruby 1.9) :
%a{ href: 'http://haml-lang.com/', title: 'Haml home' } Haml
Le style HTML est aussi
%a( href='http://haml-lang.com/' title='Haml home') Haml
Haml Coffee supporte certain des fonctions incluses dans les aides (EN) de Ruby Haml.
Les aides existantes gardent le contexte, il n'est pas nécessaire d'utiliser =>
.
Entoure un block de Haml avec des chaînes, sans espaces entre.
!= surround '(', ')', ->
%a{:href => "food"} chicken
produit
(<a href='food'>chicken</a>)
Ajoute un bloc à la fin d'un bloc Haml, sans espace entre.
click
!= succeed '.', ->
%a{:href=>"thing"} here
produit
click
<a href='thing'>here</a>.
Précède un bloc HAML d'une chaîne, sans espace entre.
!= precede '*', ->
%span.small Not really
produit
*<span class='small'>Not really</span>
Haml Coffee supporte le référencement d'objets, mais implémenté d'une manière différente à cause de la manière dont fonctionne CoffeeScript et du moteur.
Les crochets contiennent l'objet CoffeeScript object ou la classe qui sera utilisé pour la classe et l'ID.
La classe utilise le nom du constructeur de l'objet (transformé pour utiliser des underscores plutôt que du camelCase) et l'ID utilise le nom du constructor, suivi de la valeur de propriété id
ou de la valeur de la fonction #to_key
ou de la fonction #id
(dans cet ordre).
Le second argument permet de spécifier un préfixe.
Par exemple :
%div[@user, 'greeting']
Hello
produit
<div class='greeting_user' id='greeting_user_15'>
Hello!
</div>
Si vous avez besoin d'utiliser autre chose que le nom du constructeur, vous pouvez utiliser la fonction #hamlObjectRef
sur l'objet :
:coffeescript
class User
id: 23
hamlObjectRef: -> 'custom'
%div[new User()]
Hello
produit
<div class='custom' id='custom_23'>
Hello!
</div>
Haml Coffee supporte uniquement une directive qui étend la syntaxe Haml
Vous pouvez utiliser la directive +include
pour inclure un autre fichier :
%h1 Include
+include 'partials/test'
Cela cherchera le fichier template et l'incluera.
En imaginant que partials/test
contient
%p Partial content
Le résultat final sera
<h1>Include</h1>
<p>Partial content</p>
Haml & CoffeeScript forment une équipe gagnante, utilisant tous les deux l'indentation pour les blocs et se complètement parfaitement pour cette raison.
Il n'est pas conseillé d'avoir beaucoup de complexité dans vos fichiers templates.
Quand vous définissez un attribut sans l'entourer de guillemets (ou d'apostrophes), Haml-Coffee considérera que c'est du CoffeeScript à exécuter au moment du rendu.
Par défaut, ces attributs sont échappés avant d'être insérés dans le document. Vous pouvez changer ce comportement avec l'option adéquate du compilateur.
Les attributs style HTML sont les plus limités et ne peuvent utiliser qu'au plus une variable simple :
%img(src='/images/demo.png' width=@width height=@height alt=alt)
Les variables @width
et @height
doivent être passées au rendu et alt
doit être défini avant ce bout de code.
Les attributs styles Ruby peuvent être plus complexes et appeler des fonctions :
%header
%user{ :class => App.currentUser.get('status') }= App.currentUser.getDisplayName()
Vous pouvez aussi utiliser le style Ruby 1.9 :
%header
%user{ class: App.currentUser.get('status') }= App.currentUser.getDisplayName()
Vous pouvez aller encore plus loin en utilisant une interpolation entre guillemets :
%header
%user{ class: "#{ if ~@user.get('roles').indexOf('admin') then 'normal' else 'admin' }" }= @user.getDisplayName()
Réflechissez à deux fois avant d'utiliser des attributs complexes dans votre fichier template. Il y a d'autres places plus adaptées pour ça, comme vos modèles, vos objets vues ou vos helpers.
Vous pouvez définir vos attributs sur plusieurs avec l'indentation qui vous plait, ce qui vous permet par exemple de faire :
%input#password.hint{ type: 'password', name: 'registration[password]',
data: { hint: 'Something very important', align: 'left' } }
L'exemple ci-dessus vous montre aussi l'utilisation de l'attribut data-
HTML5.
Vous pouvez exécuter n'importe quel code CoffeeScript dans vos templates :
- for project in @projects
- if project.visible
.project
%h1= project.name
%p&= project.description
Il y a plusieurs formats pour exécuter du code :
- Exécuter du code sans rien insérer dans le document :
-
- Exécuter du code et insérer le résultat :
=
Toute insertion dans le document est échappée par défaut. Vous pouvez changer ce comportement avec l'option du compilateur adéquate.
Il y a trois variations pour exécuter le code et l'insérer dans le document, dont deux qui changent l'échappement :
- Exécute le code et n'échappe pas le résultat :
!=
- Exécute le code et échappe le résultat :
&=
- Préservation des espaces à l'insertion :
~
Encore une fois, référez-vous à la référence Haml pour plus de détails.
Le code à exécuter doit être palcé sur une seul ligne et contrairement à Ruby Haml, vous ne pouvez pas exécuter du code multi-lignes en ajoutant une virgule à la fin de votre ligne.
Cependant, vous pouvez utiliser la notation multi-lignes |
:
- links = { |
home: '/', |
docs: '/docs', |
about: '/about' |
} |
%ul
- for name, link of links
%li
%a{ href: link }= name
Notez bien que la ligne est concaténée à la compilation, vous ne pouvez donc pas omettre les crochets comme vous le feriez en CoffeeScript. Il est donc recommandé d'utiliser le filtre CoffeeScript pour avoir des vrais blocs de code multi-lignes :
:coffeescript
links =
home: '/'
docs: '/docs'
about: '/about'
%ul
- for name, link of links
%li
%a{ href: link }= name
Vous pouvez aussi créer des functions qui génèrent du HAML
- sum = (a, b) ->
%div
%span= a
%span= b
%span= a+b
= sum(1,2)
= sum(3,4)
Ou passer le résultat HTML généré à une fonction
= postProcess ->
%a{ href: '/' }
Le contenu des filtres :coffeescript
est exécuté lors du rendu et n'insère rien dans le document.
C'est pratique pour exécuter du code sur plusieurs lignes sans avoir à préfixer chaque ligne avec -
:
%body
:coffeescript
tags = ['CoffeeScript', 'Haml']
project = 'Haml Coffee'
%h2= project
%ul
- for tag in tags
%li= tag
La section suivante décrit les options disponibles depuis l'API JavaScript & en tant que vue Express.
Les options en ligne de commande peuvent être différentes. Par exemple, au lieu de passer --escape-html=false
vous devez passer l'argument --disable-html-escaping
.
Vous pouvez voir la liste des arguments via haml-coffee --help
.
- Nom 'format'
- Type:
String
- Défaut:
html5
The Haml parser knows different HTML formats to which a given template can be rendered and it must be one of:
- xhtml
- html4
- html5
Doctype, self-closing tags and attributes handling depends on this setting. Please consult the official Haml reference for more details.
- Nom:
uglify
- Type:
Boolean
- Défaut:
false
All generated HTML tags are properly indented by default, so the output looks nice. This can be helpful when debugging.
You can skip the indention by setting the uglify
option to false. This save you some bytes and you'll have increased
rendering speed.
- Nom:
escapeHtml
- Type:
Boolean
- Défaut:
true
The reserved HTML characters "
, '
, &
, <
and >
are converted to their HTML entities by default when they are
inserted into the HTML document from evaluated CoffeeScript.
You can always change the escaping mode within the template to either force escaping with &=
or force unescaping with
!=
.
- Nom:
escapeAttributes
- Type:
Boolean
- Défaut:
true
All HTML attributes that are generated by evaluating CoffeeScript are also escaped by default. You can turn of HTML
escaping of the attributes only by setting escapeAttributes
to false. You can't change this behaviour in the template
since there is no Haml markup for this to instruct the compiler to change the escaping mode.
- Nom:
cleanValue
- Type:
Boolean
- Défaut:
true
Every output that is generated from evaluating CoffeeScript code is cleaned before inserting into the document. The
default implementation converts null
or undefined
values into an empty string and marks real boolean values with a
hidden marker character. The hidden marker character is necessary to distinguish between String values like 'true'
,
'false'
and real boolean values true
, false
in the markup, so that a boolean attribute conversion can quickly
convert these values to the correct HTML5/XHTML/HTML4 representation.
- Nom:
preserve
- Type:
String
- Défaut:
textarea,pre
The preserve
option defines a list of comma separated HTML tags that are whitespace sensitive. Content from these tags
must be preserved, so that the indention has no influence on the displayed content. This is simply done by converting
the newline characters to their equivalent HTML entity.
- Nom:
autoclose
- Type:
String
- Défaut:
meta,img,link,br,hr,input,area,param,col,base
The autoclose option defines a list of tag names that should be automatically closed if they have no content.
- Nom:
placement
- Type:
String
- Défaut:
global
The placement
option defines where the template function is inserted
upon compilation.
Possible values are:
-
global
Inserts the optionally namespaced template function intowindow.HAML
. -
'standalone'
Returns the template function without wrapping it -
amd
Wraps the template function into adefine()
statement to allow async loading via AMD.
See AMD support for more information.
- Nom:
dependencies
- Type:
Object
- Défaut:
{ hc: 'hamlcoffee' }
The dependencies
option allows you to define the modules that must be required for the AMD template define
function.
The object key will be the function parameter name of the module the object value defines. See AMD support for more
information.
Haml Coffee provides helper functions for HTML escaping, value cleaning and whitespace preservation, which must be available at render time. By default every generated template function is self-contained and includes all of the helper functions.
However you can change the reference to each helper function by providing the appropriate compiler option and there are good reasons to do so:
- You want to reduce the template size and provide all the helpers from a central place.
- You want to customize a helper function to better fit your needs.
To change these functions, simply assign the new function name to one of the following options:
customHtmlEscape
: Escape the reserved HTML characters into their equivalent HTML entity.customPreserve
: Converting newlines into their HTML entity.customFindAndPreserve
: Find whitespace sensitive tags and preserve their content.customCleanValue
: Clean the value that is returned after evaluating some inline CoffeeScript.customSurround
: Surrounds a block of Haml code with strings, with no whitespace in between.customSucceed
: Appends a string to the end of a Haml block, with no whitespace between.customPrecede
: Prepends a string to the beginning of a Haml block, with no whitespace between.customReference
: Creates the Haml object reference.
The customSurround
, customSucceed
and customPrecede
are bound to the template context.
You can find a default implementation for all these helper functions in Haml Coffee Assets.
- Global dependencies
- Trivial dependency detection
Haml Coffee has built in AMD support by setting the placement
option to amd
. This will generate a module definition
for the JavaScript template. The dependencies
options can be used to provide a mapping of module names to parameters.
To illustrate this, the default value will result in the following module declaration:
define ['hamlcoffee'], (hc) ->
When the template contains a require call in the form of
- require 'module'
- require 'deep/nested/other'
it will be added to the module definition list
define ['hamlcoffee', 'module', 'deep/nested/other'], (hc, module, other) ->
allowing you to render a partial template:
!= module()
!= other()
Of course the require call can have different quotes or parenthesises, allowing you to directly require and render:
!= require("another/other")()
Haml-Coffee uses Guard for development, which you can install Guard with the Ruby Bundler:
$ bundle install
Install the Node modules with NPM:
$ npm install
and run Guard to automatically compile your CoffeeScripts and run the Jasmine specs on file modification:
$ bundle exec guard
Feel free to take a look at the crispy changelog instead of crawling through the commit history.
Haml Coffee in the Rails asset pipeline:
- Michael Kessler (@netzpirat, flinkfinger.com)
- Sebastion Deutsch (@sippndipp, 9elements)
- Jan Varwig (@agento, 9elements)
See all contributors on the contributor page.
Traduction par Vendethiel.
(The MIT License)
Copyright (c) 2011 9elements, 2011-2013 Michael Kessler
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.