Module:Template parameter value/testcases
Documentation for this module may be created at Module:Template parameter value/testcases/doc
Documentation for this module may be created at Module:Template parameter value/testcases/doc
local p = {}
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
--Forked version of getParameters from [[Module:Transcluder]] with extra features removed
local function escapeString(str)
return string.gsub(str, '[%^%$%(%)%.%[%]%*%+%-%?%%]', '%%%0')
end
local function getParameters(template)
local parameters, parameterOrder = {}, {}
local params = string.match(template, '{{[^|}]-|(.*)}}')
if params then
local count = 0
-- Temporarily replace pipes in subtemplates and wikilinks to avoid chaos
for subtemplate in string.gmatch(params, '{%b{}}') do
params = string.gsub(params, escapeString(subtemplate), string.gsub(subtemplate, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
end
for wikilink in string.gmatch(params, '%[%b[]%]') do
params = string.gsub(params, escapeString(wikilink), string.gsub(wikilink, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
end
for parameter in mw.text.gsplit(params, '|') do
local parts = mw.text.split(parameter, '=')
local key = mw.text.trim(parts[1])
local value
if #parts == 1 then
value = key
count = count + 1
key = tostring(count)
else
value = mw.text.trim(table.concat(parts, '=', 2))
end
value = string.gsub(string.gsub(value, '@@:@@', '|'), '@@_@@', '=')
key = string.gsub(string.gsub(key, '@@:@@', '|'), '@@_@@', '=')
table.insert(parameterOrder, key)
parameters[key] = value
end
end
return parameters, parameterOrder
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
--Module entry point. Returns a success boolean and either the target template or why it failed
function p.getTemplate(page, templates, options)
if not templates then --Required parameters
return false, "Missing required parameter 'templates'"
end
options = options or {}
local template_index = tonumber(options.template_index) or 1
local treat_as_regex = options.treat_as_regex or false
if type(templates) == "string" then
-- TODO: Find a good way to allow specifying multiple templates via template invocation
-- (Modules can just provide a table so no concerns there)
-- Comma splitting is a bad idea (lots of templates have a comma in their name)
templates = {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
if not treat_as_regex then
wantedTemplate = escapeString(wantedTemplate)
end
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
return true, template
end
end
end
end
return false, "No valid template found"
end
--Module entry point. Returns a success boolean and either the target parameter's value or why it failed
function p.getParameter(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 success, text = p.getTemplate(page, templates, options)
if not success then
return success, text
else
local parameter_index = tonumber(options.parameter_index) or 1
local ignore_subtemplates = options.ignore_subtemplates or false
local only_subtemplates = options.only_subtemplates or false
local ignore_blank = options.ignore_blank or false
local value
if ignore_subtemplates then
value = getParameters(text)[parameter] or ""
else
local params = getAllParameters(text, ignore_blank, only_subtemplates)
value = params[parameter][parameter_index] or ""
end
value = string.gsub(value, "</?%a*include%a*>", "")
value = mw.text.trim(value) --technically wrong in some cases but not a big issue
return true, mw.text.decode(value) --decode due to PrepareText
end
end
--Template entry point. Returns either "yes" or nothing depending on if the wanted template is found
--Will return error text if no template is provided
function p.hasTemplate(frame)
local args = require('Module:Arguments').getArgs(frame)
local yesno = require("Module:Yesno")
local page = args[1] or args.page
local template = args[2] or args.template
local template_index = tonumber(args[3] or args.N) or 1
if not template or template == "" then
return '<span class="error">No template provided for hasTemplate</span>'
end
local follow = yesno(args.follow) or false
if follow then
page = require("Module:Redirect").luaMain(page)
end
local options = {
template_index = template_index,
treat_as_regex = yesno(args.treat_as_regex) or false,
}
local success, _ = p.getTemplate(page, template, options)
return success and "yes" or ""
end
--Template entry point for getParameter. Returns an empty string upon failure
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:Template parameter value'
})
local yesno = require("Module:Yesno")
local options = {
template_index = args[3] or args.template_index,
parameter_index = args[5] or args.parameter_index,
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,
treat_as_regex = yesno(args.treat_as_regex) or false,
}
local page = args[1] or args.page
local template = args[2] or args.template
local parameter = args[4] or args.parameter
local success, result = p.getParameter(page, template, parameter, options)
if not success then
return ""
else
if args.dontprocess then
return result
else
return frame:preprocess(result)
end
end
end
--Backwards compatability
p.getValue = p.getParameter
--Potentially useful module entry points
p.matchAllTemplates = matchAllTemplates
p.getParameters = getParameters
p.getAllParameters = getAllParameters
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.