Module:UKB
Appearance
Functionality for {{UKB criterion}}
[edit]Code | Result |
---|---|
{{#invoke:UKB|criterion|new}}
|
is created during the contest |
{{#invoke:UKB|criterion|new|redirects=true}}
|
is created during the contest (including redirects) |
{{#invoke:UKB|criterion|existing}}
|
was created before the contest started |
{{#invoke:UKB|criterion|bytes|1000}}
|
expanded by at least 1000 bytes |
{{#invoke:UKB|criterion|namespaces|0|10}}
|
is in one of the following namespaces: article or template |
{{#invoke:UKB|criterion|namespaces|0|10|site=www.wikidata.org}}
|
is in one of the following namespaces: article or template in www.wikidata.org |
{{#invoke:UKB|criterion|namespaces|0}}
|
is an article |
{{#invoke:UKB|criterion|backlinks|List of Presidents of Egypt}}
|
linked from List of Presidents of Egypt |
{{#invoke:UKB|criterion|forwardlinks|Bergen}}
|
links to Bergen |
{{#invoke:UKB|criterion|templates|Copy edit}}
|
tagged with {{Copy edit}} |
{{#invoke:UKB|criterion|templates|Citation needed|Unreferenced}}
|
tagged with {{Citation needed}} or {{Unreferenced}} |
{{#invoke:UKB|criterion|categories|Iceland}}
|
is in the category Iceland |
{{#invoke:UKB|criterion|categories|Iceland|nn:Island|se:Islánda}}
|
is in at least one of these categories: Iceland, Island or Islánda |
{{#invoke:UKB|criterion|categories|Apes|ignore=Humans,Hominidaes in fiction}}
|
is in the category Apes, except for Humans or Hominidaes in fiction |
{{#invoke:UKB|criterion|pages|Iceland|Greenland}}
|
Iceland or Greenland |
{{#invoke:UKB|criterion|sparql|query=?item wdt:P31 wd:Q146. }}
|
té un ítem a Wikidata que encaixa amb aquesta consulta SPARQL |
{{#invoke:UKB|criterion|sparql|query=?item wdt:P31 wd:Q146. |description=about cats }}
|
about cats (Wikidata query) |
If the generated text isn't suitable, it can be overriden using |description=
:
Code | Result |
---|---|
{{#invoke:UKB|criterion|namespaces|0|10|description=in the main namespace}}
|
in the main namespace |
Functionality for {{UKB points}}
[edit]Code | Result |
---|---|
{{#invoke:UKB|rule|new|20}}
|
You get 20 points for creating a new page (except for redirects) |
{{#invoke:UKB|rule|redirect|1}}
|
You get 1 point for creating a new redirect |
{{#invoke:UKB|rule|qualified|2}}
|
"qualified" is not a valid point rule |
{{#invoke:UKB|rule|edit|1}}
|
You get 1 point per edit |
{{#invoke:UKB|rule|byte|0.1}}
|
You get 0.1 points per byte added |
{{#invoke:UKB|rule|byte|1|max=100}}
|
You get 1 point per byte added, but a maximum of 100 points per page |
{{#invoke:UKB|rule|bytebonus|20|3000}}
|
You get 20 bonus points when more than 3000 bytes are added to a page |
{{#invoke:UKB|rule|word|3}}
|
You get 3 points per word added to the content (words in templates, tables etc. don't count) |
{{#invoke:UKB|rule|word|3|max=100}}
|
You get 3 points per word added to the content (words in templates, tables etc. don't count), but a maximum of 100 points per page |
{{#invoke:UKB|rule|wordbonus|20|3000}}
|
You get 20 bonus points when more than 3000 words are added to a page |
{{#invoke:UKB|rule|image|3}}
|
You get 3 points per image added |
{{#invoke:UKB|rule|image|3|max=100}}
|
You get 3 points per image added, but a maximum of 100 points per page |
{{#invoke:UKB|rule|image|3|max=100|ownimage=10}}
|
You get 3 points per image added (10 points for images you upload), but a maximum of 100 points per page |
{{#invoke:UKB|rule|image|3|max=100|ownimage=10|initialimagelimit=0}}
|
You get 3 points per image added to pages that had a maximum of 0 images before (10 points for images you upload), but a maximum of 100 points per page |
{{#invoke:UKB|rule|ref|3|1}}
|
You get 3 points per added reference, and 1 point per re-use of existing references |
{{#invoke:UKB|rule|ref|3|1|max=100}}
|
You get 3 points per added reference, and 1 point per re-use of existing references, but a maximum of 100 points per page |
{{#invoke:UKB|rule|templateremoval|10|Citation needed|Unreferenced}}
|
You get 10 points for removing {{Citation needed}} or {{Unreferenced}} |
{{#invoke:UKB|rule|exlink|3}}
|
You get 3 points for adding an external link |
{{#invoke:UKB|rule|exlink|2|max=10}}
|
You get 2 points for adding an external link, but a maximum of 10 points per page |
{{#invoke:UKB|rule|wikidata|2|properties=P18,P2096}}
|
You get 2 points for adding P18 or P2096 to items that didn't already have this |
{{#invoke:UKB|rule|wikidata|2|properties=P569|require_reference=yes}}
|
You get 2 points for adding P569 to items that didn't already have this |
{{#invoke:UKB|rule|wikidata|2|max=10|properties=P569|all=yes}}
|
You get 2 points per P569 added, but a maximum of 10 points per page |
{{#invoke:UKB|rule|wikidata|2|labels=nb,nn,se}}
|
You get 2 points for adding Wikidata label (nb, nn or se) to items that didn't already have this |
{{#invoke:UKB|rule|wikidata|2|aliases=nb,nn,se}}
|
You get 2 points for adding Wikidata alias (nb, nn or se) to items that didn't already have this |
{{#invoke:UKB|rule|wikidata|2|descriptions=nb,nn,se}}
|
You get 2 points for adding Wikidata description (nb, nn or se) to items that didn't already have this |
-------------------------------------------------------
-- This module is copied from the master version in --
-- [[no:Module:UKB]]. Do not change it on this wiki, --
-- but propose changes in the master module instead. --
-------------------------------------------------------
-- The module is used by [[User:UKBot]] for --
-- organizing editing contests on Wikipedia. --
-- See https://github.com/WikimediaNorge/UKBot/ for --
-- the bot's code, and contribution. --
-------------------------------------------------------
-- Copied from version:
-- https://no.wikipedia.org/w/index.php?title=Modul:UKB&oldid=25078992
require('strict')
local p = {}
local TNT = require('Module:TNT')
local I18NDATASET = 'I18n/UKB.tab'
local getArgs = require('Module:Arguments').getArgs
--- Get a localized message.
-- @param key The message key
-- @param ... Parameters to be passed to the message ($1, $2, etc.)
-- @return localized string
local function msg( key, ... )
return TNT.format( I18NDATASET, key, ... )
end
--- Reverse a mapping to get a list of localized names => canonical names
-- @param mapping A table containing key-value pairs where the key is the canonical name and the value is an array table of aliases
-- @return A table of localized names => canonical names
local function mappingReverser(mapping)
local ret = {}
for canonical, synonyms in pairs(mapping) do
for _, synonym in ipairs(synonyms) do
ret[synonym] = canonical
end
local keyIsPresent, translations = pcall(msg, 'arg-' .. canonical)
if keyIsPresent then
translations = mw.text.split(translations, '|')
for _, translation in ipairs(translations) do
ret[translation] = canonical
end
end
end
return ret
end
--- Get the argument mapping for a type of item
-- @param itemType The mapping subtype to get. Either 'criteria' or 'rules'
-- @param returnType Which mapping to get; 'canonical' or 'translated'
-- @return A table of mappings
local function getArgumentMapping(itemType, returnType)
-- if a new argument is added, it should also be added to the i18n module
-- in [[c:Data:I18n/UKB.tab]]
local argumentMapping = {
['criteria'] = {
['backlinks'] = { 'backlink' },
['bytes'] = { 'byte' },
['categories'] = { 'category' },
['forwardlinks'] = { 'forwardlink' },
['new'] = {},
['existing'] = {},
['namespaces'] = { 'namespace' },
['pages'] = { 'page' },
['sparql'] = {},
['stub'] = {}, -- deprecated, not in i18n
['templates'] = { 'template' }
},
['rules'] = {
['bytes'] = { 'byte' },
['bytebonus'] = {},
['categoryremoval'] = {},
['edit'] = {},
['eligiblepage'] = {},
['extlink'] = { 'exlink', 'externallink' },
['image'] = { 'images' },
['listbyte'] = { 'listbytes' },
['newpage'] = {},
['newredirect'] = {},
['reference'] = { 'ref' },
['section'] = {},
['templateremoval'] = {},
['wikidata'] = {},
['word'] = { 'words' },
['wordbonus'] = {}
},
['modifiers'] = {
['aliases'] = {},
['all'] = {},
['description'] = {},
['descriptions'] = {},
['distinct'] = {},
['ignore'] = {},
['initialimagelimit'] = {},
['labels'] = {},
['max'] = {},
['ownimage'] = {},
['properties'] = {},
['query'] = {},
['requirereference'] = { 'require reference', 'require_reference' },
['redirects'] = { 'redirect' },
['site'] = {},
}
}
if returnType == 'canonical' then
return argumentMapping[itemType]
end
local translatedMap = {
['criteria'] = mappingReverser(argumentMapping.criteria),
['rules'] = mappingReverser(argumentMapping.rules),
['modifiers'] = mappingReverser(argumentMapping.modifiers)
}
return translatedMap[itemType]
end
--[ Helper methods ] ------------------------------------------------------------------
--- Make an error string
-- @tparam string text Text to be wrapped in an error class
-- @treturn string The text wrapped in an error class
local function makeErrorString(text)
local html = mw.html.create('strong')
:addClass('error')
:wikitext(text)
return tostring(html)
end
--- Get an error string
-- @tparam string key A message key (from i18n)
-- @tparam string arg An argument to pass along to the message function
-- @treturn string An error message
local function getErrorString(key, arg)
return makeErrorString(msg(key, arg))
end
--- Parse and translate anonymous and named arguments
-- @tparam table frame A frame object
-- @tparam string|nil itemType An item type to return ('criteria', 'rules' or nil)
-- @treturn table A table of anonymous arguments (args)
-- @treturn table A table of named arguments (kwargs)
local function parseArgs(frame, itemType, translate)
local args = {}
local kwargs = {}
local canonicalMap = getArgumentMapping(itemType, 'translated')
if itemType == nil then
canonicalMap = {}
end
local kwargsMap = getArgumentMapping('modifiers', 'translated')
for k, v in pairs(getArgs(frame)) do
v = mw.text.trim(frame:preprocess(v))
if v ~= '' then
if type(k) == 'number' then
if k == 1 and canonicalMap[v] ~= nil and translate then
args[1] = canonicalMap[v]
else
args[k] = v
end
else
if kwargsMap[k] ~= nil and translate then
kwargs[kwargsMap[k]] = v
else
kwargs[k] = v
end
end
end
end
return args, kwargs
end
--- Turn an array table into a string in list form
-- @tparam table items An array of items
-- @tparam string itemType Maybe unnecessary?
-- @tparam string word The strings 'or' or 'and' (representing i18n message keys)
-- @treturn string A string with the table returned as a list
local function listify(items, itemType, word)
word = word or 'or'
if #items == 0 then
return getErrorString('anon-argument-missing', itemType)
end
if #items == 1 then
return items[1]
end
return mw.text.listToText(items, ', ', ' ' .. msg(word) .. ' ' )
end
--- Get link data for a link to a page in a specific namespace
-- @tparam table frame A frame object
-- @tparam string ns A canonical (English) namespace name; 'Template' and 'Category' supported
-- @tparam string page A page name
-- @treturn table A table containing: language code, link target and page name
local function makeNsLink(frame, ns, page)
local linkTarget
local nsNumbers = {
['Template'] = 10,
['Category'] = 14
}
local lang, pageName = mw.ustring.match(page, '^([a-z]+):(.+)$') -- FIXME: Better language code detection
if lang then
-- English namespace name is guaranteed to work, avoids need to maintain
-- lists of namespace names in the module
linkTarget = mw.ustring.format(':%s:%s:%s', lang, ns, pageName)
else
linkTarget = mw.ustring.format(':%s:%s', frame:callParserFunction('ns', nsNumbers[ns]), page)
end
return {
['lang'] = lang,
['linkTarget'] = linkTarget,
['pageName'] = pageName or page
}
end
--- Make a link to a single template, wrapped in curly brace syntax
-- @tparam table frame A frame object
-- @tparam template Name of a template (optionally with an interlanguage prefix)
-- @treturn string An HTML string linking to the template in question
local function makeTemplateLink(frame, template)
local nsLink = makeNsLink(frame, 'Template', template)
local wikitext = mw.text.nowiki('{{') .. mw.ustring.format('[[%s|%s]]', nsLink['linkTarget'], nsLink['pageName']) .. mw.text.nowiki('}}')
local html = mw.html.create('span')
:addClass('template-link')
:css('font-family', 'monospace,monospace')
:wikitext(wikitext)
return tostring(html)
end
--- Make a link to a single category
-- @tparam table frame A frame object
-- @tparam category Name of a category (optionally with an interlanguage prefix)
-- @treturn string An HTML string linking to the category in question
local function makeCategoryLink(frame, category)
local nsLink = makeNsLink(frame, 'Category', category)
return mw.ustring.format('[[%s|%s]]', nsLink['linkTarget'], nsLink['pageName'])
end
--- Make a list of templates
-- @tparam table frame A frame object
-- @tparam table args An array of template names (optionally with interlanguage prefixes)
-- @treturn table A table of template links
local function makeTemplateList(frame, args)
local templates = {}
for i, v in ipairs(args) do
table.insert(templates, makeTemplateLink(frame, v))
end
setmetatable(templates, {
__tostring = function(self)
return listify(templates, 'templates')
end
})
return templates
end
--- Make a list of categories
-- @tparam table frame A frame object
-- @tparam table args An array of category names (optionally with interlanguage prefixes)
-- @treturn table A table of category links
local function makeCategoryList(frame, args)
local categories = {}
for i, v in ipairs(args) do
v = mw.text.trim(v)
if v ~= '' then
table.insert(categories, makeCategoryLink(frame, v))
end
end
setmetatable(categories, {
__tostring = function(self)
return listify(categories, 'categories')
end
})
return categories
end
--- Make a list of templates
-- @tparam table args An array of page names (optionally with interlanguage prefixes)
-- @treturn table A table of page links
local function makePageList(args)
local pages = {}
for i, v in ipairs(args) do
v = mw.text.trim(v)
if v ~= '' then
local lang, page = string.match(v, '^([a-z]+):(.+)$')
if lang then
table.insert(pages, string.format('[[:%s:%s|%s]]', lang, page, page))
else
table.insert(pages, string.format('[[:%s]]', v))
end
end
end
setmetatable(pages, {
__tostring = function(self)
return listify(pages, 'pages')
end
})
return pages
end
--- Make a list of namespaces
-- @tparam table args An array of namespace IDs
-- @treturn table A table of namespace names
local function makeNsList(args)
local namespaces = {}
local namespaceName = msg('article')
for _, namespaceId in ipairs(args) do
namespaceId = mw.text.trim(namespaceId)
if namespaceId ~= '' then
if namespaceId ~= "0" then
namespaceName = '{{lc:{{ns:' .. namespaceId .. '}}}}'
end
table.insert(namespaces, namespaceName)
end
end
setmetatable(namespaces, {
__tostring = function(self)
return listify(namespaces, 'namespaces')
end
})
return namespaces
end
--[ Criterion format methods ]-------------------------------------------------------------
local criterion = {}
--- Formatter function for the backlinks criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.backlinks(args, kwargs, frame)
local pageList = makePageList(args)
return msg('criterion-backlinks', #pageList, tostring(pageList))
end
--- Formatter function for the bytes criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.bytes(args, kwargs, frame)
return msg('criterion-bytes', args[1])
end
--- Formatter function for the categories criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.categories(args, kwargs, frame)
local categoryList = makeCategoryList(frame, args)
local ret = msg('criterion-categories', #categoryList, tostring(categoryList))
if kwargs.ignore ~= nil then
local ignoredCats = mw.text.split(kwargs.ignore, ',')
ignoredCats = makeCategoryList(frame, ignoredCats)
ret = ret .. msg('categories-except', #ignoredCats, tostring(ignoredCats))
end
return ret
end
--- Formatter function for the existing criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.existing(args, kwargs, frame)
return msg('criterion-existing')
end
--- Formatter function for the forwardlinks criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.forwardlinks(args, kwargs, frame)
local pages = makePageList(args)
return msg('criterion-forwardlinks', #pages, tostring(pages))
end
--- Formatter function for the namespaces criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.namespaces(args, kwargs, frame)
local nsList = makeNsList(args)
local message
if #nsList == 1 and args[1] == '0' then
message = msg('criterion-namespace-0')
else
message = msg('criterion-namespace', #nsList, tostring(nsList))
end
if kwargs.site ~= nil then
return msg('page-at-site', message, mw.ustring.format('[https://%s %s]', kwargs.site, kwargs.site))
end
return message
end
--- Formatter function for the new page criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.new(args, kwargs, frame)
if kwargs.redirects ~= nil then
return msg('criterion-new-with-redirects')
end
return msg('criterion-new')
end
--- Formatter function for the pages (page list) criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.pages(args, kwargs, frame)
local pages = makePageList(args)
return msg('criterion-pages', #pages, tostring(pages))
end
--- Formatter function for the SPARQL criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.sparql(args, kwargs, frame)
local query = ''
if kwargs.distinct ~= nil then
query = 'SELECT DISTINCT ?item WHERE {\n ' .. kwargs.query .. '\n}'
else
query = 'SELECT ?item WHERE {\n ' .. kwargs.query .. '\n}'
end
local url = 'http://query.wikidata.org/#' .. mw.uri.encode(query, 'PATH')
if kwargs.description ~= nil then
return msg('criterion-sparql-with-explanation', kwargs.description, url)
end
return msg('criterion-sparql', url)
end
--- Formatter function for the templates criterion
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the criterion
function criterion.templates(args, kwargs, frame)
local templates = makeTemplateList(frame, args)
return msg('criterion-templates', #templates, tostring(templates))
end
--- Main function for getting criterion messages
-- @tparam table frame A frame object
-- @treturn string A string representing the criterion (or an error message string)
function p.criterion(frame)
local args, kwargs = parseArgs(frame, 'criteria', true)
local criterionArg = table.remove(args, 1)
local permittedCriteria = getArgumentMapping('criteria', 'canonical')
if criterionArg == nil or criterionArg == '' then
return frame:preprocess(getErrorString('argument-missing', 'criterion'))
elseif permittedCriteria[criterionArg] == nil or criterion[criterionArg] == nil then
return frame:preprocess(getErrorString('invalid-criterion', criterionArg))
end
-- Use manual description if given
if kwargs.description ~= nil and criterionArg ~= 'sparql' then
return kwargs.description
end
return frame:preprocess(criterion[criterionArg](args, kwargs, frame))
end
--[ Rule format methods ]-------------------------------------------------------------
local rule = {}
--- Formatter function for custom rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.custom(points, args, kwargs, frame)
return msg('rule-custom', points, kwargs.description)
end
--- Formatter function for image rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.image(points, args, kwargs, frame)
local out
local tplargs = {
['points'] = points,
}
if kwargs.initialimagelimit ~= nil then
out = msg('rule-image-limited', points, kwargs.initialimagelimit)
else
out = msg('rule-image', points)
end
if kwargs.ownimage ~= nil then
out = out .. ' ' .. msg('rule-image-own', kwargs.ownimage)
end
return out
end
--- Formatter function for Wikidata rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.wikidata(points, args, kwargs, frame)
local out
local params
local argTypes = { msg('properties'), msg('labels'), msg('aliases'), msg('descriptions') }
local results = {}
if kwargs.properties == nil and kwargs.labels == nil and kwargs.aliases == nil and kwargs.descriptions == nil then
return getErrorString('argument-missing', listify(argTypes))
end
if kwargs.properties ~= nil then
params = mw.text.split(kwargs.properties, ',')
for k, v in pairs(params) do
params[k] = string.format('[[:d:Property:%s|%s]]', v, v)
end
table.insert(results, listify(params))
end
if kwargs.labels ~= nil then
params = mw.text.split(kwargs.labels, ',')
table.insert(results, msg('label') .. ' (' .. listify(params) .. ')')
end
if kwargs.aliases ~= nil then
params = mw.text.split(kwargs.aliases, ',')
table.insert(results, msg('alias') .. ' (' .. listify(params) .. ')')
end
if kwargs.descriptions ~= nil then
params = mw.text.split(kwargs.descriptions, ',')
table.insert(results, msg('description') .. ' (' .. listify(params) .. ')')
end
results = table.concat( results, ' ' .. msg('and') .. ' ' )
if kwargs.all ~= nil then
out = msg('rule-wikidata-all', points, results)
else
out = msg('rule-wikidata-first', points, results)
end
if kwargs.requireReference ~= nil then
out = out .. ' ' .. msg('rule-wikidata-require-reference')
end
return out
end
--- Formatter function for reference rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.reference(points, args, kwargs, frame)
return msg('rule-reference', points, args[1])
end
--- Formatter function for template removal rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.templateremoval(points, args, kwargs, frame)
local templateList = makeTemplateList(frame, args)
return msg('rule-templateremoval', points, #templateList, tostring(templateList))
end
--- Formatter function for category removal rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.categoryremoval(points, args, kwargs, frame)
local categoryList = makeCategoryList(args)
return msg('rule-categoryremoval', points, #categoryList, tostring(categoryList))
end
--- Formatter function for section adding rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.section(points, args, kwargs, frame)
if kwargs.description ~= nil then
return msg('rule-section-desc', points, kwargs.description)
end
return msg('rule-section', points, #args, listify(args))
end
--- Formatter function for byte bonus rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.bytebonus(points, args, kwargs, frame)
return msg('rule-bytebonus', points, args[1])
end
--- Formatter function for word bonus rules
-- @tparam number points A number of points; may by a float
-- @tparam table args Anonymous arguments to the module
-- @tparam table kwargs Keyword arguments to the module
-- @treturn string A message corresponding to the rule
function rule.wordbonus(points, args, kwargs, frame)
return msg('rule-wordbonus', points, args[1])
end
--- Main function for getting criterion messages
-- @tparam table frame A frame object
-- @treturn string A string representing the rule (or an error message string)
function p.rule(frame)
local args, kwargs = parseArgs(frame, 'rules', true)
local ruleArg = table.remove(args, 1)
local points = table.remove(args, 1)
local permittedRules = getArgumentMapping('rules', 'canonical')
if ruleArg == nil or ruleArg == '' then
return frame:preprocess(getErrorString('argument-missing', 'rule'))
elseif permittedRules[ruleArg] == nil then
return frame:preprocess(getErrorString('invalid-rule', ruleArg))
end
if kwargs.description ~= nil then
ruleArg = 'custom'
end
-- All rules requires argument 1: number of points awarded
if points == nil then
return frame:preprocess(getErrorString('argument-missing', '1 (number of points)'))
end
points = mw.language.getContentLanguage():formatNum(tonumber(points))
-- If there's a rule formatter function, use it.
-- Otherwise, use the string from the messages table.
local out
if rule[ruleArg] ~= nil then
out = rule[ruleArg](points, args, kwargs, frame)
else
-- It shouldn't be necessary to check if the message exists here, because
-- of the previous check against permittedRules above
out = msg('rule-' .. ruleArg, points)
end
if kwargs.site ~= nil then
out = msg('rule-site', out, mw.ustring.format('[https://%s %s]', kwargs.site, kwargs.site))
end
if kwargs.max ~= nil then
out = msg('base-rule-max', out, mw.language.getContentLanguage():formatNum(tonumber(kwargs.max)))
end
return frame:preprocess(out)
end
--- Function to generate documentation for a module or template using this module
-- Not implemented yet
function p.generateDocs(frame)
-- Generate documentation subpage for templates using the module
end
--- Function to get warnings about duplicate or invalid i18n values
-- Not implemented yet
function p.getI18nWarnings(frame)
-- Function to be used on /doc page, to report any duplicate arguments
-- from the i18n, and potentially other things that should be fixed in the
-- i18n for the current language.
end
--- Get a single message string from the module's i18n, localized into the page
--- if possible
-- @tparam table frame A frame object
-- @treturn string A formatted message (or an HTML error string if the key doesn't exist)
function p.getMessage(frame)
local args, kwargs = parseArgs(frame, nil, false)
local key = table.remove(args, 1)
local exists, message = pcall(msg, key, args)
if exists then
if mw.isSubsting() then
-- substitute magic words etc. if the module proper is being substed
message = mw.ustring.gsub( message, '{{(#?%a+):', '{{subst:%1:' )
end
return frame:preprocess(message)
else
return getErrorString('message-key-missing', key)
end
end
--- Function to get i18n data for use by the bot
-- @treturn string A JSON-encoded string of all keys and (localized) values from the i18n dataset
function p.getAllI18n()
local lang = mw.title.getCurrentTitle().pageLang:getCode()
local sensible = {}
local i18n = mw.ext.data.get(I18NDATASET, lang)['data']
for _,v in ipairs(i18n) do
-- turn the array of message objects into a sensible key->value mapping
sensible[v[1]] = v[2]
end
return mw.text.jsonEncode(sensible)
end
return p