PC Gaming Shelter
An archive dedicated to preserving PC Gaming history and more

Module:Utils

From PC Gaming Shelter
Revision as of 23:40, 23 March 2026 by WikiVisor (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Utils/doc

local p = {}

local function splitBy(str, sep)
	local t = {}
	for part in str:gmatch("[^" .. sep .. "]+") do
		table.insert(t, mw.text.trim(part))
	end
	return t
end

function p.setCategory(categoryString)
	if not categoryString then return end
	local category = string.format('[[Category:%s]]', categoryString)
	return category
end

function p.setShortDescription(description)
	if not description then return end
	local frame = mw.getCurrentFrame()
	local shortDescription = frame:preprocess(string.format('{{SHORTDESC:%s}}', description))
	return shortDescription
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


-- ------------------------------------------------------------------
-- |  p.createInfobox()
-- ------------------------------------------------------------------
-- Build an infobox from the template arguments that called this module.
--
-- Parameters
-- ----------
-- * frame      – The current Frame object.
-- * category   – 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()`.
-- * sections   - A plan of sections and properties.
--
-- Returns
-- -------
-- An `mw.html` object that contains:
--
--   * The main category (via `p.setCategory(cat)`),
--   * A fully populated infobox
--
-- The returned HTML is rendered directly into the page where the module
-- was invoked.
--------------------------------------------------------------------
local function isSectionNotEmpty(args, rows)
	for _, rowKey in pairs(rows) do
        if args[rowKey] ~= nil then
			return true
        end
    end
    return false
end

function p.createInfobox(frame, cat, properties, sections, footer)
    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)
    -- ShortDescription
    local shortDescription = p.setShortDescription(args['Description'])
    -- Assemble
    local html = mw.html.create()
    local infobox = html:tag('div'):addClass('infobox d-flex flex-column card shadow-none rounded-0 bg-transparent mb-4 float-sm-right')
    -- Sections
    for key, cfg in pairs(sections) do
    	if isSectionNotEmpty(args, cfg.rows) == true then
        local section = infobox:tag('div'):addClass('infobox-block'):css({
            ['order'] = cfg.order or '0'
        })
        -- Heading
        local heading = cfg.heading or nil
        if heading and heading ~= '' then
            section:tag('div'):addClass('infobox-section-header'):wikitext(heading)
        end
        -- Content
        local data = {}
        local dataProperties = cfg.rows or {}
        for k, v in pairs(dataProperties) do
            local value = args[v]
            if value then
                data[v] = value
            end
        end
        -- Renderer
        local template = tostring(cfg.template) or 'Infobox/Generic'
        local content = frame:expandTemplate{
            title = template,
            args = data
        }
        section:tag('div'):addClass('infobox-row d-flex flex-column'):wikitext(content)
        end
    end
    -- Footer
	if footer and footer ~= '' then
		local renderFooter = frame:expandTemplate {
			title = footer
		}
		html:tag('div'):addClass('page-footer bg-dark'):wikitext('\n' .. renderFooter)
	end
    return html
        :wikitext(category)
        :wikitext(shortDescription)
end

return p