Modulo:Progetti interessati

Info Istruzioni per l'uso
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Progetti interessati/man (modifica · cronologia)
Sandbox: Modulo:Progetti interessati/sandbox (modifica · cronologia) · Sottopagine: lista · Test: Modulo:Progetti interessati/test (modifica · cronologia · esegui)

Modulo che implementa il template {{Progetti interessati}}.

Ha due sottopagine di configurazione:



--[[
* Modulo che implementa il template Progetti interessati.
]]--

require('strict')

local getArgs = require('Modulo:Arguments').getArgs
local cfg = mw.loadData('Modulo:Progetti interessati/Configurazione')
local catPrefix = mw.loadData('Modulo:Progetti interessati/Categorie')
-- Nomi e valori consentiti dei parametri di monitoraggio/importanza richiesti da più funzioni
local gradeParams = { 'accuratezza', 'scrittura', 'fonti', 'immagini' }
local validGrades = { a = true, b = true, c = true, d = true, e = true }
local validImportances = { massima = true, alta = true }

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

-- Wrapper di mw.title.exists, verifica sia che name sia valido, sia che esista.
--
-- @param {string} name
-- @return {boolean}
local function titleExists(name)
	local title = mw.title.new(name)
	return title and title.exists
end

-- Restituisce il valore della valutazione ("a", "b", "c" o "d") più bassa inserita
-- nei quattro parametri "accuratezza", "scrittura", "fonti" e "immagini".
--
-- @param {table} args
-- @return {string}
local function lowestGrade(args)
	local t = { args.accuratezza, args.scrittura, args.fonti, args.immagini }
	table.sort(t)
	return t[4]
end

-- Restituisce l'icona da visualizzare per il progetto specificato,
-- utilizzando il template Icona argomento e verificando se è un sottoprogetto.
--
-- @param {string} name
-- @return {string}
local function getIcon(name)
	local icon = mw.getCurrentFrame():expandTemplate {
		title = 'Icona argomento',
		args = { name }
	}
	if icon == '' then
		local subpage = mw.title.new('Progetto:' .. name).subpageText
		if subpage ~= name then
			icon = mw.getCurrentFrame():expandTemplate {
				title = 'Icona argomento',
				args = { subpage }
			}
		end
	end
	icon = icon == '' and 'Crystal Clear app ksirtet.png' or icon

	return string.format('[[File:%s|20x20px|alt= ]]', icon)
end

-- Restituisce il valore del parametro importanzaN relativo al progettoN specificato,
-- o nil se non usato dall'utente.
--
-- @param {string} projParam
-- @param {table} args
-- @return {string}
local function getImportance(projParam, args)
	local num = mw.ustring.match(projParam, '^progetto(%d)$')
	local param = num and ('importanza' .. num) or
				  (projParam == 'progetto' and 'importanza' or nil)
	return args[param]
end

-- Controlla gli argomenti importanzaN e quelli per la valutazione del monitoraggio.
-- Per ogni parametro progettoN specificato crea una table con i dati del progetto.
--
-- @param {table} args
-- @return {table} gli argomenti passati alla funzione
-- @return {table} una sequence di table che descrivono i singoli progetti
-- @return {table} eventuali categorie di errore
-- @return {string} un eventuale messaggio di errore per i progetti non esistenti
local function parseArgs(args)
	local errcat = {}
	local projects = {}
	local nonexistingProjects = {}
	local errmsg
	local importanceParams = { 'importanza' }
	local projectParams = { 'progetto' }

	-- controllo importanza
	for i = 2, cfg.max_progetti do
		table.insert(importanceParams, 'importanza' .. i)
	end
	for _, param in ipairs(importanceParams) do
		if args[param] and not validImportances[args[param]] then
			args[param] = nil
			table.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con importanza invalida]]')
		end
	end

	-- controllo valutazioni
	for _, param in ipairs(gradeParams) do
		if args[param] and not validGrades[args[param]] then
			if args[param] ~= 'nc' then
				table.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con valutazione invalida]]')
			end
			args[param] = nil
		end
	end
	args.data = args.data and args.data:lower() or nil

	-- popola la tabella projects
	if args.progetto then
		for i = 2, cfg.max_progetti do
			table.insert(projectParams, 'progetto' .. i)
		end
		for _, param in ipairs(projectParams) do
			if args[param] then
				local name = cfg.alias[args[param] and args[param]:lower()] or
							 mw.language.getContentLanguage():ucfirst(args[param])
				if titleExists('Progetto:' .. name) then
					table.insert(projects, {
						name = name,
						subpage = mw.title.new('Progetto:' .. name).subpageText,
						monitoraggio = titleExists(string.format('Progetto:%s/Monitoraggio voci', name)),
						importance = getImportance(param, args),
						icon = getIcon(name),
						catPrefix = catPrefix[name:lower()]
					})
				else
					table.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con progetto non esistente]]')
					table.insert(nonexistingProjects, name)
				end
			end
		end
	else
		-- almeno un progetto deve essere specificato
		table.insert(errcat, '[[Categoria:Errori di compilazione del template Progetti interessati]]')
	end

	-- messaggio d'errore con progetti non esistenti
	if #nonexistingProjects > 0 then
		local descr = #nonexistingProjects > 1 and 'non esistono i progetti' or 'non esiste il progetto'
		errmsg = string.format('<span class="error" style="margin:5px 10%%">Errore: %s %s</span>',
							   descr, mw.text.listToText(nonexistingProjects))
	end

	return args, projects, errcat, errmsg
end

-- Formatta i valori assegnati ai parametri "accuratezza", "scrittura", "fonti" e "immagini".
--
-- @param {string} value
-- @return {table}
local function getLabelGrade(value)
	local codeStyle = {
		['font-weight'] = 'bold',
		['font-size'] = '155%',
		['padding-left'] = '.2em',
		['padding-right'] = '.2em',
		border = '1px solid lightsteelblue',
		background = cfg.colors[value] or 'white'
	}
	return mw.html.create('code')
		:css(codeStyle)
		:wikitext(value and value:upper() or '<small>nc</small>')
end

-- Restituisce true se almeno un progetto tra quelli specificati
-- ha attivato il monitoraggio.
--
-- @param {table} projects
-- @return {boolean}
local function hasMonitoraggio(projects)
	local ret = false
	for _, project in ipairs(projects) do
		if project.monitoraggio then
			ret = true
			break
		end
	end
	return ret
end

-- =============================================================================
--                       Funzioni base del Monitoraggio
-- =============================================================================

-- Restituisce il risultato del monitoraggio in base alle valutazioni inserite
-- nei quattro parametri "accuratezza", "scrittura", "fonti" e "immagini".
-- Il valore restituito, dal basso verso l'alto, può essere:
-- "0.2", "0.3", "0.4", "0.5", "IMMAGINI", "F", "W", "BOZZA", "1", "2", "3", "4".
--
-- @param {table} args
-- @return {string}
local function getLivello(args)
	local ret

	-- è presente accuratezza
	if args.accuratezza then
		if not args.scrittura then
			ret = '0.4'
		elseif not args.fonti then
			ret = '0.3'
		elseif not args.immagini then
			ret = '0.2'
		else
			-- sono presenti tutti e quattro i parametri di valutazione
			if args.accuratezza == 'e' then
				ret = 'BOZZA'
			elseif args.scrittura == 'e' then
				ret = 'W'
			elseif args.fonti == 'e' then
				ret = 'F'
			elseif args.immagini == 'e' then
				ret = 'IMMAGINI'
			else
				local values = { a = 4, b = 3, c = 2, d = 1 }
				ret = tostring(values[lowestGrade(args)])
			end
		end
	-- manca accuratezza
	else
		if args.scrittura or args.fonti or args.immagini then
			ret = '0.5'
		else
			ret = nil
		end
	end

	return ret
end

-- Restituisce le categorie di servizio in base al livello del monitoraggio ottenuto,
-- agli eventuali parametri "importanza" e alla presenza di errori utente di compilazione.
--
-- @param {string} livello
-- @param {table} args
-- @param {table} projects
-- @return {table}
local function getCategories(livello, args, projects)
	local ret = {}
	local cat

	local suffix = livello and cfg.livello[livello].cat or 'non compilate'

	-- per la "Situazione generale" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
	cat = string.format('[[Categoria:Voci monitorate - %s]]', suffix)
	table.insert(ret, cat)

	for _, project in ipairs(projects) do
		if project.monitoraggio then
			cat = string.format('[[Categoria:Voci monitorate Progetto %s]]', project.name)
			table.insert(ret, cat)
		end
	end

	for _, gradeParam in ipairs(gradeParams) do
		-- per la "Situazione monitoraggio per parametro" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
		cat = string.format('[[Categoria:Voci monitorate - %s %s]]',
							gradeParam, (args[gradeParam] or 'nc'):upper())
		table.insert(ret, cat)

		-- categorie per il [[template:Tabella monitoraggio]]
		for _, project in ipairs(projects) do
			if project.monitoraggio then
				cat = string.format('Categoria:Progetto:%s/Tabella monitoraggio automatico - %s %s',
									project.name, gradeParam, args[gradeParam] or 'nc')
				if titleExists(cat) then
					table.insert(ret, '[[' .. cat .. ']]')
				end
			end
		end
	end

	-- categorie per il [[template:Tabella monitoraggio]]
	for _, project in ipairs(projects) do
		if project.monitoraggio then
			cat = string.format('Categoria:Voci monitorate Progetto %s - %s',
								project.name, suffix)
			if titleExists(cat) then
				table.insert(ret, '[[' .. cat .. ']]')
			end
		end
		if project.importance and project.catPrefix then
			cat = string.format('Categoria:%s - importanza %s', project.catPrefix, project.importance)
			table.insert(ret, '[[' .. cat .. ']]')
		end
	end

	-- per la "Situazione monitoraggio per mese" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]
	if livello then
		if args.data then
			cat = string.format('Categoria:Voci monitorate - %s', args.data)
			if titleExists(cat) then
				table.insert(ret, '[[' .. cat .. ']]')
			else
				table.insert(ret, '[[Categoria:Errori di compilazione del template Progetti interessati]]')
			end
		else
			table.insert(ret, '[[Categoria:Voci monitorate - non datate]]')
		end
	elseif (args.data or args.utente) and not args.note then
		table.insert(ret, '[[Categoria:Pagine con template Progetti interessati con utente o data e senza monitoraggio]]')
	end

	return ret
end

-- =============================================================================
--                            Classe ProjectsTable
-- =============================================================================

-- La classe ProjectsTable rappresenta la prima delle due tabelle HTML
-- prodotte dal modulo, quella per elencare i wikiprogetti.

local ProjectsTable = {}

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

-- Restituisce la tabella HTML con una riga di introduzione e una per la sottotabella progetti.
--
-- @return {string}
function ProjectsTable:getHTML()
	local tableStyle = {
		margin = '5px 10%',
		width = '80%',
		border = '1px solid #a7d7f9',
		['background-color'] = cfg.bgcolor,
	}
	local text = #self.projects > 1 and cfg.progetti.text2 or cfg.progetti.text
	local tableNode = mw.html.create('table'):css(tableStyle)
	tableNode
		:tag('tr')
			:tag('td')
				:css('width', '52px')
				:css('text-align', 'center')
				:wikitext(cfg.progetti.icon)
				:done()
			:tag('td')
				:wikitext(mw.getCurrentFrame():preprocess(text))
				:done()
	tableNode
		:tag('tr')
			:tag('td')
				:attr('colspan', '2')
				:node(self:_getNodeProjects())
				:done()

	if titleExists(mw.getCurrentFrame():preprocess('WP:Bibliografia/{{SUBJECTPAGENAME}}')) then
	tableNode
		:tag('tr')
			:tag('td')
				:css('text-align', 'center')
				:attr('colspan', '2')				:wikitext(mw.getCurrentFrame():preprocess('[[WP:Bibliografia/{{SUBJECTPAGENAME}}|Bibliografia utilizzabile]]'))
				:done()
	end

	return tostring(tableNode)
end

-- Restituisce la sottotabella HTML con un progetto per riga.
--
-- @return {table}
function ProjectsTable:_getNodeProjects()
	local tableStyle = {
		width = '100%',
		['border-collapse'] = 'collapse'
	}
	local tableNode = mw.html.create('table'):css(tableStyle)

	-- progetti
	for _, project in ipairs(self.projects) do
		tableNode:tag('tr')
			:css('background-color', 'white')
			:css('border', 'thin solid #D8D8D8')
			:tag('td')
				:css('width', '28px')
				:css('text-align', 'center')
				:wikitext(project.icon)
				:done()
			:tag('td')
				:css('width', '1px')
				:css('white-space', 'nowrap')
				:wikitext(string.format("'''[[Progetto:%s|%s]]'''", project.name, project.subpage))
				:done()
			:tag('td')
				:addClass('plainlinks')
				:css('padding-left', '5px')
				:wikitext(self:_getWlinkProject(project))
				:done()
			:tag('td')
				:css('width', '11em')
				:wikitext((project.importance and project.catPrefix) and
						  string.format('[[:Categoria:%s - importanza %s|importanza %s]]',
						  project.catPrefix, project.importance, project.importance) or '')
				:done()
	end

	return tableNode
end

-- Restituisce il link al progetto, al bar di progetto e all'eventuale monitoraggio delle voci.
--
-- @param {table} project
-- @return {string}
function ProjectsTable:_getWlinkProject(project)
	local links = {}
	local fmtIcon = '[[File:Rpb dialog icon.svg|23x15px|bar di progetto|link=Discussioni progetto:%s]]'
	local fmtIcon2 = '[[File:VisualEditor - Icon - Search-big.svg|20x20px|monitoraggio voci|link=Progetto:%s/Monitoraggio voci]]'

	table.insert(links, string.format(fmtIcon, project.name))
	table.insert(links, string.format('[[Discussioni progetto:%s|bar di progetto]]', project.name))
	-- link monitoraggio opzionale
	if project.monitoraggio then
		table.insert(links, string.format(fmtIcon2, project.name))
		table.insert(links, string.format('[[Progetto:%s/Monitoraggio voci|monitoraggio voci]]', project.name))
	end

	return table.concat(links, ' ')
end

-- =============================================================================
--                            Classe MonitoraggioTable
-- =============================================================================

-- La classe ProjectsTable rappresenta la seconda delle due tabelle HTML
-- prodotte dal modulo, quella per visualizzare la valutazione del monitoraggio.

local MonitoraggioTable = {}

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

-- Restituisce la tabella HTML con una riga di introduzione e una per la sottotabella
-- collassabile per "accuratezza", "scrittura", "fonti" e "immagini".
-- Termina con due righe opzionali in base alla presenza delle note e della data.
--
-- @return {string}
function MonitoraggioTable:getHTML()
	local tableStyle = {
		margin = '5px 10% 5px 10%',
		width = '80%',
		border = '1px solid #a7d7f9',
		['background-color'] = cfg.bgcolor
	}
	local tableNode = mw.html.create('table')
	tableNode
		:addClass('mw-collapsible mw-collapsed')
		:css(tableStyle)

	-- livello
	tableNode
		:node(self:_getNodeLivello())
	-- valutazioni
	tableNode
		:tag('tr')
			:tag('td')
				:attr('colspan', '3')
				:css('background-color', 'none')
				:css('font-size', '95%')
				:tag('table')
					:css('width', '100%')
					:css('border-collapse', 'collapse')
					:node(self:_getNodeGrade('accuratezza'))
					:node(self:_getNodeGrade('scrittura'))
					:node(self:_getNodeGrade('fonti'))
					:node(self:_getNodeGrade('immagini'))
	-- note
	if self.args.note then
		tableNode
			:tag('tr')
				:tag('td')
					:css('padding-left', '0.2em')
					:attr('colspan', '3')
					:wikitext(string.format("'''Note:''' %s%s",
							  self.args.note:match('^[#*]') and '\n' or '',
							  self.args.note))
	end
	-- data
	if self.args.data then
		local data = self:_getTextData()
		tableNode
			:tag('tr')
				:tag('td')
					:css('text-align', 'right')
					:css('font-size', '80%')
					:css('line-height', '1')
					:attr('colspan', '3')
					:wikitext(string.format('Monitoraggio effettuato %s%s',
							  data:match('^[ao]') and 'nell\'' or 'nel ', data))
	end

	return tostring(tableNode)
end

-- Restituisce la prima riga della tabella HTML, contenente il risultato del monitoraggio
-- oppure l'indicazione che il monitoraggio non è ancora stato effettuato.
--
-- @return {table}
function MonitoraggioTable:_getNodeLivello()
	local text, icon
	if self.livello then
		if self.livello:sub(1, 1) == '0' then
			icon, text = cfg.monitoraggio.icon_pc, cfg.monitoraggio.text_pc
		else
			icon, text = cfg.monitoraggio.icon, cfg.monitoraggio.text
			text = string.format('%s<br />Ha ottenuto una valutazione di livello %s <small>(%s)</small>.',
								 text, self:_getWlinkLivello(), self:_getTextData())
		end
	else
		icon, text = cfg.monitoraggio.icon_nc, cfg.monitoraggio.text_nc
	end
	return mw.html.create('tr')
		:tag('td')
			:css('width', '52px')
			:css('text-align', 'center')
			:wikitext(icon)
			:done()
		:tag('td')
			:wikitext(mw.getCurrentFrame():preprocess(text))
			:done()
end

-- Restituisce il wikilink del risultato del monitoraggio, formattato opportunamente.
--
-- @return {string}
function MonitoraggioTable:_getWlinkLivello()
	local codeStyle = {
		['font-weight'] = 'bold',
		['padding-left'] = '.4em',
		['padding-right'] = '.4em',
		border = '1px solid lightsteelblue',
		background = cfg.livello[self.livello].color,
		color  = 'blue'
	}
	local text = string.format('[[:Categoria:Voci monitorate - %s|%s]]',
							   cfg.livello[self.livello].cat, cfg.livello[self.livello].label)
	local codeNode = mw.html.create('code')
	codeNode:css(codeStyle)
	codeNode:wikitext(text)
	return tostring(codeNode)
end

-- Restituisce la data del monitoraggio se esiste la relativa categoria
-- di monitoraggio per mese oppure un messaggio di errore.
--
-- @return {string}
function MonitoraggioTable:_getTextData()
	local ret
	if self.args.data then
		local cat = string.format('Categoria:Voci monitorate - %s', self.args.data)
		if titleExists(cat) then
			ret = self.args.data
		end
	end
	return ret or "<span style=\"color:red;\">'''''mese e anno'''''</span>"
end

-- Restituisce la riga della tabella HTML per ciascuna delle quattro valutazioni di
-- "accuratezza", "scrittura", "fonti" e "immagini", formattata opportunamente.
--
-- @param {string} param
-- @return {table}
function MonitoraggioTable:_getNodeGrade(param)
	return mw.html.create('tr')
		:css('background-color', 'white')
		:css('border', 'thin solid #D8D8D8')
		:tag('td')
			:css('width', '52px')
			:css('text-align', 'center')
			:node(getLabelGrade(self.args[param]))
			:done()
		:tag('td')
			:wikitext(cfg[param][self.args[param] or 'nc'] .. ' ' .. cfg[param].help)
			:done()
end

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

local p = {}

-- Funzione per l'utilizzo da un altro modulo.
function p._livello(args)
	return getLivello(parseArgs(args))
end

-- Funzione per {{#invoke:Progetti interessati|livello}}.
function p.livello(frame)
	return p._livello(getArgs(frame))
end

-- Funzione per {{#invoke:Progetti interessati|categorie}}.
function p.categorie(frame)
	local args, projects = parseArgs(getArgs(frame))
	local livello = getLivello(args)
	local categories = getCategories(livello, args, projects)
	return args.debug and ( table.concat(categories, '<br />'):gsub('%[%[', '[[:') ) .. '<br />' or
		   table.concat(categories)
end

-- Funzione per il sottotemplate {{Progetti interessati/classe}}
-- per retrocompatibilità con template che lo usavano.
function p.classe(frame)
	local value = frame:getParent().args[1]
	return tostring(getLabelGrade(validGrades[value] and value or nil))
end

-- Funzione per il template {{Progetti interessati}}.
function p.main(frame)
	local args, projects, errcat, errmsg = parseArgs(getArgs(frame, { parentOnly = true }))
	if hasMonitoraggio(projects) then
		local livello = getLivello(args)
		local categories = mw.title.getCurrentTitle().namespace == 1 and
					   	(table.concat(getCategories(livello, args, projects)) .. table.concat(errcat)) or ''
		return (errmsg or '') ..
			   ProjectsTable:new(projects):getHTML() ..
			   MonitoraggioTable:new(livello, args):getHTML() ..
			   categories
	else
		return (errmsg or '') ..
			   ProjectsTable:new(projects):getHTML() ..
			   table.concat(errcat)
	end
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.