Module:Utils: Difference between revisions
From PC Gaming Shelter
Created page with "local p = {} function p.createInfobox() end return p" |
No edit summary |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
function p. | function p.setCategory(categoryString) | ||
if not categoryString then return end | |||
local category = string.format('[[Category:%s]]', categoryString) | |||
return category | |||
end | |||
function p.setProperties(propMap, args) | |||
local props = {} | |||
for argName, def in pairs(propMap) do | |||
local val = args[argName] | |||
if val ~= nil then | |||
local propKey = def[1] | |||
local sep = def[2] or nil | |||
if type(val) == "string" and #def > 1 and sep == "file" then | |||
if val:find("^%w+:%s*") then | |||
val = val:gsub("^%w+:%s*", "") -- strip namespace, we add it later | |||
end | |||
val = string.format("File:%s", val) | |||
elseif type(val) == "string" and #def > 1 and sep then | |||
val = splitBy(val, sep) | |||
end | |||
props[propKey] = val | |||
end | |||
end | |||
return props | |||
end | |||
function p.infoboxSectionClasses() | |||
return { | |||
['onecolumn'] = 'infobox-section d-flex flex-column py-1 border rounded-0 p-2 mb-2', | |||
['twocolumns'] = 'infobox-section d-flex flex-column flex-sm-row border rounded-0 p-2 mb-2' | |||
} | |||
end | |||
-- ------------------------------------------------------------------ | |||
-- | p.createInfobox() | |||
-- ------------------------------------------------------------------ | |||
-- Build an infobox from the template arguments that called this module. | |||
-- | |||
-- Parameters | |||
-- ---------- | |||
-- * frame – The current Frame object. | |||
-- * cat – Main category string to add before the page content. | |||
-- * properties – A mapping of user‑argument names → SMW property keys | |||
-- (optionally followed by a separator). These are used | |||
-- to set SMW properties via `mw.smw.set()`. | |||
-- * order – An ordered list that defines the order in which | |||
-- sections appear inside the infobox. Each entry must | |||
-- match a key in `properties` or in the `infodata` | |||
-- table below. | |||
-- * subobjects - The table with names of templates responsible for subobjects creation | |||
-- The module expects the the parent template parameter name **is equal** | |||
-- to the name of the template: | |||
-- `...` | |||
-- `|TemplateName={{TemplateName|...}}{{TemplateName|...}}` | |||
-- Returns | |||
-- ------- | |||
-- An `mw.html` object that contains: | |||
-- | |||
-- * The main category (via `p.setCategory(cat)`), | |||
-- * A fully populated infobox `<div>` with sections in the order | |||
-- specified by **order** and styled according to **infodata**, | |||
-- | |||
-- The returned HTML is rendered directly into the page where the module | |||
-- was invoked. | |||
-------------------------------------------------------------------- | |||
function p.createInfobox(frame, category, properties, order, data, subobjects) | |||
local currentTitle = mw.title.getCurrentTitle().fullText | |||
local args = frame:getParent().args | |||
-- SMW properties | |||
local propMap = properties | |||
local props = p.setProperties(propMap, args) or {} | |||
mw.smw.set(props) | |||
-- Main category | |||
local category = p.setCategory(cat) | |||
-- Assemble | |||
local html = mw.html.create() | |||
-- Infobox | |||
local infoboxData = html:tag('div'):addClass('infobox d-flex flex-col card shadow-none rounded-0 bg-transparent mb-4 float-sm-end') | |||
-- Header | |||
infoboxData:tag('div') | |||
:addClass('infobox-header card-header border rounded-0 pt-0 px-2 mb-2 text-center text-uppercase') | |||
:tag('div'):wikitext(currentTitle) | |||
-- Cover image | |||
local coverImage = args['Image'] or nil | |||
if coverImage then | |||
infoboxData:tag('div') | |||
:addClass('infobox-img card-img border rounded-0 p-2') | |||
:wikitext(string.format('[[File:%s|560px|class=pageimage]]', coverImage)):done() | |||
end | |||
-- Other props | |||
local propOrder = order | |||
-- Infobox sections | |||
local sectionFormat = data | |||
-- Helper: Render the value | |||
local function renderValue(frame, key, rawValue, fmt) | |||
if fmt.template == 'render' then | |||
return frame:expandTemplate{ | |||
title = 'render', | |||
args = { | |||
string.format(fmt.value, rawValue), | |||
fmt.separator, | |||
fmt.valuefmt | |||
} | |||
} | |||
else | |||
return string.format(fmt.value, rawValue) | |||
end | |||
end | |||
-- Render infobox sections | |||
local number = 1 | |||
for _, key in ipairs(propOrder) do | |||
local rawValue = args[key] | |||
if rawValue then | |||
local fmt = sectionFormat[key] or { value = '%s' } | |||
local renderedLabel = string.format(fmt.label or '%s', key) | |||
local renderedValue = renderValue(frame, key, rawValue, fmt) | |||
infoboxData:tag('div'):css({order = number}):addClass(fmt.class) | |||
:tag('div'):addClass('infobox-label px-2'):wikitext(renderedLabel):done() | |||
:tag('div'):addClass('infobox-value px-2'):wikitext(renderedValue .. isImmediateLabel):done() | |||
number = number + 1 | |||
end | |||
end | |||
-- SMW subobjects | |||
if subobjects and #subobjects > 0 then | |||
for _, obj in ipairs(subobjects) do | |||
local key = obj.subobject | |||
local label = obj.label or key | |||
local subobjectData = args[key] | |||
if key and subobjectData then | |||
infoboxData:tag('div'):css({ ['order'] = '500'}) | |||
:addClass(p.infoboxSectionClasses()['twocolumns']) | |||
:tag('div'):addClass('infobox-label px-2') | |||
:wikitext(label) | |||
:done() | |||
:tag('div'):addClass('infobox-value px-1') | |||
:tag('ul'):wikitext(subobjectData):done() | |||
:done() | |||
end | |||
end | |||
end | |||
-- Printout | |||
html | |||
:wikitext(category) | |||
return html | |||
end | end | ||
return p | return p | ||
Revision as of 19:39, 22 March 2026
Documentation for this module may be created at Module:Utils/doc
local p = {}
function p.setCategory(categoryString)
if not categoryString then return end
local category = string.format('[[Category:%s]]', categoryString)
return category
end
function p.setProperties(propMap, args)
local props = {}
for argName, def in pairs(propMap) do
local val = args[argName]
if val ~= nil then
local propKey = def[1]
local sep = def[2] or nil
if type(val) == "string" and #def > 1 and sep == "file" then
if val:find("^%w+:%s*") then
val = val:gsub("^%w+:%s*", "") -- strip namespace, we add it later
end
val = string.format("File:%s", val)
elseif type(val) == "string" and #def > 1 and sep then
val = splitBy(val, sep)
end
props[propKey] = val
end
end
return props
end
function p.infoboxSectionClasses()
return {
['onecolumn'] = 'infobox-section d-flex flex-column py-1 border rounded-0 p-2 mb-2',
['twocolumns'] = 'infobox-section d-flex flex-column flex-sm-row border rounded-0 p-2 mb-2'
}
end
-- ------------------------------------------------------------------
-- | p.createInfobox()
-- ------------------------------------------------------------------
-- Build an infobox from the template arguments that called this module.
--
-- Parameters
-- ----------
-- * frame – The current Frame object.
-- * cat – Main category string to add before the page content.
-- * properties – A mapping of user‑argument names → SMW property keys
-- (optionally followed by a separator). These are used
-- to set SMW properties via `mw.smw.set()`.
-- * order – An ordered list that defines the order in which
-- sections appear inside the infobox. Each entry must
-- match a key in `properties` or in the `infodata`
-- table below.
-- * subobjects - The table with names of templates responsible for subobjects creation
-- The module expects the the parent template parameter name **is equal**
-- to the name of the template:
-- `...`
-- `|TemplateName={{TemplateName|...}}{{TemplateName|...}}`
-- Returns
-- -------
-- An `mw.html` object that contains:
--
-- * The main category (via `p.setCategory(cat)`),
-- * A fully populated infobox `<div>` with sections in the order
-- specified by **order** and styled according to **infodata**,
--
-- The returned HTML is rendered directly into the page where the module
-- was invoked.
--------------------------------------------------------------------
function p.createInfobox(frame, category, properties, order, data, subobjects)
local currentTitle = mw.title.getCurrentTitle().fullText
local args = frame:getParent().args
-- SMW properties
local propMap = properties
local props = p.setProperties(propMap, args) or {}
mw.smw.set(props)
-- Main category
local category = p.setCategory(cat)
-- Assemble
local html = mw.html.create()
-- Infobox
local infoboxData = html:tag('div'):addClass('infobox d-flex flex-col card shadow-none rounded-0 bg-transparent mb-4 float-sm-end')
-- Header
infoboxData:tag('div')
:addClass('infobox-header card-header border rounded-0 pt-0 px-2 mb-2 text-center text-uppercase')
:tag('div'):wikitext(currentTitle)
-- Cover image
local coverImage = args['Image'] or nil
if coverImage then
infoboxData:tag('div')
:addClass('infobox-img card-img border rounded-0 p-2')
:wikitext(string.format('[[File:%s|560px|class=pageimage]]', coverImage)):done()
end
-- Other props
local propOrder = order
-- Infobox sections
local sectionFormat = data
-- Helper: Render the value
local function renderValue(frame, key, rawValue, fmt)
if fmt.template == 'render' then
return frame:expandTemplate{
title = 'render',
args = {
string.format(fmt.value, rawValue),
fmt.separator,
fmt.valuefmt
}
}
else
return string.format(fmt.value, rawValue)
end
end
-- Render infobox sections
local number = 1
for _, key in ipairs(propOrder) do
local rawValue = args[key]
if rawValue then
local fmt = sectionFormat[key] or { value = '%s' }
local renderedLabel = string.format(fmt.label or '%s', key)
local renderedValue = renderValue(frame, key, rawValue, fmt)
infoboxData:tag('div'):css({order = number}):addClass(fmt.class)
:tag('div'):addClass('infobox-label px-2'):wikitext(renderedLabel):done()
:tag('div'):addClass('infobox-value px-2'):wikitext(renderedValue .. isImmediateLabel):done()
number = number + 1
end
end
-- SMW subobjects
if subobjects and #subobjects > 0 then
for _, obj in ipairs(subobjects) do
local key = obj.subobject
local label = obj.label or key
local subobjectData = args[key]
if key and subobjectData then
infoboxData:tag('div'):css({ ['order'] = '500'})
:addClass(p.infoboxSectionClasses()['twocolumns'])
:tag('div'):addClass('infobox-label px-2')
:wikitext(label)
:done()
:tag('div'):addClass('infobox-value px-1')
:tag('ul'):wikitext(subobjectData):done()
:done()
end
end
end
-- Printout
html
:wikitext(category)
return html
end
return p
