Velocity

About

Community

Docs

Tools

Comparisons

Site Translations

Table des Mati?res
  1. A propos de ce document
  2. Velocity, qu'est-ce que c'est?
  3. Qu'est-ce que Velocity peut faire pour moi?
    1. L'exemple de MudStore
  4. Introduction au Velocity Template Language (VTL)
  5. Hello Velocity World!
  6. Les commentaires
  7. Les r?f?rences
    1. Variables
    2. Propri?t?s
    3. M?thodes
  8. Notation formelle des r?f?rences
  9. Notation silencieuse des r?f?rences
  10. Sortie litt?rale
    1. Devise
    2. Echapper des r?f?rences VTL valides
  11. Substitution de cas
  12. Directives
    1. Set
    2. Cha?nes de caract?res litt?rales
    3. Conditions
      1. Op?rateurs relationnels et logiques
    4. Boucles
    5. Include
    6. Parse
    7. Stop
    8. Velocimacros
  13. Echappement des directives VTL
  14. VTL: Questions de format
  15. Autres caract?ristiques et sujets divers
    1. Math
    2. Op?rateur de port?e (range)
    3. Questions pointues: Echappement et !
    4. Compl?ments divers sur les Velocimacros
    5. Concat?nation de cha?nes
  16. Donnez votre avis


A propos de ce document

Le Guide de l'utilisateur Velocity a pour but d'aider les concepteurs de page et les fournisseurs de contenu ? se familiariser avec Velocity et avec la syntaxe de son langage de script, simple mais puissant, le Velocity Template Language (VTL). Beaucoup d'exemples dans ce guide concernent l'utilisation de Velocity pour l'inclusion de contenu dynamique dans des sites web, mais tous les exemples du VTL pourraient aussi bien s'appliquer ? d'autres pages ou gabarits.

Merci de choisir Velocity!


Velocity, qu'est-ce que c'est?

Velocity est un moteur de substitution, bas? sur Java. Il permet aux concepteurs de pages web de faire r?f?rence ? des m?thodes d?finies dans du code Java. Les concepteurs de pages peuvent travailler en ?quipe avec des programmeurs Java pour d?velopper des sites web dans l'architecture MVC (Mod?le-Vue-Contr?leur), ce qui signifie que les infographistes peuvent se concentrer sur la cr?ation d'un site au d?sign attractif et les programmeurs peuvent se consacrer enti?rement ? l'?criture de code de qualit?. Velocity s?pare le code Java des pages web, ce qui rend le site plus facile ? maintenir dans le long terme et fournit une alternative r?aliste aux Java Server Pages (JSPs) ou ? PHP.

Velocity peut ?tre utilis? pour g?n?rer des pages web, du SQL, du Postcript et tout ce qui peut ?tre g?n?r? ? partir d'un gabarit. Vous pouvez l'utiliser comme un utilitaire ind?pendant pour g?n?rer du code source ou des ?tats imprim?s, ou bien comme un composant int?gr? dans d'autres syst?mes. A terme, Velocity fournira les services d'inclusion pour le framework d'applications web Turbine. Velocity et Turbine fournissent un service d'inclusion qui permettra de d?velopper des applications web dans une v?ritable architecture MVC.


Qu'est-ce que Velocity peut faire pour moi?
L'exemple de MudStore

Supposons que vous soyez un concepteur de pages pour une boutique en ligne sp?cialis?e dans la vente de terre cuite. Appelons-la "The Online Mud Store". Les affaires marchent fort. Les clients passent commande pour diff?rents types et diverses quantit?s de terre cuite. Ils s'identifient sur votre site avec un nom d'utilisateur et un mot de passe, ce qui leur permet de suivre leurs commandes et d'en passer de nouvelles. Pour l'instant, vous vendez de la glaise Terracotta, un produit qui marche bien. Quelques-uns de vos clients ach?tent r?guli?rement de la glaise Bright Red, que vous vendez aussi, bien s?r, mais qui n'a pas autant la cote et qui se trouve d'habitude rel?gu?e dans les marges de vos pages. Les informations relatives ? chaque client sont suivies dans votre base de donn?es, et donc un jour la question se pose: pourquoi ne pas utiliser Velocity pour proposer des offres sp?ciales ? une client?le cibl?e, celle qui est la plus int?ress?e ? un type de marchandise?

Avec Velocity, il est tr?s facile de personnaliser les pages web pour certains visiteurs. En tant que concepteur de pages du MudRoom, vous voulez maintenant r?aliser la page d'accueil que verra votre client apr?s s'?tre identifi? sur votre site.

Vous tenez une r?union avec les ing?nieurs d?veloppement de votre entreprise, et tout le monde s'accorde sur le fait que $customer contiendra les informations relatives au client qui s'est connect? et $mudsOnSpecial tous les types de terre disponibles ? la vente en ce moment. L'objet $flogger contient diff?rentes m?thodes pour aider ? la promotion de certains produits. Pour la t?che qui nous concerne, occupons-nous seulement de ces trois r?f?rences. Rappelez-vous que vous n'avez pas ? vous soucier de la mani?re dont les d?veloppeurs vont extraire les informations n?cessaires de la base de donn?es, vous supposez seulement que ?a fonctionne -- ce qui vous permet de vous occuper de votre part du boulot et les d?veloppeurs de la leur.

Vous pouvez inclure l'instruction VTL suivante dans votre page web:

<HTML>
<BODY>
Hello $customer.Name!
<table>
#foreach( $mud in $mudsOnSpecial )
   #if ( $customer.hasPurchased($mud) )
      <tr>
        <td>
          $flogger.getPromo( $mud )
        </td>
      </tr>
   #end
#end
</table>

    

Les d?tails pr?cis de l'instruction foreach seront d?crits un peu plus loin; ce qui compte pour l'instant, c'est l'impact que peut avoir ce petit script sur votre site web. Quand un client qui appr?cie habituellement la glaise BrightRed se connecte, et que ce produit est en vente, c'est ce qu'il verra en premier lieu. Si un client qui a achet? beaucoup de Terracotta se connecte, c'est la vente de Terracotta qui sera affich?e en t?te et au centre. La flexibilit? de Velocity est tr?s grande, limit?e seulement par votre cr?ativit?.

Dans le manuel de r?f?rence du VTL, vous trouverez la documentation de beaucoup d'autres ?l?ments de Velocity, qui ensemble vous donnent la puissance et la souplesse dont vous avez besoin pour faire de votre site web une pr?sence sur le web. Lorsque vous deviendrez de plus en plus familiers avec ces ?l?ments, vous mettrez ? votre service toute la puissance de Velocity.



Introduction au Velocity Template Language (VTL)

Le Velocity Template Language (VTL) a ?t? con?u pour inclure du contenu dynamique dans une page web de la mani?re la plus facile, la plus simple et la plus propre. M?me un infographiste avec peu ou pas de bagage en programmation sera rapidement capable d'utiliser le VTL pour incorporer du contenu dynamique dans un site web.

VTL utilise des r?f?rences pour embarquer du contenu dynamique dans un site web, et une variable est un type de r?f?rence. Une variable fait r?f?rence ? quelque chose qui est d?fini dans le code Java, ou elle peut prendre sa valeur d'une instruction VTL dans la page web. Voici un exemple d'instruction VTL

#set( $a = "Velocity" )

Cette instruction VTL -- comme toutes les instructions VTL d'ailleurs -- commence par le caract?re # et contient une directive set. Quand un visiteur demande votre page web, le moteur de substitution Velocity (Velocity Templating Engine) recherche dans votre page tous les caract?res #, d?termine lesquels marquent le d?but d'instructions VTL, et quels caract?res # n'ont rien ? voir avec le VTL.

Le caract?re #est suivi d'une directive, set. La directive setutilise une expression (entre parenth?ses) -- une ?quation qui assigne une valeur? une variable. La variable est ?crite ? gauche et sa valeur ? droite; les deux sont s?par?s par un caract?re =.

Dans l'exemple ci-dessus, la variable est $aet la valeur est Velocity. Cette variable, comme toutes les r?f?rences, commence par le caract?re $. Les valeurs sont toujours entour?es d'apostrophes; dans Velocity, il n'y a jamais de confusion possible entre les types de donn?es puisque seules des cha?nes de caract?res (informations de type texte) peuvent ?tre pass?es ? des variables.

Le truc suivant peut ?tre utile pour mieux comprendre comment Velocity fonctionne :Les r?f?rences commencent par $ et sont utilis?es pour r?cup?rer quelque chose. Les directives commencent par #et sont utilis?es pour faire quelque chose.

Dans l'exemple ci-dessus, #setest utilis? pour assigner une valeur ? une variable. La variable, $a, peut alors ?tre utilis?e dans le gabarit pour produire "Velocity".


Hello Velocity World!

Une fois qu'une valeur a ?t? assign?e ? une variable, vous pouvez faire r?f?rence ? cette variable n'importe o? dans votre document HTML. Dans l'exemple suivant, une valeur est assign?e ? $foo et r?f?renc?e plus loin.

<html>
<body>
#set( $foo = "Velocity" )
Hello $foo World!
</body>
</html>

Le r?sultat est une page web o? s'imprime "Hello Velocity World!".

Pour rendre les instructions contenant des directives VTL plus lisibles, nous vous encourageons ? d?buter chaque instruction VTL sur une nouvelle ligne -- mais vous n'?tes pas oblig? de proc?der ainsi. La directive set sera revue avec davantage de d?tails plus loin.


Les commentaires

Les commentaires permettent d'inclure du texte descriptif qui ne sera pas report? dans la sortie du moteur d'inclusion. Les commentaires sont une mani?re utile de se rappeler et d'expliquer ? d'autres ce que font les instructions VTL, ou ? toute autre fin utile. Voici un exemple de commentaire en VTL.

## Ceci est un commentaire d'une seule ligne.

Un commentaire d'une ligne commence par ## et se termine ? la fin de la ligne. Si vous voulez ?crire quelques lignes de commentaires, pas besoin de multiplier ces commentaires d'une ligne. Les commentaires multi-lignes, qui commencent par #* et se terminent par *#, sont l? pour ce cas de figure.

Ceci est du texte ? l'ext?rieur du commentaire multi-lignes. Les visiteurs du site peuvent le voir.

#*
  Ici commence donc un commentaire de plusieurs lignes.
  Les visiteurs du site ne le verront pas, parce que le
  moteur de substitution de Velocity
  (Velocity Templating Engine) l'ignore.
*#

Ce texte-ci est ? l'ext?rieur du commentaire: il est visible.

Voici quelques exemples pour clarifier la mani?re dont les commentaires d'une et plusieurs lignes fonctionnent:

Ce texte est visible. ## Ce texte ne l'est pas.
Ce texte est visible.
Ce texte est visible. #* Ce texte, qui fait partie d'un commentaire
de plusieurs lignes, n'est pas visible. Ce texte n'est pas visible;
il faut aussi partie du commentaire multi-lignes.
Ce texte n'est toujours pas visible. *# Ce texte est ? l'ext?rieur
du commentaire, il est donc visible.
## Ce texte n'est pas visible.

Il y a un troisi?me type de commentaires, le bloc de commentaires VTL, que vous pouvez utiliser pour ?crire des informations telles que l'auteur du document ou la version.

#**
Ceci est un bloc de commentaires VTL, qui
peut ?tre utilis? pour inscrire des informations
telles que l'auteur ou la version du document.
@author
@version 5
*#


Les r?f?rences

Il y a trois types de r?f?rences en VTL: les variables, les propri?t?s et les m?thodes. En tant que concepteur utilisant le VTL, vous et vos ing?nieurs devez vous mettre d'accord sur les noms des r?f?rences, de mani?re ? pouvoir les utiliser correctement dans vos gabarits de pages.

Tout ce qui entre et sort d'une r?f?rence est trait? comme un objet cha?ne de caract?res. S'il y a un objet qui repr?sente $foo(un objet Integer par exemple), Velocity appellera sa m?thode .toString() pour convertir l'objet en String.

Variables
La notation abr?g?e pour une variable consiste en un caract?re "$" initial suivi d'un IdentificateurVTL. Un identificateur VTL doit commencer par une lettre (a .. z ou A .. Z). Le reste des caract?res est limit? aux types suivants:

  • lettre (a .. z, A .. Z)
  • chiffre (0 .. 9)
  • tiret ("-")
  • trait de soulignement ("_")

Voici quelques exemples de r?f?rences valides en VTL:

$foo
$mudSlinger
$mud-slinger
$mud_slinger
$mudSlinger1

Lorsque VTL r?f?rence une variable, telle que $foo, la variable peut prendre sa valeur soit d'une directive set dans le gabarit, soit d'un programme Java. Par exemple, si la variable Java $foo a la valeur bar ? la ligne ? laquelle il est fait appel au gabarit, bar remplace toutes les instances de $foo dans la page web. Autrement, si j'inclus l'instruction

#set( $foo = "bar" )

la sortie sera la m?me pour toutes les instances de $foo qui suivent cette directive.

Propri?t?s
Les propri?t?s sont la seconde esp?ce de r?f?rences en VTL et elles ont un format qui les distingue. La notation abr?g?e consiste en un caract?re $ initial suivi d'un identifiant VTL, suivi d'un point (".") et d'un autre identifiant VTL. Quelques exemples de r?f?rences valides de propri?t?s en VTL:

$customer.Address
$purchase.Total

Prenons le premier exemple, $customer.Address. Cette expression peut avoir deux significations. Elle peut signifier: "Regarde dans la table de hachage identifi?e par customer et renvoie la valeur associ?e ? la cl? Address. Mais $customer.Address peut aussi faire r?f?rence ? une m?thode (les r?f?rences qui d?signent des m?thodes seront discut?es dans la section suivante); $customer.Address pourrait ?tre une mani?re abr?g?e d'?crire $customer.getAddress(). Quand quelqu'un demande votre page, Velocity va d?terminer laquelle de ces deux possibilit?s a un sens, et retournera la valeur appropri?e.

M?thodes
Une m?thode est d?finie dans le code Java et peut faire quelque chose d'utile, comme effectuer un calcul ou prendre une d?cision. Les m?thodes sont des r?f?rences qui consistent en un caract?re "$" initial, suivi d'un identifiant VTL, suivi d'un corps de m?thode. Un corps de m?thode VTL consiste en un identifiant VTL suivi du caract?re parenth?se ouvrante ("("), ?ventuellement suivi d'une liste de param?tres, suivi du caract?re parenth?se fermante (")"). Quelques exemples de r?f?rences de m?thodes valides en VTL:

$customer.getAddress()
$purchase.getTotal()
$page.setTitle( "My Home Page" )
$person.setAttributes( ["Strange", "Weird", "Excited"] )

Les deux premiers exemples -- $customer.getAddress() et $purchase.getTotal() -- peuvent avoir l'air semblables ? ceux utilis?s dans la section pr?c?dente, consacr?e aux Propri?t?s, $customer.Address et $purchase.Total. Si vous avez devin? que ces exemples sont li?s entre eux d'une mani?re ou d'une autre, vous avez raison!

Les propri?t?s VTL peuvent ?tre utilis?es comme une notation abr?g?e pour des m?thodes VTL. La propri?t? $customer.Address a exactement le m?me effet que l'utilisation de la m?thode $customer.getAddress(). Il est g?n?ralement pr?f?rable d'utiliser une propri?t? lorsqu'il y en a une de disponible. La principale diff?rence entre les Propri?t?s et les M?thodes est que pour les m?thodes, on peut sp?cifier une liste de param?tres.

La notation abr?g?e peut ?tre utilis?e pour les m?thodes suivantes

$sun.getPlanets()
$annelid.getDirt()
$album.getPhoto()

On s'attend logiquement ? ce que ces m?thodes retournent les noms des plan?tes qui tournent autour du soleil, qu'elles nourissent notre ver de terre ou prennent une photo dans un album. Il n'y a que la notation longue qui fonctionne pour les m?thodes suivantes:

$sun.getPlanet( ["Earth", "Mars", "Neptune"] )
## On ne peut pas passer une liste de param?tres avec $sun.Planets

$sisyphus.pushRock()
## Velocity suppose que je veux dire $sisyphus.getRock()

$book.setTitle( "Homage to Catalonia" )
## On ne peut pas passer une liste de param?tres

Notation formelle des r?f?rences
Dans les exemples ci-dessus, nous avons utilis? la notation abr?g?e pour les r?f?rences, mais il y a aussi une notation formelle pour les r?f?rences, illustr?e ci-dessous:

${mudSlinger}
${customer.Address}
${purchase.getTotal()}

Dans presque tous les cas, vous utiliserez pour les r?f?rences la notation abr?g?e, mais dans certains cas la notation formelle est requise pour une ex?cution correcte.

Supposons que vous soyez en train de construire dynamiquement une phrase dans laquelle $vice doit ?tre utilis? comme base pour la construction d'un nom de la phrase. Le but est de permettre ? quelqu'un de choisir le mot de base et de produire l'un des deux r?sultats suivants: "Jacques est pyromane" ou "Jacques est cleptomane". L'utilisation de la notation abr?g?e ne convient pas pour cette t?che. Consid?rons en effet l'exemple suivant:

Jacques est un $vicemane.

La syntaxe est ici ambigu?, et Velocity suppose que $vicemane, et non $vice, est l'identifiant que vous pensiez utiliser. Ne trouvant pas de valeur pour $vicemane, il renverra $vicemane. L'utilisation de la notation formelle peut r?soudre ce probl?me.

Jacques est un ${vice}mane.

Cette fois Velocity sait que $vice, et non $vicemane, est la r?f?rence. La notation formelle est souvent utile quand les r?f?rences sont directement adjacentes ? du texte au sein d'un gabarit.

Notation silencieuse des r?f?rences
Lorsque Velocity rencontre une r?f?rence non d?finie, son comportement normal est de produire une image de la r?f?rence. Par exemple, supposons que la r?f?rence suivante apparaisse dans un gabarit VTL:

<input type="text" name="email" value="$email"/>

Quand le formulaire est charg? pour la premi?re fois, la variable r?f?renc?e par $email n'a pas de valeur, mais vous pr?f?reriez un champ de texte vide ? la valeur "$email". L'utilisation de la notation silencieuse contourne le comportement normal de Velocity; au lieu d'utiliser $email dans le code VTL, utilisez $!email. L'exemple pr?c?dent ressemblerait donc ? ceci:

<input type="text" name="email" value="$!email"/>

A pr?sent, quand le formulaire est charg? pour la premi?re fois et que $email n'a toujours pas de valeur, une cha?ne vide sera produite au lieu de "$email".

La notation formelle et la notation silencieuse peuvent ?tre utilis?es ensemble, comme illustr? ci-dessous.

<input type="text" name="email" value="$!{email}"/>


Sortie litt?rale

VTL utilise des caract?res sp?ciaux, comme $ et # pour accomplir sa t?che; il faut donc prendre quelques pr?cautions pour utiliser ces caract?res dans vos gabarits. Cette section est consacr?e ? l'?chappement du caract?re $.

Devise
Il n'y a pas de probl?me particulier ? ?crire "J'ai achet? un sac de 2 kg de patates au march? de la ferme pour seulement $2.50!". Comme dit plus haut, un identifiant VTL commence toujours par une lettre, majuscule ou minuscule, et donc $2.50 ne serait pas pris par erreur pour une r?f?rence.

Echapper des r?f?rences VTL valides
Il peut se produire dans certains cas que Velocity se trouve induit en confusion. Echapper les caract?res sp?ciaux est le meilleur moyen de traiter les caract?res sp?ciaux du VTL dans vos gabarits, et ceci se fait en utilisant le caract?re backslash (\).

#set( $email = "foo" )
$email

Lorsque Velocity rencontre une r?f?rence ? $email dans votre gabarit VTL, il cherche dans le contexte la valeur correspondante. Ici, la sortie sera foo, parce que $email est d?fini. Si $email n'?tait pas d?fini, la sortie serait $email.

Supposons que $email soit d?fini (par exemple, cette r?f?rence a la valeur foo) et que vous vouliez produire $email. Il y a diff?rentes mani?res de le faire, mais la plus simple est d'utiliser le caract?re d'?chappement.

## La ligne qui suit d?finit $email dans ce gabarit:
#set( $email = "foo" )
$email
\$email
\\$email
\\\$email

sera rendu comme:

foo
$email
\foo
\$email

Notez que le caract?re \ s'applique au $ ? partir de la gauche. Cette r?gle d'application ? partir de la gauche fait que \\\$email est rendu comme \\$email. Comparons maintenant ces examples ? ce qui se passe lorsque $email n'est pas d?fini.

$email
\$email
\\$email
\\\$email

sera rendu comme:

$email
\$email
\\$email
\\\$email

Remarquez comment Velocity traite les r?f?rences d?finies diff?remment de celles qui n'ont pas ?t? d?finies. Voici par exemple une directive set qui donne ? $foo la valeur gibbous.

#set( $foo = "gibbous" )
$moon = $foo

La sortie sera: $moon = gibbous -- o? $moon est rendu litt?ralement puisqu'il n'est pas d?fini, alors que gibbous est rendu au lieu de $foo.

Il est aussi possible d'?chapper les directives VTL; ceci est d?crit plus en d?tail dans la section Directives.


Substitution de cas

Maintenant que les r?f?rences vous sont famili?res, vous pouvez commencer ? les mettre en pratique dans vos propres gabarits. Les r?f?rences, dans Velocity, tirent avantage de certains principes Java que les concepteurs de gabarits vont trouver commodes. Par exemple:

$foo

$foo.getBar()
## est ?quivalent ?
$foo.Bar

$data.getUser("jon")
## est ?quivalent ?
$data.User("jon")

$data.getRequest().getServerName()
## est ?quivalent ?
$data.Request.ServerName
## est ?quivalent ?
${data.Request.ServerName}

Ces exemples illustrent diff?rentes mani?res d'utiliser les m?mes r?f?rences. Velocity tire parti de l'introspection Java et des caract?ristiques des beans pour r?soudre les noms de r?f?rence en objets du contexte et aussi en leurs m?thodes. Il est possible d'inclure et d'?valuer des r?f?rences ? peu pr?s partout dans votre gabarit.

Velocity utilise comme mod?les les sp?cifications des Beans telles qu'elles ont ?t? d?finies par Sun Microsystems; il est donc sensible ? la casse (majuscules/minuscules); les d?veloppeurs se sont toutefois battus pour intercepter et corriger les erreurs des utilisateurs chaque fois que c'est possible. Lorsque la m?thode getFoo() est r?f?renc?e dans un gabarit par $bar.foo, Velocity essayera d'abord $getfoo. Si ceci ?choue, Velocity essayera $getFoo. De m?me, si un gabarit fait r?f?rence ? $bar.Foo, Velocity essayera d'abord $getFoo() et ensuite getfoo().

Note: Dans un gabarit, les r?f?rences ? des variables d'instance ne sont pas r?solues. Il n'y a que les r?f?rences ?quivalentes aux attributs des accesseurs (getter / setter) des JavaBeans qui sont r?solues (autrement dit $foo.Name est r?solu par l'appel de la m?thode d'instance getName() de la classe Foo, mais pas en une variable d'instance publique Name de cette classe Foo).


Directives

Les r?f?rences permettent aux concepteurs de pages de g?n?rer du contenu dynamique pour des sites web alors que les directives -- des ?l?ments de script, faciles ? utiliser, qui peuvent ?tre mis en oeuvre pour manipuler de mani?re cr?ative la sortie d'un code Java -- permet aux concepteurs de vraiment prendre en charge l'apparence et le contenu du site web.

#set

La directive #set s'utilise pour donner une valeur ? une r?f?rence. Une valeur peut ?tre assign?e soit ? une r?f?rence de type variable, soit ? une r?f?rence de type propri?t?, et ceci toujours entre parenth?ses, comme montr? ici:

#set( $primate = "monkey" )
#set( $customer.Behavior = $primate )

Le c?t? gauche (left hand side -- LHS) de l'assignation doit ?tre une r?f?rence variable ou propri?t?. Le membre de droite (right hand side -- RHS) peut ?tre de l'un des types suivants:

  • Une r?f?rence (variable)
  • Une cha?ne de caract?res litt?rale
  • Une r?f?rence (propri?t?)
  • Une r?f?rence ? une m?thode
  • Un nombre litt?ral
  • Une ArrayList

Les exemples suivants montrent chacun des types susmentionn?s:

#set( $monkey = $bill ) ## r?f?rence (variable)
#set( $monkey.Friend = "monica" ) ## cha?ne de caract?res litt?rale
#set( $monkey.Blame = $whitehouse.Leak ) ## r?f?rence (propri?t?)
#set( $monkey.Plan = $spindoctor.weave($web) ) ## r?f?rence ? une m?thode
#set( $monkey.Number = 123 ) ## nombre litt?ral
#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList

NOTE: Dans le dernier exemple, les ?l?ments d?finis avec l'op?rateur [..] sont accessibles en utilisant les m?thodes d?finies dans la classe ArrayList. Ainsi, par exemple, on peut acc?der au premier ?l?ment en ?crivant $monkey.Say.get(0)

Le membre de droite peut aussi ?tre une expression arithm?tique simple:

#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )

Si le membre de droite est une r?f?rence ? une m?thode ou ? une propri?t? dont la valeur est null, il ne sera pas affect? au membre de gauche. Il n'est pas possible d'enlever une r?f?rence existante du contexte par ce biais-l?. Ceci peut troubler les d?butants en Velocity. Par exemple:

#set( $result = $query.criteria("name") )
Le r?sultat de la premi?re requ?te est $result

#set( $result = $query.criteria("address") )
Le r?sultat de la seconde requ?te est $result

Si $query.criteria("name") renvoie la cha?ne "bill", et que $query.criteria("address") renvoie null, le code VTL ci-dessus sera rendu de la mani?re suivante:

Le r?sultat de la premi?re requ?te est bill

Le r?sultat de la seconde requ?te est bill

Ceci induit en confusion les nouveaux venus, qui construisent des boucles #foreach qui tentent de faire un #set sur une r?f?rence ? partir d'une r?f?rence ? une propri?t? ou une m?thode et testent imm?diatement cette r?f?rence avec une directive #if. Par exemple:

#set( $criteria = ["name", "address"] )

#foreach( $criterion in $criteria )

    #set( $result = $query.criteria($criterion) )

    #if( $result )
        Query was successful
    #end

#end

Dans l'exemple ci-dessus, il ne serait pas avis? de se reposer sur l'?valuation de $result pour d?terminer si une requ?te a ?t? couronn?e de succ?s. Une fois que $result a re?u une valeur par un #set (et a donc ?t? ajout? au contexte), il ne peut pas recevoir la valeur null (et se trouver ainsi enlev? du contexte). Les d?tails des directives #if et #foreach sont trait?s plus loin dans ce document.

Une solution ? ce probl?me serait de pr?-positionner $result ? false. Si l'appel ? $query.criteria() ?choue, il est possible de faire la v?rification.

#set( $criteria = ["name", "address"] )

#foreach( $criterion in $criteria )

    #set( $result = false )
    #set( $result = $query.criteria($criterion) )

    #if( $result )
        La requ?te a abouti correctement
    #end

#end

Contrairement ? d'autres directives Velocity, la directive #set n'a pas d'instruction #end.

Cha?nes de caract?res litt?rales

Lorsque vous utilisez la directive #set, les cha?nes de caract?res litt?rales d?limit?es par des guillements sont interpr?t?es et rendues de la mani?re suivante:

#set( $directoryRoot = "www" )
#set( $templateName = "index.vm" )
#set( $template = "$directoryRoot/$templateName" )
$template

La sortie produite sera

www/index.vm

Toutefois, lorsque la cha?ne de caract?res litt?rale est d?limit?e par des apostrophes, elle n'est pas interpr?t?e.

#set( $foo = "bar" )
$foo
#set( $blargh = '$foo' )
$blargh

Ce qui est rendu de la mani?re suivante:

  bar
  $foo

Cette caract?ristique d'utilisation des apostrophes pour rendre du texte non interpr?t? est le comportement par d?faut de Velocity. Ce comportement peut ?tre chang? en ?ditant le fichier velocity.properties et en y ?crivant l'entr?e: stringliterals.interpolate=false.


Conditions
If / ElseIf / Else

La directive #if de Velocity permet ? du texte d'?tre inclus ? la g?n?ration d'une page web seulement si la condition qui suit l'instruction if est v?rifi?e. Par exemple:

#if( $foo )
   <strong>Velocity!</strong>
#end

La variable $foo est ?valu?e pour d?terminer si elle vaut true, ce qui se produit dans l'une des deux cas suivants; (i) $foo est une variable bool?enne (true/false) dont la valeur est vrai (true), ou (ii) la valeur de $foo est diff?rente de null. On se rappelle que le contexte de Velocity ne contient que des Objets, et donc lorsqu'on dit un bool?en, il sera repr?sent? comme un objet de la classe Boolean contenant la valeur logique appropri?e.

Ce qui est contenu entre l'instruction #if et l'instruction #end sera produit en sortie si la condition est ?valu?e comme vraie. Dans l'exemple pr?c?dent, si $foo est true, la sortie sera: "Velocity!". A l'inverse, si $foo a la valeur null, ou si c'est un bool?en de valeur false, l'instruction est ?valu?e comme fausse, et il n'y a pas de sortie produite.

Un ?l?ment #elseif ou #else peut ?tre utilis? dans la directive #if. Notez que le moteur Velocity (Velocity Template Engine) s'arr?tera ? la premi?re expression ?valu?e comme vraie. Dans l'exemple suivant, supposons que $foo vaut 15 et que $bar vaut 6.

#if( $foo < 10 )
    <strong>Go North</strong>
#elseif( $foo == 10 )
    <strong>Go East</strong>
#elseif( $bar == 6 )
    <strong>Go South</strong>
#else
    <strong>Go West</strong>
#end

Dans cet exemple, $foo est plus grand que 10, donc les deux premi?res comparaisons ?chouent. Ensuite, $bar est compar? ? 6, ce qui donne vrai, et dont la sortie produit est Go South.

Notez que pour l'instant, dans Velocity, les comparaisons num?riques sont restreintes aux comparaisons d'entiers (Integers) -- tout le reste sera ?valu? comme faux. La seule exception est l'?galit? '==': dans ce cas Velocity teste si les objets de chaque c?t? de '==' sont de la m?me classe.

Op?rateurs logiques et relationnels

Velocity utilise l'op?rateur d'?quivalence pour d?terminer les relations entre des variables. Voici un exemple simple pour illustrer la mani?re d'utiliser l'op?rateur d'?quivalence.

#set ($foo = "deoxyribonucleic acid")
#set ($bar = "ribonucleic acid")

#if ($foo == $bar)
  Dans ce cas, il est clair qu'ils ne sont pas ?quivalents. Donc...
#else
  Ils ne sont pas ?quivalents et c'est ceci qui sera produit en sortie.
#end

Velocity a aussi des op?rateurs ET, OU et NON. Pour plus d'informations, r?f?rez-vous au VTL Reference Guide (en anglais). Ci-dessous, quelques exemples illustrent l'utilisation des op?rateurs logiques ET, OU et NON.

##ET logique

#if( $foo && $bar )
   <strong> Ceci ET cela.</strong>
#end

La directive #if() ne sera ?valu?e comme true que si $foo et $bar sont true tous les deux. Si $foo est false, l'expression sera globalement ?valu?e comme false et $bar ne sera pas ?valu?. Si $foo vaut true, le moteur Velocity testera la valeur de $bar; si $bar vaut true, alors l'expression dans son enti?ret? vaut true et la sortie Ceci ET cela est produite. Si $bar est false, alors il n'y aura pas de sortie produite puisque l'expression enti?re est fausse.

Les op?rateurs logiques OU fonctionnent de la m?me mani?re, si ce n'est qu'une seule des r?f?rences doit ?tre ?valu?e ? true pour que l'expression enti?re soit consid?r?e comme vraie. Voyez l'exemple suivant:

##OU logique

#if( $foo || $bar )
    <strong>Ceci OU cela</strong>
#end

Si $foo vaut true, le moteur Velocity n'a pas besoin d'?valuer $bar; que $bar soit vrai ou faux ne change rien ? l'affaire, l'expression sera vraie, et Ceci OU cela sera produit en sortie. Mais si $foo est false, la valeur de $bar doit ?tre v?rifi?e. Dans ce cas, si $bar est faux lui aussi, l'expression sera fausse et il n'y aura pas de sortie produite. Sinon, si $bar est vrai, alors l'expression enti?re est vraie, et la sortie est Ceci OU cela.

Avec l'op?rateur logique NON, il n'y a qu'un seul argument :

##NON logique

#if( !$foo )
  <strong>PAS ?a</strong>
#end

Cette fois, si $foo vaut true, alors !$foo est ?valu? comme false, et il n'y a pas de sortie. Si $foo est false, alors !$foo est ?valu? ? true et PAS ?a est produit en sortie. Attention ? ne pas confondre ceci avec la r?f?rence silencieuse $!foo que nous avons d?j? rencontr?e et qui repr?sente quelque chose de compl?tement diff?rent.


Boucles
Boucle Foreach

L'?l?ment #foreach permet d'it?rer. Par exemple:

<ul>
#foreach( $product in $allProducts )
    <li>$product</li>
#end
</ul>

Cette boucle #foreach parcourt un ? un tous les produits (cibles) de la liste $allProducts (objet). A chaque passage dans la boucle, une valeur de $allProducts est plac?e dans la variable $product.

Le contenu de la variable $allProducts est un vecteur (Vector), une table de hachage (Hashtable) ou un tableau (Array). La valeur assign?e ? $product est un objet Java, et peut ?tre r?f?renc?e en tant que telle par une variable. Par exemple, si $product est en effet une classe Product en Java, son nom peut ?tre r?cup?r? en r?f?ren?ant la m?thode $product.Name (c'est-?-dire $Product.getName()).

Supposons que $allProducts soit une Hashtable. Si vous voulez retrouver les valeurs des cl?s et les objets de la Hashtable, vous pouvez utiliser un bout de code comme celui-ci:

<ul>
#foreach( $key in $allProducts.keySet() )
    <li>Key: $key -> Value: $allProducts.get($key)</li>
#end
</ul>

Velocity fournit un moyen simple de conna?tre le compteur de boucle, de sorte qu'on puisse faire quelque chose comme:

<table>
#foreach( $customer in $customerList )
    <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end
</table>

Le nom par d?faut de la variable/r?f?rence du compteur de bouche est sp?cifi? dans le fichier velocity.properties. Par d?faut le compteur d?marre ? 1, mais ceci aussi peut ?tre param?tr? (? 0 ou 1) dans le fichier velocity.properties. Voici ? quoi ressemble la section Propri?t?s du compteur de boucle dans le fichier velocity.properties:

# Default name of the loop counter
# variable reference.
directive.foreach.counter.name = velocityCount

# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1


Include

L'?l?ment de script #include permet au concepteur de gabarits d'importer un fichier local, qui est alors ins?r? ? l'endroit o? la directive #include est d?finie. Le contenu du fichier n'est pas rendu en passant par le moteur de substitution. Pour des raisons de s?curit?, le fichier ? inclure ne peut se trouver que sous TEMPLATE_ROOT.

#include( "one.txt" )

Le fichier auquel la directive #include fait r?f?rence est inclus entre des guillemets. Si plusieurs fichiers doivent ?tre inclus, leurs noms doivent ?tre s?par?s par des virgules.

#include( "one.gif","two.txt","three.htm" )

Le fichier ? inclure ne doit pas n?cessairement ?tre appel? par son nom; en fait, il est souvent pr?f?rable d'utiliser une variable plut?t qu'un nom de fichier. Ce qui peut ?tre utile pour cibler ce qui est produit en fonction de crit?res d?termin?s au moment o? la page est demand?e. Voici un exemple qui utilise ? la fois un nom de fichier et une variable.

#include( "greetings.txt", $seasonalstock )


Parse

L'?l?ment de script #parse permet au concepteur de gabarits d'importer un fichier local contenant du VTL. Velocity va alors interpr?ter le VTL et rendre le gabarit sp?cifi?.

#parse( "me.vm" )

Comme la directive #include, #parse peut prendre en argument une variable plut?t qu'un nom de gabarit. Tous les gabarits auxquels il est fait r?f?rence par #parse doivent se trouver sous TEMPLATE_ROOT. Contrairement ? la directive #include, #parse ne peut prendre qu'un seul argument.

Les gabarits VTL peuvent contenir des instructions #parse faisant r?f?rence ? des gabarits qui ? leur tour contiennent des #parse. Par d?faut ? 10, la ligne parse_directive.maxdepth du fichier velocity.properties permet aux utilisateurs de personnaliser le nombre de r?f?rences #parse que l'on peut rencontrer dans un gabarit. (Note: Si la propri?t? parse_directive.maxdepth est absente du fichier velocity.properties, Velocit? positionne cette valeur par d?faut ? 10). La r?cursion est permise; par exemple si le gabarit dofoo.vm contient les lignes suivantes:

Count down.
#set( $count = 8 )
#parse( "parsefoo.vm" )
All done with dofoo.vm!

Il fait r?f?rence au gabarit parsefoo.vm, qui peut contenir le VTL suivant:

$count
#set( $count = $count - 1 )
#if( $count > 0 )
    #parse( "parsefoo.vm" )
#else
    All done with parsefoo.vm!
#end

Apr?s que "Count down." soit affich?, Velocity passe par parsefoo.vm, comptant ? rebours ? partir de 8. Lorsque le compte ? rebours atteint 0, il affiche le message "All done with parsefoo.vm!". A ce stade, Velocity va retourner ? dofoo.vm et produire le message "All done with dofoo.vm!".


Stop

L'?l?ment de script #stop permet au concepteur de gabarits d'arr?ter l'ex?cution du moteur de substitution. Cette directive peut ?tre utile pour le d?bogage.

#stop


Velocimacros

L'?l?ment de script #macro permet aux concepteurs de d?finir un segment r?p?table d'un gabarit VTL. Les "Velocimacros" sont tr?s utiles dans un grand nombre de sc?narios, simples ou complexes. Une Velocimacro, ?crite dans le seul but de s'?conomiser un peu de frappe et de minimiser les fautes, servira d'introduction au concept de Velocimacro.

#macro( d )
<tr><td></td></tr>
#end

La Velocimacro d?finie dans cet exemple est d; elle peut ?tre appel?e d'une mani?re semblable ? toute autre directive VTL:

#d()

Lorsque ce gabarit est appel?, Velocity remplace #d() par une ligne contenant une cellule de donn?es vide.

Une Velocimacro peut prendre n'importe quel nombre d'arguments -- m?me z?ro, comme on l'a vu dans l'exemple -- mais lorsque la macro est appel?e, elle doit l'?tre avec le m?me nombre d'arguments que dans la d?finition. Beaucoup de Velocimacros sont plus sophistiqu?es que celle d?finie ci-dessus; voici une Velocimacro qui prend deux arguments, une couleur et un tableau.

#macro( tablerows $color $somelist )
#foreach( $something in $somelist )
    <tr><td bgcolor=$color>$something</td></tr>
#end
#end

La Velocimacro d?finie dans cet exemple, tablerows, prend deux arguments. Le premier argument prend la place de $color et le second argument prend la place de $somelist.

Tout ce qui peut ?tre mis dans un gabarit VTL peut aussi trouver place dans le corps d'une Velocimacro. La Velocimacro tablerows contient une instruction foreach. On remarquera qu'il y a deux instructions #end dans la d?finition de la Velocimacro #tablerows; la premi?re termine le #foreach, la seconde termine la d?finition de la Velocimacro.

#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )
#set( $color = "blue" )
<table>
    #tablerows( $color $greatlakes )
</table>

Notez que $greatlakes prend la place de $somelist. Quand la Velocimacro #tablerows est appel?e dans ce contexte, la sortie suivante est produite:

<table>
    <tr><td bgcolor="blue">Superior</td></tr>
    <tr><td bgcolor="blue">Michigan</td></tr>
    <tr><td bgcolor="blue">Huron</td></tr>
    <tr><td bgcolor="blue">Erie</td></tr>
    <tr><td bgcolor="blue">Ontario</td></tr>
</table>

Les Velocimacros peuvent ?tre d?finies inline dans un gabarit Velocity; elles ne sont pas disponibles dans ce cas pour d'autres gabarits Velocity sur le m?me site web. D?finir une Velocimacro pour qu'elle puisse ?tre partag?e par tous les gabarits a des avantages ?vidents: cela r?duit le besoin de red?finir la Velocimacro dans de nombreux gabarits, cela ?conomise du travail et r?duit les occasions de se tromper, cela assure qu'un chagement fait une seule fois dans une macro est aussit?t disponible dans tous les gabarits.

Si la Velocimacro #tablerows($color $list) avait ?t? d?finie dans une biblioth?que de gabarits Velocimacros, cette macro aurait pu ?tre utilis?e dans n'importe lequel des gabarits usuels. Elle pourrait ?tre utilis?e de nombreuses fois et dans des buts diff?rents. Dans le gabarit mushroom.vm consacr? ? toute esp?ce de champignons, la Velocimacro #tablerows pourrait ?tre appel?e pour donner la liste des parties d'un champignon typique.

#set( $parts = ["volva","stipe","annulus","gills","pileus"] )
#set( $cellbgcol = "#CC00FF" )
<table>
#tablerows( $cellbgcol $parts )
</table>

Lors de l'ex?cution d'une requ?te pour mushroom.vm, Velocity trouverait la Velocimacro #tablerows dans la biblioth?que de gabarits (d?finie dans le fichier velocity.properties) et produirait la sortie suivante:

<table>
    <tr><td bgcolor="#CC00FF">volva</td></tr>
    <tr><td bgcolor="#CC00FF">stipe</td></tr>
    <tr><td bgcolor="#CC00FF">annulus</td></tr>
    <tr><td bgcolor="#CC00FF">gills</td></tr>
    <tr><td bgcolor="#CC00FF">pileus</td></tr>
</table>
Arguments d'une Velocimacro

Les Velocimacros peuvent prendre comme argument tout ?l?ment VTL parmi les suivants:

  • R?f?rence: tout ce qui commence par '$'
  • Cha?ne de caract?res litt?rale: quelque chose comme "$foo" ou 'hello'
  • Nombre litt?ral: 1, 2 etc
  • Intervalle d'entiers (IntegerRange) : [ 1..2] ou [$foo .. $bar]
  • ObjectArray : [ "a", "b", "c"]
  • Valeur bool?enne true
  • Valeur bool?enne false

Lorsqu'on passe des r?f?rences comme arguments ? des Velocimacros, notez que ces r?f?rences sont pass?es "par nom". Ce qui veut dire que leur valeur est "g?n?r?e" ? chaque utilisation ? l'int?rieur d'une Velocimacro. Cette particularit? vous permet de passer des r?f?rences contenant des appels de m?thodes et que la m?thode soit appel?e ? chaque fois. Par exemple, en appelant la Velocimacro suivante comme indiqu?:

     #macro( callme $a )
         $a $a $a
     #end

     #callme( $foo.bar() )
   

le r?sultat est que la m?thode bar() de la r?f?rence $foo est appel?e trois fois.

A premi?re vue, cette particularit? est surprenante mais si vous consid?rez la raison d'?tre originelle des Velocimacros (?liminer la duplication par couper/coller de VTL d'usage courant), ?a a bien s?r un sens. Cela vous permet de faire des choses ?tonnantes telles que passer ? la Velocimacro des objets ayant un ?tat, comme un objet qui g?n?re des couleurs en s?quences r?p?t?es pour colorer les lignes d'un tableau.

Si vous ?prouvez le besoin de contourner ce comportement, vous pouvez toujours assigner la valeur re?ue de la m?thode ? une nouvelle r?f?rence et passer cette r?f?rence:

     #set( $myval = $foo.bar() )
     #callme( $myval )
  
Propri?t?s des Velocimacros

Plusieurs entr?es du fichier velocity.properties permettent une impl?mentation flexible des Velocimacros. Ces lignes sont comment?es en d?tail dans le Developer Guide (en anglais).

velocimacro.library - Une liste (d?limit?e par des virgules, de toutes les biblioth?ques de gabarits Velocimacro. Par d?faut, Velocity ne recherche qu'une biblioth?que: VM_global_library.vm. Le chemin de gabarits donn? ici est utilis? pour trouver les biblioth?ques de Velocimacros.

velocimacro.permissions.allow.inline - Cette propri?t?, qui peut prendre les valeurs true ou false, d?termine si les Velocimacros peuvent ?tre d?finies dans des gabarits ordinaires. La valeur par d?faut, true, permet aux concepteurs de gabarits de d?finir des Velocimacros dans les gabarits eux-m?mes.

velocimacro.permissions.allow.inline.to.replace.global - Les valeurs possibles sont true ou false, pour cette propri?t? qui permet ? l'utilisateur de sp?cifier si une Velocimacro d?finie en ligne dans un gabarit peut remplacer un gabarit d?fini globalement, celui qui a ?t? d?fini au d?marrage par la propri?t? velocimacro.library. La valeur par d?faut, false, emp?che les Velocimacros d?fines inline dans un gabarit de remplacer celles qui sont d?finies dans les biblioth?ques de gabarits charg?es au d?marrage.

velocimacro.permissions.allow.inline.local.scope - Cette propri?t?, qui peut prendre les valeurs true ou false (false par d?faut), contr?le si les Velocimacros d?finies inline ont leur visibilit? limit?e au gabarit qui les d?finit. En d'autres mots, avec cette propri?t? d?finie ? true, un gabarit peut d?finir des Velocimacros inline qui ne seront utilisables que par le gabarit qui les d?finit. Vous pouvez utiliser cette possibilit? pour concocter quelques artifices amusants: si une VM globale appelle une autre VM globale, d?finie inline, un gabarit peut d?finir une impl?mentation "priv?e" de la seconde VM, qui sera appell?e par la premi?re VM quand celle-ci est appel?e elle-m?me dans le gabarit. Aucun autre gabarit n'est affect?.

velocimacro.context.localscope - Cette propri?t? peut valoir true ou false, la valeur par d?faut est false. Quand elle vaut true, toute modification du contexte via #set() ? l'int?rieur d'une Velocimacro est consid?r?e 'locale' ? cette Velocimacro et n'affectera pas le contexte de fa?on permanente.

velocimacro.library.autoreload - Cette propri?t? contr?le le chargement automatique de la biblioth?que de Velocimacro. La valeur par d?faut est false. Quand elle est positionn?e ? true la biblioth?que source appel?e pour une Velocimacro sera v?rifi?e pour voir si elle a chang? et sera recharg?e si n?cessaire. Ceci vous permet de modifier et de tester des biblioth?ques de Velocimacro sans avoir ? red?marrer votre application ou votre moteur de servlets, exactement comme vous pouvez le faire pour des gabarits ordinaires. Ce mode ne fonctionne que quand le cache est d?sactiv? dans les resource loaders (par exemple file.resource.loader.cache = false). Cette possibilit? a ?t? con?ue pour le d?veloppement, pas pour la production.

Autres remarques sur les Velocimacros

A ce stade, les Velocimacros doivent ?tre d?finies avant d'?tre utilis?es dans un gabarit. Cela signifie que vos d?clarations #macro() doivent pr?c?der l'usage des Velocimacros.

Il est important de s'en souvenir si l'on essaye d'interpr?ter (#parse()) un gabarit contenant des directives #macro() inline. Puisque l'interpr?tation se fait au moment de l'ex?cution, et que l'interpr?teur d?cide au moment de l'interpr?tation si, dans un gabarit, un ?l?ment qui a l'air d'une VM en est vraiment une, #parse()-er un ensemble de d?clarations de VM ne produira pas le r?sultat escompt?. Pour contourner ce probl?me potentiel, on peut utiliser la propri?t? velocimacro.library pour que Velocity charge vos VMs au d?marrage.


Echappement des directives VTL

Les directives VTL peuvent ?tre ?chapp?es avec le caract?re barre de fraction invers?e ("\"), de la m?me mani?re que les r?f?rences VTL valides.

## #include( "a.txt" ) renders as <contents of a.txt>
#include( "a.txt" )

## \#include( "a.txt" ) renders as \#include( "a.txt" )
\#include( "a.txt" )

## \\#include ( "a.txt" ) renders as \<contents of a.txt>
\\#include ( "a.txt" )

Il faut prendre des pr?cautions particuli?res lorsqu'on ?chappe des directives VTL qui contiennent plusieurs ?l?ments de script en une seule directive (comme dans le cas d'une instruction conditionnelle if-else-end). Voici un exemple typique d'instruction VTL if:

#if( $jazz )
    Vyacheslav Ganelin
#end

Si $jazz est vrai, la sortie produite est:

Vyacheslav Ganelin

Si $jazz, il n'y a pas de sortie produite. Echapper des ?l?ments de script modifie la sortie. Consid?rons le cas suivant:

\#if( $jazz )
    Vyacheslav Ganelin
\#end

Que $jazz soit vrai ou faux, la sortie sera:

 #if($ jazz )
     Vyacheslav Ganelin
 #end

En fait, puisque tous les ?l?ments de script sont ?chapp?s, $jazz n'est jamais ?valu? en vue d'en conna?tre la valeur logique. Supposons que les barres de fraction inverses pr?c?dent les ?l?ments de script qui sont l?gitimement ?chapp?s:

\\#if( $jazz )
   Vyacheslav Ganelin
\\#end

Dans ce cas, si $jazz est vrai, la sortie est

\ Vyacheslav Ganelin
\

Pour comprendre, notons que le #if( arg ) , lorsqu'il est termin? par un retour ? la ligne, omettra ce retour ? la ligne de la sortie produite. Donc, le corps du bloc #if() suit la premi?re barre '\', rendue par le '\\' qui pr?c?de #if(). Le dernier \ est sur une ligne diff?rente du texte qui pr?c?de parce qu'il y a un retour chariot apr?s 'Ganelin', et donc le \\ final, qui pr?c?de le #end fait partie du corps du bloc.

Si $jazz est faux, il n'y a pas de sortie produite. Notons que les choses vont commencer ? mal se passer si des ?l?ments de script ne sont pas ?chapp?s correctement.

\\\#if( $jazz )
    Vyacheslave Ganelin
\\#end

Ici le #if est ?chapp?, mais il y a un #end qui reste l?, et trop de terminaisons vont causer une erreur dans l'interpr?tation.


VTL: Questions de format

Bien que le VTL soit souvent montr? dans ce guide de l'utilisateur avec des sauts de ligne et des espaces, le VTL ci-dessous:

#set( $imperial = ["Munetaka","Koreyasu","Hisakira","Morikune"] )
#foreach( $shogun in $imperial )
    $shogun
#end

est tout aussi valide que le bout de code suivant, post? par Geir Magnusson Jr. ? la liste de diffusion Velocity (pour illustrer un point sans rapport avec notre sujet):

Send me #set($foo = ["$10 and ","a cake"])#foreach($a in $foo)$a #end please.

Velocity dig?re les blancs inutiles. La directive qui pr?c?de peut donc s'?crire de la mani?re suivante:

Send me
#set( $foo = ["$10 and ","a cake"] )
#foreach( $a in $foo )
$a
#end
please.

ou encore:

Send me
#set($foo       = ["$10 and ","a cake"])
                 #foreach           ($a in $foo )$a
         #end please.

Dans tous les cas, la sortie sera identique.


Autres caract?ristiques et sujets divers
Math

Velocity a quelques fonctions math?matiques int?gr?es, fonctions que l'on peut utiliser dans les gabarits avec la directive set. Les ?quations suivantes sont des exemples d'addition, soustraction, multiplication et division respectivement:

#set( $foo = $bar + 3 )
#set( $foo = $bar - 4 )
#set( $foo = $bar * 6 )
#set( $foo = $bar / 2 )

Lorsqu'une op?ration de division est ex?cut?e, le r?sultat sera un entier. Le reste ?ventuel de la division peut ?tre obtenu en utilisant l'op?rateur modulo (%).

#set( $foo = $bar % 5 )

Seuls les entiers (...-2, -1, 0, 1, 2...) sont admis comme op?randes des ?quations math?matiques en Velocity; lorsqu'un non-entier est rencontr?, cela est signal? et null sera renvoy? dans la sortie produite.


Op?rateur d'intervalle (range)

L'op?rateur d'intervalle peut ?tre utilis? en conjonction avec les instructions #set et #foreach. C'est assez commode pour produire un tableau d'objets contenant des entiers; l'op?rateur d'intervalle est construit comme ceci:

[n..m]

n et m doivent tous deux ?tre ou renvoyer des entiers. Que m soit plus grand ou plus petit que n importe peu, si cela se produit le tableau d?compte. Voici quelques exemples de l'op?rateur de port?e:

Premier exemple:
#foreach( $foo in [1..5] )
$foo
#end

Second exemple:
#foreach( $bar in [2..-2] )
$bar
#end

Troisi?me exemple:
#set( $arr = [0..1] )
#foreach( $i in $arr )
$i
#end

Quatri?me exemple:
[1..3]

Produit la sortie suivante:

Premier exemple:
1 2 3 4 5

Second exemple:
2 1 0 -1 -2

Troisi?me exemple:
0 1

Quatri?me exemple:
[1..3]

Il est ? noter que l'op?rateur d'intervalle ne produit le tableau qu'utilis? en conjonction avec les directives #set et #foreach, comme d?montr? dans le quatri?me exemple.

Les concepteurs de pages web soucieux de construire des tables de taille standard, mais dans lequelles il n'y a pas assez de donn?es pour remplir la table, trouveront cet op?rateur d'intervalle particuli?rement utile.


Questions pointues: Echappement et !

Lorsqu'une r?f?rence est annul?e par le caract?re ! et que ce caract?re ! est pr?c?d? par un caract?re d'?chappement \, la r?f?rence est trait?e de mani?re particuli?re. A noter: les diff?rences entre l'?chappement ordinaire et le cas particulier o? \ pr?c?de ! comme ici:

#set( $foo = "bar" )
$\!foo
$\!{foo}
$\\!foo
$\\\!foo

Ceci produit la sortie suivante:

$!foo
$!{foo}
$\!foo
$\\!foo

A comparer avec l'?chappement ordinaire, o? \ pr?c?de $:

\$foo
\$!foo
\$!{foo}
\\$!{foo}

Ce qui produit la sortie suivante:

\$foo
\$!foo
\$!{foo}
\bar

Compl?ments divers sur les Velocimacros

Cette section est une mini-FAQ sur diff?rents sujets relatifs aux Velocimacros. Cette section ?voluera au fil du temps, et cela vaudra donc la peine d'y revenir occasionnellement pour y chercher de nouvelles informations.

Note: tout au long de cette section, 'Velocimacro' sera habituellement abr?g? en 'VM'.

Puis-je utiliser une directive ou une autre VM comme argument d'une VM?

Exemple : #center( #bold("hello") )

Non. Une directive n'est pas un argument valide d'une directive, et en pratique, pour l'essentiel, une VM est une directive.

Pourtant..., il y a des choses que vous pouvez faire. Une solution, simple, est de tirer avantage du fait que l'apostrophe (") restitue son contenu. Vous pouvez donc ?crire quelque chose comme

#set($stuff = "#bold('hello')" )
#center( $stuff )

Vous pouvez m?me vous ?pargner une ?tape...

#center( "#bold( 'hello' )" )

Mais il est ? noter, dans ce dernier exemple, que l'argument est ?valu? ? l'int?rieur de la VM, pas au niveau de l'appel. En d'autres termes, l'argument pass? ? la VM est pass? dans son int?gralit? et ?valu? dans la VM ? laquelle il a ?t? pass?. Ceci permet d'?crire des choses comme:

#macro( inner $foo )
  inner : $foo
#end

#macro( outer $foo )
   #set($bar = "outerlala")
   outer : $foo
#end

#set($bar = 'calltimelala')
#outer( "#inner($bar)" )

La sortie produite est

Outer : inner : outerlala

puisque l'?valuation de "#inner($bar)" se produit ? l'int?rieur de #outer(), et c'est donc la valeur $bar positionn?e ? l'int?rieur de #outer() qui est utilis?e.

Ceci est tout ? fait intentionnel, et c'est une caract?ristique jalousement gard?e - les arguments sont pass?s 'par nom' aux VM, de sorte qu'on puisse passer aux VM un genre de "r?f?rences avec ?tat" telles que

#macro( foo $color )
  <tr bgcolor=$color><td>Hi</td></tr>
  <tr bgcolor=$color><td>There</td></tr>
#end

#foo( $bar.rowColor() )

et appeler rowColor() plusieurs fois, plut?t qu'une fois. Pour ?viter cela, il faut appeler la m?thode hors de la VM et passer la valeur ? la VM.

#set($color = $bar.rowColor())
#foo( $color )
Peut-on enregistrer des Velocimacros avec #parse() ?

Pour l'instant, les Velocimacros doivent ?tre d?finies avant d'?tre utilis?es dans un gabarit. Ce qui signifie que les d?clarations #macro() doivent pr?c?der l'usage des Velocimacros.

Il est important de s'en souvenir si l'on essaye d'interpr?ter avec #parse() un gabarit qui contient des directives #macro() d?finies inline. Puisque le #parse() a lieu au moment de l'ex?cution, et que l'interpr?teur d?cide ? ce moment si quelque chose qui ressemble syntaxiquement ? une VM dans le gabarit en est vraiment une au moment de l'interpr?tation, #parse()-r un ensemble de d?clarations de VM ne fonctionnera pas comme on pourrait le pr?voir. Pour contourner ce comportement, il suffit d'utiliser velocimacro.library pour que Velocity charge vos VM's au d?marrage.

Qu'est-ce que le Velocimacro Autoreloading?

Il existe une propri?t?, con?ue pour le d?veloppement, pas pour la production:

velocimacro.library.autoreload

dont la valeur par d?faut est false. Lorsque cette propri?t? est positionn?e ? true, en m?me temps que

<type>.resource.loader.cache = false

(o? <type> est le nom du chargeur de ressources que vous utilisez, par exemple 'file'), le moteur Velocity va automatiquement prendre en compte les changements apport?s ? vos fichiers de biblioth?ques Velocimacro, au fur et ? mesure que vous les modifiez, de sorte que vous n'ayez pas ? arr?ter le moteur de servlet (ou l'application) ou avoir recours ? tout autre subterfuge de ce genre pour recharger vos Velocimacros.

Voici ? quoi peut ressembler un ensemble simple de propri?t?s.

    file.resource.loader.path = templates
    file.resource.loader.cache = false
    velocimacro.library.autoreload = true
    

Ne gardez pas cette configuration en production.


Concat?nation de cha?nes

Une question habituelle parmi les d?veloppeurs est: Comment concat?ner des cha?nes de caract?res? Y a-t'il quelque chose de semblable ? l'op?rateur '+' en Java?.

Pour concat?ner des r?f?rences en VTL, il suffit de les 'mettre ensemble'. Le contexte dans lequel vous voulez les assembler ainsi a une certaine importance, il faut donc illustrer notre propos par quelques exemples.

Dans le flux habituel d'un gabarit (lorsqu'on m?lange les r?f?rences avec du contenu ordinaire):

       #set( $size = "Big" )
       #set( $name = "Ben" )

      Cette horloge sonne comme $size$name.
   

produira 'Cette horloge sonne comme BigBen'. Pour prendre des exemples plus int?ressants, lorsqu'on veut concat?ner des cha?nes pour les passer ? une m?thode ou les assigner ? une nouvelle r?f?rence, il suffit d'?crire:

      #set( $size = "Big" )
      #set( $name = "Ben" )

      #set($clock = "$size$name" )

      Cette horloge sonne comme $clock.
    

Ce qui produit le m?me r?sultat. Dernier exemple, lorsqu'on veut m?langer des cha?nes "statiques" avec des r?f?rences, il peut ?tre n?cessaire d'utiliser les "r?f?rences formelles" rencontr?es plus haut:

      #set( $size = "Big" )
      #set( $name = "Ben" )

      #set($clock = "${size}Tall$name" )

      Cette horloge sonne comme $clock.
    

Et maintenant le r?sultat produit est 'Cette horloge sonne comme BigTallBen'. La notation formelle est requise pour que l'interpr?teur comprenne que l'on souhaite utiliser '$size' et non '$sizeTall', ce qui serait le cas si les accolades n'?taient pas pr?sentes.



Donnez votre avis

Si vous rencontrez des erreurs dans le manuel (autres que des erreurs de traduction), ou si vous voulez faire part de votre avis sur le Guide de l'utilisateur Velocity, envoyez un mail ? la Velocity user list. Merci!



Copyright © 1999-2005, The Apache Software Foundation