Module:WikiProject banner/templatepage explained

require('strict')local p =

p.templatepage = function(args, raw_args, inactive_status)local wikilink = function(link, display) if link then return display and ''..display..'' or ''..link..'' else return display or endend----------------------------- Initialise variables ------------------------------local sandbox-- = '/sandbox'local cfg = mw.loadData('Module:WikiProject banner/config' .. (sandbox or ))local cfg_tp = cfg.template_page -- convenient shortcut for template_page configuration settingslocal lang = mw.language.getContentLanguagelocal current_page = mw.title.getCurrentTitlelocal on_sandbox = lang:lc(current_page.subpageText)

'sandbox' -- on sandbox subpage or current_page.namespace

2 -- in User namespace or current_page.rootText

'WPBannerMeta' -- subpage of Template:WPBannerMetalocal frame = mw.getCurrentFramelocal parameter_format = function(parameter, value) local code = parameter and mw.html.create('code') :addClass('tpl-para') :css('word-break', 'break-word') :wikitext('|' .. parameter .. '=' .. (value or )) :done return tostring(code)endlocal yesno = require('Module:Yesno')local messageBox = require('Module:Message box').mainlocal project = args.PROJECT or local banner_name = mw.title.new(args.BANNER_NAME or 'Template:WikiProject ' .. project)local project_name = args.PROJECT_NAME or 'WikiProject ' .. projectlocal notices, tracking_cats =, local add_tracking = function(tracking, show_on_sandbox) local category = tracking.category or cfg_tp.default_tracking -- uses by default local key = tracking.sort_key or (project~= and project or '*') -- sort key defaults to name of project if not on_sandbox or show_on_sandbox then table.insert(tracking_cats, wikilink('Category:' .. category, key)) endendlocal project_link = args.PROJECT_LINK or 'Wikipedia:WikiProject ' .. project----------------------------- Count notes/taskforces ----------------------------local task_forces, notes, taskforce_categories =,, for arg_name, _ in pairs(raw_args) do local tf_match = mw.ustring.match(arg_name,'^tf (%d+)$') if tf_match then table.insert(task_forces, tf_match) end local tf, cat = mw.ustring.match(arg_name,'^tf (%d+) cat (%d+)$') if tf then if not taskforce_categories[tf] then-- initialise table taskforce_categories[tf] = end table.insert(taskforce_categories[tf], cat) end local note_match = mw.ustring.match(arg_name,'^note (%d+)$') if note_match then table.insert(notes, note_match) endendtable.sort(task_forces, function (x, y) return tonumber(x) < tonumber(y) end)table.sort(notes, function (x, y) return tonumber(x) < tonumber(y) end)----------------------------- Demonstrative banner ------------------------------args.PROJECT = args.PROJECT or args.class = raw_args.class and not inactive_status and 'C'args.importance = raw_args.importance and 'High'args.priority = raw_args.priority and 'High'args.auto = raw_args.auto and 'inherit'args.attention = raw_args.attention and 'yes'args.infobox = raw_args.infobox and 'yes'args.b1 = raw_args.b1 and 'yes'args.b2 = raw_args.b2 and 'no'args.b3 = raw_args.b3 and 'foo'args.b4 = raw_args.b4 and 'yes'args.b5 = raw_args.b5 and 'na'args.b6 = raw_args.b6args['image-needed'] = raw_args['image-needed'] and 'yes'args['collaboration-candidate'] = raw_args['collaboration-candidate'] and 'yes'args['collaboration-current'] = raw_args['collaboration-current'] and 'yes'args['collaboration-past'] = raw_args['collaboration-past'] and 'yes'args['a class'] = raw_args['a class'] and 'current'args['peer review'] = raw_args['peer review'] and 'yes'args['old peer review'] = raw_args['old peer review'] and 'yes'for _, tf in ipairs(task_forces) do args['tf '..tf] = 'yes' if raw_args['tf '..tf..' importance'] then args['tf '..tf..' importance'] = 'Top' endendfor _, note in ipairs(notes) do local text_arg = args['NOTE_'..note..'_TEXT'] if text_arg and text_arg~= then args['note '..note] = 'yes' endendlocal demo_banner, note_count, tf_count, assessment_link = require('Module:WikiProject banner' .. (sandbox or ))._main(args, args, true, banner_name)if not assessment_link then --temporary code until main module updated assessment_link = args.ASSESSMENT_LINKendif not assessment_link then local project_link = mw.title.new(args.PROJECT_LINK or 'Wikipedia:' .. project_name) local fallback = mw.title.new(project_link.prefixedText .. '/Assessment') assessment_link = fallback.exists and fallback.prefixedTextelseif assessment_link

'no' then assessment_link = nilend----------------------------- Project status ------------------------------------if inactive_status then table.insert(notices, cfg_tp.inactive:format(inactive_status))end----------------------------- Quality criteria ----------------------------------local custom_mask = banner_name:subPageTitle('class')if args.QUALITY_CRITERIA

'custom' then add_tracking(cfg_tp.quality_criteria.custom_tracking) if custom_mask.exists and #custom_mask:getContent>1 then table.insert(notices, cfg_tp.quality_criteria.custom:format(custom_mask.prefixedText )) else table.insert(notices, string.format(cfg_tp.quality_criteria.missing, parameter_format('QUALITY_CRITERIA'), custom_mask.prefixedText )) endend----------------------------- Custom importance mask ----------------------------local custom_mask = banner_name:subPageTitle('importance')if args.IMPORTANCE_SCALE

'subpage' then if custom_mask.exists and #custom_mask:getContent>1 then table.insert(notices, string.format(cfg_tp.custom_importance_mask.in_use, custom_mask.prefixedText )) else table.insert(notices, string.format(cfg_tp.custom_importance_mask.missing, parameter_format('IMPORTANCE_SCALE'), custom_mask.prefixedText )) endelseif custom_mask.exists and #custom_mask:getContent>1 then table.insert(notices, string.format(cfg_tp.custom_importance_mask.unused, custom_mask.prefixedText, parameter_format('IMPORTANCE_SCALE','subpage') ))end----------------------------- Collapsed sections --------------------------------local more_than = function(n) return n>=2 and string.format(cfg_tp.more_than.more, tostring(n)) or n

1 and cfg_tp.more_than.one or n

0 and cfg_tp.more_than.zeroendlocal tf_threshold = tonumber(args.TF_COLLAPSE) or (args.TF_HEADER and cfg.task_force.lower_threshold) or cfg.task_force.upper_thresholdif tf_count > tf_threshold then table.insert(notices, string.format(cfg_tp.task_force.collapsing, tf_count, more_than(tf_threshold), parameter_format('TF_COLLAPSE') ))endlocal note_threshold = tonumber(args.COLLAPSED) or 2local hook_collapsedif args.HOOK_COLLAPSED then local success, result = pcall(mw.ext.ParserFunctions.expr, args.HOOK_COLLAPSED) hook_collapsed = success and tonumber(result) or nil if args.HOOK_COLLAPSED

'auto' then hook_collapsed = args.HOOK_NOTE and 1 or 0 -- default assumption is that HOOK_NOTE produces max one note endendif note_count > note_threshold then table.insert(notices, string.format(cfg_tp.note.collapsing, note_count, more_than(note_threshold), parameter_format('COLLAPSED') ))endif args.HOOK_NOTE then if not hook_collapsed then table.insert(notices, string.format(cfg_tp.note.counter, parameter_format('HOOK_NOTE'), parameter_format('HOOK_COLLAPSED') )) add_tracking(cfg_tp.note.tracking) endend----------------------------- Assessment link -----------------------------------if raw_args.class or raw_args.importance then local url = mw.uri.fullUrl(banner_name.prefixedText,) if args.ASSESSMENT_LINK then if not mw.title.new(args.ASSESSMENT_LINK).exists then table.insert(notices, string.format(cfg_tp.assessment_link.missing, wikilink(args.ASSESSMENT_LINK), tostring(url), parameter_format('ASSESSMENT_LINK') )) end endend----------------------------- Project parameter ---------------------------------if args.PROJECT

then table.insert(notices, cfg_tp.project.text) add_tracking(cfg_tp.project.tracking)end----------------------------- Subst check ---------------------------------------if not raw_args.substcheck then table.insert(notices, string.format(cfg_tp.substcheck.text, parameter_format('substcheck') )) add_tracking(cfg_tp.substcheck.tracking)end----------------------------- Portal link ---------------------------------------if args.PORTAL then local portal_image = require('Module:Portal')._image(args.PORTAL) local portal_link = mw.title.new('Portal:' .. args.PORTAL) local explain if portal_link and portal_link.exists then if portal_image

'Portal-puzzle.svg' then explain = string.format(cfg_tp.portal.no_image, cfg_tp.portal.instructions) else explain = string.format(cfg_tp.portal.image_link, wikilink(':File:' .. portal_image), cfg_tp.portal.instructions ) end else explain = string.format(cfg_tp.portal.missing, parameter_format('PORTAL')) add_tracking(cfg_tp.portal.tracking) end local text = string.format(cfg_tp.portal.text, portal_link.prefixedText, explain ) table.insert(notices, text)end----------------------------- Task forces ---------------------------------------for _, k in ipairs(task_forces) do local name_parameter = 'TF_'..k..'_NAME' if raw_args['tf '..k] and not args['TF_'..k..'_NAME'] then table.insert(notices, string.format(cfg_tp.task_force.text, parameter_format('TF_'..k..'_NAME') )) add_tracking(cfg_tp.task_force.tracking) endend----------------------------- Parameter checking --------------------------------if not inactive_status then local category = mw.title.new(cfg.unknown_parameters.tracking:format(project_name)) local text = string.format(category.exists and cfg_tp.parameters.tracking or cfg_tp.parameters.create, ':' .. category.fullText ) table.insert(notices, text)end----------------------------- Assessment categories -----------------------------local importance_name = args.IMPN or (raw_args.priority and 'priority' or cfg.importance.default_name)local check_assessment_categories = function(project, assessment_cat, quality, importance_scale, prefix, tf_name) assessment_cat = assessment_cat or ((project or ) .. ' articles') local missing_cats = local red_cats_in_use = false local check_cat = function(cat_name, preload) local category = mw.title.new('Category:' .. cat_name) if not category.exists then local url = mw.uri.fullUrl('Category:' .. cat_name,) local pages_in_category = mw.site.stats.pagesInCategory(cat_name, 'pages') if pages_in_category>0 then red_cats_in_use = true end local label = pages_in_category>0 and 'create' or 'create' local create_link = wikilink(':' .. category.prefixedText) .. '  - ([' .. tostring(url) .. ' ' .. label .. '])' table.insert(missing_cats, create_link) end end if quality then check_cat(lang:ucfirst(assessment_cat) .. ' by quality', cfg_tp.check_assessment.meta_preload) for _, class in ipairs(cfg_tp.check_assessment.classes) do local cat_name = (class

'Unassessed' and 'Unassessed' or class..'-Class') .. ' ' .. assessment_cat check_cat(cat_name, cfg_tp.check_assessment.quality_preload) end end if importance_scale and importance_scale~='inline' and importance_scale~='subpage' then check_cat(lang:ucfirst(assessment_cat) .. ' by ' .. importance_name, cfg_tp.check_assessment.meta_preload) for _, importance in ipairs(cfg_tp.check_assessment.importances) do local cat_name = importance .. '-' .. importance_name .. ' ' .. assessment_cat check_cat(cat_name, cfg_tp.check_assessment.importance_preload) end end if #missing_cats>0 then local intro = string.format(cfg_tp.check_assessment.text, tf_name or project or , parameter_format((prefix or ) .. cfg_tp.check_assessment.parameter_suffix) ) local list = mw.html.create('ul') for _, missing in ipairs(missing_cats) do list:tag('li'):wikitext(missing):done end list:done if red_cats_in_use then add_tracking(cfg_tp.check_assessment.tracking) end return messageBox('ombox',) end return endlocal missing_cats, warnings =, local red_other_cats_in_use = falselocal check_other_category = function(cat_name) if cat_name and cat_name~='none' then local category = mw.title.new('Category:' .. (cat_name or )) if category and not category.exists then local pages_in_category = mw.site.stats.pagesInCategory(cat_name, 'pages') if pages_in_category>0 then red_other_cats_in_use = true end table.insert(missing_cats, wikilink(':' .. category.prefixedText)) end endendtable.insert(warnings, check_assessment_categories(project, args.ASSESSMENT_CAT, raw_args.class and args.QUALITY_CRITERIA~='custom', (raw_args.importance or raw_args.priority) and (args.IMPORTANCE_SCALE or )))local ntf, check_task_forces = #task_forces, if ntf>10 then -- too many task forces to check all, so check a selection instead local used = math.randomseed(os.time) for i = 1, 10 do local new repeat new = math.random(ntf) until not used[new] table.insert(check_task_forces, task_forces[new]) used[new] = true end table.sort(check_task_forces, function (x, y) return tonumber(x) < tonumber(y) end) table.insert(notices, string.format(cfg_tp.check_assessment.too_many, table.concat(check_task_forces,', ')))else check_task_forces = task_forcesendfor _, k in ipairs(check_task_forces) do local tf_prefix = 'TF_' .. k .. '_' table.insert(warnings, check_assessment_categories(project, args[tf_prefix..'ASSESSMENT_CAT'] or (args[tf_prefix..'NAME'] or )..' articles', raw_args.class and yesno(args[tf_prefix..'QUALITY']) and args.QUALITY_CRITERIA~='custom', raw_args['tf '..k..' importance'] and (args.IMPORTANCE_SCALE or ), tf_prefix, args[tf_prefix..'NAME'] )) check_other_category(args[tf_prefix .. 'MAIN_CAT']) for _, p in ipairs(taskforce_categories[k] or) do check_other_category(args[tf_prefix .. 'CAT_' .. p]) endend----------------------------- Template categories -------------------------------local pagetype_module = require('Module:Pagetype')._mainlocal pagetype = function(title) return pagetype_moduleendif on_sandbox then add_tracking(cfg_tp.template_categories.sandbox, true)elseif inactive_status then add_tracking(cfg_tp.template_categories.inactive)else if raw_args.class then add_tracking(cfg_tp.template_categories.with_quality) else add_tracking(cfg_tp.template_categories.without_quality) end if (args.PROJECT_NAME

'WikiProject '..project or not args.PROJECT_NAME) and current_page.rootPageTitle.prefixedText~='Template:WikiProject ' .. project then add_tracking(cfg_tp.template_categories.non_standard) end local template_category = mw.title.new('Category:' .. project_name .. ' templates') if template_category.exists and pagetype(template_category)~='redirect' then table.insert(tracking_cats, wikilink(template_category.fullText, '*')) else local template_category2 = mw.title.new('Category:' .. project_name) if template_category2.exists and pagetype(template_category2)~='redirect' then table.insert(tracking_cats, wikilink(template_category2.fullText)) else add_tracking end endend----------------------------- Check parameters ----------------------------------local parameters = local append_table = function(source) for _, v in ipairs(source) do table.insert(parameters, v) endendappend_table(cfg_tp.parameters.parameters)for _, k in ipairs(task_forces) do local task_force_parameters = local prefix = string.format(cfg_tp.parameters.taskforce.prefix, k) for _, p in ipairs(cfg_tp.parameters.taskforce.suffix) do table.insert(task_force_parameters, prefix .. p) end for _, p in ipairs(taskforce_categories[k] or) do table.insert(task_force_parameters, 'tf ' .. k .. ' cat ' .. p) table.insert(task_force_parameters, prefix .. 'CAT_' .. p) end append_table(task_force_parameters)endfor _, k in ipairs(notes) do local note_parameters = local prefix = string.format(cfg_tp.parameters.note.prefix, k) for _, p in ipairs(cfg_tp.parameters.note.suffix) do table.insert(note_parameters, prefix .. p) end append_table(note_parameters) check_other_category(args[prefix .. 'CAT'])endfor _, set in ipairs(cfg_tp.parameters.extra) do local allow_parameters = false if set.trigger then table.insert(parameters, set.trigger) allow_parameters = raw_args[set.trigger] and true elseif set.triggers then append_table(set.triggers) for _, trig in ipairs(set.triggers) do if raw_args[trig] then allow_parameters = true end end end if allow_parameters then append_table(set.parameters) if set.categories then append_table(set.categories) for _, cat in ipairs(set.categories) do check_other_category(args[cat]) end end endendparameters.preview = cfg_tp.parameters.previewparameters.unknown = on_sandbox and or cfg_tp.parameters.categorylocal parameter_check = current_page.rootPageTitle.text

'WikiProject Military history' and or require('Module:Check for unknown parameters')._check(parameters, raw_args)----------------------------- Other categories ----------------------------------if raw_args.attention then local attention_cat = args.ATTENTION_CAT or string.format(cfg.attention.default_cat, project) check_other_category(attention_cat)endif raw_args.infobox then local infobox_cat = args.INFOBOX_CAT or string.format(cfg.infobox.default_cat, project) check_other_category(infobox_cat)endif raw_args.auto then local auto_cat = args.AUTO_ASSESS_CAT or string.format(cfg.auto.default_cat, project) check_other_category(auto_cat)endcheck_other_category(args.MAIN_CAT)if #missing_cats>0 then local list = mw.html.create('ul') for _, missing in ipairs(missing_cats) do list:tag('li'):wikitext(missing):done end list:done table.insert(warnings, messageBox('ombox',)) if red_other_cats_in_use then add_tracking(cfg_tp.check_other.tracking) endend----------------------------- Produce notices -----------------------------------local notice_html, notice_listif #notices>=1 then notice_html = mw.html.create('ul') for _, notice in ipairs(notices) do notice_html:tag('li'):wikitext(notice):done end notice_list = ' ' .. cfg_tp.notice_text .. tostring(notice_html)endlocal info = messageBox('ombox',)----------------------------- Auto documentation --------------------------------local td_params, auto_doc, parameter_name =,, local basic, full, parameter_used, param =,,, local class_module = require('Module:Class')local template_code = mw.title.getCurrentTitle:getContentfor _, parameter in pairs(parameters) do parameter_name[parameter] = string.match(template_code, '%|%s*' .. parameter:gsub('%-','%%%-') .. '%s*=%s*