Utilisateur:Carfois/Astuces pour la programmation des modèles

Cette page rassemble quelques astuces de programmation de modèles sur des points techniques. Il est préférable de prendre bien connaissance de toutes les pages d'aide sur les modèles avant de s'y plonger.

Remarques

  • ces astuces ont été glanées sur des pages d'aide ou dans le code de différents modèles ;
  • ces astuces ne devraient être utilisées qu'en dernier recours, et ne pas polluer les modèles qui pourraient s'en passer.

Logique

modifier

Ou logique

modifier

Méthode

modifier

Pour tester un si un des paramètres param1, param2, param3, ... est renseigné, on utilise la forme :

{{#if:{{{param1|}}}{{{param2|}}}{{{param3|}}}|...

Explication

modifier

Pour tester un si un des paramètres param1, param2, param3, ... est défini, il est préférable d'utiliser la forme :

{{#if:{{{param1|}}}{{{param2|}}}{{{param3|}}}|...

à la forme :

{{#if:{{{param1|{{{param2|{{{param3|}}}}}}}}}|...

En effet, l'augmentation rapide du nombre d'accolades fermantes de la seconde forme nuit à la lisibilité et accroit le risque d'erreur.

Combinaison logique complexe

modifier

Méthode

modifier

Pour gérer les branchements liés à des combinaisons logiques de résultats de tests, il peut être utile de définir une sous-fonction par test. Cette sous fonction qui renvoie 1 si le test est vrai, 0 sinon. On réalise ensuite un #switch sur la concaténation des 1 et 0.

Explication

modifier

Par exemple, pour trois tests :

{{#switch:{{fonc1|{{{1|}}}}}{{fonc2|{{{2|}}}}}{{fonc3|{{{3|}}}|{{{4|}}}}}
|000|010|111=résultat1
|001|011|100=résultat2
|#default=résultat3
}}


Opérations mathématiques

modifier

Obtenir une division euclidienne avec les Parser Functions

modifier

Voici un petit bout de code dans l'esprit des one-liner program pour pallier le problème des modulos négatifs. Le mot-clé mod des Parser Functions rend des modulos négatifs lorsque le dividende est négatif, ce qui peut donner des résultats assez gênants.

Méthode

modifier

Soit <d> le dividende (négatif ou positif) et <m> le modulus :

  • {{#expr: (<d> mod <m> < 0)*<m> + <d> mod <m>}}.

Explication

modifier

Le bout de code (<d> mod <m> < 0) vaut 1 si le modulo est strictement négatif, 0 sinon. Le code proposé équivaut donc à un if :

  • si <d> mod <m> < 0, alors on ajoute 1*<m>=<m> au modulo original ;
  • si <d> mod <m> >= 0, alors on conserve le modulo original.

Exemples

modifier
  • {{#expr: -10 mod 7}} donne -3 alors qu'on attendrait 4 en division euclidienne (-10 = -2 * 7 + 4) ;
  • {{#expr: (-10 mod 7 < 0)*7 + -10 mod 7}} donne 4
  • {{#expr: (-7 mod 7 < 0)*7 + -7 mod 7}} donne 0


Chaînes de caractères

modifier

Supprimer le trim automatique sur les blocs then/else

modifier

Méthode

modifier

Par défaut, les fonctions du étendues du parseur (ParserFunctions) suppriment les espaces avant et après leurs arguments. On peut contourner ce comportement de la manière suivante :

{{{{p{{#if:<test>}}|1|2}}|a
| b}}

Donnera "a" précédé d'un saut de ligne si le test est vrai, " b" si le test est faux.

Explication

modifier

L'opération trim consiste à supprimer les espaces, tabulations, sauts de lignes, etc. avant et après une chaîne de caractères. Le comportement de MediaWiki est le suivant :

  • pas de trim pour les paramètres non nommés ;
  • trim pour les paramètres nommés ;
  • trim pour les paramètres des ParserFunctions
{{#if:<test>}}|a
| b}}

Donnera "a" (sans saut de ligne) si le test est vrai, "b" (sans espace avant) si le test est faux. On peut souhaiter contourner ce comportement. C'est possible de la manière suivante :

{{{{p{{#if:<test>}}|1|2}}|a
| b}}

En effet, la partie

p{{#if:<test>}}|1|2}}

renvoie p1 si vrai, p2 si faux. Les modèles {{p1}} et {{p2}} sont définis de manière à renvoyer leur premier ou leur second paramètre. Les paramètres n'étant pas nommés, le trim n'est pas exécuté.

Exemple

modifier

Il existe des modèles qui utilisent cette astuce : {{if}} et {{Fonctions contrôle/if sans trim}}.

Tableaux

modifier

Utiliser le balisage HTML

modifier

Méthode

modifier

Dans un modèle, l'utilisation du balisage HTML est moins aléatoire que celui de la syntaxe wiki.

Explication

modifier
Premier problème : les barres verticales. Le mélange entre les barres verticales du tableau et celles des fonctions du parseur va imposer l'utilisation de la famille de modèles {{(!}}, {{!+}}, {{!-}}, {{!}}, {{!)}}, qui est un peu lourde.
Second problèmes : les sauts de ligne

Un exemple avec des lignes optionnelles :

{| border="1px solid"
|+ titre
{{ligne optionnelle|paramètres...}}
{{ligne optionnelle|paramètres...}}
{{ligne optionnelle|paramètres...}}
{{ligne optionnelle|paramètres...}}
|}

Le code de la ligne optionnelle étant celui-ci :

{{#if:<test>
    |{{!-}}
{{!}} col1
{{!}} col2
}}

Si seules la première ligne et la quatrième ligne sont affichées, on aura quelque chose de la forme :

{| border="1px solid"
|+ titre
|-
| col1
| col2


|-
| col1
| col2
|}

Qui donne :

titre
col1 col2


col1 col2

On voit que le tableau est déformé car le premier "col2" est suivis d'un double saut de ligne.

Substitutions différées

modifier

Méthode

modifier

On utilise subst: ou safesubst: dans le code d'un modèle pour différer la substitution du modèle :

  • subst: est utilisé pour un modèle qu'on utilise toujours avec subst:
  • safesubst: est utilisé pour un modèle qu'on utilise avec ou sans subst:

Explication

modifier

Inscrire directement les mots clés subst: ou safesubst: entraîne une substitution dès l'enregistrement du modèle, ce qui ne correspond pas au résultat souhaité.

Le paramètre nommé "" n'est en principe jamais utilisé, donc pas défini. Les codes {{{|subst:}}} et {{{|safesubst:}}} seront remplacés par subst: ou safesubst: lors de l'interprétation du modèle. La substitution ne se fait qu'à ce moment.

Remarque : L'astuce qui consiste à écrire

sub<includeonly></includeonly>st:

pour éviter la substitution directe est à éviter car elle nuit à la lisibilité du code.

Exemple substitution différée

modifier

Soit le modèle M qui affiche le jour courant :

code {{M}} {{subst:M}}
{{subst:CURRENTDAY}} Le jour d'enregistrement du modèle (en dur dans le code) Le jour d'enregistrement du modèle (en dur dans le code)
{{{{{|subst:}}}CURRENTDAY}} {{subst:CURRENTDAY}} Le jour d'enregistrement de la page (en dur dans le code)
{{{{{|safesubst:}}}CURRENTDAY}} Le jour d'affichage de la page Le jour d'enregistrement de la page (en dur dans le code)

CURRENTDAY 5 3 {{subst:CURRENTDAY}} Le jour d'enregistrement de la page (en dur dans le code) 5 Le jour d'affichage de la page

Stockage d'informations

modifier

Il peut être utile de stocker des informations sur un sujet pour fournir une liste de paramètres à un ou plusieurs modèles sans avoir à remplir plusieurs fois manuellement les champs.

Champ par champ

modifier

La méthode générale permet de récupérer les champs voulus

Méthode

modifier

Créer une sous-page de modèle Modèle:<sujet>/<paramètres> contenant le code :

{{#switch:{{{1|}}}
|param1=valeur1
|param2=valeur2
...
|paramn=valeurn
}}

Explication

modifier

Grâce au switch, l'appel {{<sujet>/<paramètres>|paramk}} renverra valeurk.

Exemple

modifier

Voir le modèle {{Géolocalisation/France}}.

En bloc

modifier

L'autre option est de récupérer les informations en bloc pour les transmettre à un modèle. Cette méthode fait l'économie du #switch.

Méthode

modifier

Créer une sous-page de modèle Modèle:<sujet>/<paramètres> contenant le code :

{{{{{modèle}}}
|param1=valeur1
|param2=valeur2
...
|paramn=valeurn
}}

Explication

modifier

L'appel {{<sujet>/<paramètres>|un modèle}} va transmettre au modèle "Modèle:un modèle" tous les paramètres.

Exemple

modifier

Voir le modèle {{Country data France}}.

Comparaison des deux méthodes

modifier

La seconde méthode est plus rapide (une seule transclusion), mais souffre de trois inconvénients : tous les paramètres stockés, et rien que ces paramètres, sont transmis au modèle. On peut néanmoins contourner une de ces limitations ainsi :

  • l'appel {{<sujet>/<paramètres>|modèle=#switch:paramk}} renvoie valeurk ;

Remarque : l'appel {{<sujet>/<paramètres>|modèle=mon modèle{{!}}param0{{=}}valeur0}} ne permet pas de transmettre un paramètre param0 qui n'est pas dans le bloc initial, car "mon modèle" n'est pas interprêté comme un nom de modèle.

Conclusion

modifier

La première méthode semble préférable à la seconde, mais peut-être y a-t-il quand même une possibilité de transmettre un paramètre externe au modèle choisi.