Module:Check for unknown parameters: Difference between revisions

From NvWiki
Jump to navigation Jump to search
m 1 revision imported: Import modules used with Template:Infobox software
Line 1: Line 1:
{{Permanently protected}}
-- This module may be used to compare the arguments passed to the parent
{{oldtfdfull|date= 2019 December 30 |result=no consensus |disc=Module:Check for deprecated parameters|merge=self}}
-- with a list of arguments, returning a specified result if an argument is
{{talk header}}
-- not on the list
{{WikiProject banner shell|
{{WikiProject Templates|module_for_template_maintenance=y}}
}}
{{User:MiszaBot/config
| algo=old(90d)
| archive=Module talk:Check for unknown parameters/Archive %(counter)d
| counter=1
| maxarchivesize=900K
| archiveheader={{aan}}
| minthreadsleft=2
| minthreadstoarchive=1
}}


== Bulk include all mapframe parameters ==
require ('strict');


Rather than having to copy and paste all 20+ [[Module:Infobox mapframe]] parameters into the check at the bottom of the page, I’m wondering if we can add a hook of some kind? Something like {{para|mapframe_params|on}} that will automatically include the hardcoded mapframe parameters? Alternatively could we create a {{tl|Infobox mapframe/parameters}} that is just a list of parameters and then pass that in? IF the parameters for [[Module:Infobox mapframe]] were to change for some reason, that would involve updating a LOT of infoboxes. This would make that process easier. —'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 22:23, 30 September 2025 (UTC)
local p = {}


:Sounds sensible &mdash;&nbsp;Martin <small>([[User:MSGJ|MSGJ]]&nbsp;·&nbsp;[[User talk:MSGJ|talk]])</small> 07:47, 1 October 2025 (UTC)
local mapframe_params = {
::{{ping|Frietjes}} I know you put a lot of work into this module. Any thoughts?
'coord',
::Also a quick search reveals that at least [https://en.wikipedia.org/w/index.php?title=Special:Search&limit=250&offset=0&ns10=1&search=insource%3A%2Finfobox+mapframe%2Fi+-intitle%3A%2F%5C%2F%2F 100] templates use [[Module:Infobox mapframe]] so it would definitely help. '''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 09:28, 1 October 2025 (UTC)
'coordinates',
::: {{u|Zackmann08}} this seems reasonable, so long as this is the only module that we are supporting.  if there are going to be multiple modules that we want to support, we could provide a link to a data page.  something like {{para|params_data|Module:Infobox mapframe/parameters}} or {{para|params_data1|Module:Infobox mapframe/parameters}} or whatever.  back in the early days of this module, it was suggested that it would be more efficient if the list of parameters lived in module space and were loaded using <code>mw.loadData</code> but this would only really help if the template using this module were being called multiple times on each page, so not as big of an issue for infoboxes. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 14:54, 2 October 2025 (UTC)
'id',
::::I’m a fan of either solution. I guess the second solution provides support for future expansions better but that could always been performed as a [[refactor]] down the line if needed. '''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 18:06, 2 October 2025 (UTC)
'qid',
:::::{{ping|Frietjes|MSGJ}} I have mocked up a solution in the sandbox. Not married to the parameter names of course but I did do some testing in my own sandbox and it seems to work just fine. All I did was {{mlx|Check for unknown parameters/sandbox|check|mapframe_args{{=}}y}}.
'mapframe',
:::::<s>Now there is a drawback I noticed... If you look, for example, at {{tl|Infobox zoo}} you will see in the implementation the following:</s>
'mapframe-area_km2',
:::::<s>The significance of this is that some of those parameters, {{para|mapframe-marker}}, {{para|mapframe-width}} and a few others are NOT valid parameters to be passed in to {{tl|Infobox zoo}} as they are hardcoded in the Infobox code.</s>
'mapframe-area_mi2',
:::::<s>So we are left with a few options</s>
'mapframe-caption',
:::::# <s>Use {{para|mapframe_args|y}} and just not care that there are a few extra params included (seems like a slippery slope to me but probably not a big deal)</s>
'mapframe-coord',
:::::# <s>Don't use the {{para|mapframe_args|y}} and go back to the old school way of copying and pasting all the params in the check for unknown list</s>
'mapframe-coordinates',
:::::# <s>Add an additional {{para|_exclude}} which takes a CSV of mapframe_args to NOT pass to the check. (This idea takes from [[Module:Template wrapper]].)</s>
'mapframe-custom',
:::::<s>Let me know your thoughts. Happy to experiment with option 3 if there is interest.</s> Also if this is implemented, I'll commit to updating the necessary documentation as well as taking on cleaning up the actual calls to the module so the new param is used. --'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 07:06, 6 October 2025 (UTC)
'mapframe-frame-coord',
::::::{{ping|Zackmann08}} you may not be understanding the obscure way that [[Module:Infobox mapframe]] is parsing the arguments with getArgs in autoArgs(). the <code>parentFirst=true</code> flag is set, so that the parameter passed into {{tl|Infobox zoo}} ''overrides'' the parameter provided in the template code itself. In other words, {{para|mapframe-marker|zoo}} is simply the default. If {{para|mapframe-marker}} is set to something else, it will override zoo. This is true with any of the other parameters. Whomever wrote the template code didn't realize this. I'll fix the code to make it less obscure, but you don't have to do anything. — [[User:Hike395|hike395]] ([[User talk:Hike395|talk]]) 12:18, 6 October 2025 (UTC)
'mapframe-frame-coordinates',
:::::::{{ping|Hike395}} thanks for the explanation! That dramatically simplifies things! I have struck my previous comments as they are no longer relevant. - '''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 17:03, 6 October 2025 (UTC)
'mapframe-frame-height',
'mapframe-frame-width',
'mapframe-geomask',
'mapframe-geomask-fill',
'mapframe-geomask-fill-opacity',
'mapframe-geomask-stroke-color',
'mapframe-geomask-stroke-colour',
'mapframe-geomask-stroke-width',
'mapframe-height',
'mapframe-id',
'mapframe-length_km',
'mapframe-length_mi',
'mapframe-line',
'mapframe-line-stroke-color',
'mapframe-line-stroke-colour',
'mapframe-marker',
'mapframe-marker-color',
'mapframe-marker-colour',
'mapframe-point',
'mapframe-population',
'mapframe-shape',
'mapframe-shape-fill',
'mapframe-shape-fill-opacity',
'mapframe-shape-stroke-color',
'mapframe-shape-stroke-colour',
'mapframe-stroke-color',
'mapframe-stroke-colour',
'mapframe-stroke-width',
'mapframe-switcher',
'mapframe-type',
'mapframe-width',
'mapframe-wikidata',
'mapframe-zoom'
}


== Edit request 9 October 2025 ==
local function trim(s)
return s:match('^%s*(.-)%s*$')
end


{{edit fully-protected|answered=yes}}
local function isnotempty(s)
'''Description of suggested change:''' Bulk include the [[Module:Infobox mapframe]] args as per the above discussion. Calling the module with {{para|mapframe_args|1}} will automatically include the valid parameters from the module so that the numerous parameters do not have to be copied and pasted. This has been mocked up in the [[Module:Check for unknown parameters/sandbox|sandbox]]. The diff is avaliable {{compare pages|Module:Check for unknown parameters|Module:Check for unknown parameters/sandbox|here}}. Thanks in advance. --'''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 03:26, 9 October 2025 (UTC)
return s and s:match('%S')
:{{done}}<!-- Template:EP --> &mdash;&nbsp;Martin <small>([[User:MSGJ|MSGJ]]&nbsp;·&nbsp;[[User talk:MSGJ|talk]])</small> 18:33, 9 October 2025 (UTC)
end
:Please document the new feature, thank you &mdash;&nbsp;Martin <small>([[User:MSGJ|MSGJ]]&nbsp;·&nbsp;[[User talk:MSGJ|talk]])</small> 18:34, 9 October 2025 (UTC)
::{{ping|MSGJ}} THANK YOU!!!!! About to break for lunch but will make documenting the feature and implementing it my first task when I return. '''[[User:Zackmann08|<span style="color:#00ced1">Zack</span><span style="color:#007F94">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange;">What I been doing</span>]]</sub>) 18:35, 9 October 2025 (UTC)


== Discussion at [[Module talk:Check for clobbered parameters#Rename]] ==
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '&lt;' .. tag .. '&gt;...&lt;/' .. tag .. '&gt;')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end


[[File:Symbol watching blue lashes high contrast.svg|25px|link=|alt=]]&nbsp;You are invited to join the discussion at [[:Module talk:Check for clobbered parameters#Rename|Module talk:Check for clobbered parameters §&nbsp;Rename]]. <!-- Template:Please see --> —⁠[[User:Andrybak|andrybak]] ([[User talk:Andrybak|talk]]) 03:11, 17 December 2025 (UTC)
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
 
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
if isnotempty(args['mapframe_args']) then
for _, v in ipairs(mapframe_params) do
    knownargs[v] = 1
end
end
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) )  then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
 
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
 
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview_text == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
 
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
 
return table.concat(res)
end
 
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
 
return p

Revision as of 16:56, 26 December 2025

Template:Used in system Template:Module rating Template:Cascade-protected template

Module:Check for unknown parameters is used to check for uses of unknown parameters in a template or module. It may be appended to a template at the end or called directly from a module.

Usage

From a template

To sort entries into a tracking category by parameter, use:

To sort the entries into a tracking category by parameter with a preview error message, use:

For an explicit red error message, use:

To use Lua patterns, use:

From a module

To call from a module, use:

local checkForUnknownParameters = require("Module:Check for unknown parameters")
local result = checkForUnknownParameters._check(validArgs, args)

Where the first set of args are the module args below and the second set of args are the parameters that are checked.

Parameters

  • arg1, arg2, ..., argN, are the known parameters.
  • Unnamed (positional) parameters can be added too: |1|2|arg1|arg2|....
  • Lua patterns (similar to regular expressions) usage with parameters is also supported (such as: |regexp1=header[%d]+, |regexp2=date[1-9], |regexp3=data[%d]+[abc]?). This is useful when there are many known parameters which use a systematic pattern.
  • |unknown= – what happens when an unknown parameter is used. Typically use either a tracking category to place pages that use unknown parameters, or an error.
  • |preview= – the text to be displayed when in preview mode and an unknown parameter is used.
  • The _VALUE_ keyword, if used, will be changed to the name of the parameter. This is useful for either sorting the entries in a tracking category, or for provide more explicit information.
  • |ignoreblank=1 – by default, the module makes no distinction between a defined-but-blank parameter and a non-blank parameter. That is, both unlisted |foo=x and |foo= are reported. To only track non-blank parameters use |ignoreblank=1. If you clean your arguments with Module:Arguments and call this module afterwards, you need not use this parameter as that module ignores blank arguments by default.
  • |showblankpositional=1 – by default, the module ignores blank positional parameters. That is, an unlisted |2= is ignored. To Template:Em blank positional parameters in the tracking use |showblankpositional=1.
  • |mapframe_args= – When this is set to a non-null value, the various Module:Infobox mapframe parameters will be automatically included in the list of valid parameters. This eliminates the need to manually add all 20+ params. NOTE this should only be used when Template:Mlx is in the template calling Check for unknown. Do NOT use if using {{Infobox mapframe}} as not all parameters are included when calling the template.

Example

{{Infobox
| above = {{{name|}}}

| label1 = Height
| data1 = {{{height|}}}

| label2 = Weight
| data2 = {{{weight|}}}

| label3 = Website
| data3 = {{{website|}}}
}}<!-- 
  end infobox, start tracking
-->{{#invoke:Check for unknown parameters|check
| unknown = {{Main other|[[Category:Some tracking category|_VALUE_]]}}
| preview = unknown parameter "_VALUE_" | height | name | website | weight 
}}

Call from within Lua code

See the end of Module:Rugby box for a simple example or Module:Infobox3cols or Module:Flag for more complicated examples.

See also

User scripts


-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list

require ('strict');

local p = {}

local mapframe_params = {
	'coord',
	'coordinates',
	'id',
	'qid',
	'mapframe',
	'mapframe-area_km2',
	'mapframe-area_mi2',
	'mapframe-caption',
	'mapframe-coord',
	'mapframe-coordinates',
	'mapframe-custom',
	'mapframe-frame-coord',
	'mapframe-frame-coordinates',
	'mapframe-frame-height',
	'mapframe-frame-width',
	'mapframe-geomask',
	'mapframe-geomask-fill',
	'mapframe-geomask-fill-opacity',
	'mapframe-geomask-stroke-color',
	'mapframe-geomask-stroke-colour',
	'mapframe-geomask-stroke-width',
	'mapframe-height',
	'mapframe-id',
	'mapframe-length_km',
	'mapframe-length_mi',
	'mapframe-line',
	'mapframe-line-stroke-color',
	'mapframe-line-stroke-colour',
	'mapframe-marker',
	'mapframe-marker-color',
	'mapframe-marker-colour',
	'mapframe-point',
	'mapframe-population',
	'mapframe-shape',
	'mapframe-shape-fill',
	'mapframe-shape-fill-opacity',
	'mapframe-shape-stroke-color',
	'mapframe-shape-stroke-colour',
	'mapframe-stroke-color',
	'mapframe-stroke-colour',
	'mapframe-stroke-width',
	'mapframe-switcher',
	'mapframe-type',
	'mapframe-width',
	'mapframe-wikidata',
	'mapframe-zoom'
}

local function trim(s)
	return s:match('^%s*(.-)%s*$')
end

local function isnotempty(s)
	return s and s:match('%S')
end

local function clean(text)
	-- Return text cleaned for display and truncated if too long.
	-- Strip markers are replaced with dummy text representing the original wikitext.
	local pos, truncated
	local function truncate(text)
		if truncated then
			return ''
		end
		if mw.ustring.len(text) > 25 then
			truncated = true
			text = mw.ustring.sub(text, 1, 25) .. '...'
		end
		return mw.text.nowiki(text)
	end
	local parts = {}
	for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
		pos = remainder
		table.insert(parts, truncate(before) .. '&lt;' .. tag .. '&gt;...&lt;/' .. tag .. '&gt;')
	end
	table.insert(parts, truncate(text:sub(pos or 1)))
	return table.concat(parts)
end

function p._check(args, pargs)
	if type(args) ~= "table" or type(pargs) ~= "table" then
		-- TODO: error handling
		return
	end

	-- create the list of known args, regular expressions, and the return string
	local knownargs = {}
	
	if isnotempty(args['mapframe_args']) then
		for _, v in ipairs(mapframe_params) do
    		knownargs[v] = 1
		end
	end
	
	local regexps = {}
	for k, v in pairs(args) do
		if type(k) == 'number' then
			v = trim(v)
			knownargs[v] = 1
		elseif k:find('^regexp[1-9][0-9]*$') then
			table.insert(regexps, '^' .. v .. '$')
		end
	end
	
	-- loop over the parent args, and make sure they are on the list
	local ignoreblank = isnotempty(args['ignoreblank'])
	local showblankpos = isnotempty(args['showblankpositional'])
	local values = {}
	for k, v in pairs(pargs) do
		if type(k) == 'string' and knownargs[k] == nil then
			local knownflag = false
			for _, regexp in ipairs(regexps) do
				if mw.ustring.match(k, regexp) then
					knownflag = true
					break
				end
			end
			if not knownflag and ( not ignoreblank or isnotempty(v) )  then
				table.insert(values, clean(k))
			end
		elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
			local knownflag = false
			for _, regexp in ipairs(regexps) do
				if mw.ustring.match(tostring(k), regexp) then
					knownflag = true
					break
				end
			end
			if not knownflag and ( showblankpos or isnotempty(v) ) then
				table.insert(values, k .. ' = ' .. clean(v))
			end
		end
	end

	-- add results to the output tables
	local res = {}
	if #values > 0 then
		local unknown_text = args['unknown'] or 'Found _VALUE_, '

		if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
			local preview_text = args['preview']
			if isnotempty(preview_text) then
				preview_text = require('Module:If preview')._warning({preview_text})
			elseif preview_text == nil then
				preview_text = unknown_text
			end
			unknown_text = preview_text
		end
		for _, v in pairs(values) do
			-- Fix odd bug for | = which gets stripped to the empty string and
			-- breaks category links
			if v == '' then v = ' ' end

			-- avoid error with v = 'example%2' ("invalid capture index")
			local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
			table.insert(res, r)
		end
	end

	return table.concat(res)
end

function p.check(frame)
	local args = frame.args
	local pargs = frame:getParent().args
	return p._check(args, pargs)
end

return p