Référence Gabarits
-
Voir aussi : l’introduction sur les gabarits.
Navigation dans le référentiel objet
Si le référent est un objet :
{name}
(la première lettre en minuscule) fait référence, dans l’ordre, au premier des éléments défini (existant et non null) parmi :- au résultat de la méthode
name()
de l’objet référent, - à la valeur de la propriété
$name
de l’objet référent ; si l’objet référent est de classe Reflection Property et la propriété est$value
, la valeur est formatée suivant les paramètres de localisation en vigueur, - à la valeur du paramètre
'name'
renseigné par le contrôleur ou la vue, - à défaut de référence trouvée, le moteur de template essaie de lire la propriété de l’objet référent, soit
null
si la propriété existe sans valeur, ou ce qui permet d’appeler la méthode magique __get() si elle est prévue, mais générera une erreur si la propriété$name
n’existe pas dans l’objet référent et qu’aucune méthode magique n’est définie.
Chaînage d’éléments
{element.sub_property.subMethod}
Il est possible de naviguer dans le référentiel objet, en séparant les noms de propriétés par des
.
comme suit :{object.sub_property.subMethod}
retourne la valeur retournée par la méthodesubMethod()
de l’objet stocké dans la propriétésub_property
de l’objet stocké dans la propriétéobject
de l’objet / élément référent.Chaque élément entre les
.
est parsé indépendamment, et sert de référentiel à l’élément suivant.Le dernier élément d’une chaîne doit toujours pouvoir être d’un type qui peut être changé en chaîne de caractères. S’il fait référence à un objet, une valeur textuelle doit pouvoir en être retournée avec strval grâce à la méthode magique __toString
Navigation dans un tableau
Si le référent est un tableau :
{name}
fait référence à la valeur du tableau correspondant à l’indice'name'
.<!--element-->
ouvre un bloc dont le contexte est l’élément d’indice'name'
du tableau, idéalement quand celui-ci est de type objet ou tableau.<!--end-->
ferme le bloc, et revient au contexte parent.
Constantes
{'Some value'}
ou{"Some value"}
parse une constante, dont la valeur sera retournée telle quelle.{NAME}
(tout en majuscules) fait référence, dans l’ordre, à :- si l’objet référent est un tableau, à l’élément d’indice
'NAME'
, - à la valeur de la constante globale
NAME
, - à la valeur de la constante globale
_NAME
, {PHPSESSID}
est remplacé par l’identifiant de session PHP retourné par session_id().
Opérateurs d’affichage de valeur, de négation, de non-répétition
- Le symbole
.
seul permet d’afficher l’objet du contexte courant sous forme de chaîne de caractère (résultat de__toString()
pour un objet par exemple). Par exemple{.}
.
- Précéder un symbole d’un point d’exclamation
!
réalise une négation de l’équivalent booléen de sa valeur.
Par exemple<!--!happy-->Some text<!--end-->
n’affichera le texte que si la propriété$happy
équivaut àfalse
.
- Si votre symbole se termine par une astérisque
*
, la valeur ne sera affichée que si elle ne l’a pas déjà été pour le même identifiant. Par exemple dans une boucle pour un tableau on ne répètera pas les lignes avec un nom identique :
<ul> <table> <tr><th>|name|</th><th>|visited city|</th></tr> <!--men--> <!--visited_cities--> <tr><td>{..name*}</td><td>{name}</td></tr> <!--end--> </table> <!--end-->
Dans l’exemple ci-dessus on liste pour chaque homme (man) les villes qu’il a visité (visited cities), sans répéter pour chaque ligne le nom de la personne si la même personne a visité plusieurs villes.
Notes :{..name*}
fait référence au nom d’un homme,{name}
au nom de la ville visitée, partant du contexte d’une ville visitée.
Accès aux classes tierces, aux propriétés et méthodes statiques
{Class_Name}
ou{Namespace\Class_Name}
(commence par une majuscule suivie d’une minuscule) fait référence à un nom de classe et sera parsé par le nom complet de la classe.{Class_Name.property_name}
permet de récupérer la valeur d’une propriété statique de la classeClass_Name
.{Class_Name.methodName}
récupère la valeur de retour d’une méthode statique de la classeClass_Name
.Appels de fonctions
{functionName}
parse le résultat d’une fonction (remplacer functionName par le nom de la fonction). Des paramètres peuvent être précisés entre les parenthèses, ils seront parsés dans le cadre du même référentiel que la fonction. Les parenthèses{functionName()}
peuvent être indiquées mais sont optionnelles si l’appel à la fonction ne requiert pas de paramètre.Exemple :
{functionName(name)}
: équivaut à un appel PHPfunctionName($object->name);
où$object
est l’objet référent.Fonctions spéciales agissant sur l’objet référence
- De manière générale : {
functionName} (remplacer par le nom de ta fonction) appelle la méthode
getFunctionName()@ correspondante de la classe Html\Template\Functions.
- @application récupère le nom de l’application courante, stockée dans le paramètre de configuration app.
- @class permet de récupérer le nom de la classe (espace de nommage inclus) de l’objet référent racine utilisé lors de l’appel à Html_Template.
- @count récupère le nombre d’éléments du référent (qui doit être un tableau).
- @counter donne la valeur suivante pour le compteur associé au contexte courant.
- @date transforme la valeur en objet Date_Time. A associer à une variable embarquant une date dans une chaîne de caractères par exemple.
- @display récupère l’affichage associé à une classe, une propriété, une méthode, pour des référents de types Reflection_… ou objets.
- @edit parse l’élément référent en champ de saisie. On doit avoir parcouru auparavant une propriété Reflection_Property_Value, ou récupéré sa valeur, pour pouvoir la transformer en champ de saisie de formulaire.
- @empty renvoie
true
si l’objet est vide,false
sinon.
- @endWithMultiple réordonne une liste de propriétés pour placer les propriétés de type tableau (multiples) en dernier.
- @escapeName remplace les
.
par des>
dans un chemin de propriétés, pour utilisation dans un attribut HTMLname
.
- @expand ajoute les sous-propriétés des propriétés @integrated d’une liste de propriétés.
- @feature récupère le nom de la fonctionnalité indiquée par la vue lors du chargement du moteur de template.
- @first renvoie le premier élément d’un tableau.
- @isFirst renvoie
true
si l’élément courant d’un tableau, dans une boucle, est le premier élément.
- @isLast renvoie
true
si l’élément courant d’un tableau, dans une boucle, est le dernier élément.
- @key renvoie la clé de l’élément courant d’un tableau, dans une boucle.
- @lines divise un texte contenant des retours à la ligne en un tableau de lignes.
- @link retourne un lien (URI) vers l’objet. La fonctionnalité peut être passée comme paramètre, par exemple
{
link(edit)}@ .
- @loc localise la valeur d’après le contexte utilisateur : formats de date, numérique, etc.
- @null renvoie
true
si l’objet estnull
.
- @numeric renvoie
true
si la valeur est numérique (is_numeric()
).
- @object renvoie l’objet référent le plus proche. Si le référent n’est pas un objet, remonte le référentiel jusqu’à trouver un objet.
- @parse parse la valeur en utilisant le moteur de templates, si elle contient des
{choses}
par exemple.
- @properties renvoie la listes propriétés non statiques de l’objet référent, chacun stocké dans un Reflection_Property_Value.
- @propertiesOutOfTabs la liste des propriétés non statiques qui ne sont pas classées par l’annotation de classe @group de l’objet référent.
- @property récupère le Reflection_Property_Value correspondant à la propriété de l’objet passée en paramètre.
- @propertySelect récupère le Property_Select correspondant à la propriété de l’objet passée en paramètre.
- @rootClass le nom de la classe du premier objet en partant du référent racine.
- @rootObject le premier objet en partant du référent racine, c’est à dire l’objet de base ayant servi à l’appel du moteur de templates si c’est un objet, ou le premier objet en redescendant le référentiel. Renverra
null
si aucun objet n’est présent dans le référentiel.
- @sort trie une collection (
array
) d’objets.
- @startingBlocks renvoie les noms de blocs si la propriété courante débute un bloc de sous-formulaire.
- @stoppingBlocks renvoie les noms de blocs si la propriété courante ferme un bloc de sous-formulaire.
- @top le tout premier référent, qui a été utilisé lors de l’appel au moteur de templates par la vue.
- @void renvoie
true
si la chaîne de caractère est vide (longueur = 0).
- @value la valeur de l’élément courant d’un tableau, dans une boucle.
- @zero renvoie
true
si la valeur est exactement ‘0’ (numérique ou chaîne de caractère).
Vous trouverez une liste exhaustive des fonctions dans la classe Html\Template\Functions du framework.
Mise en forme de valeur
Lorsque le référent est une valeur, ou un objet dont on peut consulter la valeur (
__toString()
), il peut être considéré comme un objet Displayable et ainsi toutes ses fonctions de mises en forme peuvent être utilisées comme une sous-propriété ou une méthode de Displayable.Exemples de mise en forme d’une propriété
$name
de l’objet référent :{name.display}
: la valeur du nom, nom de propriété, de classe où de méthode, sous forme affichable ; par exemple'unNom'
,'un_nom'
ou'Un_Nom'
deviendront'un nom'
,
{name.lower}
: valeur tout en minuscules,
{name.ucfirst}
: premier caractère en majuscule,
{name.ucwords}
: premier caractère de chaque mot en majuscule,
{name.under}
: remplace les espaces par des tirets bas _,
{name.upper}
: valeur tout en majuscules,
etc.
Bloc HTML conditionnel
Écriture compacte, avec descente dans le sous-objet :
<!--condition--> <span>There is a condition</span> <!--end-->
Écriture explicite, avec descente dans le sous-objet :
<!--with condition--> <span>There is a condition</span> <!--end-->
Si l’élément parsé
condition
contient une valeur non vide, 0,false
, etc au sens de la fonction empty() de PHP, le bloc HTML est affiché.
Dans le cas contraire, rien ne s’affiche.
Dans tous les cas les commentaires<!--condition-->
sont supprimés du HTML parsé.Si
condition
est un objet, l’écriture ci-dessus rentre dans le contexte de cet objet.Pour effectuer une condition sur objet renseigné ou non, sans rentrer dans le contexte objet, il faut utiliser l’écriture
<!--condition?-->
,<!--if condition-->
, ou encore<!--if condition?-->
, qui sont équivalentes.Exemple : soit
$object
un objet contenant des propriétés$name
et$characteristics
, cette dernière contenant un objet avec des propriétés$color
et$shape
:Dans ce premier exemple on rentre dans le contexte de
$characteristics
, uniquement si elle ne vaut pasnull
, ce qui permet d’accéder directement aux propriétés de$characteristics
. Si on a besoin d’accéder aux propriétés de l’objet du contexte parent$object
, ça reste possible comme dans l’exemple ci-dessous :
<!--object--> <!--characteristics--> <ul> <li>{.name}</li> <li>{color}</li> <li>{shape}</li> </ul> <!--end--> <!--end-->
Équivalent de l’exemple ci-dessus, en écriture explicite :
<!--with object--> <!--foreach characteristics--> <ul> <li>{.name}</li> <li>{color}</li> <li>{shape}</li> </ul> <!--end--> <!--end-->
Dans cet autre exemple, on teste que
$characteristics
est non-nul mais on reste dans le contexte de l’objet parent, ce qui permet d’accéder à des propriétés d’@object@ . On peut toujours accéder aux propriétés de$characteristics
comme dans cet exemple, en partant du contexte parent :
<!--object--> <!--characteristics?--> <ul> <li>{name}</li> <li>{characteristics.color}</li> <li>{characteristics.shape}</li> </ul> <!--end--> <!--end-->
Équivalent de l’exemple ci-dessus, en écriture explicite :
<!--with object--> <!--if characteristics--> <ul> <li>{name}</li> <li>{characteristics.color}</li> <li>{characteristics.shape}</li> </ul> <!--end--> <!--end-->
Bloc HTML boucle
<!--@properties--> {name} : {value}<br> <!--end-->
Si l’élément parsé contient une valeur non vide, le bloc HTML est affiché autant de fois que d’éléments retournés. L’élément parsé doit donc être un tableau.
Dans l’exemple @properties@ est la fonction spéciale qui retourne la liste des propriétés de l’objet du référentiel. Chaque propriété consiste en un objet disposant notamment des propriétés
$name
et$value
, affichées dans le bloc de code HTML répété.Écriture compacte ou explicite
Dans les exemples ci-dessus, on a vu que les blocs de structure peuvent être présentés sous forme d’une écriture compacte – sans mot clé : juste le nom de la variable -, ou explicite : un mot clé venant “documenter” l’opération attendue.
Les mots-clés possibles sont :
- foreach : pour parcourir un tableau.
- with : pour entrer dans le contexte d’un sous-objet.
- if : pour n’afficher le bloc que si la condition équivaut àtrue
sans rentrer dans le contexte du sous-objet.Remontée aux objets référents précédents
Un
-
ou un.
, suivi d’un identifiant de membre, représente une remontée à l’objet référent précédent.Par exemple dans une descente dans un objet simple (sous-propriété par exemple), le
-
permet de revenir à l’objet parent avant d’interroger l’un de ses membres. Ici l’objet parent et l’objet stocké dans la sous-propriété$sub_property
ont tous deux une propriété$name
:
<!--sub_property--> {name} est dans son parent {-name} <!--end-->
Par exemple dans une boucle dans un tableau, le
-
ou.
permet de reprendre comme référent le tableau, pour afficher le nombre d’éléments par exemple.
<!--@properties--> {name} (sur {-@count} éléments)<br> <!--end-->
Deux tirets (
-
) ou deux points (.
) qui se suivent permettent une remontée à l’objet référent avant le tableau. Par exemple :
{uneprop} <!--@properties--> {name} : {value} - retour parent : {--a_property}<br> <!--end-->
Ici la valeur de la propriété$a_property
sera affiché une fois avant la boucle, et pour chaque élément de la boucle.On peut avoir besoin de redescendre, après être remonté sur un référent. Ça se fait avec le
+
. En raison de cette notation “pour redescendre”, il est conseillé d’utiliser la notation-
plutôt que.
tant qu’on est dans un contexte où la lisibilité n’est pas impactée (voir paragraphe suivant).Les notations
-
ou.
peuvent être utilisées indifféremment.
Le-
est déconseillé dans les éléments de structure, où il sera source de confusion pour le mainteneur de code eu égard au tag HTML<!--
qui va le précéder.
Dans l’exemple ci-dessous il est plus compliqué de compter le nombre de remontées (au nombre de 2 ici) : on distingue mal le<!--
et le--
qui le suit directement :
<!----parent_object_property--> <li>{sub_property}</li> <!----end-->
Dans cet autre exemple c’est plus clair : on distingue mieux le<!--
des..
:
<!--..parent_object_property--> <li>{sub_property}</li> <!--end-->
Inclusion d’un gabarit
On peut inclure le contenu d’un autre gabarit dans le gabarit courant :
{/Un_autre_gabarit.html}
Le / indique qu’on souhaite inclure une URI tierce. Le nom du fichier HTML représentant le gabarit suffit, it.rocks ira le chercher dans son dossier de stockage suivant le Chemin d’inclusion standard.
Appel à un contrôleur et inclusion du résultat
On peut appeler un contrôleur et inclure le résultat, pour un contrôleur qui génère une vue, dans le gabarit courant :
{/Class/feature}
Cet exemple appellera le contrôleur de la fonctionnalité
feature
pour la classeClass
, et en inclura le résultat dans la page HTML.Besoin d’appeler un contrôleur pour un identifiant d’enregistrement stocké dans une propriété ?
{/Full/Class/Name/{id}/feature}
Toutefois, afin d’éviter de citer explicitement
id
dans votre code, vous pouvez si vous êtes comme ici dans le contexte de l’objet correspondant utiliser la fonction de moteur de template @link :
{{@link}}
L’exemple précédent prendra la fonctionnalité par défaut, en fonction de l’état de l’objet. Vous pouvez préciser explicitement la fonctionnalité :
{{@link('feature')}}
Notez que deux accolades sont nécessaires : le premier niveau d’accolade calcule le lien, sous forme de texte, le deuxième niveau considèrera qu’il faut appeler le contrôleur représenté par ce lien.Gabarits inclus et découpage des entêtes / pied
La bonne pratique consiste à écrire des gabarits complets, avec entêtes et pieds HTML, de façon à pouvoir consulter votre page HTML dans un navigateur, tester le code Javascript et l’envoyer à la validation W3C sans autre manipulation qu’un copier-coller global.
Les gabarits étant conçus pour être inclus dans votre gabarit principal main.html ou comme inclusions dans vos autres gabarits, il faut délimiter la partie entête et pied à retirer lors de l’inclusion.
Pour celà vous délimitez votre code entre
<!--BEGIN-->
et<!--END-->
. Tout ce qui est avant<!--BEGIN-->
et après<!--END-->
sera ignoré.A noter toutefois : les éléments HTML
title
,meta
etlink
duhead
seront récupérées dynamiquement dans votre page HTML, de façon à modifier les affichages et liens correspondants de votre navigateur. Ils doivent donc être renseignés avec soin dans vos sous-gabarits.Voir aussi : Inclusion de gabarits.
Gabarits inclus en sous-section
Vous pouvez indiquer plusieurs zones de découpages pour vos gabarits avec des gabarits inclus en sous-section.
La délimitation
<!--BEGIN-->
et<!--END-->
pourra être différente en fonction d’un contexte envoyé dans votre contrôleur / vue à travers le paramètre de vue Parameter::CONTAINER.Exemple de sous-section nommée “sub_section” :
<!--BEGIN--> Will be displayed only if the 'sub_section' container has not been required. <!--BEGIN:sub_section--> Things displayed into the general context, and when in 'sub_section' context. <!--END:sub_section--> <!--END-->
Avec un appel normal, tout ce qui est entre
<!--BEGIN-->
et<!--END-->
est affiché.Si vous préparez vos paramètres comme ceci dans votre contrôleur, seule la partie entre
<!--BEGIN:sub_section-->
et<!--END:sub_section-->
sera visible :
$parameters->set(Parameter::CONTAINER, 'sub_section');
Voir aussi : Inclusion de sous-section de gabarit.
Traduction et traduction composite
- Lorsqu’on écrit du texte en langue normalisée – l’anglais – dans un template, on peut demander sa traduction en l’incluant simplement entre barres verticals
|
.
Exemple :
|Tell me something|
: le logiciel utilisera le module Translation pour traduire ‘Tell me something’ dans la langue de l’utilisateur.- La traduction composite est également possible :
|Tell me ¦something¦|
traduira en deux étapes : ‘Tell me $1’, et ‘something’. Cela permet de limiter le nombre de traductions à maintenir pour des phrases proches.
- On peut ne pas traduire une partie le la phrase avec l’opérateur de négation
!
: par exemple|I got !{number}! coins on my pocket|
traduira uniquement ‘I got $1 coins on my pocket’, et pas les différentes valeurs que peut prendrenumber
.
- Des exemples complets de traduction composite peuvent être consultés dans le template standard de la liste de données. Un exemple :
|!{rows_count}! ¦lines¦ match your search|
déclenchera la traduction indépendante de ‘$1 $2 match your search’, ‘lines’, et ne traduira jamais le nombre de lignesrows_count
.
Javascript et commentaires
Le code javascript dans les pages HTML est clairement déconseillé si l’on veut respecter les conventions de codage de it.rocks, qui visent notamment à séparer les modules développés dans des langages différents. Si vous souhaitez toutefois coder en javascript, les caractères
{
et}
qui servent ici de délimiteurs pour les templates HTML continueront d’être utilisés pour javascript tant que l’accolade ouvrante{
est suivie d’un espace ou un retour à la ligne. Bref tant que votre code javascript n’est pas compacté, il ne sera pas traité par le parseur HTML, et vous n’avez pas besoin d’utiliser de caractères d’échapement.Exemples :
<script> function uneFunc() { return "pas de souci grâce à l'espace { "; } </script> <script> if(unecondition){return "ça n'est pas bon, il faut un espace après chaque {"; } </script>
Si vous avez vraiment besoin d’indiquer une accolade directement suivi d’autre chose q’un espace, sans que le parseur HTML n’en interprète le contenu, doublez l’accolade comme suit :
<script> function uneFunc() { return "L'accolade {{sera} remplacée par une seule"; } </script>
Les commentaires HTML sont toujours acceptés : pour cela
<!--
doit simplement être suivi d’un espace, par exemple<!-- commentaire conservé -->
. Ces commentaires sont envoyés au navigateur.Vous pouvez rédiger des commentaires HTML qui ne sont pas envoyés au navigateur. Deux notations sont autorisées :
<!--// Commentaire non envoyé -->
et<!--# Commentaire non envoyé -->
. - au résultat de la méthode