Perfectionnement en Lua/Créer un modèle Lua
Au cours des chapitres précédentes, nous avons ébauché un module ; capable d’afficher le contenu de la librairie Scribunto mw.site. Nous créons désormais un modèle, qui doit permettre aux utilisateurs d’appeler les fonctions contenues dans notre module.
L’objectif est de permettre à l’utilisateur d’extraire, toutes les informations contenues dans la librairie ; en utilisant un modèle. La difficulté consiste à échanger les arguments entre utilisateur, modèle, module et librairie.
Nous poursuivons l’étude de l’objet frame, en manipulant les arguments du modèle appelant.
Prérequis
modifierCe chapitre suppose que vous ayez assimilé la leçon Introduction au Lua, ainsi que les premières leçons de perfectionnement où nous préparons le code qui sert de point de départ à cette nouvelle leçon.
Créer un modèle utilisant un script Lua
modifier- Accéder au Module:Bac à sable.
- Supprimer le code existant.
- Ajouter le code suivant et enregistrer la page :
local p = {}
-- Ce module vise à afficher les données de la librairie Scribunto mw.site ; en particulier mw.site.namespaces et w.site.stat.
local site = mw.site -- La variable locale récupère l’objet
local namespaces = mw.site.namespaces
function form_table(t)
local r = '' -- Formulaire vierge
for k, v in pairs(t) do
if type(v) == 'string'or type(v)=='number' then r = r .. '; '.. k.. ': ' .. (v) .. '\n' end
if type(v) == 'boolean' then r = r ..'; '..k ..' : '..tostring(v)..'\n' --
end
end --Ajoute k et v au formulaire, si v est une chaine ou un nombre.
return r
end
function form_namespaces(t) -- Résumé de tous les espaces de noms
local r = ''
for k, v in pairs(t) do
r = r..': '..k..' ; ' .. v.name .. ' ; ' .. v.canonicalName
-- Ajouter nombre de pages
r = r .. '; ' .. mw.site.stats.pagesInNamespace(v.id)
-- Ajouter données correspondantes de l'espace discussion
talk = v.associated
if talk ~= nil then r=r..'\n:::('..talk.id..' ' ..talk.name.. ')\n' else r=r..'\n' end
end
return r
end
function p.site(frame) -- Version 2
local key = frame.args[1] -- frame récupère la clé
local r = site[key] -- appel la clé de la table
if frame.args[1] == nil then r = form_table(site) end -- affiche toutes les clés
if type(site[key]) == 'table' then r = form_table(site[key]) end -- affiche toutes les clés de la table reçue en argument
local key2 = frame.args[2]
if type(site[key]) == 'table' and key2 ~= nil then r = site[key][key2] end -- affiche la valeur arg2 de la table arg1
if key == 'namespaces' then -- traitement particulier pour la table namespaces
r = namespace(frame.args[2], frame.args[3]) -- appel de la sous-fonction avec les arguments numéro 2 et 3.
end
if key == 'interwikiMap' then
r = interwiki(frame.args[2], frame.args[3])
end
-- local r = ''
-- for k, v in pairs(parent.args) do
-- r = r .. '* ' .. k .. ' ; ' .. v .. '\n'
-- end
return r -- retourne le résultat
end
function namespace(filter, key) -- Reçoit le numéro ou bien le label de l'espace ; appel form_ns() et retourne le formulaire des propriétés.
local r = '' -- Résultats
local ns_id = tonumber(filter) -- nil si impossible number désigne id
local ns_name = tostring(filter) -- string désigne label
local t = {} -- table des résulats
if ns_id == nil then -- si ns_id est nul
t = mw.site.namespaces[ns_name] -- reçoit le label
else -- si ns_id existe
t = mw.site.namespaces[ns_id] -- reçoit l'identifiant
end
if filter == nil then -- Si pas de table selectionnée
t = site.subjectNamespaces -- On ne tient compte que des
r = form_namespaces(t) -- espaces sujets et affiche le résumé
else
r = r .. form_table(t) -- Affiche formulaire pour l'espace de noms
end
if key ~= nil then r = t[key] end -- si clé indiquée affiche valeur
return r -- Retourne les données contenues dans la table namespaces
end
function p.namespace(frame) -- Reçoit le numéro ou bien le label de l'espace ; appel form_ns() et retourne le formulaire des propriétés.
local r = namespace(frame.args[1], frame.args[2])
return r -- Retourne le formulaire des propriétés scribunto de l'espace
end
function p.showTable(frame)
t = site
key1 = frame.args[1]
key2 = frame.args[2]
if key1 ~= nil then t = site[key1] end
if key2 ~= nil then
if tonumber(key2) ~= nil then t = t[tonumber(key2)] end
else t = t[key2]
end
local r = showTable(t)
return r
end
function showTable(t)
local r = '' -- Variable texte pour le résultat
for k, v in pairs(t) do -- Itération de la table
r = r .. '* ' .. tostring(k).. ' ; ' .. tostring(v) .. '\n'
end
return r
end
function p.interwiki(frame) -- à terminer
local r = interwiki(frame.args[2])
return r
end
function interwiki(option, key)
local r = ''
local t = site.interwikiMap()
if option == nil then r = showTable(site.interwikiMap()) end
if option == 'local' then r = showTable(site.interwikiMap('local')) end
if option == '!local' then r = showTable(site.interwikiMap('!local')) end
if option ~= 'local' and option ~= '!local' and option ~= nil then
r = showTable(t[option]) end
if key ~= nil then r = t[option][key] end
return r
end
function p.pages_in_nsid(frame)
local result = mw.site.stats.pagesInNamespace(tonumber(frame.args[1]))
return result
end
return p
Création d’un modèle
modifierNous aboutissons à la finalité des modules Scribunto. Leur utilité consiste effectivement à faciliter la programmation ou l’édition, des modèles qui utilisaient auparavant une syntaxe difficile.
Les modèles Lua sont des modèles qui appellent simplement un module Scribunto et dont les arguments sont traités par le module Scribuntu et son code Lua.
La Wikiversité dispose d’un modèle dédié aux tests :
Modèle Bac à sable
modifier- Rendez-vous sur la page Modèle:Bac à sable
- Vérifiez l’historique du modèle,
- Si personne ne l’utilise en ce moment éditez le modèle et remplacez le code existant par le code suivant :
{{#invoke:Bac à sable|site}}
Tester votre nouveau modèle
modifier- Rendez-vous sur "votre page de test".
- Ajouter le code suivant et enregistrer la page:
{{Bac à sable}}
Si votre site ne dispose pas d’un modèle semblable ; la procédure consiste à créer le modèle de test dans vos pages personnelles :
Modèle dans vos pages perso
modifier- Éditez votre page de test, ou éditez cette page de discussion.
- Ajoutez le lien suivant puis enregistrez :
- {{Utilisateur:Youni Verciti/Site}}
- Le modèle appelé, n’existe pas, cliquez sur le lien rouge.
- Sur la page du nouveau modèle, placez l’appel au module de la façon suivante :
- {{#Invoke:Bac à sable|site}}
- Enregistrez la nouvelle page en renseignant le résumé :
- Modèle de test pour [[Projet:Laboratoire/Lua/Perfectionnement/Créer un modèle Lua]]
- Pour tester votre nouveau modèle, retournez sur "votre page de test" ; le même lien qui vous a permis de créer le nouveau modèle, affiche désormais son résultat.
Le résultat doit correspondre à ceci
modifier- siteName: Wikiversité
- currentVersion: 1.44.0-wmf.3 (b4aac1f)
- scriptPath: /w
- server: //fr.wikiversity.org
- stylePath: /w/skins
Comprendre le nouveau modèle
modifier {{Invoke#Bac à sable|site}}
Le modèle contient uniquement l’appel au module …, mais il doit nécessairement désigner une fonction … .
Actuellement notre modèle affiche le résultat de la fonction … mais est incapable de transmettre ses arguments à notre module.
Si nous essayons d’appeler la fonction namespaces() en utilisant le modèle :
{{Site|namespaces}}
le modèle continue à retourner le résultat de la fonction site().
Nous devons modifier la fonction principale site() pour lui permettre de convertir les arguments du modèle en arguments valides pour le code du module. Nous utilisons la fonction getParent() de l’objet frame pour obtenir la table des arguments du modèle.
Par précaution le code suivant permet de vérifier comment scribunto ordonne les arguments de l’objet parent (le modèle).
local parent = frame:getParent()
for k, v in pairs(parent.args) do
r = r .. ’* ’ .. k .. ’ ; ’ .. v .. ’\n’
end
local parent = frame:getParent()
if parent.args[1] ~=nil then frame.args[1] = parent.args[1] end
if parent.args[2] ~=nil then frame.args[2] = parent.args[2] end
if parent.args[3] ~=nil then frame.args[3] = parent.args[3] end
Conclusion
modifierFélicitation! Vous êtes capable de créer, tester et comprendre un modèle Lua qui utilise un module Scribunto. Vous savez utiliser la fonction getParent() de l’objet frame ; afin d’ordonner les arguments du modèle au sein du script.
Continuez avec le chapitre suivant.
Voir aussi
modifierLua initiation (Scribunto objet Frame) FAQ : Obtenir le nom de la fonction ?
Références
modifier