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
m posizione MAB
aggiunto gruppo Enciclopedie
Riga 12: Riga 12:
-- Permette di definire l'ordine di visualizzazione dei vari gruppi
-- Permette di definire l'ordine di visualizzazione dei vari gruppi
local orderedGroupNames = {
local orderedGroupNames = {
'Ufficiali', 'Politica', 'Calcio', 'Sport', 'Software', 'Videogiochi', 'Fumetti',
'Ufficiali', 'Politica', 'Calcio', 'Sport', 'Software', 'Videogiochi',
'Cinema', 'Musica', 'MAB', 'Architettura', 'Geografia', 'Biografie', 'Letteratura'
'Fumetti', 'Cinema', 'Musica', 'MAB', 'Architettura', 'Geografia',
'Biografie', 'Letteratura', 'Enciclopedie'
}
}
-- Numero di collegamenti esterni oltre il quale sono raggruppati
-- Numero di collegamenti esterni oltre il quale sono raggruppati
Riga 325: Riga 326:
end
end
if #formattedLinks > 0 then
if #formattedLinks > 0 then
local groupTitle = groupName == 'Enciclopedie' and
table.insert(formattedGroups, string.format("* Banche dati %s: %s",
mw.ustring.lower(groupName),
groupName or 'Banche dati ' .. mw.ustring.lower(groupName)
table.insert(formattedGroups, string.format("* %s: %s", groupTitle,
table.concat(formattedLinks, '<span style="font-weight:bold;">&nbsp;·</span> ')))
table.concat(formattedLinks, '<span style="font-weight:bold;">&nbsp;·</span> ')))
end
end

Versione delle 15:09, 14 lug 2018

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', 'Politica', 'Calcio', 'Sport', 'Software', 'Videogiochi',
	'Fumetti', 'Cinema', 'Musica', 'MAB', 'Architettura', 'Geografia',
	'Biografie', 'Letteratura', 'Enciclopedie'
}
-- 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'

-- =============================================================================
--                            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} linkConf - la configurazione per questo collegamento esterno
-- @param {string} from - entityId se diverso da quello collegato alla pagina corrente
-- @return {table} un nuovo oggetto ExtLink
function ExtLink:new(url, linkConf, from)
	local self = {}
	setmetatable(self, { __index = ExtLink })

	self.url = url
	self.linkConf = linkConf
	self.from = from

	return self
end

-- Restituisce il parametro titolo per citaweb.
--
-- @return {string}
function ExtLink:_getTitolo()
	local currTitle = getCurrentTitle()
	return self.from and mWikidata._getLabel({ self.from }) or 
		   (self.linkConf.titolo and self.linkConf.titolo:gsub('$1', currTitle) or currTitle)
end

-- Restituisce il parametro posttitolo per citaweb.
--
-- @return {string}
function ExtLink:_getPostTitolo()
	local ret
	if #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 citaweb
-- 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
	-- aggiunge la disambiguazione se c'è più di un collegamento esterno con la stesso sito
	return self.sitodis and string.format('%s (%s)', sito, self.sitodis) or 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.citaweb({
				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 sito (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.citaweb({
				url = self.url[1],
				titolo = self:_getTitolo(),
				posttitolo = self:_getPostTitolo(),
				sito = self:_getSito(),
				editore = self.linkConf.editore,
				lingua = self.linkConf.lingua,
				cid = self.linkConf.cid
			}) .. 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()) 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 = ''
	-- 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(args.from)

	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.
--
-- @param {string} from
-- @return {table}
function LinksManager:_getExtLinks(from)
	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, from) then
				local url = mWikidata._getProperty({ linkConf.pid, from = from, snaktype = 'value', pattern = linkConf.url }, true)
				if url then
					table.insert(ret[groupName], ExtLink:new(url, linkConf, from))
					-- categorie
					table.insert(self.categories, string.format('[[%sCategoria:%s letta da Wikidata]]',
								 self.catColon, linkConf.pid))
					-- 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", groupTitle,
				table.concat(formattedLinks, '<span style="font-weight:bold;">&nbsp;·</span> ')))
		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