Module:Template parameter value
Kaonekelo
| This Lua module is used on approximately 9,930,000 pages, or roughly 25321% 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. |
Implements {{Template parameter value}}
Module usage
[kulemba source]The module can be used directly for other modules through the function getValue(page, templates, parameters, options), which will return a success boolean and either the resulting parameter value or why it failed.
page, templates, and parameters are all required arguments. options is an optional table which can have the parameters template_index, parameter_index, ignore_subtemplates, only_subtemplates, and ignore_blank. More info on what these parameters do can be found in the template's template data.
Testcases
[kulemba source]Testcases are available at Module talk:Template parameter value/testcases
local p = {}
local _getParameters = require("Module:Transcluder").getParameters
local yesno = require("Module:Yesno")
local PrepareText = require("Module:Wikitext Parsing").PrepareText
local function getTitle(title)
local success, titleObj = pcall(mw.title.new, title)
if success then return titleObj
else return nil end
end
--string.gmatch will check the largest block it can without re-scanning whats inside, but we need whats inside
local function matchAllTemplates(str)
local matches = {}
for template in string.gmatch(str, "{%b{}}") do
table.insert(matches, template)
local innerContent = string.sub(template, 3, -3)
for _,subtemplate in next,matchAllTemplates(innerContent) do
table.insert(matches, subtemplate)
end
end
return matches
end
--Transcluder's getParameters, but force all keys to be a string (helps with template inputs)
local function getParameters(template)
local parameters, text, paramOrder = _getParameters(template)
local newParams = {}
for key,value in next,parameters do
newParams[tostring(key)] = value
end
local newParamOrder = {}
for index,key in next,paramOrder do
newParamOrder[index] = tostring(key)
end
return newParams, text, newParamOrder
end
-- Returns a table containing parameters and a table with the order in which each of their values were found.
-- Since this considers all subtemplates, a single parameter is expected to have multiple values.
-- E.g. {{ABC|X={{DEF|X=Value|Y=Other value}}{{ABC|X=Yes}}|Y=P}}
-- Would return {X={"{{DEF|X=Value|Y=Other value}}", "Value", "Yes"}, Y={"Other value", "P"}}
local function getAllParameters(template, ignore_blank, only_subtemplates)
local parameterTree = setmetatable({}, {
__index = function(self,key)
rawset(self,key,{})
return rawget(self,key)
end
})
local params, _, paramOrder = getParameters(template)
for _,key in ipairs(paramOrder) do
local value = params[key]
if not ignore_blank or value ~= "" then
if not only_subtemplates then
table.insert(parameterTree[key], value) --Insert the initial value into the tree
end
for subtemplate in string.gmatch(value, "{%b{}}") do --And now check for subvalues
local subparams = getAllParameters(subtemplate, ignore_blank)
for subkey,subset in next,subparams do
for _,subvalue in ipairs(subset) do
table.insert(parameterTree[subkey], subvalue) --And add any we find to our tree
end
end
end
end
end
return parameterTree
end
--Primary module entry point. Returns a success boolean and either the result or why it failed
function p.getValue(page, templates, parameter, options)
if not (templates and parameter) then --Required parameters
return false, "Missing required parameters 'templates' and 'parameter'"
end
parameter = tostring(parameter) --Force consistency
options = options or {}
--mix of camelCase and under_score is kept for backwards compatability
local template_index = tonumber(options.templateIndex or options.template_index) or 1
local parameter_index = tonumber(options.parameterIndex or options.parameter_index) or 1
local ignore_subtemplates = options.ignoreSubtemplates or options.ignore_subtemplates or false
local only_subtemplates = options.onlySubtemplates or options.only_subtemplates or false
local ignore_blank = options.ignoreBlank or options.ignore_blank or false
if type(templates) == "string" then
templates = mw.text.split(templates, ", ?")
end
local title = getTitle(page)
if title == nil then
return false, "Requested title doesn't exist"
end
local content = PrepareText(title:getContent() or "")
local foundTemplates = 0
for _,template in next,matchAllTemplates(content) do
for _,wantedTemplate in pairs(templates) do
local firstLetter = string.sub(wantedTemplate, 1, 1)
local firstUpper, firstLower = firstLetter:upper(), firstLetter:lower()
if firstUpper ~= firstLower then
wantedTemplate = "[" .. firstUpper .. firstLower .. "]" .. string.sub(wantedTemplate, 2)
end
if string.match(template, "^{{%s*"..wantedTemplate.."%s*[|}]") then
foundTemplates = foundTemplates + 1
if foundTemplates == template_index then --Found our wanted template
local value
if ignore_subtemplates then
value = getParameters(template)[parameter] or ""
else
local params = getAllParameters(template, ignore_blank, only_subtemplates)
value = params[parameter][parameter_index] or ""
end
value = string.gsub(value, "</?%a*include%a*>", "")
value = mw.text.trim(value)
return true, mw.text.decode(value) --due to PrepareText
end
end
end
end
return false, "No valid template found"
end
--Template entry point. Returns an empty string upon failure
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:Template parameter value'
})
local options = {
template_index = args[3],
parameter_index = args[5],
ignore_subtemplates = yesno(args.ignore_subtemplates or args.ist) or false,
only_subtemplates = yesno(args.only_subtemplates) or false,
ignore_blank = yesno(args.ignore_blank) or false,
}
local success, result = p.getValue(args[1], args[2], args[4], options)
if not success then
return ""
else
return frame:preprocess(result)
end
end
--Potentially useful module entry points
p.matchAllTemplates = matchAllTemplates
p.getParameters = getParameters
p.getAllParameters = getAllParameters
return p