יחידה:ParamValidator: הבדלים בין גרסאות בדף
תוכן שנמחק תוכן שנוסף
ניסוי |
החלפת המנוע. הוספת פונקציה calculateViolations( frame, subpages ) שאפשר לקרוא לה ממודול אחר. |
||
שורה 7:
it exports two functions: validateParams(), called from page using {{#invoke: }} and returns a string,
and calculateViolations(), called from another module, and returns a table with a list of violations, keyed on violation type as described below.
both use the metadata in the templatedata object to validate the parameters. the list of detected violations appear below:
* "no-templatedata": no valid tempaltedata was found in tempalte page, or documentation subpage
שורה 23 ⟵ 19:
* "empty-deprecated": parameters with empty value, marked as "deprecated" in tempaltedata
* "empty-required": missing or empty parameter marked as "required" in tempaltedata
calculateViolations() returns a table, keyed on violation type, whose values are tables of parameter name : parameter value
* "any": at least one of the above properies has non-empty value, and the corresponding error actually exists.
* "multiple": more than one of the above properies (not including "any") has non-empty value, and the corresponding error actually exists.
it retrieves the template's templatedata, and uses it to validate the parameters passed to the template.
if any violations found, it returns am appropriate string. this string will typically include some maintenance category, and/or error message.
the operation of the module is controlled by a single parameter passed to it. this string should be valid JSON describing the actions.
the fields of this structure has the following keys, with string or null value:
if any of these error-conditions exists, and "options" has non-empty value for the corresponding key, will be appended to the output,
after replacing the follwing tokens:
שורה 54 ⟵ 62:
]=]
function
return not s or type( s ) == 'string' and mw.text.trim( s ) == ''
end
function extract_options( frame )
local ok, options = pcall( mw.text.jsonDecode, frame.args.options )
options = ok and options or {}
local n, more = 0
repeat
n = n + 1
ok, more = pcall( mw.text.jsonDecode, frame.args['options' .. n] )
if ok then
for k, v in pairs( more ) do options[k] = v end
end
until not ok
return options
end
function build_namelist(
local res = { template_name }
if sp then
if type( sp ) == 'string' then sp = { sp } end
שורה 80 ⟵ 89:
end
-- this is the function to be called by other modules. it expects the frame, and then an optional list of subpages, e.g. { "Documentation" }.
-- if second parameter is nil, only tempalte page will be searched for templatedata.
function calculateViolations( frame, subpages )
-- this can be made more sophisticated later, e.g. for "wiki page" and such
function compatible( val, typ )
if typ == 'number' and not mw.language.getCurrentLanguage():parseNumber( val ) then return false end
return true
end
local t_frame = frame:getParent()
local t_args, template_name = t_frame.args, t_frame:getTitle()
local td_source = build_namelist(
local templatedata = require( 'Module:ReadTd' ).ReadTemplateData( td_source )
local
if not td_params then return { ['no-templatedata'] = { [''] = '' } } end
-- from this point on, we know templatedata is valid.
local res = {} -- before returning to caller, we'll prune empty tables
-- handle undeclared and deprecated
for p_name, value in pairs( t_args ) do
local tp_param, noval, numeric, table_name = td_params[p_name], empty( value ), tonumber( p_name )
if not tp_param then -- not in TD: this is called undeclared
-- calculate the relevant table for this undeclared parameter, based on parameter and value types
table_name =
noval and numeric and 'empty-undeclared-numeric' or
noval and not numeric and 'empty-undeclared' or
not noval and numeric and 'undeclared-numeric' or
'undeclared' -- tzvototi nishar.
else -- in td: test for depracation and mistype. if deprecated, no further tests
table_name = tp_param.deprecated and not noval and 'deprecated' or
tp_param.deprecated and noval and 'empty-deprecated' or
not compatible( tp_param.type, value ) and 'incompatible'
end
-- report it.
if table_name then
res[table_name] = res[table_name] or {}
res[table_name][p_name] = value
end
end
-- test for empty/missing paraeters declared "required"
for p_name, param in pairs( td_params ) do
if param.required and empty( t_args[p_name] ) then
res['empty-required'] = res['empty-required'] or {}
res['empty-required'][p_name] = ''
end
end
return res
end
-- this is the "user" version, called with {{#invoke:}} returns a string, as defined by the options parameter
function validateParams( frame )
local options, report, template_name = extract_options( frame ), '', frame:getParent():getTitle()
local wrap_report = function()
if empty( report ) then return '' end
local naked = mw.title.new( template_name )['text']
report = ( options['wrapper-prefix'] or "<div class = 'paramvalidator-wrapper'>" )
שורה 108 ⟵ 162:
local ignore = function( p_name )
for _,
if
end
return false
שורה 115 ⟵ 169:
local replace_macros = function( s, param_names )
if s and ( type( param_names ) == 'table' ) then
local k_ar, kv_ar = {}, {}
table.insert( kv_ar, k .. ': ' .. v)
end
s = mw.ustring.gsub( s, 'paramname', table.concat( k_ar, ', ' ) )
s = mw.ustring.gsub( s, 'paramandvalue', table.concat( kv_ar, ', ' ) )
end
return s
שורה 138 ⟵ 182:
local report_params = function( key, param_names )
return res
end
-- assert options is not empty.
assert( next( options ), 'expecting valid "options" parameter')
-- get the errors.
local violations = calculateViolations( frame, options['doc-subpage'] )
-- special request of bora: use skip_empty_numeric
if violations['empty-undeclared-numeric'] then
for i = 1, tonumber( options['skip-empty-numeric'] ) or 0 do
violations['empty-undeclared-numeric'][i] = nil
end
end
-- handle ignore list, and prune empty violations - in that order!
local offenders = 0
for name, tab in pairs( violations ) do
-- remove ignored parameters from all violations
for pname in pairs( tab ) do if ignore( pname ) then tab[pname] = nil end end
-- prune empty violations
if next( tab ) == nil then violations[name] = nil end
-- WORK IS DONE. report the errors.
-- if report then count it.
if violations[name] and report_params( name, tab ) then offenders = offenders + 1 end
end
if offenders > 1 then report_params( 'multiple' ) end
if offenders ~= 0 then report_params( 'any' ) end -- could have tested for empty( report ), but since we count them anyway...
return wrap_report()
שורה 214 ⟵ 219:
return {
['validateparams'] = validateParams,
['calculateViolations'] = calculateViolations
}
|