Modulo:Progetti interessati

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').getArgslocal 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ù funzionilocal 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.existsend-- 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 == '' thenlocal subpage = mw.title.new('Progetto:' .. name).subpageTextif subpage ~= name thenicon = mw.getCurrentFrame():expandTemplate {title = 'Icona argomento',args = { subpage }}endendicon = icon == '' and 'Crystal Clear app ksirtet.png' or iconreturn string.format('[[File:%s|20x20px]]', 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 esistentilocal function parseArgs(args)local errcat = {}local projects = {}local nonexistingProjects = {}local errmsglocal importanceParams = { 'importanza' }local projectParams = { 'progetto' }-- controllo importanzafor i = 2, cfg.max_progetti dotable.insert(importanceParams, 'importanza' .. i)endfor _, param in ipairs(importanceParams) doif args[param] and not validImportances[args[param]] thenargs[param] = niltable.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con importanza invalida]]')endend-- controllo valutazionifor _, param in ipairs(gradeParams) doif args[param] and not validGrades[args[param]] thenif args[param] ~= 'nc' thentable.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con valutazione invalida]]')endargs[param] = nilendendargs.data = args.data and args.data:lower() or nil-- popola la tabella projectsif args.progetto thenfor i = 2, cfg.max_progetti dotable.insert(projectParams, 'progetto' .. i)endfor _, param in ipairs(projectParams) doif args[param] thenlocal name = cfg.alias[args[param] and args[param]:lower()] or mw.language.getContentLanguage():ucfirst(args[param])if titleExists('Progetto:' .. name) thentable.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()]})elsetable.insert(errcat, '[[Categoria:Pagine con template Progetti interessati con progetto non esistente]]')table.insert(nonexistingProjects, name)endendendelse-- almeno un progetto deve essere specificatotable.insert(errcat, '[[Categoria:Errori di compilazione del template Progetti interessati]]')end-- messaggio d'errore con progetti non esistentiif #nonexistingProjects > 0 thenlocal 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))endreturn args, projects, errcat, errmsgend-- 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 = falsefor _, project in ipairs(projects) doif project.monitoraggio thenret = truebreakendendreturn retend-- =============================================================================--                       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 accuratezzaif args.accuratezza thenif not args.scrittura thenret = '0.4'elseif not args.fonti thenret = '0.3'elseif not args.immagini thenret = '0.2'else-- sono presenti tutti e quattro i parametri di valutazioneif args.accuratezza == 'e' thenret = 'BOZZA'elseif args.scrittura == 'e' thenret = 'W'elseif args.fonti == 'e' thenret = 'F'elseif args.immagini == 'e' thenret = 'IMMAGINI'elselocal values = { a = 4, b = 3, c = 2, d = 1 }ret = tostring(values[lowestGrade(args)])endend-- manca accuratezzaelseif args.scrittura or args.fonti or args.immagini thenret = '0.5'elseret = nilendendreturn retend-- 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 catlocal 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) doif project.monitoraggio thencat = string.format('[[Categoria:Voci monitorate Progetto %s]]', project.name)table.insert(ret, cat)endendfor _, 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) doif project.monitoraggio thencat = string.format('Categoria:Progetto:%s/Tabella monitoraggio automatico - %s %s',project.name, gradeParam, args[gradeParam] or 'nc')if titleExists(cat) thentable.insert(ret, '[[' .. cat .. ']]')endendendend-- categorie per il [[template:Tabella monitoraggio]]for _, project in ipairs(projects) doif project.monitoraggio thencat = string.format('Categoria:Voci monitorate Progetto %s - %s',project.name, suffix)if titleExists(cat) thentable.insert(ret, '[[' .. cat .. ']]')endendif project.importance and project.catPrefix thencat = string.format('Categoria:%s - importanza %s', project.catPrefix, project.importance)table.insert(ret, '[[' .. cat .. ']]')endend-- per la "Situazione monitoraggio per mese" di [[Progetto:Qualità/Monitoraggio voci/Tabella]]if livello thenif args.data thencat = string.format('Categoria:Voci monitorate - %s', args.data)if titleExists(cat) thentable.insert(ret, '[[' .. cat .. ']]')elsetable.insert(ret, '[[Categoria:Errori di compilazione del template Progetti interessati]]')endelsetable.insert(ret, '[[Categoria:Voci monitorate - non datate]]')endelseif (args.data or args.utente) and not args.note thentable.insert(ret, '[[Categoria:Pagine con template Progetti interessati con utente o data e senza monitoraggio]]')endreturn retend-- =============================================================================--                            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 ProjectsTablefunction ProjectsTable:new(projects)local self = {}setmetatable(self, { __index = ProjectsTable })self.projects = projectsreturn selfend-- 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.textlocal 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}}')) thentableNode:tag('tr'):tag('td'):css('text-align', 'center'):attr('colspan', '2'):wikitext(mw.getCurrentFrame():preprocess('[[WP:Bibliografia/{{SUBJECTPAGENAME}}|Bibliografia utilizzabile]]')):done()endreturn 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)-- progettifor _, project in ipairs(self.projects) dotableNode: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()endreturn tableNodeend-- 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 opzionaleif project.monitoraggio thentable.insert(links, string.format(fmtIcon2, project.name))table.insert(links, string.format('[[Progetto:%s/Monitoraggio voci|monitoraggio voci]]', project.name))endreturn 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 MonitoraggioTablefunction MonitoraggioTable:new(livello, args)local self = {}setmetatable(self, { __index = MonitoraggioTable })self.livello = livelloself.args = argsreturn selfend-- 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)-- livellotableNode:node(self:_getNodeLivello())-- valutazionitableNode: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'))-- noteif self.args.note thentableNode: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-- dataif self.args.data thenlocal 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))endreturn 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, iconif self.livello thenif self.livello:sub(1, 1) == '0' thenicon, text = cfg.monitoraggio.icon_pc, cfg.monitoraggio.text_pcelseicon, text = cfg.monitoraggio.icon, cfg.monitoraggio.texttext = string.format('%s<br />Ha ottenuto una valutazione di livello %s <small>(%s)</small>.', text, self:_getWlinkLivello(), self:_getTextData())endelseicon, text = cfg.monitoraggio.icon_nc, cfg.monitoraggio.text_ncendreturn 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 retif self.args.data thenlocal cat = string.format('Categoria:Voci monitorate - %s', self.args.data)if titleExists(cat) thenret = self.args.dataendendreturn 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) thenlocal 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() ..   categorieselsereturn (errmsg or '') ..   ProjectsTable:new(projects):getHTML() ..   table.concat(errcat)endendreturn p