Utilisateur:Juju2004/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 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)

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.