Perfectionnement en Lua/Créer un modèle Lua

Leçons de niveau 14
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Créer un modèle Lua
Icône de la faculté
Chapitre no 4
Leçon : Perfectionnement en Lua
Chap. préc. :Organiser les fonctions
Chap. suiv. :Regex
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Perfectionnement en Lua : Créer un modèle Lua
Perfectionnement en Lua/Créer un modèle Lua
 », n'a pu être restituée correctement ci-dessus.


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[modifier | modifier le wikicode]

Ce 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 | modifier le wikicode]

  1. Accéder au Module:Bac à sable.
  2. Supprimer le code existant.
  3. 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[modifier | modifier le wikicode]

Nous 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 | modifier le wikicode]

  1. Rendez-vous sur la page Modèle:Bac à sable
  2. Vérifiez l’historique du modèle,
  3. 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 | modifier le wikicode]

  1. Rendez-vous sur "votre page de test".
  2. 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 | modifier le wikicode]

  1. Éditez votre page de test, ou éditez cette page de discussion.
  2. Ajoutez le lien suivant puis enregistrez :
    {{Utilisateur:Youni Verciti/Site}}
  3. Le modèle appelé, n’existe pas, cliquez sur le lien rouge.
  4. Sur la page du nouveau modèle, placez l’appel au module de la façon suivante :
    {{#Invoke:Bac à sable|site}}
  5. Enregistrez la nouvelle page en renseignant le résumé :
    Modèle de test pour [[Projet:Laboratoire/Lua/Perfectionnement/Créer un modèle Lua]]
  6. 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 | modifier le wikicode]

  • siteName: Wikiversité
  • currentVersion: 1.42.0-wmf.24 (7262f67)
  • scriptPath: /w
  • server: //fr.wikiversity.org
  • stylePath: /w/skins

Comprendre le nouveau modèle[modifier | modifier le wikicode]

{{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[modifier | modifier le wikicode]

Fé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[modifier | modifier le wikicode]

Lua initiation (Scribunto objet Frame) FAQ : Obtenir le nom de la fonction ?

Références[modifier | modifier le wikicode]

Manuel de référence MediaWiki