m (Changed protection settings for "Module:Class": To match cascading protection on parent Template:Class ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))) |
m (1 revision imported) |
Latest revision as of 20:50, 26 July 2022
Documentation for this module may be created at Module:Class/doc
-- This module implements [[Template:Class]], [[Template:Class/icon]] and
-- [[Template:Class/colour]].
local mArguments -- lazily loaded
local configuration = mw.loadData('Module:Class/configuration')
local definitions = configuration.definitions
local msg = configuration.messages
local p = {}
--------------------------------------------------------------------------------
-- Argument helper functions
--------------------------------------------------------------------------------
local function getRawArgs(frame, wrapper)
--Retrieves the arguments from the frame
mArguments = mArguments or require('Module:Arguments')
return mArguments.getArgs(frame, {
wrappers = wrapper,
trim = false,
removeBlanks = false
})
end
local function makeInvokeFunction(func, wrapper)
--Wraps a general function into an invokable version
return function (frame)
local args = getRawArgs(frame, wrapper)
return func(args)
end
end
--------------------------------------------------------------------------------
-- String helper functions
--------------------------------------------------------------------------------
local function trim(str)
--Trims strings, passes through non-strings without modification
return (type(str) == 'string') and mw.text.trim(str) or str
end
local function normalizeValue(val)
--Normalizes strings, particularly class codes
if type(val) == 'string' then val = trim(val):lower() end
if val == '' then val = nil end
return val
end
local function ucfirst(str)
--Capitalizes the first character of a string
return mw.ustring.upper(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str, 2)
end
--------------------------------------------------------------------------------
-- Definition helper functions
--------------------------------------------------------------------------------
local function getDefinition(code)
--Retrieves the definition and canonical class code for a given code.
--Returns two values: the definition object and the canonical class code
--string.
local canonicalCode = normalizeValue(code)
if code == msg.defaultCode then canonicalCode = code end
local class = definitions[canonicalCode]
while class and class.alias do
canonicalCode = class.alias
class = definitions[class.alias]
end
if not class then
return nil, nil
end
return class, canonicalCode
end
local function getDefault()
--Shortcut function for retrieving the default definition
return getDefinition(msg.defaultCode) end
local function getProperty(class, default, map)
--Retrieves a given property from a string given a class definition, a
--default class definition, and a map for the path to traverse through the
--class object. The map should be a sequential table of string property
--names, e.g. {"colour", "base"} would retrieve someClass.colour.base
local prop, dProp = class, default
for k, v in ipairs(map) do
prop = ((type(prop) == 'table') or nil) and prop[v]
dProp = ((type(dProp) == 'table') or nil) and dProp[v]
end
if prop == nil then prop = dProp end
return prop
end
--------------------------------------------------------------------------------
-- Color functions
--------------------------------------------------------------------------------
function p._colour(code)
--Retrieves the base colour for a given code
return getProperty(getDefinition(code), getDefault(), msg.baseColourPath)
end
function p.colour(frame)
--Retrieves the base colour for a given code; is invokable
local args = getRawArgs(frame, msg.colourTemplateLocation)
-- Nowiki tags prevent output beginning with "#" from triggering bug 14974.
return frame:extensionTag('nowiki', p._colour(args[1]))
end
--------------------------------------------------------------------------------
-- Icon functions
--------------------------------------------------------------------------------
function p._icon(args)
--Retrieves an icon image and formats it as wikitext
local class = getDefinition(args[msg.argumentNames.class] or args[1])
local default = getDefault()
local file = getProperty(class, default, msg.iconPath)
local label =
getProperty(class, default, msg.tooltipPath) or
ucfirst(getProperty(class, default, msg.fullLabelPath))
local attrib = getProperty(class, default, msg.iconAttribPath)
local span = mw.html.create('span')
span
:cssText(args[msg.argumentNames.style])
:attr('title', label)
:wikitext(
string.format(
'[[File:%s|%s|16px%s|class=noviewer|alt=]]',
file,
label,
attrib and '' or '|link='
)
)
return tostring(span)
end
p.icon = makeInvokeFunction(p._icon, msg.iconTemplateLocation)
--Invokable version of p._icon
--------------------------------------------------------------------------------
-- Class functions
--------------------------------------------------------------------------------
function p._class(args)
--Parses its arguments into a table cell with an optional icon, a name
--linked to an appropriate category, and appropriate colour styling
local classDef, classCode =
getDefinition(args[msg.argumentNames.class] or args[1])
local default = getDefault()
local iconDefault = getProperty(classDef, default, msg.iconDefaultPath)
local shortLabel = getProperty(classDef, default, msg.shortLabelPath)
local categoryRoot = getProperty(classDef, default, msg.categoryRootPath)
--o is short for "options", go for "get options". Bool true → case-sensitive
local o, go = {}, msg.getOptions
for k, v in pairs(go) do
o[k] = v[2] and trim(args[v[1]]) or normalizeValue(args[v[1]])
end
local cell = mw.html.create(o.header and 'th' or 'td')
--image=yes forces icon, image=no disables it, otherwise checks default
local icon = iconDefault and (o.image ~= msg.no) or (o.image == msg.yes)
icon = icon and p.icon(args) .. ' ' or ''
local category
if o.fullcategory then
category = o.fullcategory
elseif o.category then
category = string.format(msg.catRootFormat, categoryRoot, o.category)
elseif o.topic then
category = string.format(msg.catTopicFormat, categoryRoot, o.topic)
else
category = string.format(msg.catBasicFormat, categoryRoot)
end
local text = string.format(msg.categoryFormat, category, shortLabel)
cell
:addClass(msg.globalClass)
:addClass(
o.bold == msg.no and msg.classPrefix .. msg.unboldClassSuffix or nil
)
:addClass(msg.classPrefix .. (classCode or msg.defaultClassSuffix))
:attr('rowspan', tonumber(o.rowspan))
:wikitext(icon, text)
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = {src = msg.stylesLocation}
} .. tostring(cell)
end
p.class = makeInvokeFunction(p._class, msg.templateLocation)
--Invokable version of p._class
return p