<param> is the parameter's name as listed in the TemplateData
<key> is key neccessary to look in the appropriate subtable of whitelist.unique_arguments_t{}  
local function validate_unique_param (param, key, cfg_aliases_t)
if true == whitelist.unique_arguments_t[key][param] or true == validate_basic_param (param) then
return true;
end
end  
----------------------------< V A L I D A T E _ I D _ P A R A M >--------------------------------------------  
looks for <param> <alias> in identifier_aliases_t{}. When found, returns true; nil else  
<param> is the parameter's name as listed in the TemplateData
<alias> is the alias that we're looking for  
local function validate_id_alias (param, alias)
return identifier_aliases_t[param] and identifier_aliases_t[param][alias];
end  
----------------------------< P A R A M _ E R R O R_ M S G >-------------------------------------------------  
local function param_error_msg (param)
return '<spanmonospace">|' .. param .. '=</span> is not a valid parameter';
end  
----------------------------< D U P _ A L I A S _ E R R O R_ M S G >-----------------------------------------  
local function dup_alias_error_msg (param, alias)
return '<spanmonospace">|' .. param .. '=</span> has duplicate aliases: <span font-family:"monospace";>|' .. alias .. '=</span>';
end  
----------------------------< D U P _ A L I A S E S _ C H E C K >--------------------------------------------  
create an associative array of <param> aliases. if <alias> already present in <aliases_t> add an error message
to <out>  
local function dup_aliases_check (param, alias, aliases_t, out_t)
if not aliases_t[alias] then
aliases_t[alias] = true;
else
table.insert (out_t, dup_alias_error_msg (param, alias));
end
end  
----------------------------< A L I A S _ E R R O R_ M S G >-------------------------------------------------  
local function alias_error_msg (param, alias)
return '<code>|' .. alias .. '=</code> is not a valid alias of: <code>|' .. param .. '=</code>';
end  
--[[--------------------------< C F G _ A L I A S E S _ T _ M A K E >------------------------------------------  
convert this from cfg.aliases{}:
['AccessDate'] = {'access-date', 'accessdate'}  
to this in out_t{}
['access-date'] = 'AccessDate',
['accessdate'] = 'AccessDate',  
to test if |accessdate= is an aliases of |access-date=:
if out_t['access-date'] == out_t['accessdate']  
local function cfg_aliasts_t_make
local out_t = {};
for meta, params_t in pairs (cfg.aliases) do
if 'table' == type (params_t) then -- metaparameters that are assigned string values do not have aliases
for _, param in ipairs (params_t) do -- for each alias
param = param:gsub ('#', ''); -- get rid of enumerators
out_t[param] = meta; -- add it to the output table
end
end
end
--error (mw.dumpObject (out_t))
return out_t;
end  
--2 template's TemplateData structure (everything between <TemplateData>
and </TemplateData> tag case insensitive). Returns error messages when errors found, empty string else.  
When called from a different page:  
where the <canonical template name> is the template's canonical name with or without namespace and or subpages  
local function template_data_validate
local args_t = getArgs ;  
if not args_t[1] then
return '<span>Error: cs1|2 template name required</span>';
end  
local template_idx = args_t[1]:lower:match ('cit[ae][^/]+'); -- args_t[1] has something
if not template_idx then -- but if not a cs1|2 template abandon with error message
return '<span>Error: cs1|2 template name required</span>';
else
template_idx = template_idx:gsub (' ', ''); -- is what appears to be a cs1|2 template so strip spaces
end  
local cfg_aliases_t = cfg_aliasts_t_make ;  
local template_t = templates_t[template_idx];
local out = {};  
local template_doc = template_t[1];
local json_t = template_data_json_get (template_doc);  
if not json_t then
table.insert (out, 'Error: can\'t find TemplateData');
else
for param, param_t in pairs (json_t['params']) do
local param_i; -- this will be the parameter name that gets validated
if param:find ('[Ss]2[Cc][Ii][Dd]') then -- |s2cid*= parameters are not enumerated ...
param_i = param; -- ... so don't convert the '2' to '#'
else
param_i = param:gsub ('%d+', '#'); -- for enumerated parameters, convert the enumerator digits to a single '#' character; all others unmolested
end  
local param_is_valid; -- boolean true when param is valid; nil else
if template_t[2] then -- if template is a preprint or uses unique parameters of 'document' parameters
if 'document' == template_t[2] then -- if a template
param_is_valid = validate_document_param (param_i, template_t[2]);
if param_is_valid then
local aliases_t = {}; -- used by dup_aliases_check
if param_t['aliases'] then
for _, alias in ipairs (param_t['aliases']) do
dup_aliases_check (param, alias, aliases_t, out);
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerator digits to a single '#' character
if not validate_document_param (alias_i, template_t[2]) then -- is 'alias' a known parameter?
table.insert (out, alias_error_msg (param, alias)); -- may be known but is not supported
elseif cfg_aliases_t[param_i:gsub ('#', *)] ~= cfg_aliases_t[alias_i:gsub ('#', *)] then -- is 'alias' known to be an alias of 'param'?
table.insert (out, alias_error_msg (param, alias));
end
end
end
else -- here when param not valid preprint param
table.insert (out, param_error_msg (param))
end
elseif whitelist.preprint_arguments_t[template_t[2]] then -- if a preprint template
param_is_valid = validate_preprint_param (param_i, template_t[2]);
if param_is_valid then
local aliases_t = {}; -- used by dup_aliases_check
if param_t['aliases'] then
for _, alias in ipairs (param_t['aliases']) do
dup_aliases_check (param, alias, aliases_t, out);
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerator digits to a single '#' character
if not validate_preprint_param (alias_i, template_t[2]) then -- is 'alias' a known parameter?
table.insert (out, alias_error_msg (param, alias)); -- may be known but is not supported
elseif cfg_aliases_t[param_i:gsub ('#', *)] ~= cfg_aliases_t[alias_i:gsub ('#', *)] then -- is 'alias' known to be an alias of 'param'?
table.insert (out, alias_error_msg (param, alias));
end
end
end
else -- here when param not valid preprint param
table.insert (out, param_error_msg (param))
end
elseif whitelist.unique_arguments_t[template_t[2]] then -- if a unique parameters template
param_is_valid = validate_unique_param (param_i, template_t[2]);
if param_is_valid then
local aliases_t = {}; -- used by dup_aliases_check
if param_t['aliases'] then
for _, alias in ipairs (param_t['aliases']) do
dup_aliases_check (param, alias, aliases_t, out);
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character
if not validate_unique_param (alias_i, template_t[2]) then -- is 'alias' a known parameter?
table.insert (out, alias_error_msg (param, alias));
elseif cfg_aliases_t[param_i:gsub ('#', *)] ~= cfg_aliases_t[alias_i:gsub ('#', *)] then -- is 'alias' known to be an alias of 'param'?
table.insert (out, alias_error_msg (param, alias));
end
end
end
else -- here when param not valid unique parameter
table.insert (out, param_error_msg (param))
end
else -- should never be here if coder is doing the thing ...
table.insert (out, 'internal error: unexpected keyword in templates_t: ' .. template_t[2]);
break;
end
else -- here when not unique or preprint
param_is_valid = validate_basic_param (param_i);
if param_is_valid then
local aliases_t = {}; -- used by dup_aliases_check
if param_t['aliases'] then
for _, alias in ipairs (param_t['aliases']) do
dup_aliases_check (param, alias, aliases_t, out)
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character