Perfectionnement en Lua/Organiser les fonctions

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


Nous avons ébauché une fonction site puis une fonction namespace(s) qui utilisent les sous-fonctions form_table et form_namespace.

Ce chapitre nous permettra d’améliorer l’utilisation des fonctions de notre script. Nous aborderons enfin, les fonctions elle-mêmes disponibles, dans les tables la librairie mw.site.

Prérequis[modifier | modifier le wikicode]

Ce chapitre suppose que vous ayez assimilé les leçons Perfectionnement en Lua/Scribunto objet Site et Perfectionnement en Lua/Manipuler une table complexe.

Créer un script Lua avec des sous-fonctions[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
-- Sous-fonctions
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 .. '\n'
	end
	-- Ajouter nombre de pages
	-- Ajouter données correspondantes de l'espace discussion
	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

--Fonctions
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 = ''  -- Résultats
	local ns_id   = tonumber(frame.args[1]) -- nil si impossible number désigne id
	local ns_name = tostring(frame.args[1]) -- 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 frame.args[1] == nil then
		t = site.subjectNamespaces -- On ne tient compte que des
		r = form_namespaces(t)     -- espaces sujets
	else
		r = r .. form_table(t) -- Affiche formulaire pour l'espace de noms
	end
	if frame.args[2] ~= nil then r = t[frame.args[2]] end
	return r  -- Retourne le formulaire des propriétés scribunto de l'espace
end

function p.site(frame)        -- Version 2 
	--local r = ''
	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 key2 ~= nil then r =  site[key][key2] end -- affiche la valeur arg2 de la table arg1
	if key == 'namespaces' then r = form_namespaces(site[key]) end
	return r                  -- retourne le résultat
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

Scinder une sous-fonction[modifier | modifier le wikicode]

La fonction site doit être capable d’utiliser la fonction namespace. Nous devons écrire le correspondant.

Si l’utilisateur appel la table namespaces nous devons filtrer les arguments deux et trois qui contiendront alors ; l’id de la table pour l’espace sélectionné, la clé de la valeur à afficher pour la table sélectionnée.

r = namespace(filtre [,clé])

La fonction p.namespace(frame), doit pouvoir continuer à fonctionner ; nous allons la vider pour créer une sous-fonction.

Nous ajoutons la ligne suivante à la fonction site

	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.

Nous créons la sous-fonction namespace(), dans laquelle nous copions le contenu de p.namespace(). Ensuite nous organisons les arguments filter et key qui recevront les arguments frame des fonctions appelantes.

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ésultats
	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 sélectionné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

Nous pouvons désormais utiliser la sous-fonction dans la fonction principale ; en attribuant les arguments de l’objet frame.

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

Exploiter les fonctions Site[modifier | modifier le wikicode]

La librairie Site met à disposition des fonctions, pour faciliter nos manipulations.

Nous utilisons la fonction mw.site.stats.pagesInNamespace( ns ) pour ajouter le nombre des pages de l’espace à la fonction form_namespace :

-- Ajouter nombre de pages (dans la boucle)
	r = r .. '; pages : ' .. mw.site.stats.pagesInNamespace(v.id).. '\n

Utilisation des meta-tables[modifier | modifier le wikicode]

La librairie site offre des meta-tables qui permettent de filtrer facilement les espaces de noms selon qu’il s’agisse d’espace sujet ou d’espace de discussion.

  • subjectNamespaces : table des espaces de noms sujets.
  • talkNamespaces : table des espaces de noms discussions.
  • associated : table de l’espace de nom associé (précédent ou suivant).

Notre fonction p.form_namespace reçoit la meta-table site.subjectNamespaces ; c’est-à-dire qu’elle tient compte uniquement des espaces sujets. Nous souhaitons désormais afficher un résumé des caractéristiques de chaque espace de nom associé.

Nous utilisons la meta-table associated pour ajouter un résumé de l’espace discussion :

-- 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

mw.site.interwikiMap[modifier | modifier le wikicode]

Lors de l’observation du contenu de la table site, nous avons remarqué la présence de la fonction interwikiMap. La mw:LUAREF précise que la fonction retourne la tables des liens interwiki.

L’exercice consiste à créer la fonction capable d’afficher :

  • la liste des liens interwikiMap (complète ou filtrée selon local/!local)
  • la table de chaque lien (complète ou filtrée selon la clé souhaitée)
-- solution non disponible

Tester votre nouveau script[modifier | modifier le wikicode]

  1. Rendez-vous sur "votre page de test".
  2. Ajouter le code suivant et enregistrer la page:
{{#Invoke:Bac à sable|site|namespaces}} 
{{#Invoke:Bac à sable|site|namespaces|Faculté|id}}
{{#Invoke:Bac à sable|site|namespaces|Aide|isContent}}
{{#Invoke:Bac à sable|namespace|Aide}}

Le résultat doit correspondre à ceci[modifier | modifier le wikicode]

Comprendre le nouveau script[modifier | modifier le wikicode]

Conclusion[modifier | modifier le wikicode]

Félicitation! Vous êtes capable de créer, tester et comprendre un script Lua qui contient des sous-fonctions. Vous êtes en mesure d’administrer les arguments issus de l’objet frame et ceux utiles aux sous-fonctions. Continuez avec le chapitre Créer un modèle Lua, vous apprendrez à administrer les arguments issus des modèles.

Voir aussi[modifier | modifier le wikicode]

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

Manuel de référence MediaWiki