![]() | This Lua module is used on
approximately 10,100,000 pages, or roughly 17% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
This module implements Template:Class, Template:Class/icon and Template:Class/colour.
Following are notes documenting the model for the class definition JSON.
DEFAULT
) and canonical class codes are, so far, strictly alphabetic (bplus
, not b+
)alias
that contains the canonical class code string.categoryRoot
FA-Class
.colour
#6699ff
base
textOnBlack
textOnWhite
icon
file
File:
prefix, preferably formatted with underscores,
[model 2] e.g. Featured_article_star.svg
default
requiresAttribution
true
if the file
property refers to a file that is not public domain or CC0-licensed. When a file is PD/CC0 and thus this property false
, we can disable image linking and alt text, which is good for accessibility for purely-decorative images.labels
adjective
full
short
Redirect
or GA
). One particular precedent imported to this property is that class code unassessed
uses ???
as its short label. This property is highly tentative.tooltip
page
Wikipedia:Featured articles
DEFAULT
object, using capitalization to separate it from other keys, defines defaults that can be used. This should either be a complete object (all properties mandatory) or an alias to a complete object. In English Wikipedia's case this is currently an alias to the unassessed
class definition.
-- This module implements [[Template:Class]], [[Template:Class/icon]] and
-- [[Template:Class/colour]].
local mArguments -- lazily loaded
local definitions = mw.loadJsonData('Module:Class/definition.json')
local p = {}
--------------------------------------------------------------------------------
-- Local configuration and messages
--------------------------------------------------------------------------------
local cfg = {
defaultCode = 'DEFAULT',
classPrefix = 'assess-',
globalClass = 'assess',
defaultClassSuffix = 'default',
unboldClassSuffix = 'unbold',
catRootFormat = '%s %s',
catTopicFormat = '%s %s articles',
catBasicFormat = '%s articles',
categoryFormat = '[[:Category:%s|%s]]',
templateLocation = 'Template:Class',
iconTemplateLocation = 'Template:Class/icon',
colourTemplateLocation = 'Template:Class/colour',
stylesLocation = 'Module:Class/styles.css',
baseColourPath = {'colour', 'base'},
iconPath = {"icon", "file"},
iconDefaultPath = {"icon", "default"},
iconAttribPath = {"icon", "requiresAttribution"},
fullLabelPath = {"labels", "full"},
shortLabelPath = {"labels", "short"},
categoryRootPath = {"categoryRoot"},
tooltipPath = {"labels", "tooltip"},
yes = "yes",
no = "no",
argumentNames = {
class = "class",
style = "style"
},
getOptions = {
--First item is localized argument name, second is case-sensitivity
bold = {"bold", false},
header = {"header", false},
image = {"image", false},
rowspan = {"rowspan", false},
fullcategory = {"fullcategory", true},
category = {"category", true},
topic = {"topic", true}
}
}
--------------------------------------------------------------------------------
-- 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 == cfg.defaultCode then canonicalCode = code end
local class = definitionscanonicalCode
while class and class.alias do
canonicalCode = class.alias
class = definitionsclass.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(cfg.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 propv
dProp = ((type(dProp) == 'table') or nil) and dPropv
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(), cfg.baseColourPath)
end
function p.colour(frame)
--Retrieves the base colour for a given code; is invokable
local args = getRawArgs(frame, cfg.colourTemplateLocation)
-- Nowiki tags prevent output beginning with "#" from triggering bug 14974.
return frame:extensionTag('nowiki', p._colour(args1]))
end
--------------------------------------------------------------------------------
-- Icon functions
--------------------------------------------------------------------------------
function p._icon(args)
--Retrieves an icon image and formats it as wikitext
local class = getDefinition(argscfg.argumentNames.class or args1])
local default = getDefault()
local file = getProperty(class, default, cfg.iconPath)
local label =
getProperty(class, default, cfg.tooltipPath) or
ucfirst(getProperty(class, default, cfg.fullLabelPath))
local attrib = getProperty(class, default, cfg.iconAttribPath)
local size = args.size or '16px'
local span = mw.html.create('span')
span
:cssText(argscfg.argumentNames.style])
:attr('title', label)
:wikitext(
string.format(
'[[File:%s|%s|' .. size .. '%s|class=noviewer|alt=]]',
file,
label,
attrib and '' or '|link='
)
)
return tostring(span)
end
p.icon = makeInvokeFunction(p._icon, cfg.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(argscfg.argumentNames.class or args1])
local default = getDefault()
local iconDefault = getProperty(classDef, default, cfg.iconDefaultPath)
local shortLabel = getProperty(classDef, default, cfg.shortLabelPath)
local categoryRoot = getProperty(classDef, default, cfg.categoryRootPath)
--o is short for "options", go for "get options". Bool true → case-sensitive
local o, go = {}, cfg.getOptions
for k, v in pairs(go) do
ok = v2 and trim(argsv1]]) or normalizeValue(argsv1]])
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 ~= cfg.no) or (o.image == cfg.yes)
icon = icon and p.icon(args) .. ' ' or ''
local category
if o.fullcategory then
category = o.fullcategory
elseif o.category then
category = string.format(cfg.catRootFormat, categoryRoot, o.category)
elseif o.topic then
category = string.format(cfg.catTopicFormat, categoryRoot, o.topic)
else
category = string.format(cfg.catBasicFormat, categoryRoot)
end
local text = string.format(cfg.categoryFormat, category, shortLabel)
cell
:addClass(cfg.globalClass)
:addClass(
o.bold == cfg.no and cfg.classPrefix .. cfg.unboldClassSuffix or nil
)
:addClass(cfg.classPrefix .. (classCode or cfg.defaultClassSuffix))
:attr('rowspan', tonumber(o.rowspan))
:wikitext(mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src = cfg.stylesLocation} }, icon, text)
return tostring(cell)
end
p.class = makeInvokeFunction(p._class, cfg.templateLocation)
--Invokable version of p._class
return p
![]() | This Lua module is used on
approximately 10,100,000 pages, or roughly 17% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
This module implements Template:Class, Template:Class/icon and Template:Class/colour.
Following are notes documenting the model for the class definition JSON.
DEFAULT
) and canonical class codes are, so far, strictly alphabetic (bplus
, not b+
)alias
that contains the canonical class code string.categoryRoot
FA-Class
.colour
#6699ff
base
textOnBlack
textOnWhite
icon
file
File:
prefix, preferably formatted with underscores,
[model 2] e.g. Featured_article_star.svg
default
requiresAttribution
true
if the file
property refers to a file that is not public domain or CC0-licensed. When a file is PD/CC0 and thus this property false
, we can disable image linking and alt text, which is good for accessibility for purely-decorative images.labels
adjective
full
short
Redirect
or GA
). One particular precedent imported to this property is that class code unassessed
uses ???
as its short label. This property is highly tentative.tooltip
page
Wikipedia:Featured articles
DEFAULT
object, using capitalization to separate it from other keys, defines defaults that can be used. This should either be a complete object (all properties mandatory) or an alias to a complete object. In English Wikipedia's case this is currently an alias to the unassessed
class definition.
-- This module implements [[Template:Class]], [[Template:Class/icon]] and
-- [[Template:Class/colour]].
local mArguments -- lazily loaded
local definitions = mw.loadJsonData('Module:Class/definition.json')
local p = {}
--------------------------------------------------------------------------------
-- Local configuration and messages
--------------------------------------------------------------------------------
local cfg = {
defaultCode = 'DEFAULT',
classPrefix = 'assess-',
globalClass = 'assess',
defaultClassSuffix = 'default',
unboldClassSuffix = 'unbold',
catRootFormat = '%s %s',
catTopicFormat = '%s %s articles',
catBasicFormat = '%s articles',
categoryFormat = '[[:Category:%s|%s]]',
templateLocation = 'Template:Class',
iconTemplateLocation = 'Template:Class/icon',
colourTemplateLocation = 'Template:Class/colour',
stylesLocation = 'Module:Class/styles.css',
baseColourPath = {'colour', 'base'},
iconPath = {"icon", "file"},
iconDefaultPath = {"icon", "default"},
iconAttribPath = {"icon", "requiresAttribution"},
fullLabelPath = {"labels", "full"},
shortLabelPath = {"labels", "short"},
categoryRootPath = {"categoryRoot"},
tooltipPath = {"labels", "tooltip"},
yes = "yes",
no = "no",
argumentNames = {
class = "class",
style = "style"
},
getOptions = {
--First item is localized argument name, second is case-sensitivity
bold = {"bold", false},
header = {"header", false},
image = {"image", false},
rowspan = {"rowspan", false},
fullcategory = {"fullcategory", true},
category = {"category", true},
topic = {"topic", true}
}
}
--------------------------------------------------------------------------------
-- 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 == cfg.defaultCode then canonicalCode = code end
local class = definitionscanonicalCode
while class and class.alias do
canonicalCode = class.alias
class = definitionsclass.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(cfg.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 propv
dProp = ((type(dProp) == 'table') or nil) and dPropv
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(), cfg.baseColourPath)
end
function p.colour(frame)
--Retrieves the base colour for a given code; is invokable
local args = getRawArgs(frame, cfg.colourTemplateLocation)
-- Nowiki tags prevent output beginning with "#" from triggering bug 14974.
return frame:extensionTag('nowiki', p._colour(args1]))
end
--------------------------------------------------------------------------------
-- Icon functions
--------------------------------------------------------------------------------
function p._icon(args)
--Retrieves an icon image and formats it as wikitext
local class = getDefinition(argscfg.argumentNames.class or args1])
local default = getDefault()
local file = getProperty(class, default, cfg.iconPath)
local label =
getProperty(class, default, cfg.tooltipPath) or
ucfirst(getProperty(class, default, cfg.fullLabelPath))
local attrib = getProperty(class, default, cfg.iconAttribPath)
local size = args.size or '16px'
local span = mw.html.create('span')
span
:cssText(argscfg.argumentNames.style])
:attr('title', label)
:wikitext(
string.format(
'[[File:%s|%s|' .. size .. '%s|class=noviewer|alt=]]',
file,
label,
attrib and '' or '|link='
)
)
return tostring(span)
end
p.icon = makeInvokeFunction(p._icon, cfg.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(argscfg.argumentNames.class or args1])
local default = getDefault()
local iconDefault = getProperty(classDef, default, cfg.iconDefaultPath)
local shortLabel = getProperty(classDef, default, cfg.shortLabelPath)
local categoryRoot = getProperty(classDef, default, cfg.categoryRootPath)
--o is short for "options", go for "get options". Bool true → case-sensitive
local o, go = {}, cfg.getOptions
for k, v in pairs(go) do
ok = v2 and trim(argsv1]]) or normalizeValue(argsv1]])
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 ~= cfg.no) or (o.image == cfg.yes)
icon = icon and p.icon(args) .. ' ' or ''
local category
if o.fullcategory then
category = o.fullcategory
elseif o.category then
category = string.format(cfg.catRootFormat, categoryRoot, o.category)
elseif o.topic then
category = string.format(cfg.catTopicFormat, categoryRoot, o.topic)
else
category = string.format(cfg.catBasicFormat, categoryRoot)
end
local text = string.format(cfg.categoryFormat, category, shortLabel)
cell
:addClass(cfg.globalClass)
:addClass(
o.bold == cfg.no and cfg.classPrefix .. cfg.unboldClassSuffix or nil
)
:addClass(cfg.classPrefix .. (classCode or cfg.defaultClassSuffix))
:attr('rowspan', tonumber(o.rowspan))
:wikitext(mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = {src = cfg.stylesLocation} }, icon, text)
return tostring(cell)
end
p.class = makeInvokeFunction(p._class, cfg.templateLocation)
--Invokable version of p._class
return p