<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://the-democratika.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ATemplate_parameter_value</id>
	<title>Module:Template parameter value - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://the-democratika.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ATemplate_parameter_value"/>
	<link rel="alternate" type="text/html" href="https://the-democratika.com/wiki/index.php?title=Module:Template_parameter_value&amp;action=history"/>
	<updated>2026-04-05T02:11:52Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://the-democratika.com/wiki/index.php?title=Module:Template_parameter_value&amp;diff=9937&amp;oldid=prev</id>
		<title>&gt;Pppery: Changed protection settings for &quot;Module:Template parameter value&quot;: Up to full due to 11 million transclusions ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://the-democratika.com/wiki/index.php?title=Module:Template_parameter_value&amp;diff=9937&amp;oldid=prev"/>
		<updated>2024-11-25T21:44:09Z</updated>

		<summary type="html">&lt;p&gt;Changed protection settings for &amp;quot;&lt;a href=&quot;/wiki/index.php/Module:Template_parameter_value&quot; title=&quot;Module:Template parameter value&quot;&gt;Module:Template parameter value&lt;/a&gt;&amp;quot;: Up to full due to 11 million transclusions ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite))&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
local PrepareText = require(&amp;quot;Module:Wikitext Parsing&amp;quot;).PrepareText&lt;br /&gt;
&lt;br /&gt;
local function getTitle(title)&lt;br /&gt;
	local success, titleObj = pcall(mw.title.new, title)&lt;br /&gt;
	if success then return titleObj&lt;br /&gt;
	else return nil end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--string.gmatch will check the largest block it can without re-scanning whats inside, but we need whats inside&lt;br /&gt;
local function matchAllTemplates(str)&lt;br /&gt;
	local matches = {}&lt;br /&gt;
	for template in string.gmatch(str, &amp;quot;{%b{}}&amp;quot;) do&lt;br /&gt;
		table.insert(matches, template)&lt;br /&gt;
		local innerContent = string.sub(template, 3, -3)&lt;br /&gt;
		for _,subtemplate in next,matchAllTemplates(innerContent) do&lt;br /&gt;
			table.insert(matches, subtemplate)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return matches&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Forked version of getParameters from [[Module:Transcluder]] with extra features removed&lt;br /&gt;
local function escapeString(str)&lt;br /&gt;
	return string.gsub(str, &amp;#039;[%^%$%(%)%.%[%]%*%+%-%?%%]&amp;#039;, &amp;#039;%%%0&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
local function getParameters(template)&lt;br /&gt;
	local parameters, parameterOrder = {}, {}&lt;br /&gt;
	local params = string.match(template, &amp;#039;{{[^|}]-|(.*)}}&amp;#039;)&lt;br /&gt;
	if params then&lt;br /&gt;
		local count = 0&lt;br /&gt;
		-- Temporarily replace pipes in subtemplates and wikilinks to avoid chaos&lt;br /&gt;
		for subtemplate in string.gmatch(params, &amp;#039;{%b{}}&amp;#039;) do&lt;br /&gt;
			params = string.gsub(params, escapeString(subtemplate), string.gsub(subtemplate, &amp;quot;.&amp;quot;, {[&amp;quot;%&amp;quot;]=&amp;quot;%%&amp;quot;, [&amp;quot;|&amp;quot;]=&amp;quot;@@:@@&amp;quot;, [&amp;quot;=&amp;quot;]=&amp;quot;@@_@@&amp;quot;}) )&lt;br /&gt;
		end&lt;br /&gt;
		for wikilink in string.gmatch(params, &amp;#039;%[%b[]%]&amp;#039;) do&lt;br /&gt;
			params = string.gsub(params, escapeString(wikilink), string.gsub(wikilink, &amp;quot;.&amp;quot;, {[&amp;quot;%&amp;quot;]=&amp;quot;%%&amp;quot;, [&amp;quot;|&amp;quot;]=&amp;quot;@@:@@&amp;quot;, [&amp;quot;=&amp;quot;]=&amp;quot;@@_@@&amp;quot;}) )&lt;br /&gt;
		end&lt;br /&gt;
		for parameter in mw.text.gsplit(params, &amp;#039;|&amp;#039;) do&lt;br /&gt;
			local parts = mw.text.split(parameter, &amp;#039;=&amp;#039;)&lt;br /&gt;
			local key = mw.text.trim(parts[1])&lt;br /&gt;
			local value&lt;br /&gt;
			if #parts == 1 then&lt;br /&gt;
				value = key&lt;br /&gt;
				count = count + 1&lt;br /&gt;
				key = tostring(count)&lt;br /&gt;
			else&lt;br /&gt;
				value = mw.text.trim(table.concat(parts, &amp;#039;=&amp;#039;, 2))&lt;br /&gt;
			end&lt;br /&gt;
			value = string.gsub(string.gsub(value, &amp;#039;@@:@@&amp;#039;, &amp;#039;|&amp;#039;), &amp;#039;@@_@@&amp;#039;, &amp;#039;=&amp;#039;)&lt;br /&gt;
			key = string.gsub(string.gsub(key, &amp;#039;@@:@@&amp;#039;, &amp;#039;|&amp;#039;), &amp;#039;@@_@@&amp;#039;, &amp;#039;=&amp;#039;)&lt;br /&gt;
			table.insert(parameterOrder, key)&lt;br /&gt;
			parameters[key] = value&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return parameters, parameterOrder&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns a table containing parameters and a table with the order in which each of their values were found.&lt;br /&gt;
-- Since this considers all subtemplates, a single parameter is expected to have multiple values.&lt;br /&gt;
-- E.g. {{ABC|X={{DEF|X=Value|Y=Other value}}{{ABC|X=Yes}}|Y=P}}&lt;br /&gt;
-- Would return {X={&amp;quot;{{DEF|X=Value|Y=Other value}}&amp;quot;, &amp;quot;Value&amp;quot;, &amp;quot;Yes&amp;quot;}, Y={&amp;quot;Other value&amp;quot;, &amp;quot;P&amp;quot;}}&lt;br /&gt;
local function getAllParameters(template, ignore_blank, only_subtemplates)&lt;br /&gt;
	local parameterTree = setmetatable({}, {&lt;br /&gt;
		__index = function(self,key)&lt;br /&gt;
			rawset(self,key,{})&lt;br /&gt;
			return rawget(self,key)&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
	local params, paramOrder = getParameters(template)&lt;br /&gt;
	for _,key in ipairs(paramOrder) do&lt;br /&gt;
		local value = params[key]&lt;br /&gt;
		if not ignore_blank or value ~= &amp;quot;&amp;quot; then&lt;br /&gt;
			if not only_subtemplates then&lt;br /&gt;
				table.insert(parameterTree[key], value) --Insert the initial value into the tree&lt;br /&gt;
			end&lt;br /&gt;
			for subtemplate in string.gmatch(value, &amp;quot;{%b{}}&amp;quot;) do --And now check for subvalues&lt;br /&gt;
				local subparams = getAllParameters(subtemplate, ignore_blank)&lt;br /&gt;
				for subkey,subset in next,subparams do&lt;br /&gt;
					for _,subvalue in ipairs(subset) do&lt;br /&gt;
						table.insert(parameterTree[subkey], subvalue) --And add any we find to our tree&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return parameterTree&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Module entry point. Returns a success boolean and either the target template or why it failed&lt;br /&gt;
function p.getTemplate(page, templates, options)&lt;br /&gt;
	if not templates then --Required parameters&lt;br /&gt;
		return false, &amp;quot;Missing required parameter &amp;#039;templates&amp;#039;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	options = options or {}&lt;br /&gt;
	&lt;br /&gt;
	local template_index = tonumber(options.template_index) or 1&lt;br /&gt;
	local treat_as_regex = options.treat_as_regex or false&lt;br /&gt;
	if type(templates) == &amp;quot;string&amp;quot; then&lt;br /&gt;
		-- TODO: Find a good way to allow specifying multiple templates via template invocation&lt;br /&gt;
		-- (Modules can just provide a table so no concerns there)&lt;br /&gt;
		-- Comma splitting is a bad idea (lots of templates have a comma in their name)&lt;br /&gt;
		templates = {templates}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local title = getTitle(page)&lt;br /&gt;
	if title == nil then&lt;br /&gt;
		return false, &amp;quot;Requested title doesn&amp;#039;t exist&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local content = PrepareText(title:getContent() or &amp;quot;&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local foundTemplates = 0&lt;br /&gt;
	for _,template in next,matchAllTemplates(content) do&lt;br /&gt;
		for _,wantedTemplate in pairs(templates) do&lt;br /&gt;
			if not treat_as_regex then&lt;br /&gt;
				wantedTemplate = escapeString(wantedTemplate)&lt;br /&gt;
			end&lt;br /&gt;
			local firstLetter = string.sub(wantedTemplate, 1, 1)&lt;br /&gt;
			local firstUpper, firstLower = firstLetter:upper(), firstLetter:lower()&lt;br /&gt;
			if firstUpper ~= firstLower then&lt;br /&gt;
				wantedTemplate = &amp;quot;[&amp;quot; .. firstUpper .. firstLower .. &amp;quot;]&amp;quot; .. string.sub(wantedTemplate, 2)&lt;br /&gt;
			end&lt;br /&gt;
			if string.match(template, &amp;quot;^{{%s*&amp;quot;..wantedTemplate..&amp;quot;%s*[|}]&amp;quot;) then&lt;br /&gt;
				foundTemplates = foundTemplates + 1&lt;br /&gt;
				if foundTemplates == template_index then --Found our wanted template&lt;br /&gt;
					return true, template&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false, &amp;quot;No valid template found&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Module entry point. Returns a success boolean and either the target parameter&amp;#039;s value or why it failed&lt;br /&gt;
function p.getParameter(page, templates, parameter, options)&lt;br /&gt;
	if not (templates and parameter) then --Required parameters&lt;br /&gt;
		return false, &amp;quot;Missing required parameters &amp;#039;templates&amp;#039; and &amp;#039;parameter&amp;#039;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	parameter = tostring(parameter) --Force consistency&lt;br /&gt;
	options = options or {}&lt;br /&gt;
	&lt;br /&gt;
	local success, text = p.getTemplate(page, templates, options)&lt;br /&gt;
	if not success then&lt;br /&gt;
		return success, text&lt;br /&gt;
	else&lt;br /&gt;
		local parameter_index = tonumber(options.parameter_index) or 1&lt;br /&gt;
		local ignore_subtemplates = options.ignore_subtemplates or false&lt;br /&gt;
		local only_subtemplates = options.only_subtemplates or false&lt;br /&gt;
		local ignore_blank = options.ignore_blank or false&lt;br /&gt;
&lt;br /&gt;
		local value&lt;br /&gt;
		if ignore_subtemplates then&lt;br /&gt;
			value = getParameters(text)[parameter] or &amp;quot;&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			local params = getAllParameters(text, ignore_blank, only_subtemplates)&lt;br /&gt;
			value = params[parameter][parameter_index] or &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		value = string.gsub(value, &amp;quot;&amp;lt;/?%a*include%a*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		value = mw.text.trim(value) --technically wrong in some cases but not a big issue&lt;br /&gt;
		return true, mw.text.decode(value) --decode due to PrepareText&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Template entry point. Returns either &amp;quot;yes&amp;quot; or nothing depending on if the wanted template is found&lt;br /&gt;
--Will return error text if no template is provided&lt;br /&gt;
function p.hasTemplate(frame)&lt;br /&gt;
	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame)&lt;br /&gt;
	local yesno = require(&amp;quot;Module:Yesno&amp;quot;)&lt;br /&gt;
	local page = args[1] or args.page&lt;br /&gt;
	local template = args[2] or args.template&lt;br /&gt;
	local template_index = tonumber(args[3] or args.N) or 1&lt;br /&gt;
	if not template or template == &amp;quot;&amp;quot; then&lt;br /&gt;
		return &amp;#039;&amp;lt;span class=&amp;quot;error&amp;quot;&amp;gt;No template provided for hasTemplate&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	local follow = yesno(args.follow) or false&lt;br /&gt;
	if follow then&lt;br /&gt;
		page = require(&amp;quot;Module:Redirect&amp;quot;).luaMain(page)&lt;br /&gt;
	end&lt;br /&gt;
	local options = {&lt;br /&gt;
		template_index = template_index,&lt;br /&gt;
		treat_as_regex = yesno(args.treat_as_regex) or false,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local success, _ = p.getTemplate(page, template, options)&lt;br /&gt;
	return success and &amp;quot;yes&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Template entry point for getParameter. Returns an empty string upon failure&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = require(&amp;#039;Module:Arguments&amp;#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = &amp;#039;Template:Template parameter value&amp;#039;&lt;br /&gt;
	})&lt;br /&gt;
	local yesno = require(&amp;quot;Module:Yesno&amp;quot;)&lt;br /&gt;
	local options = {&lt;br /&gt;
		template_index = args[3] or args.template_index,&lt;br /&gt;
		parameter_index = args[5] or args.parameter_index,&lt;br /&gt;
		ignore_subtemplates = yesno(args.ignore_subtemplates or args.ist) or false,&lt;br /&gt;
		only_subtemplates = yesno(args.only_subtemplates) or false,&lt;br /&gt;
		ignore_blank = yesno(args.ignore_blank) or false,&lt;br /&gt;
		treat_as_regex = yesno(args.treat_as_regex) or false,&lt;br /&gt;
	}&lt;br /&gt;
	local page = args[1] or args.page&lt;br /&gt;
	local template = args[2] or args.template&lt;br /&gt;
	local parameter = args[4] or args.parameter&lt;br /&gt;
	local success, result = p.getParameter(page, template, parameter, options)&lt;br /&gt;
	if not success then&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		if args.dontprocess then&lt;br /&gt;
			return result&lt;br /&gt;
		else&lt;br /&gt;
			return frame:preprocess(result)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Backwards compatability&lt;br /&gt;
p.getValue = p.getParameter&lt;br /&gt;
--Potentially useful module entry points&lt;br /&gt;
p.matchAllTemplates = matchAllTemplates&lt;br /&gt;
p.getParameters = getParameters&lt;br /&gt;
p.getAllParameters = getAllParameters&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>&gt;Pppery</name></author>
	</entry>
</feed>