Module:WikiProject banner/auxiliary

This module contains extra functions not frequently used by Module:WikiProject banner.

B-class checklist

Enables a B-class checklist. There are six official criteria (although some projects use five) that an article needs to satisfy in order to be classified as B-class. A checklist can provide a helpful aid for editors to show where an article needs improvement.

Syntax
{{#invoke:WikiProject banner|main
...

 |b1={{{b1|}}}
 |b2={{{b2|}}}
 |b3={{{b3|}}}
 |b4={{{b4|}}}
 |b5={{{b5|}}}
 |b6={{{b6|}}}
}}

Required parameters

  • The six B-Class criteria: b1, b2, b3, b4, b5, b6

Optional parameters

  • B_DISPLAY_ON_START – if set to "yes", the checklist will be displayed on every Start-class article. The default behaviour is to only display on Start-class when one or more of the parameters b1-b6 have been filled in.
  • B_MAIN_CAT – specifies a category to use when any of the checklist parameters are blank.
  • B1_CAT to B6_CAT – specifies individual categories to use when the individual checklist parameters are blank or set to no.

Custom parameter names

The standard parameter names (i.e. b1, b2, etc.) should be passed as an alternative to any custom parameters (e.g. B-Class-1, B-Class-2, etc.). For example:

b1={{{B-Class-1|{{{b1|}}}}}}

If only the standard parameters are used, then eg: b1={{{b1|}}}, etc. is fine.

Collapsing task forces

By default, the list of task forces will be collapsed into a show/hide box if there are more than 5 task forces. You can configure this behaviour with the following parameters:

  • TF_COLLAPSE – the threshold number of task forces for them to collapse, e.g. if |TF_COLLAPSE=3 then they will collapse whenever there are more than 3 task forces.
  • TF_HEADER – the heading for the collapsed section. The default is Associated task forces:

To-do list

This enables a project to-do list or other similar list to be integrated into a project banner.

Syntax
|TODO_LINK        = 
|TODO_TEXT        = 
 |TODO_TITLE      = 
 |TODO_EDITLINKS  =

There are two main parameters, |TODO_LINK= and |TODO_TEXT=. Only one should be used at any time. If the to-do list is located on a different page then TODO_LINK should be used. However, if you've just got some text to include then you can use the TODO_TEXT option instead.

If you are using |TODO_LINK= and don't want to see the edit links at the top of the textbox, set TODO_EDITLINKS=no.

Example

{{#invoke:WikiProject banner|main
|PROJECT          = Tulips
 |listas={{{listas|}}}
|NAME             = The Tulip taskforce
|IMAGE_LEFT       = Tulipa suaveolens floriade to Canberra.jpg
|TODO_LINK        = Template:To do/to do
 |TODO_TITLE      = WikiProject Tulips To-do
}}
Produces:
WikiProject iconTulips
WikiProject iconThis article is within the scope of WikiProject Tulips, a collaborative effort to improve the coverage of Tulips articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
WikiProject Tulips To-do:

(Entry last updated 21 October 2026)

  • This is just a test to-do list to help editors make sure that the text
  • shows
    1. up
    2. correctly
  • Normally, the "/to do" subpage should only be created under the article's Talk page, unless it is a notice board or project page.
  • To use this template for an article, insert {{to do}} at the top of that article's Talk discussion page. To use it for a project or as your own personal list, add it to the project page or your user page, respectively.

Quality/importance category intersection

This feature adds categories which combine quality and importance such as Category:Start-Class High-importance Kent-related articles. It has no visible output.

It takes the following parameters:

Required parameters

Optional parameters

  • QII_SUPPRESS_NA – can be set to yes to stop categories being added when either class or importance is "NA". These can also be set individually:
    • QII_SUPPRESS_NA_CLASS – can be set to yes to stop categories being added when class=NA
    • QII_SUPPRESS_NA_IMPORTANCE – can be set to yes to stop categories being added when importance=NA
  • QII_UNASSESSED_APPENDIX – text to append to the class when it is "Unassessed", e.g. |QII_UNASSESSED_APPENDIX=-Class

Image-needed note

Syntax
|image-needed={{{needs-image|}}}
 |IM_IMAGE =
 |image-details={{{details|}}}
 |image-location={{{location|}}}
 |IM_LOCATION_CATEGORY =
 |image-topic={{{topic|}}}
 |IM_TOPIC_CATEGORY =
 |image-type={{{type|}}}

This feature adds a note than can be used to track when articles needs an image, photograph, diagram, illustration, etc. It will populate various categories such as

It takes the following parameters:

Required parameters

  • image-needed – pass through whichever parameter you are using to trigger this note, e.g. |image-needed={{{needs-image|}}}.

Optional parameters

  • IM_IMAGE – specifies the icon to be used (without the File namespace prefix); the default is ([[File:Camera-photo.svg|20px]]).
  • image-type – pass through the type which can be used to accommodate other components that are needed, e.g. diagram, equation, map, etc. If this is not specified then "image or photograph" is used. E.g. |image-type={{{type|}}}.
  • image-details – to allow an editor to pass more details about the required image, e.g. |image-details={{{details|}}}.
  • image-location – pass this parameter through to allow an editor to specify the location of the requested image, e.g. |image-location={{{location|}}}. This will also populate categories of the form Category:Wikipedia requested photographs in Scotland.
  • IM_LOCATION_CATEGORY – a default category to use when the location is not specified or leads to a non-existent category.
  • image-topic – pass this through to allow an editor to specify a topic area that the photograph relates to, e.g. |image-topic={{{topic|}}}. This will populate categories such as Category:Wikipedia requested photographs of toys.
  • IM_TOPIC_CATEGORY – a default category in case the topic is not specified or leads to a non-existent category, e.g. |IM_TOPIC_CATEGORY=Wikipedia requested images of politics.

Collaboration note

Syntax
|collaboration-candidate={{{**PARAMETER**|}}}
|collaboration-current={{{**PARAMETER**|}}}
|collaboration-past={{{**PARAMETER**|}}}
 |COLL_LINK          = 
 |COLL_TEXT          =
 |COLL_IMAGE         = 
 |COLL_CANDIDATE_CAT = 
 |COLL_CURRENT_CAT   = 
 |COLL_PAST_CAT      =

This feature enables a project collaboration system to be integrated into a project banner. The following parameters are used:

Required parameters

  • collaboration-candidate – pass the parameter that will trigger the collaboration candidate note, if used, e.g. |collaboration-candidate={{{collaboration-candidate|}}}
  • collaboration-current – the parameter that will trigger the current collaboration note, if used. E.g. |collaboration-current={{{collaboration|}}}
  • collaboration-past – the parameter that will trigger the past collaboration note, if used. e.g. |collaboration-past={{{past-collaboration|}}}
  • COLL_LINK – the full link to where the review for the particular article is held. E.g. |COLL_LINK=Wikipedia:WikiProject Paranormal/Collaboration

Optional parameters

  • COLL_TEXT – the text to display in place of the default "project collaboration", e.g. |COLL_TEXT=Collaboration of the Month
  • COLL_IMAGE – the name of the image to use. If not specified then File:Crystal 128 kuser.png is used.
  • COLL_CANDIDATE_CAT – if defined, pages using |candidate=yes will be categorised into this category, e.g. |COLL_CANDIDATE_CAT=Paranormal collaboration candidates → Category:Paranormal collaboration candidates
  • COLL_CURRENT_CAT – if defined, pages using |current=yes will be categorised into this category, e.g. |COLL_CURRENT_CAT=Paranormal collaborations → Category:Paranormal collaborations
  • COLL_PAST_CAT – if defined, pages using |past=yes will be categorised into this category, e.g. |COLL_PAST_CAT=Past paranormal collaborations → Category:Past paranormal collaborations

A-class review note

Syntax
|a class={{{**PARAMETER**|}}}
 |ACR_SUBPAGE_LINK      = 
 |ACR_REVIEW_LINK       = 
 |ACR_PASS_CAT          = 
 |ACR_FAIL_CAT          = 
 |ACR_CURRENT_CAT       = 
 |ACR_PRELOAD           =

This feature enables an A-Class review process to be integrated into a project banner. The following parameters are used:

Required parameters

  • a class – the parameter that will trigger the note. Accepted values are "pass", "fail", "current" (any capitalisation); everything else is treated as null. Eg: a class={{{A-Class|}}}
  • ACR_SUBPAGE_LINK – the full link to where the review for this particular article is held. Eg: Wikipedia:WikiProject Tulips/Assessment/{{SUBJECTPAGENAME}}
  • ACR_REVIEW_LINK – the full link to the main A-Class review page (where instructions etc. are held). Eg: Wikipedia:WikiProject Tulips/Review#A-Class review

Optional parameters

  • ACR_PASS_CAT – pages using |a class=pass will be categorised into this category. Eg: Successful requests for Tulips A-Class review → Category:Successful requests for Tulips A-Class review
  • ACR_FAIL_CAT – pages using |a class=fail will be categorised into this category. Eg: Failed requests for Tulips A-Class review → Category:Failed requests for Tulips A-Class review
  • ACR_CURRENT_CAT – pages using |a class=current will be categorised into this category. Eg: Current requests for Tulips A-Class review → Category:Current requests for Tulips A-Class review
  • ACR_IMAGE – a custom image can be set, using the same syntax as for other note images. Eg: Exquisite-kfind.png
  • ACR_SIZE – a custom image size can be set, using the usual note syntax. Eg: 20x20px
  • ACR_INVALID_CAT – pages specifying the A Class parameter without a valid SUBPAGE_LINK page existing will be categorised into this category.
  • ACR_PRELOAD – preload template, to be used when creating a new A-class review discussion page (example).

Peer review note

Syntax
|peer review={{{**PARAMETER**|}}}
|old peer review={{{**PARAMETER**|}}}
 |peer review title={{{**PARAMETER**|}}}
 |PR_LINK           = 
 |PR_IMAGE          = 
 |PR_CAT            = 
 |PR_OLD_CAT        = 
 |PR_INVALID_CAT    =

This feature enables a peer review process to be integrated into a project banner. The following parameters are used:

Required parameters

  • peer review – the parameter that will trigger the active peer review note; should be passed through, e.g. |peer review={{{peer-review|}}}
  • old peer review – the parameter that will trigger the old peer review note; should be passed through, e.g. |old peer review={{{old-peer-review|}}}
  • PR_LINK – the full link to where the review for this particular article is held, e.g. |PR_LINK=Wikipedia:WikiProject Tulips/Assessment

Optional parameters

  • PR_IMAGE – the name of the image to use. If not specified then File:Exquisite-kfind.png is used.
  • PR_CAT – if defined, pages using |peer review=yes will be categorised into this category, e.g. |PR_CAT=Requests for Tulips peer review → Category:Requests for Tulips peer review
  • PR_OLD_CAT – if defined, pages using |old peer review=yes will be categorised into this category.
  • peer review title – If the page has been moved since it was reviewed, pass this parameter to specify the old page title (the one the review was archived under) to make the link point correctly to the review.
  • PR_INVALID_CAT – if defined, pages without a valid existing peer review page will be categorised into this category.

require('strict')
local p = {}
local sandbox-- = '/sandbox' -- BE SURE TO COMMENT OUT this definition when deploying to live
local cfg = mw.loadData('Module:WikiProject banner/config' .. (sandbox or ''))
local yesno = require('Module:Yesno')
local lang = mw.getLanguage(cfg.language)

p.b_checklist = function(args, raw_args, class, demo, assessment_link)
---------------------------
-- B-class checklist ------
---------------------------
local show_checklist = false
local parameters_used = args.b1 or args.b2 or args.b3 or args.b4 or args.b5 or args.b6
if (class=='B' or class=='C' or class=='BL' or class=='CL')-- always displayed on C or B
	or ((class=='Start' or class=='List') and yesno(args.B_DISPLAY_ON_START))-- show on Start/List if option selected
	or ((class=='Start' or class=='Stub') and parameters_used) then-- show on Start or Stub if any parameters used
	show_checklist = true
end
if show_checklist then
	local scale = args.QUALITY_CRITERIA=='custom' and assessment_link and assessment_link..'#'..lang:ucfirst(cfg.quality.name)
		or cfg.b_checklist.default_scale
	local text = cfg.b_checklist.text:format(
		parameters_used and cfg.b_checklist.checked or cfg.b_checklist.not_checked,
		scale
	)
	local syntax = mw.html.create('ul')
		:css('font-size', '88%')
		:css('margin', '0px')
		:css('font-family', 'monospace, sans-serif')
		:css('padding', '1em')
		:css('border', '1px dashed #2f6fab')
		:css('background-color', '#f9f9f9')
		:css('color', 'black')
		:css('line-height', '1.1em')
		:css('list-style', 'none')
	local criteria = mw.html.create('ol')
	for i = 1, 6 do
		local b = raw_args['b'..i]
		if b and b~='unused' then -- criterion in use
			b = cfg.b_checklist.mask[b:lower()] or cfg.b_checklist.mask.default
			local image = '[[File:' .. cfg.b_checklist.icon[b] .. '.svg|16x16px|link=|alt=]]'
			local failed_cat = args['B'..i..'_CAT']
			local category = ''
			if b~='y' and b~='x' and failed_cat and not demo then -- criterion failed
				category = '[[Category:' .. failed_cat .. ']]'
			end
			if (b=='u' or b=='i') and args.B_MAIN_CAT and not demo then -- unevaluated or invalid parameter
				category = category .. '[[Category:' .. args.B_MAIN_CAT .. ']]'
			end
			local status = mw.html.create('span')
				:css('font-style', 'italic')
				:wikitext(cfg.b_checklist.status[b])
			local criterion = mw.html.create('li')
				:wikitext(image .. ' ' .. cfg.b_checklist.criteria[i] .. ': ')
				:node(status)
				:wikitext(category)
			criteria:node(criterion)
			local new_syntax = mw.html.create('li')
				:addClass('nowrap')
				:wikitext(cfg.b_checklist.syntax.prompt:format(
					tostring(i),
					cfg.b_checklist.criteria[i] .. string.rep(
						' ',
						cfg.b_checklist.syntax.max_width-#cfg.b_checklist.criteria[i]
					)
				))
			syntax:node(new_syntax)
		end
	end
	local prompt
	if not parameters_used then
		prompt = mw.html.create('span')
			:wikitext(cfg.b_checklist.syntax.text:format(tostring(mw.title.getCurrentTitle():fullUrl({action = 'edit'}))))
			:node(syntax)			
			:wikitext(cfg.b_checklist.syntax.assess)
	end
	local col1 = mw.html.create('td')
		:addClass('class-b')
		:css('padding-bottom', '5px')
		:wikitext(cfg.b_checklist.image)
	local col211 = mw.html.create('th')
		:addClass('wpb-collapsed-head mbox-text')
		:attr('colspan', '3')
		:css('font-weight', 'normal')
		:wikitext(text)
	local col212 = mw.html.create('th')
		:css('min-width', '3em')-- empty cell for show/hide toggle
	local row21 = mw.html.create('tr')
		:node(col211)
		:node(col212)
	local col221 = mw.html.create('td')
		:css('font-size', '90%')
		:node(criteria)
	local col222 = mw.html.create('td')
		:css('font-size', '88%')
		:node(prompt)
	local row22 = mw.html.create('tr')
		:node(col221)
		:node(col222)
	local table2 = mw.html.create('table')
		:addClass('plainlinks mw-collapsible mw-collapsed')
		:node(row21)
		:node(row22)
	local col2 = mw.html.create('td')
		:addClass('wpb-collapsed-notes')
		:node(table2)
	return mw.html.create('tr')
		:node(col1)
		:node(col2)
end
end

p.todo_list = function(args, frame)
---------------------------
-- To-do list -------------
---------------------------
local list
if args.TODO_LINK then
	local link = function(action)
		local url = mw.uri.fullUrl(args.TODO_LINK, {action = action})
		return mw.html.create('li'):wikitext('[' .. tostring(url) .. ' ' .. cfg.todo_list[action] .. ']')
	end
	local links = yesno(args.TODO_EDITLINKS or true, 'true') and frame:expandTemplate{title = 'Flat list', args = {
		class = 'plainlinks',
		style = 'text-align:center;font-size:90%;',
		[1] = tostring(mw.html.create('ul')
			:node(link('edit'))
			:node(link('history'))
			:node(link('watch'))
			:node(link('purge'))
		)
	}} or ''
	list = links .. '\n' .. frame:expandTemplate{title = args.TODO_LINK}
else
	list = ('\n' .. args.TODO_TEXT) or ''
end
local titlecell = mw.html.create('th')
	:css('text-align', 'left')
	:css('padding', '0.2em 2px 0.2em 0')
	:cssText(args.TODO_TITLE_STYLE)
	:wikitext((args.TODO_TITLE or cfg.todo_list.default_title) .. ':')
local listcell = mw.html.create('td')
	:css('text-align', 'left')
	:css('padding', '5px')
	:css('background-color', 'var(--background-color-base, #fff)')
	:css('color', 'inherit')
	:css('border', '1px solid var(--border-color-base, #a2a9b1)')
	:css('margin-top', '5px')
	:cssText(args.TODO_STYLE)
	:wikitext(list)
local onecellrow = function(cell)
	return mw.html.create('tr'):node(cell)
end
local table1 = mw.html.create('table')
	:addClass('mw-collapsible mw-collapsed')
	:css('width', '100%')
	:node(onecellrow(titlecell))
	:node(onecellrow(listcell))
local cell1 = mw.html.create('td')
	:attr('colspan', '3')
	:css('padding', '0')
	:node(table1)
return onecellrow(cell1)
end
p.todo_list_ = function(frame)
	return p.todo_list(frame.args, frame)
end

p.quality_importance_insection = function(args, class, importance, importance_name, assessment_cat, article, tf_prefix)
---------------------------
-- Category intersection --
---------------------------
local prefix = tf_prefix or ''
if class=='NA' and (yesno(args[prefix..'QII_SUPPRESS_NA']) or yesno(args[prefix..'QII_SUPPRESS_NA_CLASS'])) then
	return nil
end
if importance=='NA' and (yesno(args[prefix..'QII_SUPPRESS_NA']) or yesno(args[prefix..'QII_SUPPRESS_NA_IMPORTANCE'])) then
	return nil
end
local form = args[prefix..'QII_FORMAT']:gsub('C', '_C_'):gsub('I', '_I_'):gsub('T', '_T_')
if not class or not importance or not form then
	return nil
end
local new_class
if class=='' then
	new_class = 'Unassessed' .. (args[prefix..'QII_UNASSESSED_APPENDIX'] or '')
else
	new_class = class .. '-Class'
end
local check_cat = function (typ)
	local cat_name = form:gsub('_C_', new_class):gsub('_I_', importance .. '-' .. importance_name):gsub('_T_', assessment_cat .. ' ' .. typ)
	local cat = mw.title.new('Category:' .. cat_name)
	return cat.exists and #cat:getContent()>0 and cat_name
end
local cat = check_cat(article and 'articles' or 'pages')
return cat
end

p.image_needed = function(args)
---------------------------
-- Image needed -----------
---------------------------
local type = cfg.image_needed.default_type
if args['image-type'] then
	local add_article = function(word)
		local article = cfg.image_needed.article.consonant
		if cfg.image_needed.vowels[word:sub(1, 1)] then
			article = cfg.image_needed.article.vowel
		end
		return article .. ' <b>' .. word .. '</b>'
	end
	type = add_article(args['image-type'])
end
local details = ''
if args['image-details'] then
	details = ' ' .. cfg.image_needed.details:format(args['image-details'])
end
local location = ''
if args['image-location'] then
	local location_cat = mw.title.new('Category:Wikipedians in ' .. args['image-location'])
	if location_cat.exists then
		location = ' ' .. cfg.image_needed.help:format('[[:' .. location_cat.fullText .. '|' .. location_cat.text .. ']]')
	end
end
local category_exists = function(category)
	local title = mw.title.new('Category:' .. category)
	if title.exists then
		return category
	end
end
return {
	text = cfg.image_needed.text:format(type, details, location),
	image_name = args.IM_IMAGE or cfg.image_needed.default_image,
	category = args['image-location'] and category_exists(
		cfg.image_needed.location:format(
			args['image-type'] or 'photograph',
			args['image-location']
		)
	) or args.IM_LOCATION_CATEGORY,
	category2 = args['image-topic'] and category_exists(
		cfg.image_needed.topic:format(
			args['image-type'] or 'photograph',
			args['image-topic']
		)
	) or args.IM_TOPIC_CATEGORY
}
end

p.collaboration = function(args, title)
---------------------------
-- Collaboration ----------
---------------------------
local image = args.COLL_IMAGE or cfg.collaboration.default_image
local link = '[[' .. (args.COLL_LINK or '') .. '|' .. (args.COLL_TEXT or cfg.collaboration.default_text) .. ']]'
local note_args = {candidate = {}, current = {}, past = {}}
if yesno(args['collaboration-candidate'], true) then
	local subpage_link = (args.COLL_LINK or '') .. '#' .. title.subjectPageTitle.text
	note_args.candidate = {
		text = cfg.collaboration.candidate:format(subpage_link, link),
		image_name = image,
		size = cfg.collaboration.size,
		category = args.COLL_CANDIDATE_CAT
	}
end
if yesno(args['collaboration-current'], true) then
	note_args.current = {
		text = cfg.collaboration.current:format(link),
		image_name = image,
		size = cfg.collaboration.size,
		category = args.COLL_CURRENT_CAT
	}
end
if yesno(args['collaboration-past'], true) then
	note_args.past = {
		text = cfg.collaboration.past:format(link),
		image_name = image,
		size = cfg.collaboration.size,
		category = args.COLL_PAST_CAT
	}
end
return note_args
end

p.a_class = function(args, lang)
---------------------------
-- A-class review ---------
---------------------------
local status = cfg.a_class.mask[lang:lc(args['a class'])]
if status==nil then
	return {}
end
local link_exists = args.ACR_SUBPAGE_LINK and mw.title.new(args.ACR_SUBPAGE_LINK).exists or false
local link = mw.html.create('span'):css('font-weight', 'bold')
local label = cfg.a_class.status[status]
if args.ACR_SUBPAGE_LINK and status=='current' and not link_exists and args.ACR_PRELOAD then -- use custom preload template when creating discussion page
	local url = mw.uri.fullUrl(args.ACR_SUBPAGE_LINK, {
		action = 'edit',
		preload = args.ACR_PRELOAD,
		summary = cfg.a_class.create_summary
	})
	link:wikitext('[' .. tostring(url) .. ' ' .. label .. ']')
else
	link:wikitext('[[' .. (args.ACR_SUBPAGE_LINK or '') .. '|' .. label .. ']]')
end
return {
	text = cfg.a_class.text:format(
		tostring(link),
		args.ACR_REVIEW_LINK or ''
	),
	image_name = args.ACR_IMAGE or cfg.a_class.icon[status],
	size = args.ACR_SIZE or '18x18px',
	background = cfg.a_class.background,
	color = cfg.a_class.color,
	category = args[cfg.a_class.category[status]],
	category2 = not link_exists and args.ACR_INVALID_CAT
}
end

p.peer_review = function(args, title)
---------------------------
-- Peer review ------------
---------------------------
local image = args.PR_IMAGE or cfg.peer_review.default_image
local size = args.PR_SIZE or cfg.peer_review.size
local link = args.PR_LINK or ''
local pr_title = args['peer review title'] and mw.title.new(args['peer review title']) or title
local subpage_link = link .. '/' .. pr_title.subjectPageTitle.text
local invalid_cat = not mw.title.new(subpage_link).exists and args.PR_INVALID_CAT
local note_args = {current = {}, past = {}}
if yesno(args['peer review'], true) then
	note_args.current = {
		text = cfg.peer_review.current:format(subpage_link, link),
		image_name = image,
		size = size,
		category = args.PR_CAT,
		category2 = invalid_cat
	}
end
if yesno(args['old peer review'], true) then
	note_args.past = {
		text = cfg.peer_review.past:format(link, subpage_link),
		image_name = image,
		size = size,
		category = args.PR_OLD_CAT,
		category2 = invalid_cat
	}
end
return note_args
end

p.map_config = function(config, pargs)
---------------------------
-- Map configuration ------
---------------------------
local args, raw_args, parent_args, v_par = {}, {}, {}, {}
local punct = {'-', '_', ' '}
local normalise = function(s) -- convert parameter name to lowercase and collapse spaces and commonly used punctuation
	local norm = s -- string.lower(s) for case insensitivity
	if type(s)=='string' then -- this will fail for positional parameters
		for _, p in ipairs(punct) do
			norm = norm:gsub(p, '')
		end
	end
	return norm
end
if pargs.taskforce then -- split comma-separated list
	for taskforce in mw.text.gsplit(pargs.taskforce, ',%s*') do
		pargs[taskforce] = 'yes'
	end
end
for k, v in pairs(pargs) do -- build table of normalised parameters
	local normk = normalise(k)
	if not parent_args[normk] then
		parent_args[normk] = v
	end
end
local pan = function(s) -- function to look up normalised argument from parent frame
	if type(s)=='string' then -- single parameter
		return parent_args[normalise(s)]
	elseif type(s)=='table' then -- multiple parameter aliases
		for _, p in ipairs(s) do
			local normp = parent_args[normalise(p)]
			if normp then
				return normp
			end
		end
	end
end
local AddToValid
AddToValid = function(s) -- function to add string or table of strings to list of valid parameters
	if type(s)=='string' then
		table.insert(v_par, s)
	elseif type(s)=='table' then
		for _, p in ipairs(s) do
			AddToValid(p)
		end
	end
end
local first = function(s) -- function gives parameter or first parameter from list of aliases, for use in documentation
	if type(s)=='string' then -- single parameter
		return s
	elseif type(s)=='table' then -- multiple parameter aliases
		return s[1]
	end
end
local current_title = mw.title.getCurrentTitle()
args.IMAGE_LEFT = config.image and config.image.file or config.image
args.IMAGE_LEFT_SIZE = config.image and config.image.size
args.MAIN_TEXT = config.text
args.MAIN_CAT = config.category
if config.assessment then
	args.ASSESSMENT_LINK = config.assessment.link
	args.ASSESSMENT_CAT = config.assessment.topic
	if config.assessment.quality then
		raw_args.class = pargs.class or '' -- pass raw class so it can be tracked by [[Category:WikiProject banners with ignored class parameter]], etc.
	end
	if config.assessment.priority then
		AddToValid{'importance', 'priority'}
		args.importance = parent_args.importance
		raw_args.importance = 'importance'
	end
end
if config.taskforces then
	args.TF_SIZE = config.taskforces.size
	args.TF_COLLAPSE = config.taskforces.collapse
	args.TF_HEADER = config.taskforces.header
	AddToValid('taskforce')
	if config.taskforces.list then
		for k, cfg in ipairs(config.taskforces.list) do
			AddToValid{cfg.parameter, cfg.priority}
			raw_args['tf ' .. k] = first(cfg.parameter) -- trigger display on template page
			args['tf ' .. k] = pan(cfg.parameter)
			args['TF_' .. k .. '_NAME'] = cfg.name
			args['TF_' .. k .. '_LINK'] = cfg.link
			args['TF_' .. k .. '_NESTED'] = cfg.nested
			args['TF_' .. k .. '_IMAGE'] = cfg.image
			args['TF_' .. k .. '_SIZE'] = cfg.size
			args['TF_' .. k .. '_MAIN_CAT'] = cfg.category
			args['TF_' .. k .. '_QUALITY'] = cfg.quality and 'yes'
			args['TF_' .. k .. '_ASSESSMENT_CAT'] = cfg.topic
			args['tf ' .. k .. ' importance'] = pan(cfg.priority)
			raw_args['tf ' .. k .. ' importance'] = first(cfg.priority)
			if cfg.additional then
				for n, a in ipairs(cfg.additional) do
					AddToValid(a.parameter)
					args['tf ' .. k .. ' cat ' .. n] = pan(a.parameter)
					args['TF_' .. k .. '_CAT_' .. n] = a.category
				end
			end
		end
	end
end
if config.notes then
	args.NOTE_SIZE = config.notes.size
	args.COLLAPSED = config.notes.collapse
	args.COLLAPSED_HEAD = config.notes.header
	if config.notes.attention then
		AddToValid(config.notes.attention.parameter)
		raw_args.attention = first(config.notes.attention.parameter)
		args.attention = pan(config.notes.attention.parameter)
		args.ATTENTION_CAT = config.notes.attention.category
	end
	if config.notes.infobox then
		AddToValid(config.notes.infobox.parameter)
		raw_args.infobox = first(config.notes.infobox.parameter)
		args.infobox = pan(config.notes.infobox.parameter)
		args.INFOBOX_CAT = config.notes.infobox.category
	end
	if config.notes.auto then
		AddToValid(config.notes.auto.parameter)
		raw_args.auto = first(config.notes.auto.parameter)
		args.auto = pan(config.notes.auto.parameter)
		args.AUTO_ASSESS_CAT = config.notes.auto.category
	end
	if config.notes.collaboration then
		args.COLL_LINK = config.notes.collaboration.link:gsub('_FULLPAGENAME_', current_title.fullText)
		args.COLL_TEXT = config.notes.collaboration.name
		args.COLL_IMAGE = config.notes.collaboration.image
		AddToValid{config.notes.collaboration.candidate.parameter, config.notes.collaboration.current.parameter, config.notes.collaboration.past.parameter}
		raw_args['collaboration-candidate'] = first(config.notes.collaboration.candidate.parameter)
		args['collaboration-candidate'] = pan(config.notes.collaboration.candidate.parameter)
		args.COLL_CANDIDATE_CAT = config.notes.collaboration.candidate.category
		raw_args['collaboration-current'] = first(config.notes.collaboration.current.parameter)
		args['collaboration-current'] = pan(config.notes.collaboration.current.parameter)
		args.COLL_CURRENT_CAT  = config.notes.collaboration.current.category
		raw_args['collaboration-past'] = first(config.notes.collaboration.past.parameter)
		args['collaboration-past'] = pan(config.notes.collaboration.past.parameter)
		args.COLL_PAST_CAT = config.notes.collaboration.past.category
	end
	if config.notes.image then
		AddToValid{config.notes.image.parameters.needed, config.notes.image.parameters.details, config.notes.image.parameters.type, config.notes.image.parameters.location, config.notes.image.parameters.topic}
		raw_args['image-needed'] = first(config.notes.image.parameters.needed)
		args['image-needed'] = pan(config.notes.image.parameters.needed)
		args['image-type'] = pan(config.notes.image.parameters.type)
		args['image-details'] = pan(config.notes.image.parameters.details)
		args['image-location'] = pan(config.notes.image.parameters.location)
		args['image-topic'] = pan(config.notes.image.parameters.topic)
		args.IM_IMAGE = config.notes.image.image
		args.IM_LOCATION_CATEGORY = config.notes.image.categories.location
		args.IM_TOPIC_CATEGORY = config.notes.image.categories.topic
	end
	if config.notes.list then
		for k, cfg in ipairs(config.notes.list) do
			AddToValid(cfg.parameter)
			raw_args['note ' .. k] = first(cfg.parameter) -- trigger display on template page
			args['note ' .. k] = pan(cfg.parameter)
			args['NOTE_'.. k .. '_TEXT'] = cfg.text
			args['NOTE_'.. k .. '_IMAGE'] = cfg.image
			args['NOTE_'.. k .. '_SIZE'] = cfg.size
			args['NOTE_'.. k .. '_CAT'] = cfg.category
		end
	end
end
if config.todo then
	args.TODO_LINK = config.todo.link
	args.TODO_TEXT = config.todo.text
	args.TODO_STYLE = config.todo.style
	args.TODO_TITLE = config.todo.title
	args.TODO_TITLE_STYLE = config.todo.title_style
	args.TODO_EDITLINKS = config.todo.editlinks==false and 'no' or 'yes'
end
if config.doc then
	args.DOC = config.doc
end
args.PORTAL = config.portal
return args, raw_args, v_par
end

return p