Module:WikiProject banner
require('strict')
local p = {}
local sandbox-- = '/sandbox'
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 isarticle = function(class)
local article = true
for _,v in ipairs(cfg.quality.non_article_classes) do
if class==v then -- class matches one of the non-article classes
article = false
break
end
end
return article
end
local importance_mask = function(raw_importance, class, scale, banner_name, pagetype)
---------------------------
-- Importance mask --------
---------------------------
local importance
if scale=='inline' then -- pass importance without change
importance = raw_importance
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 = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = {
importance = raw_importance or '¬',
class = class,
pagetype = pagetype
}
})
end
elseif raw_importance then-- standard importance scale
importance = cfg.importance.na
if pagetype=='article' or pagetype=='redirect' or pagetype=='draft' then
local mask = cfg.importance.mask
if mask[raw_importance:lower()] then -- valid importance specified
importance = mask[raw_importance:lower()]
elseif pagetype=='article' then -- unspecified or invalid importance, use "Unknown" for articles
importance = cfg.importance.unknown
end
end
end
return importance
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)
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 pagetype=='article' then
if 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' and FQS then
out = 'FM'
else
out = resolveFQSgrade('file')
end
else
-- Define a table that maps namespace IDs to category names
local ns_to_category = {
[15] = 'category', -- Category talk
[101] = 'portal', -- Portal talk
[11] = 'template', -- Template talk
[829] = 'template', -- Module talk
[5] = 'project', -- Wikipedia talk
[119] = 'draft' -- Draft talk
}
local category = ns_to_category[ns] or 'NA'
out = resolveFQSgrade(category)
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, conflict, style)
local out = mw.html.create('span')
:addClass('wpb-header-bubbles')
:addClass(style)
:addClass(conflict and 'conflict' or nil)
: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' .. (sandbox or ''))._main({
page = demo_page,
dab = 'disambiguation page'
})
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_text = function(text)
return text and text:gsub('_PAGETYPE_', pagetype)
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)
---------------------------
-- Location warning -------
---------------------------
local warning = ''
local show_namespace_warning = not (current_title.isTalkPage or demo_page)
if show_namespace_warning then
local text = cfg.namespace_warning.text:format(
pagetype,
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 = 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 assessment_cat = args.ASSESSMENT_CAT or project .. ' articles'
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_text(args.MAIN_TEXT) or cfg.main_text:format(
pagetype,
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 article_class = p.readarticleclass({ignore_subtemplates=true}, title.prefixedText)
if article_class then -- banner shell exists
local special_chars = '([%%%(%)%.%+%-%*%?%[%]%^%$])'
local banner_name_escaped = banner_name.text
local page_content = require('Module:Wikitext Parsing').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 pagetype=='article' then
add_category(cfg.banner_shell.category.no_banner_shell_articles)
elseif 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
else
add_category(cfg.banner_shell.category.no_banner_shell)
end
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_exists = function(class, assessment_cat) -- check if category exists and is not blank
if not isarticle(class) then
local cat = mw.title.new('Category:' .. class .. '-Class' .. ' ' .. assessment_cat)
return (cat.exists and #cat:getContent()>0) and class or 'NA' -- automatically use NA for non-article pages if category does not exist
else
return class
end
end
local class = raw_args.class
if class then -- banner gives quality ratings
article_class = article_class and p.class_mask(article_class, title, false, pagetype)
local show_quality, conflict = true, false
if args.QUALITY_CRITERIA=='custom' then -- project has opted out of standard assessment scale and uses a custom mask
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
class = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = raw_args
})
if class=='' and article_class and article_class~='' then -- if unassessed and article 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 = article_class -- replace class with inherited class
local article_class_normalised = mw.text.trim(frame:expandTemplate{
title = custom_mask.prefixedText,
args = new_arg_table
})
if article_class_normalised and article_class_normalised~='' then
class = article_class_normalised -- inherit class from article_class normalised by custom mask
else
article_class = nil -- effectively no article_class for this banner
end
end
end
else
class = p.class_mask(class, title, true, pagetype)
end
if article_class then -- banner shell exists
if article_class=='' then -- no article class defined
if class=='' then -- local class also does not exist, check whether any other class parameters are defined inside the shell
local classparam = p.readarticleclass({ignore_blank=true, only_subtemplates=true}, title.prefixedText)
if classparam=='' then -- no class parameters defined, display as globally unassessed
show_quality = false -- hide quality class in project banner
end
elseif not demo_page then
add_category(cfg.banner_shell.category.no_quality_rating)
warning = warning .. display_error(cfg.banner_shell.piqa_warning)
end
elseif class=='' or class==article_class then -- local class matches article class or is blank
show_quality = false -- hide quality class in project banner
class = article_class
if raw_args.class~='' and args.QUALITY_CRITERIA~='custom' then
add_category(cfg.banner_shell.category.redundant_class)
end
elseif (article_class=='NA') and not isarticle(class) then -- article class and local class are both non-article classes
show_quality = false
else -- article class exists and differs from local class
if args.QUALITY_CRITERIA~='custom' then
conflict = true
add_category(class .. '-Class' .. ' articles with conflicting quality ratings') --TODO: add to config
end
end
end
if not isarticle(class) then
local cat = mw.title.new(cfg.quality.assessment_category:format(class, assessment_cat))
if not (cat.exists and #cat:getContent()>0) then --check if category exists and is not blank
class = 'NA' -- automatically use NA for non-article pages if category does not exist
end
end
local category = (class=='' and 'Unassessed' or class..'-Class') .. ' ' .. assessment_cat
if show_quality then -- quality rating shown in banner
local rating
if pagetype=='article' then
rating = class=='' and cfg.quality.not_yet or cfg.quality.rated:format(class)
else
rating = cfg.quality.not_required
end
local scale = args.QUALITY_CRITERIA=='custom'
and assessment_link
and cfg.quality.project_scale:format(wikilink(assessment_link..'#'..lang:ucfirst(cfg.quality.name), cfg.quality.name))
or cfg.quality.default_scale
local quality_rating = conflict and cfg.banner_shell.conflict.text or cfg.quality.rating:format(pagetype, rating, scale)
local cssClass = 'class-' .. (class=='' and 'unassessed' or class:lower())
local class_row = mw.html.create('tr')
:tag('td')
:addClass('assess')
:addClass(cssClass)
:addClass(conflict and 'conflict' or nil)
:wikitext(wikilink(':Category:' .. category, class=='' and '???' or class))
:done()
:tag('td')
:addClass('mbox-text')
:attr('colspan', '2')
:wikitext(quality_rating)
:done()
table.insert(rows, class_row)
table.insert(
nested_ratings,
1,
bubble(class=='' and 'Unassessed' or (class..'‑class'), conflict, cssClass)
)
end
add_category(category)
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
---------------------------
-- Importance assessment --
---------------------------
local importance = importance_mask(raw_args.importance or raw_args.priority, class, args.IMPORTANCE_SCALE, banner_name, pagetype)
local importance_name = args.IMPN or (raw_args.priority and 'priority' or cfg.importance.default_name)
if importance then -- banner gives importance ratings
local category = importance .. '-' .. importance_name .. ' ' .. assessment_cat
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_name = cfg.importance.scale:format(importance_name)
local scale = assessment_link
and cfg.importance.project_scale:format(assessment_link..'#'..lang:ucfirst(scale_name), scale_name)
or cfg.importance.default_scale
local importance_rating = cfg.importance.rating:format(pagetype, 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, false, cssClass)
)
end
end
add_category(category)
end
page_assessment(project, class, importance)
if args.HOOK_IMPORTANCE then
table.insert(rows, args.HOOK_IMPORTANCE)
end
if args.QII_FORMAT then
add_category(require(auxiliary).quality_importance_insection(args, class, importance, importance_name))
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 = args[tf_prefix..'ASSESSMENT_CAT'] or (args[tf_prefix..'NAME'] or '')..' articles'
local tf_importance
if raw_args['tf '..k..' importance'] then
tf_importance = importance_mask(raw_args['tf '..k..' importance'], class, args.IMPORTANCE_SCALE, banner_name, pagetype)
if tf_importance=='Unknown' and yesno(args.INHERIT_IMPORTANCE) then
tf_importance = importance
end
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 '')
:gsub('_PAGETYPE_', pagetype)
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 .. '-' .. importance_name .. ' ' .. tf_assessment_cat, tf_importance .. '-' .. importance_name)
) or ''
text = portal .. cfg.task_force.text:format(
pagetype,
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(text)
:done()
table.insert(taskforce_output, taskforce)
end
if args[tf_prefix..'HOOK'] then
table.insert(taskforce_output, args[tf_prefix..'HOOK'])
end
if yesno(args[tf_prefix..'QUALITY']) and class then
local tf_class = check_exists(class, tf_assessment_cat)
add_category((tf_class=='' and 'Unassessed' or tf_class..'-Class') .. ' ' .. tf_assessment_cat)
end
if tf_importance then
add_category(tf_importance .. '-' .. importance_name .. ' ' .. tf_assessment_cat)
end
if args[tf_prefix..'QII_FORMAT'] then
add_category(require(auxiliary).quality_importance_insection(args, class, tf_importance, importance_name, 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(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 .. '|' .. note_args.text .. '|link=|alt=]]')
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(
pagetype,
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:format(pagetype),
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:format(pagetype),
image_name = cfg.infobox.icon,
category = infobox_cat
}
end
for _, k in ipairs(notes) do
local note_prefix = 'NOTE_' .. k .. '_'
render_note{
text = parse_text(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, pagetype)
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, pagetype, 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_text(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()
---------------------------
-- Default sort -----------
---------------------------
if args.listas then
frame:preprocess('{{DEFAULTSORT:' .. args.listas .. '}}')
if title.namespace~=3 then -- exclude user talk namespace
local success, shell_listas_value = require('Module:Template parameter value').getParameter(
title.prefixedText,
cfg.banner_shell.redirects,
'listas',
{ignore_subtemplates = true, ignore_blank = true}
)
if success and shell_listas_value~='' then
if args.listas==shell_listas_value then-- same value in both (with spacing trimming)
add_category('WikiProject banners with redundant listas value')
end
else-- listas is blank or not defined in banner shell
add_category('WikiProject banners with listas value which needs moving to banner shell')
end
end
end
---------------------------
-- 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.status.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 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')
local unknown_parameters = ''
if banner_name.exists and not demo_page then -- check for unknown parameters
local parameters = {}
for parameter in banner_name:getContent():gmatch('{{{([^|}]+)') do
table.insert(parameters, parameter)
end
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 on_template_page then
local templatepage = require('Module:WikiProject banner/templatepage' .. (sandbox or '')).templatepage
return templatepage(args, raw_args, inactive_status)
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.status[args.PROJECT_STATUS] or cfg.status.default_inactive
local main_text = cfg.inactive.text:format(
'_PAGETYPE_',
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
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.