Jump to content

မေႃႇၵျူး:checkparams

လုၵ်ႉတီႈ ဝိၵ်ႇသျိၼ်ႇၼရီႇ မႃး

If you're seen a warning that "The template does not use the parameter(s)" while editing a page, the error was generated by this module. This module can detect all of the parameters that are used by a template and will generate a warning when using an unexpected parameter. In many cases, the error might be generated by a typo in the parameter name (eg, "pge" instead of "page") and can simply be corrected by consulting the template's documentation. If you're absolutely certain that a template should allow the parameter even though it's not going to actually use the parameter, you can override the automatic parameter detection by adding a | plus a comma separated list to the {{#invoke:checkparams|warn}} or the {{#invoke:checkparams|error}} line at the top of the template.

For example, to allow parameters "3" and "comment" in the following template

{{#invoke:checkparams|warn}}<!-- Validate template parameters
-->Written by {{{1}}} and {{{2}}} in {{{year}}}

change it to:

{{#invoke:checkparams|warn|1,2,3,year,comment}}<!-- Validate template parameters
The parameters '3' and 'comment' are not used, but are explicitly allowed because ....
-->Written by {{{1}}} and {{{2}}} in {{{year}}}

Note that you must list every valid parameter

Developer information

[မႄးထတ်း]

This module generates warnings when passing bad parameters to a template. It adds a user-visible warning to the preview, an {{attention}} warning to the page, and categorizes the page into Category:Pages using bad params when calling a template

  • The |1= (optional) a comma separated list of allowed parameters. If not provided, the module will scan the template and allow all parameters used by the template.
  • The |nocat= (optional) if provided, does not add page to categories

local concat = table.concat
local find = string.find
local find_arguments = require("Module:template parser").findArguments
local format_categories = require("Module:utilities").format_categories
local html_create = mw.html.create
local insert = table.insert
local match = string.match
local new_title = mw.title.new
local next = next
local nowiki = require("Module:string/nowiki")
local pairs = pairs
local process = require("Module:parameters").process
local scribunto_param_key = require("Module:utilities/scribunto parameter key")
local select = select
local sort = table.sort
local sub = string.sub
local tostring = tostring
local type = type

local export = {}

local function get_template_title(frame)
	return frame:getParent():getTitle()
end

local function get_template_content(frame)
	return new_title(get_template_title(frame)):getContent()
end

local function sort_args(a, b)
	-- sort a table of parameters in the form {k, v}, sorting numbers before strings
	a, b = a[1], b[1]
	local type_a = type(a)
	if type_a == type(b) then
		return a < b
	end
	return type_a == "number"
end

local function params_to_string(invalid_args)
	-- join a table of key, values pairs into a semicolon separated list
	local msg = {}
	for k, v in pairs(invalid_args) do
		insert(msg, {k, v})
	end
	sort(msg, sort_args)
	for i = 1, #msg do
		msg[i] = concat(msg[i], "=")
	end
	return concat(msg, "; ")
end

local function get_allowed_args(frame)
	-- returns a table of allowed params
	-- if frame.args[1] contains a comma separated list of param names, use that
	-- otherwise, detect all params used by the parent template
	local text, params = frame.args[1], {}
	if text then
		local loc, head = find(text, ",", 1, true), 1
		while loc do
			params[scribunto_param_key(sub(text, head, loc - 1))] = {}
			head = loc + 1
			loc = find(text, ",", head, true)
		end
		params[scribunto_param_key(sub(text, head))] = {}
	else
		-- iterates over all params used by parent template
		for arg in find_arguments(get_template_content(frame), frame:getParent().args) do
			params[arg] = {}
		end
	end
	return params
end

local function make_message(template_name, invalid_args, no_link, no_escape)
	local invalid_args_string = params_to_string(invalid_args)
	if not no_escape then
		invalid_args_string = nowiki(invalid_args_string)
	end
	
	local open = no_link and "" or "[["
	local close = no_link and "" or "]]"
	return "The template " .. open .. template_name .. close .. " does not use the parameter(s): " .. invalid_args_string .. ". Please see " .. open .. "Module:checkparams" .. close .. " for help with this warning."
end

local function make_warning_text(template_name, invalid_args, nowarn, noattn, nocat)
	-- generate "Invalid params" warning to be inserted into wiki page
	-- template_name (required) name of the template with invalid params
	-- invalid_args (required) table of invalid args
	-- nocat= (optional) do not included category in warning_text
	-- noattn= (optional) do not include attention seeking span in in warning_text
	-- nowarn= (optional) do not include preview warning in warning_text
	local warn, attn, cat
	
	-- show warning in previewer
	if not nowarn then
		warn = tostring(html_create("sup")
			:addClass("error")
			:addClass("previewonly")
			:tag("small")
				:wikitext(make_message(template_name, invalid_args))
			:allDone())
	end
	
	-- add attentionseeking message
	if not noattn then
		attn = tostring(html_create("span")
			:addClass("attentionseeking")
			:attr("title", make_message(template_name, invalid_args, "no_link"))
			:allDone())
	end
	
	if not nocat then
		cat = format_categories(
			{"Pages using bad params when calling " .. template_name},
			nil,
			"-"
		)
	end
	
	return (warn or "") .. (attn or "") .. (cat or "") 
end

local function remove_placeholder_args(allowed_params, invalid_args)
	-- some templates use params 1 and 3 without using 2,
	-- which means that 2 will be in the list of invalid args
	-- when used as an empty placeholder like in {{foo|1||3}}
	-- this function will detect and remove any empty positionaly placeholder args
	-- from a list of invalid_args
	local max_pos = 0
	for param in pairs(allowed_params) do
		if type(param) == "number" and param > max_pos then
			max_pos = param
		end
	end
	
	for param in pairs(invalid_args) do
		if (
			type(param) == "number" and
			param < max_pos and
			not match(invalid_args[param], "[^%z\t-\v\r ]") -- charset used by MediaWiki to trim parameters
		) then
			invalid_args[param] = nil
		end
	end
end


function export.process(frame, allowed_params, nowarn, noattn, nocat)
	-- This is desgined to be called by other Lua modules instead of calling Module:parameters.process()
	-- frame - the frame containing the arguments to be checked
	-- allowed_params - a table of valid arguments
	-- nocat - if specified, will not included category in warning_text
	-- noattn - if specified, will not include attention seeking span in in warning_text
	-- nowarn - if specified, will not include preview warning in warning_text
	-- returns valid_args, invalid_args, warning_text
	local valid_args, invalid_args = process(
		frame.args,
		allowed_params,
		"return unknown"
	)
	
	if next(invalid_args) then
		remove_placeholder_args(allowed_params, invalid_args)
	end
	
	if next(invalid_args) then
		local template_name = frame:getTitle()
		return valid_args, invalid_args, make_warning_text(template_name, invalid_args, nowarn, noattn, nocat)
	end
	
	return valid_args, invalid_args, ""
end

function export.warn(frame)
	-- This is designed to be called by non-Lua templates using "{{#invoke:checkparams|warn}}"
	-- the passed frame is checked for the following params:
	-- 1= (optional) a comma separated list of allowed parameters - if not specified, allows all parameters used as variables inside the template
	-- nowarn= (optional) do not include preview warning in warning_text
	-- noattn= (optional) do not include attention seeking span in in warning_text
	-- nocat= (optional) do not included category in warning_text
	local args = frame.args
	return select(3, export.process(
		frame:getParent(),
		get_allowed_args(frame),
		args.nowarn or false,
		args.noattn or false,
		args.nocat or false
	))
end

function export.error(frame)
	-- This is designed to be called by non-Lua templates using "{{#invoke:checkparams|error}}"
	-- the passed frame is checked for the following params:
	-- 1= (optional) a comma separated list of allowed parameters - if not specified, allows all parameters used as variables inside the template
	local allowed_args = get_allowed_args(frame)
	local invalid_args = select(2, process(
		frame:getParent().args,
		allowed_args,
		"return unknown"
	))
	
	if next(invalid_args) then
		remove_placeholder_args(allowed_args, invalid_args)
	end
	
	if next(invalid_args) then
		local template_name = get_template_title(frame)
		error(make_message(template_name, invalid_args, "no_link", "no_escape"))
	end
	
end

return export