Modulo:Navbox
Da Destiny One.
Versione del 1 ago 2015 alle 18:44 di Rotpunkt (Discussione) (non è efficiente iterare su tutta la table per ogni parametro listN/groupN del modulo, fix ripetizione funzione getListIds/getIds)
La documentazione per questo modulo può essere creata in Modulo:Navbox/man
--[[ * Modulo per implementare le funzionalità dei template Navbox e Navbox_subgroup. * Costruisce un template di navigazione basato su una table HTML. ]] require('Modulo:No globals') local getArgs = require('Modulo:Arguments').getArgs -- Configurazione local cfg = mw.loadData('Modulo:Navbox/Configurazione') ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna true se il nome dell'argomento è valido local function isValidArg(name, validArgs, maxList) local ret = validArgs[name] ~= nil if not ret then local id = name:match('^list(%d+)$') or name:match('^group(%d+)$') or name:match('^list(%d+)style$') or name:match('^group(%d+)style$') if id then ret = tonumber(id) <= maxList end end return ret end -- Ritorna gli argomenti passati al modulo, scartando quelli senza nome, -- quelli contenenti stringhe vuote e i non riconosciuti. local function parseArgs(args, isSubgroup) local ret = {} local validArgs = isSubgroup and cfg.subgroupArgs or cfg.navboxArgs local maxList = isSubgroup and cfg.subgroupMaxList or cfg.navboxMaxList for k, v in pairs(args) do if type(k) == 'string' and v ~= '' and isValidArg(k, validArgs, maxList) then ret[k] = v end end return ret end -- Ritorna una sequence contenente gli ID dei listN presenti, ordinata e senza duplicati. -- Se withGroup è true, controlla anche i groupN. local function getIds(args, withGroup) local ids = {} local ret = {} -- siccome Lua ha solo le table e non i set (elementi unici), prima popola ids usando le chiavi for k, _ in pairs(args) do local id = k:match('^list(%d+)$') or (withGroup and k:match('^group(%d+)$')) if id then ids[tonumber(id)] = 1 end end -- quindi ritorna una sequence fatta delle chiavi della table ids for k, _ in pairs(ids) do table.insert(ret, k) end table.sort(ret) return ret end -- Toglie eventuali spazi/a capo dannosi attorno ai {{,}} local function trimSep(list) local sep = mw.getCurrentFrame():expandTemplate{title=","} local sepEsc = mw.ustring.gsub(sep, '-', '%-') return mw.ustring.gsub(list, '%s*' .. sepEsc .. '%s*', sep) end -- Con il debug ridefinisce il metodo mw.html:css, -- permettendo di eseguire i test senza controllare anche i css. local function disableCSS(tableNode) local mt = getmetatable(tableNode) mt.__index.css = function(t, name, val) return t end end ------------------------------------------------------------------------------- -- classe Navbox ------------------------------------------------------------------------------- local Navbox = {} function Navbox:new(args) local self = {} local thNode local thStyle = { ['text-align'] = 'center', width = '100%', background = '#ccf', ['font-size'] = '90%' } setmetatable(self, { __index = Navbox }) self.args = args -- costruzione table self.tableNode = mw.html.create('table') if self.args.debug then disableCSS(self.tableNode) end self:_setupTableNode() -- prima row: contiene la navbar e il titolo thNode = self.tableNode:tag('tr') :tag('th') :attr('colspan', self.args.image and '3' or '2') :css(thStyle) :cssText(self.args.titlestyle) if self.args.navbar ~= 'plain' then self:_addTnavbar(thNode) end if self.args.title then self:_addTitle(thNode) end -- eventuale row per l'above if self.args.above then self:_addAboveOrBelow(self.args.above, self.args.abovestyle) end -- altre row self:_addLists() -- eventuale row finale per il below if self.args.below then self:_addAboveOrBelow(self.args.below, self.args.belowstyle) end return self end function Navbox:getHTML() return tostring(self.tableNode) end function Navbox:_setupTableNode() local tableStyle = { margin = 'auto', width = '100%', clear = 'both', border = '1px solid #aaa', padding = '2px' } self.tableNode :addClass('navbox') :addClass('mw-collapsible') :addClass(self.args.state == 'collapsed' and 'mw-collapsed' or (self.args.state == 'autocollapse' and 'autocollapse' or (not self.args.state and 'autocollapse' or nil))) :addClass('nowraplinks') :addClass('noprint') :addClass('metadata') :css(tableStyle) :cssText(self.args.style) :cssText(self.args.bodystyle) end function Navbox:_addTnavbar(node) local divStyle = { float = 'left', width = '6em', ['text-align'] = 'left', padding = '0 10px 0 0', margin = '0px' } local tnavbar = mw.getCurrentFrame():expandTemplate { title = 'Tnavbar', args = { [1] = self.args.name, ['mini'] = 1 } } node:tag('div'):css(divStyle):wikitext(tnavbar) end function Navbox:_addTitle(node) node:tag('span'):css('font-size', '110%'):wikitext(self.args.title) end function Navbox:_addAboveOrBelow(arg, argStyle) local tdStyle = { background = '#ddf', ['text-align'] = 'center', ['font-size'] = '90%' } self.tableNode :tag('tr') :tag('td') :attr('colspan', self.args.image and '3' or '2') :css(tdStyle) :cssText(argStyle) :wikitext(arg) end function Navbox:_addImage(trNode, rowspan) local tdStyle = { ['vertical-align'] = 'middle', ['padding-left'] = '7px', width = '0%' } trNode :tag('td') :attr('rowspan', rowspan) :css(tdStyle) :cssText(self.args.imagestyle) :wikitext(self.args.image) end function Navbox:_addLists() local rowIds, altStyle, altBackground local thStyle = { background = '#ddf', ['white-space'] = 'nowrap', padding = '0 10px', ['font-size'] = '90%' } -- crea una riga per ogni groupN/listN rowIds = getIds(self.args, true) for _, id in ipairs(rowIds) do local trNode = self.tableNode:tag('tr') -- groupN if self.args['group' .. id] then trNode:tag('th') :attr('colspan', self.args['list' .. id] and '1' or '2') :css(thStyle) :cssText(self.args.groupstyle) :cssText(self.args['group' .. id .. 'style']) :wikitext(self.args['group' .. id]) end -- listN if self.args['list' .. id] then local list = trimSep(self.args['list' .. id]) if (id % 2) == 0 then altStyle = self.args.evenstyle altBackground = '#f7f7f7' else altStyle = self.args.oddstyle altBackground = nil end trNode:tag('td') :attr('colspan', self.args['group' .. id] and '1' or '2') :css('width', '100%') :css('font-size', '90%') :css('text-align', self.args['group' .. id] and 'left' or 'center') :css('background', altBackground) :cssText(self.args.liststyle) :cssText(altStyle) :cssText(self.args['list' .. id .. 'style']) :wikitext(list) end if id == 1 and self.args.image then self:_addImage(trNode, #rowIds) end end end ------------------------------------------------------------------------------- -- classe NavboxSubgroup ------------------------------------------------------------------------------- local NavboxSubgroup = {} function NavboxSubgroup:new(args) local self = {} setmetatable(self, { __index = NavboxSubgroup }) self.args = args -- costruzione table self.tableNode = mw.html.create('table') if self.args.debug then disableCSS(self.tableNode) end self:_setupTableNode() self:_addLists() return self end function NavboxSubgroup:getHTML() return tostring(self.tableNode) end function NavboxSubgroup:_setupTableNode() local tableStyle = { background = 'transparent', ['font-size'] = '100%', padding = '0', border = '0', margin = '-3px', width = '100%' } self.tableNode :addClass('navbox') :addClass('nowraplinks') :css(tableStyle) :cssText(self.args.bodystyle) end function NavboxSubgroup:_addLists() local listIds, altStyle local thStyle = { background = '#ddf', padding = '0 10px', } -- crea una row per ogni listN listIds = getIds(self.args) for _, id in ipairs(listIds) do local trNode = self.tableNode:tag('tr') local list = trimSep(self.args['list' .. id]) -- i groupN sono visibili solo se c'è la corrispettiva listN if self.args['group' .. id] then trNode:tag('th') :css(thStyle) :cssText(self.args.groupstyle) :wikitext(self.args['group' .. id]) end if (id % 2) == 0 then altStyle = self.args.evenstyle else altStyle = self.args.oddstyle end trNode:tag('td') :attr('colspan', self.args['group' .. id] and '1' or '2') :css('text-align', self.args['group' .. id] and 'left' or 'center') :cssText(self.args.liststyle) :cssText(altStyle) :wikitext(list) end end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- local p = {} function p._navbox(args) return Navbox:new(parseArgs(args)):getHTML() end function p._navbox_subgroup(args) return NavboxSubgroup:new(parseArgs(args, true)):getHTML() end -- Entry-point per {{Navbox}} function p.navbox(frame) return p._navbox(getArgs(frame, {wrappers = 'Template:Navbox'})) end -- Entry-point per {{Navbox subgroup}} function p.navbox_subgroup(frame) return p._navbox_subgroup(getArgs(frame, {wrappers = 'Template:Navbox subgroup'})) end return p