Module:Utils: Difference between revisions
From PC Gaming Shelter
No edit summary |
No edit summary |
||
| (28 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
function p.clean(value) | |||
if value == nil then | |||
return nil | |||
end | |||
value = mw.text.trim(tostring(value)) | |||
return value ~= '' and value or nil | |||
end | |||
local function splitBy(str, sep) | local function splitBy(str, sep) | ||
| Line 13: | Line 22: | ||
local category = string.format('[[Category:%s]]', categoryString) | local category = string.format('[[Category:%s]]', categoryString) | ||
return category | 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 | end | ||
| Line 36: | Line 52: | ||
end | end | ||
-- ------------------------------------------------------------------ | -- ------------------------------------------------------------------ | ||
| Line 79: | Line 61: | ||
-- ---------- | -- ---------- | ||
-- * frame – The current Frame object. | -- * 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 | -- * properties – A mapping of user‑argument names → SMW property keys | ||
-- (optionally followed by a separator). These are used | -- (optionally followed by a separator). These are used | ||
-- to set SMW properties via `mw.smw.set()`. | -- to set SMW properties via `mw.smw.set()`. | ||
-- * | -- * sections - A plan of sections and properties. | ||
- | -- | ||
-- | |||
-- Returns | -- Returns | ||
-- ------- | -- ------- | ||
| Line 97: | Line 72: | ||
-- | -- | ||
-- * The main category (via `p.setCategory(cat)`), | -- * The main category (via `p.setCategory(cat)`), | ||
-- * A fully populated infobox | -- * A fully populated infobox | ||
-- | -- | ||
-- The returned HTML is rendered directly into the page where the module | -- The returned HTML is rendered directly into the page where the module | ||
-- was invoked. | -- 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, | 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 | |||
function p.availablePropertyValues(property) | |||
property = mw.text.trim(tostring(property or '')) | |||
mw. | |||
if property == '' then | |||
return {}, { 'A property name is required.' } | |||
end | end | ||
local | local params = mw.text.jsonEncode({ | ||
limit = 1000, | |||
offset = 0, | |||
property = property, | |||
local | search = '', | ||
usageCount = true | |||
}) | |||
local query = mw.uri.buildQueryString({ | |||
action = 'smwbrowse', | |||
browse = 'pvalue', | |||
params = params, | |||
format = 'json' | |||
}) | |||
local url = string.format( | |||
'%s%s/api.php?%s', | |||
'https://www.pcgamingshelter.eu', | |||
'/w', | |||
query | |||
) | |||
local data, errors = mw.ext.externalData.getExternalData({ | |||
url = url, | |||
format = 'JSON' | |||
}) | |||
if errors or not data or not data.__json then | |||
return {}, errors or { 'ExternalData returned no JSON data.' } | |||
end | end | ||
local values = data.__json.query | |||
if type(values) ~= 'table' then | |||
return {}, { 'The SMW response does not contain a query array.' } | |||
end | end | ||
return | return values | ||
end | end | ||
return p | return p | ||
Latest revision as of 09:17, 30 July 2026
Documentation for this module may be created at Module:Utils/doc
local p = {}
function p.clean(value)
if value == nil then
return nil
end
value = mw.text.trim(tostring(value))
return value ~= '' and value or nil
end
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
function p.availablePropertyValues(property)
property = mw.text.trim(tostring(property or ''))
if property == '' then
return {}, { 'A property name is required.' }
end
local params = mw.text.jsonEncode({
limit = 1000,
offset = 0,
property = property,
search = '',
usageCount = true
})
local query = mw.uri.buildQueryString({
action = 'smwbrowse',
browse = 'pvalue',
params = params,
format = 'json'
})
local url = string.format(
'%s%s/api.php?%s',
'https://www.pcgamingshelter.eu',
'/w',
query
)
local data, errors = mw.ext.externalData.getExternalData({
url = url,
format = 'JSON'
})
if errors or not data or not data.__json then
return {}, errors or { 'ExternalData returned no JSON data.' }
end
local values = data.__json.query
if type(values) ~= 'table' then
return {}, { 'The SMW response does not contain a query array.' }
end
return values
end
return p
