Modul:WikiProject banner
Penampilan
| Modul ini telah dinilai berada pada tahap beta, dan sedia untuk digunakan secara meluas. Ia masih baharu dan patut digunakan dengan berhati-hati untuk memastikan bahawa hasil penggunaannya adalah seperti yang dijangkakan. |
| Modul Lua laman ini digunakan pada banyak laman dan perubahan besar-besaran mungkin akan ternampak. Sila uji perubahan di subhalaman modul berkaitan laman kotak pasir atau laman kes ujian, atau pada modul kotak pasir anda. Pertimbang untuk membincang perubahan pada laman perbincangan sebelum melaksanakannya. |
| This module uses TemplateStyles: |
Modul:WikiProject banner/related This module implements Template:WPBannerMeta. Please refer to that template's documentation.
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 auxiliary = cfg.auxiliary_module .. (sandbox or '')
local args_module = require('Module:Arguments')
local mbox = require('Module:Message box').main
local yesno = require('Module:Yesno')
local frame = mw.getCurrentFrame()
local lang = mw.getLanguage(cfg.language)
local current_title = mw.title.getCurrentTitle()
local parameter_format = function(parameter, value)
return frame:expandTemplate{title='para', args={parameter, value or ''}}
end
local wikilink = function(link, display)
if link then
return display and '[['..link..'|'..display..']]' or '[['..link..']]'
else
return display or ''
end
end
local display_error = function(text)
local span = mw.html.create('div')
:addClass('error')
:wikitext(text)
return tostring(span)
end
local image = function(image_name, size, alt, position)
return image_name and '[[File:'
.. image_name
.. (size and '|' .. size or '')
.. (position and '|' .. position or '')
.. (alt and '|alt=' .. alt or '')
.. ']]'
end
local if_exists = function(target, fallback) -- function to add wikilink if target exists
local title = mw.title.new(target)
if title and title.exists then
return wikilink(target)
else
return fallback or target
end
end
local importance_mask = function(importance, scale, banner_name, pagetype, class)
---------------------------
-- Importance mask --------
---------------------------
local importance_normalised
if scale=='inline' then -- pass importance without change
importance_normalised = importance or ''
elseif scale=='subpage' then
local custom_mask = banner_name:subPageTitle('importance')
if custom_mask.exists and #custom_mask:getContent()>1 then -- pass to custom importance mask
importance_normalised = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = {
importance = importance,
class = class,
pagetype = pagetype
}
})
end
else -- standard importance scale
importance_normalised = cfg.importance.na
if pagetype=='article' or pagetype=='set index article' or pagetype=='redirect' or pagetype=='draft' then
local mask = cfg.importance.mask
if importance and mask[importance:lower()] then -- valid importance specified
importance_normalised = mask[importance:lower()]
elseif pagetype=='article' or pagetype=='set index article' then -- unspecified or invalid importance, use "Unknown" for articles
importance_normalised = cfg.importance.unknown
end
end
end
return importance_normalised
end
---------------------------
-- Quality class mask -----
---------------------------
p.readarticleclass = function(options, page) -- used by _main and also Module:Banner shell
page = page or current_title.prefixedText
local get_parameter_value = require('Module:Template parameter value').getParameter
local success, result = get_parameter_value(page, cfg.banner_shell.redirects, 'class', options)
return success and result
-- returns FALSE if banner shell template does not exist on page
-- returns BLANK if class parameter is not defined or is defined blank
-- otherwise returns class parameter
end
p.class_mask = function(class, title, FQS, pagetype, article)
local resolveFQSgrade = function(class)
return FQS and lang:ucfirst(class) or 'NA'
end
local out
title = title or mw.title.getCurrentTitle()
local ns = title.namespace
class = class:match('^%s*(.-)%s*$'):lower()
if pagetype=='redirect' or pagetype=='soft redirect' then
out = resolveFQSgrade('redirect')
elseif pagetype=='disambiguation page' then
out = resolveFQSgrade('disambig')
elseif article or pagetype=='article' or pagetype=='set index article' then
if pagetype=='set index article' then
out = 'List'
elseif class=='start' or class=='stub' then -- Ucfirst
out = lang:ucfirst(class)
elseif class=='b' or class=='c' or class=='fa' or class=='fl' or class=='a' or class=='ga' then -- Upper-case
out = class:upper()
elseif class=='list' or class=='sia' or class=='si' or class=='sl' then-- List
out = 'List'
else
out = '' -- unassessed
end
elseif ns==7 or ns==711 then -- File talk
if class=='fm' then
out = 'FM'
else
out = resolveFQSgrade('file')
end
else
local grade = cfg.quality.ns_to_class[ns] or 'NA'
out = resolveFQSgrade(grade)
end
return out
end
local page_assessment = function(project, class, importance) -- add PageAssessments parser function
local assessment = table.concat({project, class or '', importance or ''},'|')
frame:preprocess('{{#assessment:' .. assessment .. '}}')
end
local bubble = function(text, style)
local out = mw.html.create('span')
:addClass('wpb-header-bubbles')
:addClass(style)
:wikitext(text)
return tostring(out)
end
p._main = function(args, raw_args, demo_page, banner_name, inactive)
---------------------------
-- Initialise parameters --
---------------------------
local project = args.PROJECT or 'PROJECT'
local project_name = args.PROJECT_NAME or 'WikiProject ' .. project
local project_link = mw.title.new(args.PROJECT_LINK or 'Wikipedia:' .. project_name)
local pagetype = demo_page==true and 'article' or require('Module:Pagetype')._main({
page = demo_page,
dab = 'disambiguation page',
sia = 'set index article',
draft = 'draft'
})
local article = pagetype=='article' or pagetype=='set index article'
local rows, nested_ratings, task_forces, notes, categories, taskforce_categories = {}, {}, {}, {}, {}, {}
local add_category = function(category, key)
if category and category~='none' then
table.insert(categories, {category = category, key = key})
end
end
local parse_pt = function(text) -- function to replace _PAGETYPE_ with the actual page type
local ptype = article and 'article' or pagetype -- display "article" for articles otherwise page type
return text and text:gsub('_PAGETYPE_', ptype)
end
for arg_name, arg_value in pairs(args) do
local tf_match = mw.ustring.match(arg_name,'^tf (%d+)$')
local note_match = mw.ustring.match(arg_name,'^note (%d+)$')
if tf_match and yesno(arg_value, true) then
table.insert(task_forces, tf_match)
elseif note_match and yesno(arg_value, true) then
table.insert(notes, note_match)
else
local tf, cat = mw.ustring.match(arg_name,'^tf (%d+) cat (%d+)$')
if tf and yesno(arg_value, true) then
if not taskforce_categories[tf] then -- initialise table
taskforce_categories[tf] = {}
end
table.insert(taskforce_categories[tf], cat)
end
end
end
table.sort(task_forces, function (x, y) return tonumber(x) < tonumber(y) end)
table.sort(notes, function (x, y) return tonumber(x) < tonumber(y) end)
local assessment_category = function(cat, name)
if cat then
return cat:gsub(' articles', '') -- remove "articles" from category
else
return name or ''
end
end
local assessment_cat = assessment_category(args.ASSESSMENT_CAT, project)
---------------------------
-- Location warning -------
---------------------------
local warning = ''
if not current_title.isTalkPage and not demo_page then
local text = cfg.namespace_warning.text:format(
current_title.talkPageTitle.fullText,
parameter_format('category', 'no')
)
local sortkey = current_title.namespace==10 and cfg.namespace_warning.sortkey_on_template_page or cfg.namespace_warning.sortkey
if current_title.namespace==10 then -- on the Template namespace
text = text .. ' ' .. cfg.namespace_warning.on_template_page:format(
parameter_format('BANNER_NAME'),
current_title.prefixedText
)
end
warning = mbox('ombox', {
image = '[[File:' .. cfg.namespace_warning.image .. '|40px]]',
type = cfg.namespace_warning.type_,
text = parse_pt(text)
})
if not current_title.subjectPageTitle:inNamespace(2) then
add_category(cfg.namespace_warning.categories, sortkey)
end
end
---------------------------
-- Substitution warning ---
---------------------------
if args.substcheck=='SUBST' then
local text = cfg.subst_warning.text:format(
project_name,
'<code>{{'..banner_name.prefixedText..'}}</code>'
)
warning = warning .. mbox('ombox', {
image = '[[File:' .. cfg.subst_warning.image .. '|40px]]',
type = cfg.subst_warning.type_,
text = text,
}) .. cfg.subst_warning.categories
end
---------------------------
-- Primary image/text -----
---------------------------
local primary_image = function(image_name, size)
local cell = mw.html.create('td')
if image_name and image_name~='' then
cell:addClass('mbox-image wpb-image')
:wikitext(image(image_name, size, cfg.image.alt))
else
cell:addClass('mbox-empty-cell')
end
return cell
end
local portal = args.PORTAL
local portal_box = portal and frame:expandTemplate{title='Portal', args={portal}} or ''
local main_text = portal_box .. parse_pt(args.MAIN_TEXT or cfg.main_text:format(
project_link.prefixedText,
project_name,
args.MAIN_ARTICLE and if_exists(args.MAIN_ARTICLE) or if_exists(project, project .. ' articles'),
project_link.talkPageTitle.prefixedText
))
local image_left_size = args.IMAGE_LEFT_SIZE or cfg.image.default_size
local metadata = function(class, data)
return mw.html.create('span')
:addClass(class)
:wikitext(data)
end
local text_cell = mw.html.create('td')
:addClass('mbox-text')
:wikitext(main_text)
:tag('span')
:addClass('metadata wpb-metadata')
:node(metadata('wpb-project', project))
:node(metadata('wpb-project_link', project_link.prefixedText))
:node(metadata('wpb-banner_name', banner_name.prefixedText))
:node(metadata('wpb-assessment_cat', assessment_cat))
:done()
local primary_row = mw.html.create('tr')
:node(primary_image(args.IMAGE_LEFT, image_left_size))
:node(text_cell)
:node(primary_image(args.IMAGE_RIGHT, args.IMAGE_RIGHT_SIZE or cfg.image.default_size))
table.insert(rows, primary_row)
---------------------------
-- Banner shell checks ----
---------------------------
local title = demo_page and demo_page~=true and mw.title.new(demo_page) or current_title
local class = p.readarticleclass({ignore_subtemplates=true}, title.prefixedText)
if class then -- banner shell exists
local special_chars = '([%%%(%)%.%+%-%*%?%[%]%^%$])'
local banner_name_escaped = banner_name.text
local page_content = require('Module:Wikitext Parsing' .. (sandbox or '')).PrepareText(title:getContent()) -- get content of current page
local content_without_shell
for capture in mw.ustring.gmatch(page_content, '%b{}') do -- look for possible templates on page
for _, redirect in ipairs(cfg.banner_shell.redirects) do
if mw.ustring.find(capture, '^{{%s*' .. redirect .. '%s*[|}].*}}$') then -- found a banner shell
banner_name_escaped = banner_name_escaped:gsub(special_chars, '%%%1') -- escape each special character
capture = capture:gsub(special_chars, '%%%1')
content_without_shell = mw.ustring.gsub(page_content, capture, '') -- remove banner shell content from page content
end
if content_without_shell then break end
end
if content_without_shell then break end
end
local template_outside_shell
if content_without_shell and mw.ustring.find(content_without_shell, '{{%s*' .. banner_name_escaped .. '%s*[|}]') then -- found banner template outside of the shell
add_category(cfg.banner_shell.category.outside_shell)
end
else -- no banner shell on page
if title.namespace==3 then --User talk namespace
for _, user in ipairs(cfg.banner_shell.valid_users) do
if string.find(title.rootText, user) then
add_category(cfg.banner_shell.category.no_banner_shell)
end
end
elseif title.namespace~=2 then -- not in user namespace
add_category(cfg.banner_shell.category.no_banner_shell)
end
class = ''
end
---------------------------
-- Quality assessment -----
---------------------------
local assessment_link = args.ASSESSMENT_LINK
if not assessment_link then
local fallback = mw.title.new(project_link.prefixedText .. '/Assessment')
assessment_link = fallback.exists and fallback.prefixedText
elseif assessment_link=='no' then
assessment_link = nil
end
local check_fallbacks = function(class, category) -- function to check non-article classes and automatically fall back to NA (or other) class if category does not exist
if article or args.QUALITY_CRITERIA=='custom' then -- no fallbacks for articles or projects with custom quality scales
return class
else -- check fallbacks for non-article classes
local new_class = class
local category_exists = function(class)
local cat = mw.title.new(cfg.quality.assessment_category:format(class, category .. ' ' .. (article and 'articles' or 'pages')))
return cat.exists and #cat:getContent()>0 -- check if category exists and is not blank
end
if class=='FM' and not category_exists('FM') then
new_class = 'File' -- fall back to File-class if FM category does not exist
end
if not category_exists(new_class) then
new_class = 'NA' -- use NA for non-article pages if category does not exist
end
return new_class
end
end
if raw_args.class then -- banner gives quality ratings
class = class and p.class_mask(class, title, true, pagetype, article) -- put PIQA class through standard class mask
if args.QUALITY_CRITERIA=='custom' then -- project has opted out of standard assessment scale and uses a custom mask
local project_class
local custom_mask = banner_name:subPageTitle('class')
if custom_mask.exists and #custom_mask:getContent()>1 then
raw_args.demo_page = demo_page -- send demo_page to custom mask
project_class = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = raw_args
})
if project_class=='' and class and class~='' then -- if unassessed and PIQA class exists, check if it can be inherited
local new_arg_table = {}
for arg, val in pairs(raw_args) do -- construct new argument table to send to custom mask
new_arg_table[arg] = val
end
new_arg_table.class = class -- replace class with inherited class
project_class = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = new_arg_table
}) -- inherit project class from PIQA class normalised by custom mask
end
local category = (project_class=='' and 'Unassessed' or project_class..'-Class') .. ' ' .. assessment_cat .. ' ' .. (article and 'articles' or 'pages')
add_category(category)
if class~=project_class then -- display project class in banner
class = project_class
local rating = project_class=='' and cfg.quality.not_yet or cfg.quality.rated:format(class)
local scale = cfg.quality.project_scale:format(wikilink((assessment_link or '')..'#'..lang:ucfirst(cfg.quality.name), cfg.quality.name))
local cssClass = 'class-' .. (class=='' and 'unassessed' or class:lower())
local class_row = mw.html.create('tr')
:tag('td')
:addClass('assess'):addClass(cssClass)
:wikitext(wikilink(':Category:' .. category, class=='' and '???' or class))
:done()
:tag('td')
:addClass('mbox-text')
:attr('colspan', '2')
:wikitext(parse_pt(cfg.quality.rating:format(rating, scale)))
:done()
table.insert(rows, class_row)
table.insert(
nested_ratings,
1,
bubble(class=='' and 'Unassessed' or (class..'‑class'), cssClass)
)
end
end
else -- project uses standard PIQA assessment
class = check_fallbacks(class, assessment_cat) -- check fallbacks for non-article classes
local category = (class=='' and 'Unassessed' or (class..'-Class')) .. ' ' .. assessment_cat .. ' ' .. (article and 'articles' or 'pages')
add_category(category)
if raw_args.class~='' then -- page has a non-blank class value which is ignored
add_category(cfg.banner_shell.category.ignored_class)
end
end
end
if args.HOOK_ASSESS then
table.insert(rows, args.HOOK_ASSESS)
end
if raw_args.b1 or raw_args.b2 or raw_args.b3 or raw_args.b4 or raw_args.b5 or raw_args.b6 then
local b_checklist = require(auxiliary).b_checklist(args, raw_args, class, demo_page, assessment_link)
table.insert(rows, b_checklist)
end
---------------------------
-- Priority assessment ----
---------------------------
local importance
local importance_name = args.IMPN or (raw_args.priority and 'priority' or cfg.importance.default_name)
if raw_args.importance or raw_args.priority then -- banner gives priority ratings
importance = importance_mask(args.importance or args.priority, args.IMPORTANCE_SCALE, banner_name, pagetype, class)
local category = importance .. '-' .. importance_name .. ' ' .. assessment_cat .. ' ' .. (importance=='NA' and 'pages' or 'articles')
if importance~='NA' then -- display importance rating
local rating = importance=='Unknown' and cfg.importance.not_yet or cfg.importance.rated:format(importance, importance_name)
local scale = assessment_link
and cfg.importance.project_scale:format(assessment_link..'#'..lang:ucfirst(cfg.importance.scale:format(importance_name)), cfg.importance.scale:format(importance_name))
or cfg.importance.default_scale
local importance_rating = parse_pt(cfg.importance.rating:format(rating, scale))
local cssClass = 'import-' .. importance:lower()
local importance_row = mw.html.create('tr')
:tag('td')
:addClass('assess')
:addClass(cssClass)
:wikitext(wikilink(':Category:' .. category, importance=='Unknown' and '???' or importance))
:done()
:tag('td')
:addClass('mbox-text')
:attr('colspan', '2')
:wikitext(importance_rating)
:done()
table.insert(rows, importance_row)
if importance~='Unknown' then -- importance is not NA or Unknown
table.insert(
nested_ratings,
bubble(importance .. '‑' .. importance_name, cssClass)
)
end
end
add_category(category)
if args.QII_FORMAT then
add_category(require(auxiliary).quality_importance_insection(args, class, importance, importance_name, assessment_cat, article))
end
end
if class or importance then
page_assessment(project, class, importance)
end
if args.HOOK_IMPORTANCE then
table.insert(rows, args.HOOK_IMPORTANCE)
end
---------------------------
-- Collapsing sections ----
---------------------------
local collapse_section = function(collapse, new_rows, header)
if collapse then
local header_row = mw.html.create('tr')
:tag('th')
:attr('colspan','3')
:addClass('wpb-collapsed-head')
:wikitext(header)
:done()
local blank_row = mw.html.create('tr')
:tag('td')
:addClass('mbox-image wpb-gutter')
:css('min-width', image_left_size)
:tag('span')
:addClass('wpb-iefix')
:wikitext('/ ')
:done() --TO FIX IE
:done()
:tag('td'):done()
:tag('td'):done()
local collapsed_rows = mw.html.create('table')
:addClass('mw-collapsible mw-collapsed')
:node(header_row)
:node(blank_row)
for _, row in ipairs(new_rows) do
collapsed_rows:node(row)
end
local collapsed_section = mw.html.create('tr')
:tag('td')
:attr('colspan','3')
:addClass('wpb-collapsed-notes')
:node(collapsed_rows)
:done()
table.insert(rows, collapsed_section)
else
for _, row in ipairs(new_rows) do
table.insert(rows, row)
end
end
end
---------------------------
-- Task forces ------------
---------------------------
local nested_tf, taskforce_output = {}, {}
local tf_default_size = args.TF_SIZE or cfg.task_force.default_size
for _, k in ipairs(task_forces) do
local tf_prefix = 'TF_' .. k .. '_'
local tf_assessment_cat = assessment_category(
args[tf_prefix..'ASSESSMENT_CAT'],
args[tf_prefix..'NAME']
)
if yesno(args[tf_prefix..'QUALITY']) and class then
local tf_class = check_fallbacks(class, tf_assessment_cat)
add_category((tf_class=='' and 'Unassessed' or tf_class..'-Class') .. ' ' .. tf_assessment_cat .. ' ' .. (article and 'articles' or 'pages'))
end
local tf_importance, tf_importance_category
if raw_args['tf '..k..' importance'] then
tf_importance = importance_mask(args['tf '..k..' importance'], args.IMPORTANCE_SCALE, banner_name, pagetype, class)
if tf_importance=='Unknown' and yesno(args.INHERIT_IMPORTANCE) then
tf_importance = importance
end
tf_importance_category = tf_importance .. '-' .. importance_name .. ' ' .. tf_assessment_cat .. ' ' .. (tf_importance=='NA' and 'pages' or 'articles')
add_category(tf_importance_category)
end
if args[tf_prefix .. 'TEXT']~='none' then
local portal = args[tf_prefix..'PORTAL'] and frame:expandTemplate{
title='Portal',
args={args[tf_prefix .. 'PORTAL'], height='15', margin='0'}
} or ''
local text = ''
local tf_text = args[tf_prefix..'TEXT'] or args.TF_TEXT
if tf_text then
text = portal .. tf_text
:gsub('_NAME_', args[tf_prefix .. 'NAME'] or '')
:gsub('_LINK_', args[tf_prefix .. 'LINK'] or '')
:gsub('_IMPORTANCE_', tf_importance or '')
else
local tf_importance_text = tf_importance
and tf_importance~='NA'
and tf_importance~='Unknown'
and ' ' .. cfg.task_force.importance:format(
wikilink(':Category:' .. tf_importance_category, tf_importance .. '-' .. importance_name)
) or ''
text = portal .. cfg.task_force.text:format(
wikilink(args[tf_prefix .. 'LINK'], args[tf_prefix .. 'NAME']),
tf_importance_text
)
end
local tf_size = args[tf_prefix .. 'SIZE'] or tf_default_size
local tf_image = ''
if args[tf_prefix .. 'IMAGE'] then
tf_image = image(args[tf_prefix .. 'IMAGE'], tf_size, cfg.task_force.icon_alt, 'center')
end
local taskforce = mw.html.create('tr')
:tag('td')
:wikitext(tf_image)
:done()
:tag('td')
:addClass('mbox-text')
:attr('colspan','2')
:wikitext(parse_pt(text))
:done()
table.insert(taskforce_output, taskforce)
end
if args[tf_prefix..'HOOK'] then
table.insert(taskforce_output, args[tf_prefix..'HOOK'])
end
if args[tf_prefix..'QII_FORMAT'] then
add_category(require(auxiliary).quality_importance_insection(args, class, tf_importance, importance_name, tf_assessment_cat, article, tf_prefix))
end
if args[tf_prefix..'NAME'] then
page_assessment(project..'/'..args[tf_prefix..'NAME'], class, tf_importance)
end
if args[tf_prefix..'MAIN_CAT'] then
add_category(args[tf_prefix..'MAIN_CAT'])
end
if args[tf_prefix..'NESTED'] then
table.insert(nested_tf, wikilink(args[tf_prefix..'LINK'], args[tf_prefix..'NESTED']))
end
for _, c in ipairs(taskforce_categories[k] or {}) do-- add additional taskforce categories
add_category(args[tf_prefix..'CAT_'..c])
end
end
if args.HOOK_TF then
table.insert(taskforce_output, args.HOOK_TF)
end
local threshold = tonumber(args.TF_COLLAPSE) or (args.TF_HEADER and cfg.task_force.lower_threshold) or cfg.task_force.upper_threshold
collapse_section(
#taskforce_output > threshold,
taskforce_output,
args.TF_HEADER or cfg.task_force.header
)
---------------------------
-- Notes ------------------
---------------------------
local note_output = {}
local note_default_size = args.NOTE_SIZE or args.NOTE_1_SIZE or cfg.note.default_size
local render_note = function(note_args)--text, image_name, size, category, sort_prefix
local sort = note_args.sort_prefix and note_args.sort_prefix .. current_title.text
add_category(note_args.category, sort)
add_category(note_args.category2, sort)
if note_args.text then
local note_image = image(
note_args.image_name,
note_args.size or note_default_size,
cfg.note.icon_alt,
'center'
)
local new_note = mw.html.create('tr')
:tag('td')
:css('background', note_args.background)
:wikitext(note_image)
:done()
:tag('td')
:addClass('mbox-text')
:attr('colspan', '2')
:wikitext(parse_pt(note_args.text))
:done()
table.insert(note_output, new_note)
if note_image then
local icon = mw.html.create('span')
:addClass('wpb-header-bubbles')
:wikitext('[[File:' .. note_args.image_name .. '|' .. cfg.note.header_icon .. '|' .. parse_pt(note_args.text) .. '|alt=icon]]')
table.insert(nested_ratings, tostring(icon))
end
end
end
local auto = false
local auto_arg = args.auto and args.auto:lower()
if (auto_arg=='yes' or auto_arg=='stub') and class=='Stub' then
auto = 'stub'
elseif (auto_arg=='inherit' or auto_arg=='length') and class and class~='' then
auto = auto_arg
end
if auto then
local auto_cat = args.AUTO_ASSESS_CAT or cfg.auto.default_cat:format(project)
local auto_text = cfg.auto.assessed:format(
cfg.auto[auto], -- method of automatic assessment
parameter_format('auto')
)
local sort_prefix
if auto=='stub' then
sort_prefix = 'S'
elseif auto=='length' then
sort_prefix = 'L'
elseif auto=='inherit' then
local sort_codes = cfg.auto.sort_codes
sort_prefix = sort_codes[class] or cfg.auto.default_sort_code
end
render_note{
text = auto_text,
image_name = cfg.auto.icon,
category = auto_cat,
sort_prefix = sort_prefix
}
end
if yesno(args.attention, true) then
local attention_cat = args.ATTENTION_CAT or cfg.attention.default_cat:format(project)
render_note{
text = cfg.attention.text,
image_name = cfg.attention.icon,
category = attention_cat
}
end
if yesno(args.infobox, true) then
local infobox_cat = args.INFOBOX_CAT or cfg.infobox.default_cat:format(project)
render_note{
text = cfg.infobox.text,
image_name = cfg.infobox.icon,
category = infobox_cat
}
end
for _, k in ipairs(notes) do
local note_prefix = 'NOTE_' .. k .. '_'
render_note{
text = parse_pt(args[note_prefix..'TEXT']),
image_name = args[note_prefix..'IMAGE'],
size = args[note_prefix..'SIZE'],
category = args[note_prefix..'CAT']
}
end
if yesno(args['image-needed'], true) then
local image_needed_args = require(auxiliary).image_needed(args)
render_note(image_needed_args)
end
if yesno(args['collaboration-candidate'], true) or yesno(args['collaboration-current'], true) or yesno(args['collaboration-past'], true) then
local collaboration_args = require(auxiliary).collaboration(args, current_title)
render_note(collaboration_args.candidate)
render_note(collaboration_args.current)
render_note(collaboration_args.past)
end
if yesno(args['a class'], true) then
local a_class_args = require(auxiliary).a_class(args, lang)
render_note(a_class_args)
end
if yesno(args['peer review'], true) or yesno(args['old peer review'], true) then
local peer_review_args = require(auxiliary).peer_review(args, current_title)
render_note(peer_review_args.current)
render_note(peer_review_args.past)
end
local note_count = #note_output
if args.HOOK_NOTE then
table.insert(note_output, args.HOOK_NOTE)
local hook_collapsed = 0
if args.HOOK_COLLAPSED then
local success, result = pcall(mw.ext.ParserFunctions.expr, args.HOOK_COLLAPSED)
hook_collapsed = success and tonumber(result) or 0
if args.HOOK_COLLAPSED=='auto' then
hook_collapsed = 1
end
end
note_count = note_count + hook_collapsed
end
collapse_section(
note_count > (tonumber(args.COLLAPSED) or cfg.note.threshold),
note_output,
args.COLLAPSED_HEAD or cfg.note.header
)
---------------------------
-- Bottom text ------------
---------------------------
if args.HOOK_BOTTOM then
table.insert(rows, args.HOOK_BOTTOM)
end
if args.TODO_LINK or args.TODO_TEXT then
local todolist = require(auxiliary).todo_list(args, frame)
table.insert(rows, todolist)
end
if args.BOTTOM_TEXT then
local bottom_text = mw.html.create('tr')
:tag('td')
:attr('colspan','3')
:wikitext(parse_pt(args.BOTTOM_TEXT))
:done()
table.insert(rows, bottom_text)
end
if args.MAIN_CAT then
add_category(args.MAIN_CAT)
end
---------------------------
-- Nested display ---------
---------------------------
if args.HOOK_NESTED then
local hook_nested = args.HOOK_NESTED:gsub('^ / ', '') -- remove initial slash, will be added later
table.insert(nested_tf, hook_nested)
end
local nested_tf_str = ''
if #nested_tf>0 then
nested_tf_str = tostring(mw.html.create('span')
:addClass('wpb-nested-task-force')
:wikitext(': ' .. table.concat(nested_tf, ' / '))
)
end
local nested_ratings_str = #nested_ratings>0 and table.concat(nested_ratings, ' ') or ''
if args.HOOK_NESTED_ASSESS then
nested_ratings_str = nested_ratings_str .. tostring(mw.html.create('span')
:addClass('wpb-header-bubbles')
:wikitext(args.HOOK_NESTED_ASSESS)
)
end
local header_row = mw.html.create('tr')
:addClass('wpb-header')
:tag('td')
:addClass('wpb-header-icon')
:wikitext(image(args.IMAGE_LEFT, cfg.image.header_size, cfg.image.alt))
:done()
:tag('td')
:addClass('wpb-header-combined')
:wikitext(wikilink(project_link.prefixedText, project) .. nested_tf_str .. ' ' .. nested_ratings_str)
:done()
---------------------------
-- Prepare categories -----
---------------------------
local categories_formatted = ''
if demo_page and demo_page~=true then -- for testing purposes
local category_list = mw.html.create('ul')
for _, cat in ipairs(categories) do
local item = mw.html.create('li')
:wikitext(wikilink(':Category:' .. cat.category, cat.category))
category_list:node(item)
end
local category_box = mw.html.create('div')
:addClass('wpb-category-box')
:wikitext('Categories:')
:node(category_list)
categories_formatted = tostring(category_box)
elseif not demo_page then
local categories_linked = {}
for _, cat in ipairs(categories) do
local cat_link = wikilink('Category:' .. cat.category, cat.key)
table.insert(categories_linked, cat_link)
end
categories_formatted = table.concat(categories_linked)
end
---------------------------
-- Make banner ------------
---------------------------
local banner_rows = mw.html.create('table')
for _, row in ipairs(rows) do
banner_rows:node(row)
end
local banner = mw.html.create('table')
:addClass('tmbox tmbox-notice mw-collapsible innercollapse wpb wpb-table')
:addClass(inactive and cfg.inactive.class or nil)
:node(header_row)
:tag('tr')
:tag('td')
:addClass('mbox-text wpb-main')
:attr('colspan','2')
:node(banner_rows)
:allDone()
local tstyle = frame:extensionTag('templatestyles', '', {src='Module:Message box/tmbox.css'}) ..
frame:extensionTag ('templatestyles', '', {src = 'Module:WikiProject banner' .. (sandbox or '') .. '/styles.css'})
return warning .. tstyle .. tostring(banner) .. categories_formatted, note_count, #taskforce_output, assessment_link
end
local initialise = function(args, raw_args, inactive_status)
---------------------------
-- Initialise arguments ---
---------------------------
local parent_args = args_module.getArgs(frame, {parentOnly = true})
local category = parent_args.category or args.category or true
local demo_page = parent_args.demo_page
local config, project
if args.project then -- check for config page
project = args.project
local config_file = mw.title.new('Template:WikiProject ' .. args.project .. '/config')
if config_file.exists then
config = mw.loadJsonData(config_file.fullText)
else
return nil
end
end
local parameters, unknown_parameters = {}, ''
if config then -- use config file
args, raw_args, parameters = require(auxiliary).map_config(config, parent_args) -- map parameters from config page
args.PROJECT = project
end
local on_template_page = false
local banner_name = mw.title.new(args.BANNER_NAME or 'Template:WikiProject ' .. (args.PROJECT or 'PROJECT'))
if not demo_page then
if yesno(category, true) then
on_template_page = current_title.rootPageTitle==banner_name.rootPageTitle
else
demo_page = true
end
end
local project_name = args.PROJECT_NAME or 'WikiProject ' .. (args.PROJECT or 'PROJECT')
if banner_name.exists and not demo_page then -- check for unknown parameters
if not config then -- read template code to find valid parameters
local parameter_list = {}
for parameter in banner_name:getContent():gmatch('{{{([^|}]+)') do
parameter_list[parameter] = true
end
if parameter_list.importance==true then -- add priority as a valid alias of importance
parameter_list.priority = true
end
if args.QUALITY_CRITERIA~='custom' then -- class is unrecognised, so remove from list
parameter_list.class = false
end
parameter_list.listas = false -- remove listas even if parameter used (should be in banner shell)
for k, v in pairs(parameter_list) do
if v then
table.insert(parameters, k)
end
end
end
parameters.showblankpositional = "1"
local check_for_unknown = require('Module:Check for unknown parameters')._check
local unknowns = check_for_unknown(parameters, parent_args)
if unknowns and unknowns~='' then -- there are some unknown parameters
parameters.preview = cfg.unknown_parameters.preview:format(wikilink(banner_name.fullText))
local unknown_category = cfg.unknown_parameters.tracking:format(project_name)
if not mw.title.new(unknown_category).exists then
unknown_category = cfg.unknown_parameters.default
end
parameters.unknown = unknown_category and '[[' .. unknown_category .. '|_VALUE_]]' or ''
unknown_parameters = check_for_unknown(parameters, parent_args)
end
end
if not args.importance then -- allow priority to be used even by banners which don't support it
args.importance = parent_args.priority
end
if on_template_page then
local templatepage = require('Module:WikiProject banner/templatepage' .. (sandbox or '')).templatepage
return templatepage(args, raw_args, inactive_status, config)
else
return unknown_parameters
.. p._main(args, raw_args, demo_page, banner_name, inactive_status and true or false), nil -- nil to disregard subsequent returned values
end
end
p.main = function(frame)
local args = args_module.getArgs(frame, {frameOnly = true})
local raw_args = args_module.getArgs(frame, {frameOnly = true, removeBlanks = false})
return initialise(args, raw_args)
end
---------------------------
-- Inactive projects ------
---------------------------
p.inactive = function(frame)
local args = args_module.getArgs(frame, {frameOnly = true})
local project_name = args.PROJECT_NAME or 'WikiProject ' .. (args.PROJECT or 'PROJECT')
local project_link = mw.title.new(args.PROJECT_LINK or 'Wikipedia:' .. project_name)
local _status = cfg.inactive.status[args.PROJECT_STATUS] or cfg.inactive.default
local main_text = cfg.inactive.text:format(
project_link.prefixedText,
project_name,
_status
)
return initialise(
{
PROJECT = args.PROJECT,
BANNER_NAME = args.BANNER_NAME,
IMAGE_LEFT = cfg.inactive.image,
IMAGE_LEFT_SIZE = cfg.inactive.image_size,
MAIN_TEXT = main_text,
HOOK_NESTED_ASSESS = ' ' .. cfg.inactive.nested:format(_status),
substcheck = args.substcheck,
category = args.category
}, {
substcheck = '' -- to prevent warning on templatepage
}, _status
)
end
return p