ק
rv
ק (שינה את הגדרות ההגנה של הדף "יחידה:ParamValidator": טיפול מונע (וק:במ) ([עריכה=רק עורכי תבניות או ממשק מורשים] (בלתי מוגבלת בזמן) [העברה=רק עורכי תבניות או ממשק מורשים] (בלתי מוגבלת בזמן))) |
ק (rv) |
||
| שורה 4: | שורה 4: | ||
the source of this module is in //he.wikipedia.org/wiki/Module:ParamValidator | the source of this module is in //he.wikipedia.org/wiki/Module:ParamValidator | ||
This module exports two functions: calculateViolations( frame, subpages ), and validateParams( frame ). | This module exports two functions: calculateViolations( frame, subpages ), and validateParams( frame ). | ||
| שורה 41: | שורה 35: | ||
it expects a parameter named "options", which contains the definition of the output. typically, it's used by placing something like so: | it expects a parameter named "options", which contains the definition of the output. typically, it's used by placing something like so: | ||
<includeonly>{{#invoke: | <includeonly>{{#invoke:ParamValidatoe | validateParams | options = {{PV default options}} }}</includeonly> | ||
at the top of the template (be mindful not to add extra spaces and newlines to the template). | at the top of the template (be mindful not to add extra spaces and newlines to the template). | ||
the options parameter should be a JSON-encoded string, defining the output, and some special behaviors. | the options parameter should be a JSON-encoded string, defining the output, and some special behaviors. | ||
| שורה 102: | שורה 91: | ||
typically, this JSON structure will be placed in a separate template, and retrieved for the module-use as shown above. | typically, this JSON structure will be placed in a separate template, and retrieved for the module-use as shown above. | ||
<includeonly>{{#invoke: | <includeonly>{{#invoke:ParamValidatoe | validateParams | options = {{PV default options}} | options1 = {"key":"value"} }}</includeonly> | ||
"key" can override any of the options fields described above. | "key" can override any of the options fields described above. | ||
| שורה 113: | שורה 102: | ||
end | end | ||
, | , | ||
extract_options = function( frame, optionsPrefix ) | extract_options = function ( frame, optionsPrefix ) | ||
optionsPrefix = optionsPrefix or 'options' | optionsPrefix = optionsPrefix or 'options' | ||
| שורה 122: | שורה 111: | ||
if type( module_options ) ~= 'table' then return {} end | if type( module_options ) ~= 'table' then return {} end | ||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
return module_options[ title.namespace ] or module_options[ title.nsText ] or {} | |||
end | end | ||
| שורה 159: | שורה 147: | ||
local capture = templateContent and mw.ustring.match( templateContent, '<templatedata%s*>(.*)</templatedata%s*>' ) -- templatedata as text | local capture = templateContent and mw.ustring.match( templateContent, '<templatedata%s*>(.*)</templatedata%s*>' ) -- templatedata as text | ||
-- capture = capture and mw.ustring.gsub( capture, '"(%d+)"', tonumber ) -- convert "1": {} to 1: {}. frame.args uses numerical indexes for order-based params. | -- capture = capture and mw.ustring.gsub( capture, '"(%d+)"', tonumber ) -- convert "1": {} to 1: {}. frame.args uses numerical indexes for order-based params. | ||
if capture then return pcall( mw.text.jsonDecode, capture ) end | |||
if capture | |||
return false | return false | ||
end | end | ||
| שורה 180: | שורה 167: | ||
-- this is the function to be called by other modules. it expects the frame, and then an optional list of subpages, e.g. { "Documentation" }. | -- 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. | -- if second parameter is nil, only tempalte page will be searched for templatedata. | ||
function calculateViolations( frame, subpages ) | |||
-- used for parameter type validy test. keyed by TD 'type' string. values are function(val) returning bool. | -- used for parameter type validy test. keyed by TD 'type' string. values are function(val) returning bool. | ||
local type_validators = { | local type_validators = { | ||
['number'] = function( s ) return mw.language.getContentLanguage():parseFormattedNumber( s ) end | ['number'] = function( s ) return mw.language.getContentLanguage():parseFormattedNumber( s ) end | ||
} | } | ||
function compatible( typ, val ) | |||
local func = type_validators[typ] | local func = type_validators[typ] | ||
return type( func ) ~= 'function' or util.empty( val ) or func( val ) | return type( func ) ~= 'function' or util.empty( val ) or func( val ) | ||
end | end | ||
| שורה 202: | שורה 183: | ||
local templatedata = readTemplateData( td_source ) | local templatedata = readTemplateData( td_source ) | ||
local td_params = templatedata and templatedata.params | local td_params = templatedata and templatedata.params | ||
local all_aliases | local all_aliases = {} | ||
if not td_params then return { ['no-templatedata'] = { [''] = '' } } end | if not td_params then return { ['no-templatedata'] = { [''] = '' } } end | ||
| שורה 213: | שורה 193: | ||
for _, p in pairs( td_params ) do for _, alias in ipairs( p.aliases or {} ) do | for _, p in pairs( td_params ) do for _, alias in ipairs( p.aliases or {} ) do | ||
all_aliases[alias] = p | all_aliases[alias] = p | ||
end end | end end | ||
-- handle undeclared and deprecated | -- handle undeclared and deprecated | ||
local already_seen = {} | local already_seen = {} | ||
for p_name, value in pairs( t_args ) do | for p_name, value in pairs( t_args ) do | ||
local tp_param, noval, numeric, table_name = td_params[p_name] or all_aliases[p_name], util.empty( value ), tonumber( p_name ) | local tp_param, noval, numeric, table_name = td_params[p_name] or all_aliases[p_name], util.empty( value ), tonumber( p_name ) | ||
if not tp_param then -- not in TD: this is called undeclared | if not tp_param then -- not in TD: this is called undeclared | ||
| שורה 237: | שורה 205: | ||
noval and numeric and 'empty-undeclared-numeric' or | noval and numeric and 'empty-undeclared-numeric' or | ||
noval and not numeric and 'empty-undeclared' or | noval and not numeric and 'empty-undeclared' or | ||
not noval and numeric and 'undeclared-numeric' or | |||
'undeclared' -- tzvototi nishar. | 'undeclared' -- tzvototi nishar. | ||
else -- in td: test for | else -- in td: test for depracation and mistype. if deprecated, no further tests | ||
table_name = tp_param.deprecated and | table_name = tp_param.deprecated and not noval and 'deprecated' | ||
or tp_param.deprecated and noval and 'empty-deprecated' | or tp_param.deprecated and noval and 'empty-deprecated' | ||
or not compatible( tp_param.type, value ) and 'incompatible' | or not compatible( tp_param.type, value ) and 'incompatible' | ||
or | or already_seen[tp_param] and 'duplicate' | ||
already_seen[tp_param] = | already_seen[tp_param] = true | ||
end | end | ||
-- report it. | -- report it. | ||
| שורה 255: | שורה 221: | ||
end | end | ||
end | end | ||
-- test for empty/missing paraeters declared "required" | -- test for empty/missing paraeters declared "required" | ||
for p_name, param in pairs( td_params ) do | for p_name, param in pairs( td_params ) do | ||
| שורה 269: | שורה 235: | ||
return res | return res | ||
end | end | ||
-- this is the "user" version, called with {{#invoke:}} returns a string, as defined by the options parameter | -- 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 = util.extract_options( frame ), '', frame:getParent():getTitle() | local options, report, template_name = util.extract_options( frame ), '', frame:getParent():getTitle() | ||
local wrap_report = function() | |||
if util.empty( report ) then return '' end | |||
local naked = mw.title.new( template_name )['text'] | |||
report = ( options['wrapper-prefix'] or "<div class = 'paramvalidator-wrapper'>" ) | |||
.. report | |||
.. ( options['wrapper-suffix'] or "</div>" ) | |||
report = mw.ustring.gsub( report, 'tname_naked', naked ) | |||
report = mw.ustring.gsub( report, 'templatename', template_name ) | |||
return report | |||
end | |||
local ignore = function( p_name ) | local ignore = function( p_name ) | ||
| שורה 301: | שורה 262: | ||
local replace_macros = function( s, param_names ) | local replace_macros = function( s, param_names ) | ||
function concat_and_escape( t ) | |||
local s = table.concat( t, ', ' ) | local s = table.concat( t, ', ' ) | ||
return ( mw.ustring.gsub( s, '%%', '%%%%' ) ) | return ( mw.ustring.gsub( s, '%%', '%%%%' ) ) | ||
| שורה 350: | שורה 311: | ||
if offenders > 1 then report_params( 'multiple' ) 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... | if offenders ~= 0 then report_params( 'any' ) end -- could have tested for empty( report ), but since we count them anyway... | ||
return | return wrap_report() | ||
end | end | ||
return { | return { | ||
['validateparams'] = validateParams, | ['validateparams'] = validateParams, | ||
['calculateViolations'] = calculateViolations | ['calculateViolations'] = calculateViolations | ||
} | } | ||