Questa pagina è protetta dallo spostamento
Questa pagina è protetta

Modulo:Collegamenti esterni: differenze tra le versioni

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Contenuto cancellato Contenuto aggiunto
modifico resa dei link multipli a stesso sito sfruttandone i qualificatori e introduco categorie di errore come da discussione
Riga 95: Riga 95:
-- @param {table} [url] - uno o più URL, quanti sono i valori della proprietà Wikidata
-- @param {table} [url] - uno o più URL, quanti sono i valori della proprietà Wikidata
-- @param {table} [qualifier] - eventuali qualificatori da annettere al titolo per ciascun URL
-- @param {table} [qualifier] - eventuali qualificatori da annettere al titolo per ciascun URL
-- @param {table} linkConf - la configurazione per questo collegamento esterno
-- @param {table} linkConf - la configurazione fissa per questo collegamento esterno
-- @param {table} extraConf - altri elementi di configurazione ricavati dall'item
-- @param {string} from - entityId se diverso da quello collegato alla pagina corrente
-- @param {string} from - entityId se diverso da quello collegato alla pagina corrente
-- @return {table} un nuovo oggetto ExtLink
-- @return {table} un nuovo oggetto ExtLink
function ExtLink:new(url, qualifier, linkConf, from)
function ExtLink:new(url, qualifier, linkConf, extraConf, from)
local self = {}
local self = {}
setmetatable(self, { __index = ExtLink })
setmetatable(self, { __index = ExtLink })
Riga 109: Riga 110:
self.qualifier = #url > 1 and qualifier
self.qualifier = #url > 1 and qualifier
self.linkConf = linkConf
self.linkConf = linkConf
self.extraConf = extraConf
self.from = from
self.from = from
self.title = getCurrentTitle()
self.title = getCurrentTitle()
Riga 227: Riga 229:
lingua = self.linkConf.lingua,
lingua = self.linkConf.lingua,
cid = self.linkConf.cid,
cid = self.linkConf.cid,
autore = self.linkConf.autore,
autore = self.linkConf.autore or self.extraConf.autore,
volume = self.extraConf.volume,
p = self.extraConf.pagina,
data = self.linkConf.data or self.extraConf.data,
tipo = self.linkConf.tipo or self.sitodis
tipo = self.linkConf.tipo or self.sitodis
}) .. mEditAtWikidata._showMessage({ pid = self.linkConf.pid, qid = self.from })
}) .. mEditAtWikidata._showMessage({ pid = self.linkConf.pid, qid = self.from })
Riga 300: Riga 305:
for _, linkConf in ipairs(cfg[groupName]) do
for _, linkConf in ipairs(cfg[groupName]) do
if not linkConf.istanza or checkInstance(linkConf.istanza, self.from) then
if not linkConf.istanza or checkInstance(linkConf.istanza, self.from) then
local url, qualifier
local url, qualifier, extraConf
local claims = mWikidata._getClaims(linkConf.pid, { from = self.from, snaktype = 'value' })
local claims = mWikidata._getClaims(linkConf.pid, { from = self.from, snaktype = 'value' })
if claims and #claims > 0 then
if claims and #claims > 0 then
-- qualificatori generali
extraConf = {}
extraConf.autore = mWikidata._formatQualifiers(claims[1], 'P50')
extraConf.volume = mWikidata._formatQualifiers(claims[1], 'P478')
extraConf.pagina = mWikidata._formatQualifiers(claims[1], 'P304')
extraConf.data = mWikidata._formatQualifiers(claims[1], 'P577')
-- uno o più url ed eventuali qualificatori per distinguerli
url = {}
url = {}
for i, claim in ipairs(claims) do
for i, claim in ipairs(claims) do
Riga 336: Riga 348:
end
end
if url then
if url then
table.insert(ret[groupName], ExtLink:new(url, qualifier, linkConf, self.from))
table.insert(ret[groupName], ExtLink:new(url, qualifier, linkConf, extraConf, self.from))
-- categorie
-- categorie
local tail = #url > 1 and linkConf.multi and (qualifier == nil or #qualifier ~= #url) and
local tail = #url > 1 and linkConf.multi and (qualifier == nil or #qualifier ~= #url) and

Versione delle 02:45, 21 mar 2019

Modulo che implementa il template {{Collegamenti esterni}}.

Ha una sottopagina di configurazione per ciascun gruppo di collegamenti esterni: Errore Lua in package.lua alla linea 80: module 'Modulo:No globals' not found.

Tipo di proprietà

Quasi tutti i collegamenti si basano su proprietà di tipo "identificativo esterno", quindi per ciascuno bisognerà inserire, nel relativo gruppo della sottopagina di configurazione, almeno l'ID della proprietà Wikidata ("pid") e l'URL di formattazione ("url"). Per i rari casi di utilizzo di proprietà di tipo "URL", al posto dell'URL di formattazione va specificato il titolo del collegamento ("titolo").

Ordine collegamenti

All'interno di ciascun gruppo i collegamenti sono visualizzati nell'ordine in cui sono stati inseriti nella pagina di configurazione (ovviamente se è presente la relativa proprietà Wikidata). Per cambiare l'ordine è quindi sufficiente cambiare l'ordine dei collegamenti nelle sottopagine di configurazione.

Disambiguare i collegamenti relativi allo stesso sito web

Quando più proprietà Wikidata si riferiscono allo stesso sito web (esempio per le diverse schede di un calciatore, allenatore, dirigente, ...) e possono essere usate contemporaneamente in uno stesso elemento Wikidata, ci sono tre modi per disambiguare i collegamenti generati:

  1. differenziarli con "tipo", esempio nel primo tipo = 'calciatore' e nel secondo tipo = 'allenatore'. La disambiguazione apparirà però sempre, anche quando presente una sola proprietà nell'elemento.
  2. differenziarli con "titolo", esempio nel primo titolo = 'Scheda giocatore di $1' e nel secondo titolo = 'Scheda allenatore di $1'. La disambiguazione apparirà però sempre, anche quando presente una sola proprietà nell'elemento, inoltre la frase apparirà in corsivo anche se non fosse effettivamente il titolo della pagina.
  3. differenziarli con "sitodis", esempio nel primo sitodis = 'giocatore' e nel secondo sitodis = 'allenatore'. In questo modo, rispetto ai due metodi precedenti: (1) la disambiguazione apparirà automaticamente solo quando è presente più di una proprietà che utilizza lo stesso sito web e (2) si potranno omettere titolo e sito, lasciandoli al loro valore predefinito, ossia il titolo della pagina e il dominio dell'URL.
Controllo duplicati

Verifica automatica di proprietà duplicate: Errore Lua in package.lua alla linea 80: module 'Modulo:No globals' not found..


--[[
* Modulo che implementa il template Collegamenti esterni.
]]--

require('Modulo:No globals')

local getArgs = require('Modulo:Arguments').getArgs
local mDelink = require('Modulo:Delink')
local mWikidata = require('Modulo:Wikidata')
local mCitazione = require('Modulo:Citazione')
local mEditAtWikidata = require('Modulo:Modifica su Wikidata')
-- Permette di definire l'ordine di visualizzazione dei vari gruppi
local orderedGroupNames = {
	'Ufficiali', 'Enciclopedie', 'Politica', 'Calcio', 'Sport', 'Software', 'Videogiochi',
	'Fumetti', 'Cinema', 'Musica', 'MAB', 'Architettura', 'Geografia',
	'Biografie', 'Letteratura', 'Biologia'
}
-- Numero di collegamenti esterni oltre il quale sono raggruppati
local THRESHOLD_GROUPED_LIST = 12
-- Categorie di servizio
local catGroupedList = 'Voci con template Collegamenti esterni e collegamenti raggruppati'
local catEmpty = 'Voci con template Collegamenti esterni senza dati da Wikidata'
local catUnknownQual = 'Voci con template Collegamenti esterni e qualificatori sconosciuti'

-- =============================================================================
--                            Funzioni di utilità
-- =============================================================================

-- Restituisce la configurazione delle sottopagine.
--
-- @return {table}
local function readConfig()
	local ret = {}
	for _, groupName in ipairs(orderedGroupNames) do
		ret[groupName] = mw.loadData('Modulo:Collegamenti esterni/' .. groupName)
	end
	return ret
end

-- Restituisce il titolo della pagina corrente rimuovendo eventuale testo tra parentesi.
-- Se l'etichetta dell'elemento Wikidata contiene delle parentesi,
-- non le rimuove perché significa che fanno parte del titolo.
-- Con il parametro "from" (elemento Wikidata arbitrario) usa sempre l'etichetta.
--
-- @param {string} from
-- @return {string}
local function getCurrentTitle(from)
	local ret
	local label = mWikidata._getLabel({ from })
	if from then
		ret = label
	else
		ret = mw.title.getCurrentTitle().text
		if not (label and string.find(label, ' %(')) then
			ret = mw.text.split(ret, ' %(')[1]
		end
	end
	return ret
end

-- Restituisce il dominio dell'URL specificato.
--
-- @param {string} url
-- @return {string}
local function getDomain(url)
	return mw.uri.new(url).host:gsub('^www.', '')
end

-- Restituisce true se l'elemento collegato alla pagina o quello specificato in from
-- ha tra i valori della proprietà istanza di (P31) uno degli elementi specificati.
--
-- @param {table} [entityIds]
-- @param {string} from
-- @return {boolean}
local function checkInstance(entityIds, from)
	local args = { from = from }
	for _, entityId in ipairs(entityIds) do
		table.insert(args, entityId)
	end
	return mWikidata._instanceOf(args)
end

-- =============================================================================
--                            Classe ExtLink
-- =============================================================================

-- La classe ExtLink rappresenta un singolo collegamento esterno.
-- Al suo interno ha un riferimento alla propria configurazione (linkConf)
-- e nel caso la proprietà Wikidata abbia più valori li raccoglie tutti.

local ExtLink = {}

-- Costruttore della classe ExtLink.
--
-- @param {table} [url] - uno o più URL, quanti sono i valori della proprietà Wikidata
-- @param {table} [qualifier] - eventuali qualificatori da annettere al titolo per ciascun URL
-- @param {table} linkConf - la configurazione fissa per questo collegamento esterno
-- @param {table} extraConf - altri elementi di configurazione ricavati dall'item
-- @param {string} from - entityId se diverso da quello collegato alla pagina corrente
-- @return {table} un nuovo oggetto ExtLink
function ExtLink:new(url, qualifier, linkConf, extraConf, from)
	local self = {}
	setmetatable(self, { __index = ExtLink })

	-- sostituisce eventuali spazi con %20
	for i = 1, #url do
		url[i] = url[i]:gsub(' ', '%%20')
	end
	self.url = url
	self.qualifier = #url > 1 and qualifier
	self.linkConf = linkConf
	self.extraConf = extraConf
	self.from = from
	self.title = getCurrentTitle()
	self.title = self.from and mWikidata._getLabel({ self.from }) or
			(self.linkConf.titolo and
			self.linkConf.titolo:gsub('$1', self.title) or
			self.title)

	return self
end

-- Restituisce il parametro titolo per il modulo Citazione.
--
-- @return {string}
function ExtLink:_getTitolo()
	if self.qualifier and self.qualifier[1] ~= nil then
		return string.format('%s (%s)', self.title, self.qualifier[1])
	else
		return self.title
	end
end

-- Restituisce il parametro altrilink per il modulo Citazione.
--
-- @return {table}
function ExtLink:_getAltriLink()
	local ret
	if self.qualifier then
		local tbl = {}
		for i = 2, #self.url do
			if self.qualifier[i] == nil then
				self.qualifier[i] = 'altra versione'
			end
			table.insert(tbl, { self.url[i], string.format('%s (%s)', self.title, self.qualifier[i]) })
		end
		ret = tbl
	end
	return ret
end

-- Restituisce il parametro posttitolo per il modulo Citazione.
--
-- @return {string}
function ExtLink:_getPostTitolo(groupedList)
	local ret
	if groupedList or not self.qualifier and #self.url > 1 then
		local tbl = {}
		for i = 2, #self.url do
			table.insert(tbl, string.format('[%s %s]', self.url[i], i))
		end
		ret = string.format('(%s)', table.concat(tbl, ', '))
	end
	return ret
end

-- Restituisce la stringa da usare come "sito" per il modulo Citazione
-- o come label nel link creato come [url label].
--
-- @param {boolean} delink
-- @return {string}
function ExtLink:_getSito(delink)
	local sito
	if self.linkConf.sito then
		sito = delink and mDelink._main({ self.linkConf.sito }) or self.linkConf.sito
	else
		sito = getDomain(self.url[1])
	end
	return sito
end

-- Formatta il collegamento esterno quando la proprietà è di tipo URL.
--
-- @return {string}
function ExtLink:_formatPropertyURL()
	local formattedLinks = {}
	local currTitle = getCurrentTitle(self.from)
	local claims = mWikidata._getClaims(self.linkConf.pid, { from = self.from }) or {}
	for idx, claim in ipairs(claims) do
		local langs = mWikidata._formatQualifiers(claim, 'P407', { formatting = 'raw' }, true)
		langs = (#langs == 1 and langs[1] == 'Q652') and {} or langs
		for i, lang in ipairs(langs) do
			langs[i] = mWikidata._getLabel({ lang })
		end
		local formattedLink = mCitazione.collegamenti({
				url = mWikidata._formatStatement(claim),
				titolo = self.linkConf.titolo:gsub('$1', currTitle),
				lingua = table.concat(langs, ','),
				cid = self.linkConf.cid
			})
		table.insert(formattedLinks, '* ' .. formattedLink ..
					 mEditAtWikidata._showMessage({ pid = self.linkConf.pid, qid = self.from }))
	end
	return table.concat(formattedLinks, '\n')
end

-- Setta come necessaria la disambiguazione del link (più URL con lo stesso dominio nel gruppo),
-- se configurata tramite la chiave "sitodis" nella configurazione.
function ExtLink:needSitoDis()
	self.sitodis = self.linkConf.sitodis
end

-- Formatta il collegamento esterno come elemento di un elenco puntato.
--
-- @return {string}
function ExtLink:getListItem()
	local icon = self.linkConf.icona == 'video' and
			'[[File:35mm film frames.svg|16px|link=|alt=Filmato]]' or ''
	-- se è specificato l'URL di formattazione è una
	-- proprietà di tipo "identificativo esterno" altrimenti di tipo URL
	if self.linkConf.url then
		return '* ' .. icon .. mCitazione.collegamenti({
				url = self.url[1],
				titolo = self:_getTitolo(),
				altrilink = self:_getAltriLink(),
				posttitolo = self:_getPostTitolo(),
				sito = self:_getSito(),
				editore = self.linkConf.editore,
				lingua = self.linkConf.lingua,
				cid = self.linkConf.cid,
				autore = self.linkConf.autore or self.extraConf.autore,
				volume = self.extraConf.volume,
				p = self.extraConf.pagina,
				data = self.linkConf.data or self.extraConf.data,
				tipo = self.linkConf.tipo or self.sitodis
			}) .. mEditAtWikidata._showMessage({ pid = self.linkConf.pid, qid = self.from })
	else
		return self:_formatPropertyURL()
	end
end

-- Formatta il collegamento esterno come elemento di un elenco puntato raggruppato.
--
-- @return {string}
function ExtLink:getGroupedListItem()
	local ret = string.format('[%s %s]', self.url[1], self:_getSito(true))
	return #self.url > 1 and (ret .. ' ' .. self:_getPostTitolo(true)) or ret
end

-- =============================================================================
--                            Classe LinksManager
-- =============================================================================

-- La classe LinksManager è la classe principale del modulo.
-- Al suo interno ha un riferimento a tutti collegamenti esterni (extLinks)
-- presenti in un dato elemento Wikidata e li può restituire tutti formattati 
-- nel modo più appropriato.

local LinksManager = {}

-- Costruttore della classe LinksManager.
--
-- @param {table} args
-- @return {table} un nuovo oggetto LinksManager
function LinksManager:new(args)
	local self = {}
	setmetatable(self, { __index = LinksManager })

	self.numExtLinks = 0
	self.categories = {}
	self.catColon = ''
	self.from = args.from
	-- la pagina dei test utilizza uno stub del modulo Wikidata
	if mw.title.getCurrentTitle().prefixedText ==
	   'Discussioni modulo:Collegamenti esterni/test' then
		self:_setStubWikidata(args.stubwd)
	end
	self.extLinks = self:_getExtLinks()

	return self
end

-- Permette di specificare uno stub del modulo Wikidata
-- in modo da ottenere i valori delle proprietà in modo deterministico,
-- non dipendenti da modifiche utente a un elemento Wikidata.
--
-- @param {table} stubwd
function LinksManager:_setStubWikidata(stubwd)
	mEditAtWikidata = { _showMessage = function(frame) return '' end }
	mWikidata = stubwd
	self.catColon = ':'
	self.debug = true
end

-- Ottiene tutti i collegamenti esterni (configurati) presenti in un dato elemento Wikidata
-- suddivisi per gruppo.
--
-- @return {table}
function LinksManager:_getExtLinks()
	local ret, groupSites = {}, {}
	local cfg = readConfig()
	for _, groupName in ipairs(orderedGroupNames) do
		groupSites[groupName] = {}
		ret[groupName] = {}
		for _, linkConf in ipairs(cfg[groupName]) do
			if not linkConf.istanza or checkInstance(linkConf.istanza, self.from) then
				local url, qualifier, extraConf
				local claims = mWikidata._getClaims(linkConf.pid, { from = self.from, snaktype = 'value' })
				if claims and #claims > 0 then
					-- qualificatori generali
					extraConf = {}
					extraConf.autore = mWikidata._formatQualifiers(claims[1], 'P50')
					extraConf.volume = mWikidata._formatQualifiers(claims[1], 'P478')
					extraConf.pagina = mWikidata._formatQualifiers(claims[1], 'P304')
					extraConf.data = mWikidata._formatQualifiers(claims[1], 'P577')
					-- uno o più url ed eventuali qualificatori per distinguerli
					url = {}
					for i, claim in ipairs(claims) do
						if claim.qualifiers then
							local qualifierIds = {}
							if linkConf.multi then
								qualifierIds = mw.text.split(linkConf.multi:gsub('%s', ''), ',')
								for _, qualifierId in ipairs(qualifierIds) do
									if claim.qualifiers[qualifierId] then
										local formattedQualifier = mWikidata._formatQualifiers(claim, qualifierId, { nq = '1', formatting = 'raw' })
										if formattedQualifier then
											if not qualifier then qualifier = {} end
											qualifier[i] = mw.wikibase.getLabel(formattedQualifier)
											break
										end
									end
								end
							end
							for _, v in ipairs(qualifierIds) do qualifierIds[v] = true end
							for qualifierId in pairs(claim.qualifiers) do
								if qualifierIds[qualifierId] ~= true and qualifierId ~= 'P407' then
									table.insert(self.categories, string.format('[[%sCategoria:%s]]', self.catColon, catUnknownQual))
									break
								end
							end
						end
						claim = mWikidata._formatStatement(claim)
						if linkConf.url then
							claim = mw.message.newRawMessage(linkConf.url, claim):plain()
						end
						table.insert(url, claim)
					end
				end
				if url then
					table.insert(ret[groupName], ExtLink:new(url, qualifier, linkConf, extraConf, self.from))
					-- categorie
					local tail = #url > 1 and linkConf.multi and (qualifier == nil or #qualifier ~= #url) and
							'multipla letta da Wikidata senza qualificatore' or 'letta da Wikidata'
					table.insert(self.categories, string.format('[[%sCategoria:%s %s]]', self.catColon, linkConf.pid, tail))
					-- per verificare se un sito è ripetuto nel gruppo
					local sito = linkConf.sito and mDelink._main({ linkConf.sito }) or getDomain(linkConf.url)
					groupSites[groupName][sito] = (groupSites[groupName][sito] or 0) + 1
					self.numExtLinks = self.numExtLinks + 1
				end
			end
		end
	end
	-- verifica se un sito è ripetuto nel gruppo
	for _, groupName in ipairs(orderedGroupNames) do
		for _, extLink in ipairs(ret[groupName]) do
			local linkConf = extLink.linkConf
			local sito = linkConf.sito and mDelink._main({ linkConf.sito }) or getDomain(linkConf.url)
			if groupSites[groupName][sito] > 1 then
				extLink:needSitoDis()
			end
		end
	end
	-- categorie di servizio
	if self.numExtLinks == 0 then
		table.insert(self.categories, string.format('[[%sCategoria:%s]]', self.catColon, catEmpty))
	elseif self.numExtLinks > THRESHOLD_GROUPED_LIST then
		table.insert(self.categories, string.format('[[%sCategoria:%s]]', self.catColon, catGroupedList))
	end

	return ret
end

-- Formatta i collegamenti esterni come elenco puntato.
--
-- @param {table} [groupNames]
-- @return {string}
function LinksManager:_formatList(groupNames)
	local formattedLinks = {}
	for _, groupName in ipairs(groupNames) do
		for _, extLink in ipairs(self.extLinks[groupName]) do
			table.insert(formattedLinks, extLink:getListItem())
		end
	end
	return table.concat(formattedLinks, '\n')
end

-- Formatta i collegamenti esterni come elenco puntato, raggruppandoli.
--
-- @param {table} [groupNames]
-- @return {string}
function LinksManager:_formatGroupedList(groupNames)
	local formattedGroups = {}
	for _, groupName in ipairs(groupNames) do
		local formattedLinks = {}
		for _, extLink in ipairs(self.extLinks[groupName]) do
			table.insert(formattedLinks, extLink:getGroupedListItem())
		end
		if #formattedLinks > 0 then
			local groupTitle = groupName == 'Enciclopedie' and
				groupName or 'Banche dati ' .. mw.ustring.lower(groupName)
			table.insert(formattedGroups, string.format("* %s: %s%s", groupTitle,
				table.concat(formattedLinks, '<span style="font-weight:bold;">&nbsp;·</span> '),
				mEditAtWikidata._showMessage({ sezione = 'identifiers', qid = self.from })))
		end
	end
	return table.concat(formattedGroups, '\n')
end

-- Restituisce tutti i collegamenti esterni formattandoli come elenco puntato
-- e raggruppandoli quando sono più di THRESHOLD_GROUPED_LIST.
--
-- @return {string}
function LinksManager:getList()
	local categories, groupNames, olinks, links

	-- categorie
	categories = (mw.title.getCurrentTitle().namespace == 0 or self.debug) and
				 table.concat(self.categories) or ''
	-- i siti web ufficiali sono sempre visualizzati uno per riga
	olinks = self:_formatList({ 'Ufficiali' })
	-- tutti gli altri collegamenti
	groupNames = { unpack(orderedGroupNames, 2) }
	links = self.numExtLinks <= THRESHOLD_GROUPED_LIST and
			self:_formatList(groupNames) or 
			self:_formatGroupedList(groupNames)

	return olinks .. ((links ~= '' and olinks ~= '') and '\n' or '') .. links .. categories
end

-- =============================================================================
--                            Funzioni esportate
-- =============================================================================

local p = {}

-- Funzione di utilità per il manuale, restituisce la soglia THRESHOLD_GROUPED_LIST.
function p.threshold(frame)
	return THRESHOLD_GROUPED_LIST
end

-- Funzione di utilità per il manuale, restituisce un elenco
-- delle proprietà supportate, divise per gruppo.
function p.properties(frame)
	local res = {}
	local cfg = readConfig()
	table.sort(orderedGroupNames)
	for _, groupName in ipairs(orderedGroupNames) do
		local wdLinks = {}
		for _, linkConf in ipairs(cfg[groupName]) do
			local wdLink = string.format('* [[d:Property:%s|%s (%s)]]',
				linkConf.pid, mWikidata._getLabel({ linkConf.pid }), linkConf.pid)
			table.insert(wdLinks, wdLink) 
		end
		local group = frame.args[1] == 'modulo' and
			string.format('* [[Modulo:Collegamenti esterni/%s]] (%s)', groupName, #wdLinks) or
			mw.getCurrentFrame():expandTemplate {
				title = 'Cassetto',
				args = {
					titolo = string.format('%s (%s)', groupName, #wdLinks),
					testo = table.concat(wdLinks, '\n')
				}
			}
		table.insert(res, group)
	end
	return table.concat(res, '\n')
end

-- Funzione di utilità per il manuale, verifica l'assenza di proprietà duplicate.
function p.checkdup(frame)
	local ids, res = {}, {}
	local cfg = readConfig()
	for _, groupName in ipairs(orderedGroupNames) do
		for _, linkConf in ipairs(cfg[groupName]) do
			if ids[linkConf.pid] then
				table.insert(res, linkConf.pid)
			else
				ids[linkConf.pid] = true
			end
		end
	end
	return #res == 0 and 'nessun duplicato' or
		string.format('<span class="error">%s</span>', table.concat(res, ', ')) 
end

-- Funzione per l'utilizzo da un altro modulo.
function p._main(args)
	return LinksManager:new(args):getList()
end

-- Funzione per il template {{Collegamenti esterni}}.
function p.main(frame)
	return p._main(getArgs(frame, { parentOnly = true }))
end

return p