This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This Lua module is used on approximately 11,000,000 pages, or roughly 18% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
Banner shell |
---|
Module |
Config |
Styles |
Template:WikiProject banner shell |
Template:Banner holder |
Needs attention |
Usage
This module implements Template:WikiProject banner shell and Template:Banner holder. Please refer to those templates' documentation.
require('strict')
local p = {}
local sandbox-- = '/sandbox'
local yesno = require('Module:Yesno')
local shell = function(frame, header, content, collapsed, class)
local styles = frame:extensionTag('templatestyles', '', {src = 'Module:Message box/tmbox.css'})
.. frame:extensionTag('templatestyles', '', {src = 'Module:Banner shell' .. (sandbox or '') .. '/styles.css'})
local content_row
if content then
content_row = mw.html.create('tr')
:tag('td')
:attr('colspan', '2')
:addClass('banner-shell-inner'):addClass('outercollapse')
:wikitext(content)
:done()
end
local holder = mw.html.create('table')
:attr('role', 'presentation')
:addClass('tmbox'):addClass('tmbox-notice'):addClass('banner-shell')
:addClass(class) -- allow additional class to be specified
:addClass(content and 'mw-collapsible' or nil)
:addClass(collapsed and 'mw-collapsed' or nil)
:node(header)
:node(content_row)
return styles .. tostring(holder)
end
p.banner_holder = function(frame)
local args = require('Module:Arguments').getArgs(frame, {wrappers = {'Template:Banner holder'}})
local image = '[[File:' .. (args.image or 'NewFavicon icon.svg')
.. '|' .. (args.size or '24') .. 'px'
.. '|link=' .. (args.image_link or '')
.. '|alt=' .. (args.alt or '') .. ']]'
local image_cell = mw.html.create('td')
:addClass('mbox-image')
:wikitext(image)
local text_cell = mw.html.create('td')
:addClass('mbox-text'):addClass('banner-shell-header')
:tag('span'):addClass('nowrap'):css('float', 'left'):wikitext(string.rep(' ', 10)):done()
:wikitext(args.text or 'Other talk page banners')
local header = mw.html.create('tr'):node(image_cell):node(text_cell)
return shell(frame, header, args[1], yesno(args.collapsed))
end
local DuplicateBanners = function(text)
local capture = '<span class="wpb%-project">([%w%s]*)</span>'
local banners = {}
for project in text:gmatch(capture) do
if banners[project] == true then
return project
end
banners[project] = true
end
end
p.banner_shell = function(frame)
local cfg = mw.loadData('Module:Banner shell/config' .. (sandbox or ''))
local args = require('Module:Arguments').getArgs(frame, {wrappers = {cfg.template}})
local title = args.demo_page and mw.title.new(args.demo_page) or mw.title.getCurrentTitle()
local pagetype = require('Module:Pagetype')._main{
page = title.prefixedText,
[1] = args.class,
dab = cfg.page_types.dab,
sia = 'set index article',
soft_redirect = cfg.page_types.soft_redirect,
nonexistent = cfg.page_types.nonexistent,
timedtext = cfg.page_types.timedtext,
defaultns = 'extended'
}
local lang = mw.language.getContentLanguage()
local classmask = require('Module:WikiProject banner' .. (sandbox or '')).class_mask
local class = classmask(args.class or '', title.talkPageTitle, false, pagetype)
local demo = not yesno(args.category or true, true) or args.demo_page
local out = {}
local addCategory = function(category, sort_key)
if not demo and title.isTalkPage then
local category_title = mw.title.new('Category:' .. category)
table.insert(out, '[[' .. category_title.prefixedText .. (sort_key and ('|' .. sort_key) or '') .. ']]')
end
end
if demo and not args.demo_page then
pagetype = 'article'
end
local blp = args.blp and args.blp:lower()
if yesno(blp) or blp=='activepol' or yesno(args.living) then
local activepol = blp=='activepol' or yesno(args.activepol)
table.insert(out, frame:expandTemplate{
title = cfg.blp_template.blp,
args = {activepol = activepol and 'yes'}
})
if (yesno(blp) or blp=='activepol') and yesno(args.living) then
addCategory(cfg.tracking.redundant)
elseif (yesno(blp)==false and blp~=nil and blp~='activepol') or (yesno(args.living)==false and args.living~=nil) or blp=='other' then
addCategory(cfg.tracking.conflict)
end
elseif blp=='other' or yesno(args.blpo) then
table.insert(out, frame:expandTemplate{
title = cfg.blp_template.blpo}
)
if blp=='other' and not(yesno(args.living)) and args.living~=nil then
addCategory(cfg.tracking.redundant)
end
elseif yesno(blp)==false and yesno(args.living)==false then
addCategory(cfg.tracking.redundant)
end
local class2 = class=='' and 'Unassessed' or (class .. '-Class')
local vital
if yesno(args.vital) then
local page = mw.ustring.upper(mw.ustring.sub(title.subjectPageTitle.text, 1, 1)) -- get first letter of article name
local codepoint = mw.ustring.codepoint(page, 1, 1)
if codepoint<65 or codepoint>90 then --first letter is not between A-Z
page = 'others'
end
local data_page = mw.title.new('Wikipedia:Vital articles/data/' .. page .. '.json')
if data_page.exists then
local index = title.subjectPageTitle.text
index = tostring(tonumber(index))==index and tonumber(index) or index --convert to number if page is numerical, otherwise loadJsonData does not work
local data = mw.loadJsonData(data_page.fullText)[index]
if data then
local level = data.level and tostring(data.level)
if level and data.topic then
local link = 'Wikipedia:Vital articles/Level/' .. level
if (level=='4' or level=='5') then
link = link .. '/' .. data.topic
end
if data.sublist then
link = link .. '/' .. data.sublist
end
if data.section then
link = link .. '#' .. data.section
end
if not mw.title.new(link).exists then -- add tracking category if link does not exist
addCategory(cfg.vital.attention, 'L')
end
vital = cfg.vital.with_level:format(link, level)
else
vital = cfg.vital.without_level
end
for _, cat in ipairs(cfg.vital.categories) do
if cat:find('_CLASS') and (class=='NA' or class=='') then
addCategory(cfg.vital.attention, class=='NA' and 'N' or 'U')
elseif level==nil then
addCategory(cfg.vital.attention, 'V')
elseif data.topic==nil then
addCategory(cfg.vital.attention, 'T')
else
local category = cat
:gsub('_CLASS', class2)
:gsub('_LEVEL', level)
:gsub('_TOPIC', data.topic)
addCategory(category)
end
end
addCategory(cfg.vital.all)
else
addCategory(cfg.vital.not_listed)
end
end
end
local text, icon_image, icon_str
if class=='NA' then
icon_image = cfg.icons.type[pagetype] or cfg.icons.default
icon_str = pagetype=='page' and 'Non-article page' or lang:ucfirst(pagetype)
text = {cfg.rating.not_required:format(vital or pagetype)}
elseif class=='' then
icon_image = cfg.icons.unassessed
icon_str = 'Unassessed article'
text = {cfg.rating.not_yet:format(vital or pagetype)}
else
icon_image = cfg.icons.quality[class] or cfg.icons.unassessed
icon_str = class2 .. ' ' .. pagetype
text = {cfg.rating.rated:format(vital or pagetype, class)}
end
local icon = string.format('[[File:%s|%s|35px|class=noviewer|alt=]]', icon_image, icon_str)
table.insert(text, ' ' .. cfg.rating.scale)
if args[1] then
table.insert(text, '<br>' .. cfg.project.interest .. ' ')
table.insert(text, yesno(args.collapsed) and cfg.project.collapsed or cfg.project.uncollapsed)
local duplicate_cat = DuplicateBanners(args[1])
if duplicate_cat and title.isTalkPage then
addCategory(cfg.tracking.duplicate, duplicate_cat)
end
elseif not yesno(args.vital) then -- if no projects and not vital then add class super category
addCategory(class2 .. ' articles')
end
local header = mw.html.create('tr')
:tag('td')
:addClass('assess')
:wikitext(icon)
:done()
:tag('td')
:addClass('banner-shell-header')
:css('text-align', 'left')
:css('font-weight', 'normal')
:wikitext(table.concat(text))
:done()
table.insert(
out,
shell(frame, header, args[1], yesno(args.collapsed), 'wpbs')
)
if args.listas then
table.insert(out, frame:preprocess('{{DEFAULTSORT:' .. args.listas .. '}}'))
end
if not demo then
local tracking = require('Module:Check for unknown parameters')._check({
unknown = cfg.tracking.unknown,
preview = cfg.tracking.preview,
'1', 'blp', 'category', 'class', 'collapsed', 'demo_page', 'listas', 'living', 'vital'
}, frame:getParent().args)
table.insert(out, tracking)
for _, param in ipairs{'category', 'collapsed', 'living'} do -- check if each has a boolean value
if yesno(args[param], 'invalid')=='invalid' then
addCategory(cfg.tracking.invalid, param)
end
end
if yesno(blp)==nil and blp~=nil and blp~='other' and blp~='activepol' then
addCategory(cfg.tracking.invalid, 'Pblp')
end
if pagetype=='article' and args.class and class=='' then -- find pages with invalid class parameter
addCategory(cfg.tracking.invalid, 'Zclass')
end
end
return table.concat(out)
end
return p