Syntaxe Hapify
Pourquoi utiliser une syntaxe spécifique ?
Nous avons conçu une syntaxe capable de manipuler l'objet modèle injecté dans les templates. Cette syntaxe est optimisée pour jouer avec les propriétés de cet objet modèle en utilisant des mots courts. Cela permet de gérer des idées complexes avec des phrases simples.
Par exemple, cette boucle en JavaScript :
for (let field of root.fields.filter(f => f.searchable && f.type === 'entity')) {
out += ' Do something';
}
sera écrit comme ceci avec la syntaxe Hapify :
<<for Fields searchable and entity field>>
Do something
<<endfor>>
<<@ F se*tE f>>
Do something
<<@>>
Syntaxes longue et courte
Les templates Hapify peuvent être écrits avec une syntaxe longue ou courte.
Chacune a ses avantages :
- La syntaxe courte n'interfère pas avec le code cible lors de la lecture du template, grâce à un méta-code plus court.
- La syntaxe longue est explicite et peut être lue naturellement.
Dans un même template, vous pouvez mélanger les deux syntaxes.
Note
Tous les exemples de codes ci-dessous sont traduits en équivalent JavaScript à titre informatif. Lors de la génération, la syntaxe Hapify est convertie en code JavaScript semblable.
Balises
Les blocs de syntaxe Hapify sont enveloppés par deux balises :
- ouverture :
<<
. - fermeture :
>>
.
Échappement
Généralement utilisées pour les opérations binaires, ces balises peuvent être échappées.
Les balises échappées \<\<
(et \>\>
) sont remplacées par <<
(et >>
) lors de la génération.
Noms
Noms du modèle de données
Dans un template de type one model
:
// Create a new <<Model lower>>
const <<Model camel>> = new <<Model pascal>>();
// Create a new <<M a>>
const <<M aA>> = new <<M AA>>();
out += `// Create a new ${root.names.lower}
const ${root.names.camel} = new ${root.names.pascal}();`;
Pour un modèle de données nommé user group
, le résultat sera le suivant :
// Create a new user group
const userGroup = new UserGroup();
Noms des champs
Lister tous les champs d'un modèle de données :
<?php
$fields = array(
<<for Fields field>>
'<<field camel>>',
<<endfor>>
);
<?php
$fields = array(
<<@ F f>>
'<<f aA>>',
<<@>>
);
out += `<?php
$fields = array(
${root.fields.list.map(f => "'"+f.names.camel+"'").join(",\n\t")}
);`;
Pour un modèle de données avec les champs name
, created at
et role
:
<?php
$fields = array(
'name',
'createdAt',
'role',
);
Casses
Les casses disponibles sont :
camel
(alias :aA
) pourcamelCase
pascal
(alias :AA
) pourPascalCase
lower
(alias :a
) pourlower case
capital
(alias :A
) pourCapital Case
kebab
(alias :a-a
) pourkebab-case
header
(alias :A-A
) pourHeader-Case
snake
(alias :a_a
) poursnake_case
constant
(alias :A_A
) pourCONSTANT_CASE
compact
(alias :aa
) pourcompactcase
raw
(alias :R
) (raw) pour le nom original
Conditions
Condition simple
const utils = require('utils');
<<if Fields entity>>
const mongoDb = require('mongodb');
<<endif>>
const utils = require('utils');
<<? F tE>>
const mongoDb = require('mongodb');
<<?>>
out += `const utils = require('utils');`;
if (root.fields.filter(f => f.type === 'entity').length > 0) {
out += `\nconst mongoDb = require('mongodb');`;
}
Pour un modèle de données qui contient au moins un champ de type entity
, le résultat sera le suivant :
const utils = require('utils');
const mongoDb = require('mongodb');
Pour un modèle de données qui ne contient pas de champ de type entity
, le résultat sera le suivant :
const utils = require('utils');
Sans filtre
Le filtrage des champs est optionnel.
<<if Fields>>
// this model has at least one field
<<endif>>
<<? F>>
// this model has at least one field
<<?>>
if (root.fields.list.length > 0) {
out += ' // this model has at least one field';
}
Conditions alternatives
<<if Fields entity>>
// At least one entity field
<<elseif Fields hidden>>
// No entity field and at least one hidden field
<<else>>
// No entity field and no hidden field
<<endif>>
<<? F tE>>
// At least one entity field
<<?? F hd>>
// No entity field and at least one hidden field
<<??>>
// No entity field and no hidden field
<<?>>
if (root.fields.filter(f => f.type === 'entity').length > 0) {
out += ' // At least one entity field';
} else if (root.fields.filter(f => f.hidden).length > 0) {
out += ' // No entity field and at least one hidden field';
} else {
out += ' // No entity field and no hidden field';
}
Conditions complexes
Opérateurs
Les opérateurs disponibles pour écrire les conditions sont :
and
- alias*
ou&&
or
- alias+
ou||
and not
- aliasandNot
,/
ou&& !
or not
- aliasorNot
,-
ou|| !
Exemple
<<if Fields (entity and hidden) or (unique and not multiple)>>
// This code block is reached if the model has at least one field that validates this conditions:
// (type entity AND hidden) OR (unique AND NOT multiple)
<<endif>>
<<? F (tE*hd)+(un/ml)>>
// This code block is reached if the model has at least one field that validates this conditions:
// (type entity AND hidden) OR (unique AND NOT multiple)
<<?>>
for (let field of root.fields.filter(f => (f.type === 'entity' && f.hidden) || (f.unique && !f.multiple))) {
out += ' // ...';
}
Les conditions peuvent également être écrites avec des opérateurs natifs. Réécrivons cette dernière condition :
<<if Fields (entity && hidden) || (unique && !multiple) >>
// This code block is reached if the model has at least one field that validates this conditions:
// (type entity AND hidden) OR (unique AND NOT multiple)
<<endif>>
<<? F (tE && hd) || (un && !ml) >>
// This code block is reached if the model has at least one field that validates this conditions:
// (type entity AND hidden) OR (unique AND NOT multiple)
<<?>>
for (let field of root.fields.filter(f => (f.type === 'entity' && f.hidden) || (f.unique && !f.multiple))) {
out += ' // ...';
}
Conditions relatives au nombre d'occurrences
En précisant un nombre après le if
, on peut ajouter une condition sur le nombre minimum d’éléments requis, ici les champs :
<<if4 Fields hidden>>
// This model has at least 4 hidden fields
<<elseif2 Fields label or boolean>>
// This model has at least 2 label or boolean fields
<<else>>
// Something else
<<endif>>
<<?4 F hd>>
// This model has at least 4 hidden fields
<<??2 F lb+tB>>
// This model has at least 2 label or boolean fields
<<??>>
// Something else
<<?>>
if (root.fields.filter(f => f.hidden).length >= 4) {
out += ' // This model has at least 4 hidden fields';
} else if (root.fields.filter(f => f.label || f.type === 'boolean').length >= 2) {
out += ' // This model has at least 2 label or boolean fields';
} else {
out += ' // Something else';
}
Conditions sur les modèles de données
Tester un seul modèle de données
Dans un template de type one model
:
<<if Model isGeolocated>>
// This block is reached if the model is geolocated.
// that's means it has at least one latitude field and one longitude field
<<endif>>
<<? M pGeo>>
// This block is reached if the model is geolocated.
// that's means it has at least one latitude field and one longitude field
<<?>>
if (root.properties.isGeolocated) {
out += ' // ...';
}
Tester une liste de modèles de données
Dans un template de type all models
:
<<if Models not onlyGuest>>
// This block is reached if at least one model has not only guest actions
import 'session-service';
<<endif>>
<<? M !pOGs>>
// This block is reached if at least one model has not only guest actions
import 'session-service';
<<?>>
if (root.filter(m => !m.accesses.properties.onlyGuest).length > 0) {
out += " import 'session-service';";
}
Objets et filtres disponibles
Objet racine
Model
ou Models
(abrégé : M
) font référence à l'objet principal :
- le modèle de données dans un template de type
one model
- le tableau de modèles de données dans un template de type
all models
Objets filtrables et testables
Dans le cas d'un template de type one model
:
Fields
(alias:F
) est la liste des champsDependencies
(alias:D
) est la liste des dépendances (liste de modèles de données)ReferencedIn
(alias:RefModels
,R
) est la liste des modèles de données qui dépendent de celui-ciPrimaryField
(alias:P
) est le champ primaire du modèleAccesses
(alias:A
) est la liste des accèsCreateAccess
(alias:Ac
) est l'accès à l'action de créationReadAccess
(alias:Ar
) est l'accès à l'action de lectureUpdateAccess
(alias:Au
) est l'accès à l'action de mise à jourRemoveAccess
(alias:Ad
) est l'accès à l'action de suppressionSearchAccess
(alias:As
) est l'accès à l'action de rechercheCountAccess
(alias:An
) est l'accès à l'action de comptage
Filtrage sur les attributs de champ
Attributs disponibles pour un champ :
primary
(alias:pr
) pour le booléenprimary
unique
(alias:un
) pour le booléenunique
label
(alias:lb
) pour le booléenlabel
nullable
(alias:nu
) pour le booléennullable
multiple
(alias:ml
) pour le booléenmultiple
embedded
(alias:em
) pour le booléenembedded
searchable
(alias:se
) pour le booléensearchable
sortable
(alias:so
) pour le booléensortable
hidden
(alias:hd
) pour le booléenhidden
internal
(alias:in
) pour le booléeninternal
restricted
(alias:rs
) pour le booléenrestricted
ownership
(alias:os
) pour le booléenownership
string
(alias:tS
) pour le typestring
email
(alias:tSe
) pour le typestring
et le sous-typeemail
password
(alias:tSp
) pour le typestring
et le sous-typepassword
url
(alias:tSu
) pour le typestring
et le sous-typeurl
text
(alias:tSt
) pour le typestring
et le sous-typetext
richText
(alias:rich
,tSr
) pour le typestring
et le sous-typerich
number
(alias:tN
) pour le typenumber
integer
(alias:tNi
) pour le typenumber
et le sous-typeinteger
float
(alias:tNf
) pour le typenumber
et le sous-typefloat
latitude
(alias:tNt
) pour le typenumber
et le sous-typelatitude
longitude
(alias:tNg
) pour le typenumber
et le sous-typelongitude
boolean
(alias:tB
) pour le typeboolean
datetime
(alias:tD
) pour le typedatetime
date
(alias:tDd
) pour le typedatetime
et le sous-typedate
time
(alias:tDt
) pour le typedatetime
et le sous-typetime
enum
(alias:tU
) pour le typeenum
entity
(alias:tE
) pour le typeentity
oneOne
(alias:tEoo
) pour le typeentity
et le sous-typeoneOne
oneMany
(alias:tEom
) pour le typeentity
et le sous-typeoneMany
manyOne
(alias:tEmo
) pour le typeentity
et le sous-typemanyOne
manyMany
(alias:tEmm
) pour le typeentity
et le sous-typemanyMany
object
(alias:tO
) pour le typeobject
file
(alias:tF
) pour le typefile
image
(alias:tFi
) pour le typefile
et le sous-typeimage
video
(alias:tFv
) pour le typefile
et le sous-typevideo
audio
(alias:tFa
) pour le typefile
et le sous-typeaudio
document
(alias:tFd
) pour le typefile
et le sous-typedocument
Exemple
<<if Fields (restricted or internal) and not number>>
// Current model has at least one field matching to the condition
<<endif>>
<<? F (rs+in)/tN>>
// Current model has at least one field matching to the condition
<<?>>
if (root.fields.filter(f => (f.restricted || f.internal) && !f.number).length > 0) {
out += " // ...";
}
Filtrage sur les propriétés du modèle de données
Propriétés disponibles pour un modèle de données :
mainlyHidden
(alias:pMHd
) la majorité des champs sonthidden
(strictement)mainlyInternal
(alias:pMIn
) la majorité des champs sontinternal
(strictement)isGeolocated
(alias:pGeo
) Le modèle de données contient au moins un champlatitude
et un champlongitude
.isGeoSearchable
(alias:pGSe
) Le modèle de données contient au moins un champlatitude
et un champlongitude
recherchables.
Exemple
<<if Model isGeolocated>>
// This model contains at least one latitude field and one longitude field.
<<endif>>
<<? M pGeo>>
// This model contains at least one latitude field and one longitude field.
<<?>>
if (root.properties.isGeolocated) {
out += " // ...";
}
Propriétés d'accès disponibles pour un modèle de données :
onlyAdmin
(alias:pOAd
) Le modèle de données ne contient que des accès restreints àadmin
onlyOwner
(alias:pOOw
) Le modèle de données ne contient que des accès restreints àowner
onlyAuth
(alias:pOAu
) Le modèle de données ne contient que des accès restreints àauthenticated
onlyGuest
(alias:pOGs
) Le modèle de données ne contient que des accès restreints àguest
maxAdmin
(alias:pMAd
) L'accès le plus permissif estadmin
maxOwner
(alias:pMOw
) L'accès le plus permissif estowner
maxAuth
(alias:pMAu
) L'accès le plus permissif estauthenticated
maxGuest
(alias:pMGs
) L'accès le plus permissif estguest
noAdmin
(alias:pNAd
) Aucune action n'est restreinte àadmin
noOwner
(alias:pNOw
) Aucune action n'est restreinte àowner
noAuth
(alias:pNAu
) Aucune action n'est restreinte àauthenticated
noGuest
(alias:pNGs
) Aucune action n'est restreinte àguest
hasAdmin
(alias:pHAd
) Au moins une action est restreinte àadmin
hasOwner
(alias:pHOw
) Au moins une action est restreinte àowner
hasAuth
(alias:pHAu
) Au moins une action est restreinte àauthenticated
hasGuest
(alias:pHGs
) Au moins une action est restreinte àguest
Exemple
<<if Model onlyAdmin>>
// All actions on this model are restricted to admins
<<endif>>
<<? M pOAd>>
// All actions on this model are restricted to admins
<<?>>
if (root.accesses.properties.onlyAdmin) {
out += " // ...";
}
Filtrage sur les accès aux modèles de données
Rappel
guest
est l'accès le plus permissif et admin
le moins permissif. Par conséquent admin < owner < authenticated < guest
.
Filtres disponibles pour l'accès à une action :
admin
(alias:ad
) l'accès estadmin
owner
(alias:ow
) l'accès estowner
auth
(alias:au
) l'accès estauth
guest
(alias:gs
) l'accès estguest
gteAdmin
(alias:[ad
) l'accès est supérieur ou égal àadmin
gteOwner
(alias:[ow
) l'accès est supérieur ou égal àowner
gteAuth
(alias:[au
) l'accès est supérieur ou égal àauth
gteGuest
(alias:[gs
) l'accès est supérieur ou égal àguest
lteAdmin
(alias:ad]
) l'accès est inférieur ou égal àadmin
lteOwner
(alias:ow]
) l'accès est inférieur ou égal àowner
lteAuth
(alias:au]
) l'accès est inférieur ou égal àauth
lteGuest
(alias:gs]
) l'accès est inférieur ou égal àguest
Exemples
Teste l'accès pour une action précise :
<<if ReadAccess guest>>
// Anyone can read this model
<<endif>>
<<? Ar gs>>
// Anyone can read this model
<<?>>
if (root.accesses.read.guest) {
out += ' // ...';
}
Teste si l'action de mise à jour est restreinte soit aux administrateurs soit au propriétaire :
<<if UpdateAccess admin or owner>>
// ...
<<endif>>
<<? Au ad+ow>>
// ...
<<?>>
if (root.accesses.update.admin || root.accesses.update.owner) {
out += ' // ...';
}
Teste si au moins une action est restreinte à un utilisateur authentifié ou moins :
<<if Accesses lteAuth>>
// ...
<<endif>>
<<? A au]>>
// ...
<<?>>
if (root.accesses.filter(a => a.lteAuth).length > 0) {
out += ' // ...';
}
À savoir
Les conditions peuvent être utilisées sur un objet ou un tableau d'objets.
S'il est utilisé sur un tableau, il testera la longueur du tableau filtré par la condition fournie.
Il peut être utilisé sur n'importe quel objet contenant une méthode filter
qui reçoit un callback retournant un booléen.
Par exemple, dans la structure du modèle de données, root.dependencies
est un objet qui contient une méthode filter
.
Ainsi, cet opérateur peut tester si un modèle a des dépendances qui ont des champs avec une condition spécifique.
Itérations
Les itérations utilisent les mêmes filtres et opérateurs que les conditions.
Itération simple
Boucle sur tous les champs d'un modèle de données qui ne sont pas cachés et les assigne à la variable field
:
<?php
$fields = array(
<<for Fields not hidden field>>
'<<field camel>>',
<<endfor>>
);
<?php
$fields = array(
<<@ F !hd f>>
'<<f aA>>',
<<@>>
);
out += `<?php
$fields = array(
${
root.fields
.filter(f => !f.hidden)
.map(f => "'"+f.names.camel+"'")
.join(",\n\t")
}
);`;
Exemple pour un modèle de données avec les champs name
, created at
et role
, dont role
est caché :
<?php
$fields = array(
'name',
'createdAt',
);
Boucle sur les champs de type entity
et recherchables du modèle de données :
<<for Fields searchable and entity field>>
// ...
<<endfor>>
<<@ F se*tE f>>
// ...
<<@>>
for (let field of root.fields.filter(f => f.searchable && f.type === 'entity')) {
out += ' // ...';
}
Boucler sans filtrer
Cette opération permet de passer en revue tous les champs :
<<for Fields field>>
// ...
<<endfor>>
<<@ F f>>
// ...
<<@>>
for (let field of root.fields.list) {
out += ' // ...';
}
Boucler sur les modèles de données
Dans un template de type all models
, ceci boucle sur tous les modèles de données qui sont géo-localisés :
<<for Models isGeolocated model>>
// ...
<<endfor>>
<<@ M pGeo m>>
// ...
<<@>>
for (let model of root.filter(i => i.properties.isGeolocated)) {
out += ' // ...';
}
Boucler sur les dépendances
Dans un template de type one model
, ceci boucle sur les dépendances dont le champ référent est recherchable :
<<for Dependencies searchable dep>>
// ...
<<endfor>>
<<@ D se d>>
// ...
<<@>>
for (let dep of root.dependencies.filter(f => f.searchable)) {
out += ' // ...';
}
À savoir
Dans le cas d'un modèle de données qui se réfère à lui-même, Dependencies
exclue cette auto-dépendance.
Pour l'inclure utilisez le code suivant:
<<< for (let dep of root.dependencies.filter(f => f, false)) { >>>
// ...
<<< } >>>
Attention
Le filtrage de Dependencies
ne s'effectue que sur les champs du modèle de données courant qui portent la référence.
Le filtrage ne s'effectue pas sur les champs du modèle de données cible.
Boucler sur les modèles de données référents
Dans un template de type one model
, ceci boucle sur les modèles de données ayant une dépendance envers celui-ci et qui sont géo-localisés :
<<for ReferencedIn isGeolocated referrer>>
// ...
<<endfor>>
<<@ R pGeo r>>
// ...
<<@>>
for (let referrer of root.referencedIn.filter(m => m.properties.isGeolocated)) {
out += ' // ...';
}
À savoir
Le filtre est optionnel. Vous pouvez obtenir tous les modèles de données référents comme ceci :
<<for ReferencedIn referrer>>
// ...
<<endfor>>
Attention
Seuls les champs de type entité faisant référence sont définis dans ces modèles de données référents.
Boucler sur les accès du modèle de données
Boucle sur tous les accès restreints à un administrateur ou au propriétaire et affiche le nom de l'action :
<<for Accesses admin or owner access>>
<<=access.action>>
<<endfor>>
<<@ A ad+ow a>>
<<=a.action>>
<<@>>
for (let access of root.accesses.filter(a => a.admin || a.owner)) {
out += ` ${access.action}\n`;
}
Itération raccourcie
Boucle sur les 2 premiers champs d'un modèle de données :
<?php
$fields = array(
<<for2 Fields field>>
'<<field camel>>',
<<endfor>>
);
<?php
$fields = array(
<<@2 F f>>
'<<f aA>>',
<<@>>
);
out += `<?php
$fields = array(
${
root.fields.list
.slice(0, 2)
.map(f => "'"+f.names.camel+"'")
.join(",\n\t")
}
);`;
Pour un modèle de données avec les champs name
, email
et role
:
<?php
$fields = array(
'name',
'email',
);
Itérations imbriquées
Boucle sur les enum
Dans un template de type one model
, ce bloc définit un type TypeScript contenant les énumérations d'un champ :
<<for Fields enum field>>
type <<field pascal>> =<<for field.enum e>> | '<<e snake>>'<<endfor>>;
<<endfor>>
<<@ F tU f>>
type <<f AA>> =<<@ f.e e>> | '<<e a_a>>'<<@>>;
<<@>>
for (let field of root.fields.filter(f => f.type === 'enum')) {
out += `type ${field.names.pascal} = ${field.enum.map(e => "'"+e.names.snake+"'").join(' | ')};`;
}
type Role = | 'admin' | 'user' | 'customer';
Boucler sur les champs de tous les modèles de données
Dans un template de type all models
, ce bloc permet de passer en revue tous les champs de tous les modèles de données :
const models = {
<<for Models model>>
<<m camel>>: [
<<for model.fields field>>
'<<field camel>>',
<<endfor>>
],
<<endfor>>
}
const models = {
<<@ M m>>
<<m aA>>: [
<<@ m.f f>>
'<<f aA>>',
<<@>>
],
<<@>>
}
const models = {
user: [
'id',
'createdAt',
'email',
'name',
],
place: [
'id',
'name',
'category',
],
placeCategory: [
'id',
'createdAt',
'email',
'name',
],
}
Entrées brutes et interpolation
Cet opérateur vous permet d'écrire du JavaScript pur.
Variable personnalisée
Définit une variable personnalisée et l'ajoute à la sortie :
<<< const length = root.fields.length; >>>
// This model has <<=length>> fields
Fonction personnalisée
Définit une fonction personnalisée et l'appelle :
<<<
function fieldName(field) {
return field.names.snake.replace('_', ':');
}
>>>
<<for Fields field>>
<<=fieldName(field)>>
<<endfor>>
<<<
function fieldName(f) {
return f.names.snake.replace('_', ':');
}
>>>
<<@ F f>>
<<=fieldName(f)>>
<<@>>
id
created:at
place:category
Condition ou itération personnalisée
Ce bloc permet d'écrire une condition non gérée par la syntaxe Hapify :
<<< if (root.fields.hidden.length < 3 || root.properties.mainlyInternal) { >>>
// ...
<<< } >>>
À savoir
Dans un template Hapify de type one model
, la variable root
pointe vers le modèle de données.
Dans un template Hapify de type all models
, la variable root
pointe vers le tableau de modèles de données.
Voir aussi
Pour connaitre en détail la structure du modèle de données, reportez-vous à l'objet modèle.
Notes
Vous pouvez récupérer les notes laissées par l'utilisateur au niveau d'un champ ou d'un modèle :
<<if Model hasNotes>>// <<! Model>><<endif>>
export class <<Model pascal>> {
<<for Fields field>>
public <<field camel>>; <<if field hasNotes>>// <<! field>><<endif>>
<<endfor>>
}
<<? M hN>>// <<! M>><<?>>
export class <<M AA>> {
<<@ F f>>
public <<f aA>>; <<? f hN>>// <<! f>><<?>>
<<@>>
}
// A user can only list its own bookmarks
export class Bookmark {
public id;
public owner; // Current user when creating the bookmark
public place;
}
Il est également possible d'utiliser l'interpolation pour afficher les notes :
<<if Model hasNotes>>// <<=root.notes>><<endif>>
export class <<Model pascal>> {
<<for Fields field>>
public <<field camel>>; <<if field hasNotes>>// <<=field.notes>><<endif>>
<<endfor>>
}
<<? M hN>>// <<=root.notes>><<?>>
export class <<M AA>> {
<<@ F f>>
public <<f aA>>; <<? f hN>>// <<=field.notes>><<?>>
<<@>>
}
Erreur
N'écrivez pas ceci : <<= JSON.stringify(root) >>
.
L'objet root
a des propriétés récursives. Par conséquent, cette commande conduira à une boucle infinie.
Commentaires
Cette syntaxe écrit un commentaire dans le template sans aucune sortie dans le fichier généré.
<<# This is just a comment>>
Échappement
Il est possible d'échapper les balises de la syntaxe Hapify avec le caractère \
:
$val = 4;
$res = $val \<\< 3;
$res = 4 \>\> $val;
$val = 4;
$res = $val << 3;
$res = 4 >> $val;
Formatage
Les lignes vides ou ne contenant que du méta-code de type condition ou itération sont automatiquement supprimées suite à la génération. Pour forcer le générateur à garder une ligne vide, insérez un ou plusieurs espaces au début de celle-ci.
Attention
Hapify ne formate pas le code généré, car les règles de mise en forme sont spécifiques à chaque langage voire chaque framework. Nous vous recommandons vivement d'utiliser un formateur de code suite à la génération.
Mots réservés
La liste suivante de mots ne peut pas être utilisée pour nommer des variables.
A
, Ac
, Accesses
, ad
, Ad
, admin
, An
, and
, andNot
, Ar
, As
, au
, Au
, audio
, auth
, boolean
, CountAccess
, CreateAccess
, D
, date
, datetime
, Dependencies
, document
, else
, elseif
, em
, email
, embedded
, endfor
, endif
, entity
, enum
, F
, Fields
, file
, float
, for
, gs
, gteAdmin
, gteAuth
, gteGuest
, gteOwner
, guest
, hasAdmin
, hasAuth
, hasGuest
, hasNotes
, hasOwner
, hd
, hidden
, hN
, if
, image
, in
, integer
, internal
, isGeolocated
, isGeoSearchable
, label
, latitude
, lb
, longitude
, lteAdmin
, lteAuth
, lteGuest
, lteOwner
, M
, mainlyHidden
, mainlyInternal
, manyMany
, manyOne
, maxAdmin
, maxAuth
, maxGuest
, maxOwner
, ml
, Model
, Models
, multiple
, noAdmin
, noAuth
, noGuest
, noOwner
, not
, nu
, nullable
, number
, object
, oneMany
, oneOne
, onlyAdmin
, onlyAuth
, onlyGuest
, onlyOwner
, or
, orNot
, os
, out
, ow
, owner
, ownership
, P
, password
, pGeo
, pGSe
, pHAd
, pHAu
, pHGs
, pHOw
, pMAd
, pMAu
, pMGs
, pMHd
, pMIn
, pMOw
, pNAd
, pNAu
, pNGs
, pNOw
, pOAd
, pOAu
, pOGs
, pOOw
, pr
, primary
, PrimaryField
, R
, ReadAccess
, ReferencedIn
, RefModels
, RemoveAccess
, restricted
, rich
, richText
, root
, rs
, se
, searchable
, SearchAccess
, so
, sortable
, string
, tB
, tD
, tDd
, tDt
, tE
, tEmm
, tEmo
, tEom
, tEoo
, text
, tF
, tFa
, tFd
, tFi
, tFv
, time
, tN
, tNf
, tNg
, tNi
, tNt
, tO
, tS
, tSe
, tSp
, tSr
, tSt
, tSu
, tU
, un
, unique
, UpdateAccess
, url
, video
.