Module:Template parameter value/sandbox
![]() | This is the module sandbox page for Module:Template parameter value (diff). See also the companion subpage for test cases (run). |
![]() | This Lua module is used on approximately 11,300,000 pages, or roughly 18% 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: |
Implements {{Template parameter value}} and {{HasTemplate}}, and can be used from other modules.
Module functions
getParameter
getParameter takes 4 arguments: The page name (string), the template/s (string or table of strings), the parameter (string), and an optional options table. It will return either true
and the contents of the requested parameter or false
and a reason for failure.
The following options are available:
- template_index: Which occurrence of the template to look for the parameter in. Set to -1 for last occurrence. (default: 1)
- parameter_index: Which occurrence of the parameter to look for (default: 1; only applies when
ignore_subtemplates
is false) - ignore_subtemplates: If parameters should only be searched for in the top-level template, ignoring the parameters in subtemplates (default: false)
- only_subtemplates: If parameters should only be searched for in subtemplates of the top-level template (default: false)
- ignore_blank: Whether or not blank values should count towards
parameter_index
(default: false) - treat_as_regex: Whether or not the template string(s) should be treated as a lua regex (default: false)
getTemplate
getTemplate takes 3 arguments: The page name (string), the template/s (string or table of strings), and an optional options table. It will return either true
and the text of the requested template or false
and a reason for failure.
getTemplate supports the options template_index
and treat_as_regex
from getParameter.
Helper functions
The module exposes some of the helper functions used (matchAllTemplates
, getParameters
, and getAllParameters
) for convenience. Each function has some comments above it in the code explaining its rough purpose.
Template functions
main
implements {{Template parameter value}} and acts as a template wrapper for getParameter
.
hasTemplate
implements {{HasTemplate}} and somewhat acts as a wrapper for getTemplate
(it only provides if the template was found, not the template text itself).
Testcases
Testcases are available at Module talk:Template parameter value/testcases
local p = {}
local _getParameters = require("Module:Transcluder").getParameters
local escapeString = require("Module:String")._escapePattern
local yesno = require("Module:Yesno")
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
local function escapeComments(content)
--[[ Testing
for comment in string.gmatch(content, "%b<>") do
if string.sub(comment,1,4) == "<!--" and string.sub(comment,-3,-1) == "-->" then
local safeComment = string.gsub("<!--" .. mw.text.nowiki(string.sub(comment,4,-3)) .. "-->", "%%", "%%%%")
content = string.gsub(content, escapeString(comment), safeComment)
end
end
]]
return content
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)
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]
table.insert(parameterTree[key], value) --Insert the initial value into the tree
for subtemplate in string.gmatch(value, "{%b{}}") do --And now check for subvalues
local subparams = getAllParameters(subtemplate)
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
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 {}
local templateIndex = tonumber(options.templateIndex) or 1
local parameterIndex = tonumber(options.parameterIndex) or 1
local ignoreSubtemplates = options.ignoreSubtemplates or false
local title = getTitle(page)
if title == nil then
return false, "Requested title doesn't exist"
end
local content = escapeComments(title:getContent() or "")
--Testing
content = require("Module:Sandbox/Aidan9382/ExcessiveParsing").EET(content)
local foundTemplates = 0
local foundParameters = 0
for _,template in next,matchAllTemplates(content) do
for wantedTemplate in string.gmatch(templates, "[^,]+") do
if string.match(template, "^{{%s*"..wantedTemplate.."%s*[|}]") then
foundTemplates = foundTemplates + 1
if foundTemplates == templateIndex then --Found our wanted template
local value
if ignoreSubtemplates then
value = getParameters(template)[parameter] or ""
else
value = getAllParameters(template)[parameter][parameterIndex] or ""
end
value = string.gsub(value, "</?%a*include%a*>", "")
value = mw.text.trim(value)
--Testing
return true, mw.text.decode(value)
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 = {
templateIndex = args[3],
parameterIndex = args[5],
ignoreSubtemplates = yesno(args.ignore_subtemplates or args.ist) 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