Module:Articles by class
require('strict')
local p = {}
local frame = mw.getCurrentFrame()
local args = require('Module:Arguments').getArgs(frame)
local title = args.page and mw.title.new(args.page) or mw.title.getCurrentTitle()
local cat_name = '%s-%s %s %s'
local cats = {}
local lang = mw.language.getContentLanguage()
local class_suffix = function(class, unassessed_suffix)
local suffix = class:lower()=='unassessed' and (unassessed_suffix or '') or '-Class'
return class .. suffix
end
local col_num = function(n, link)
local text
local number = lang:formatNum(n)
if link then
text = '' .. number .. ''
else
text = number
end
return mw.html.create('td')
:attr('align', 'center')
:wikitext(text)
end
local add_category = function(cat, _sort)
local link = '' .. _sort) or '') .. ''
table.insert(cats, link)
end
local cat_in_use = function(cat)
local cat_title = mw.title.new('Category:' .. cat)
return cat_title and cat_title.exists or mw.site.stats.pagesInCategory(cat, 'pages')>0
end
local template = function(template, class, topic, page)
return frame:expandTemplate{
title = template,
args = {
[1] = class,
topic = topic,
category = topic .. ' ' .. page,
bold = 'no'
}
}
end
local create_table = function(cfg)
local class, topic, typ = title.text:match(cfg.pattern)
if not class and cfg.pattern2 then -- try alternate pattern
class, topic, typ = title.text:match(cfg.pattern2)
end
if not topic then
topic = args.topic or title.text:match('^(.+) articles by ' .. cfg.qualimp .. '$')
end
local out, exist = '', {}
if args.class and class and args.topic and topic and (args.class:lower()~=class:lower() or args.topic~=topic) then
add_category('WikiProject assessment categories needing attention')
end
topic = topic or args.topic or ''
class = class or args.class or ''
typ = typ or 'articles'
if title.namespace==14 and not title.text:match('^' .. topic .. ' articles by ' .. cfg.qualimp .. '$') then
out = frame:expandTemplate{title='Possibly empty category'}
end
for _, class in ipairs(cfg.classes) do
if cat_in_use(cat_name:format(class, cfg.suffix, topic, 'pages')) then
exist[class] = 'pages'
elseif cat_in_use(cat_name:format(class, cfg.suffix, topic, 'articles')) then
exist[class] = 'articles'
else
exist[class] = false
end
end
local header_row = mw.html.create('tr')
for _, class in ipairs(cfg.classes) do
if exist[class] then
header_row:node(template(cfg.template_name, class, topic, exist[class]))
end
end
if args.custom1 then
header_row:node(template(cfg.template_name, args.custom1, topic, 'articles'))
end
if args.custom2 then
header_row:node(template(cfg.template_name, args.custom2, topic, 'articles'))
end
if cfg.custom then
header_row:node(template(cfg.template_name, cfg.custom.name, topic, 'articles'))
end
local total_cell = mw.html.create('td'):attr('align', 'center'):wikitext('Total')
header_row:node(total_cell)
local total = 0
local pages_in_cat = function(cat)
local pages = mw.site.stats.pagesInCategory(cat, 'pages')
total = total + pages
return col_num(pages)
end
local second_row = mw.html.create('tr')
for _, class in ipairs(cfg.classes) do
if exist[class] then
second_row:node(pages_in_cat(cat_name:format(class, cfg.suffix, topic, exist[class])))
end
end
if args.custom1 then
second_row:node(pages_in_cat(cat_name:format(args.custom1, cfg.suffix, topic, 'articles')))
end
if args.custom2 then
second_row:node(pages_in_cat(cat_name:format(args.custom2, cfg.suffix, topic, 'articles')))
end
if cfg.custom then
second_row:node(pages_in_cat(cfg.custom.category:format(topic)))
end
second_row:node(col_num(total))
local caption
if args.project then -- display caption
local abc = 'articles by ' .. cfg.qualimp
local text = 'WikiProject ' .. args.project .. ' '
.. (
mw.title.new('Category:' .. topic .. ' ' .. abc).exists
and '' .. abc .. ''
or abc
) .. string.rep(' ', 3)
.. '' .. frame:expandTemplate{title = 'Purge', args = {'Refresh'}} .. ''
caption = mw.html.create('caption')
:attr('align', 'bottom')
:wikitext(text)
end
local tab = mw.html.create('table')
:addClass(args.format or 'wikitable') -- add custom CSS class if specified
:addClass('toccolours'):addClass('nomobile')
:css('table-layout', 'fixed')
:css('margin', '1em auto')
:node(header_row)
:node(second_row)
:node(caption)
if class and class~='' and class~='nocat' then
add_category(args.parent or (topic .. ' articles by ' .. cfg.qualimp), class)
local suffix = class:lower()=='unassessed' and '' or ('-' .. cfg.suffix)
add_category(class .. suffix .. ' ' .. typ, args.sort or topic)
end
return out .. tostring(tab) .. table.concat(cats)
end
p.quality_and_importance = function()
local cfg = {
quality_classes = {'FA', 'A', 'GA', 'B', 'C', 'Start', 'Stub', 'FL', 'List', 'Draft', 'Redirect', 'Unassessed'},
importance_classes = {'Top', 'High', 'Mid', 'Low', 'Unknown'},
forms = {'C T of I', 'I C T', 'C I T', 'C, I T'}
}
local projects = mw.loadJsonData('Template:Articles by Quality and Importance/config')
local pagetype = function(class)
return (class=='Redirect' or class=='Draft') and 'pages' or 'articles'
end
local totals = {}
local grand_total = 0
local unassessed_suffix = ''
local form = 'C T of I'
local class, topic, importance
if args.topic then
topic = args.topic
else
for _, form in pairs(cfg.forms) do
local offsets, order = {}, {}
for _, s in ipairs{'C', 'I', 'T'} do
table.insert(offsets, {letter = s, offset = form:find(s)})
end
table.sort(offsets, function(m, n) return m.offset for n, v in ipairs(offsets) do order[v.letter] = n end local form2 = form :gsub('C', '_C_'):gsub('I', '_I_'):gsub('T', '_T_') :gsub('_C_', '(%%a+)-Class') :gsub('_I_', '(%%a+)-importance') :gsub('_T_', '(.+) %%a+') local pattern = '^' .. form2 .. '$' local m1, m2, m3 = title.text:match(pattern) if m1 then -- match found local m = {m1, m2, m3} class = m[order.C] importance = m[order.I] topic = m[order.T] break end end if not topic then -- no topic, cannot continue if title.namespace==14 then return 'Category:WikiProject assessment categories needing attention' else return nil end end end if projects[topic] then -- configuration settings are provided if projects[topic].bottom then table.insert(cfg.importance_classes, 5, 'Bottom') end unassessed_suffix = projects[topic].unassessed_suffix or '' if projects[topic].redirect==false then table.remove(cfg.quality_classes, 11) end if projects[topic].draft==false then table.remove(cfg.quality_classes, 10) end if projects[topic].pattern then form = projects[topic].pattern end end form = form:gsub('C', '_C_'):gsub('I', '_I_'):gsub('T', '_T_') if class and class~= and importance and importance ~= then add_category(topic .. ' articles by quality and importance', class..importance) add_category(class_suffix(class, unassessed_suffix) .. ' ' .. topic .. ' ' .. pagetype(class), '*' .. importance) add_category(importance .. '-importance' .. ' ' .. topic .. ' ' .. 'articles', '*' .. class) end local corner_cell = mw.html.create('th') :attr('colspan', '2') :attr('rowspan', '2') :wikitext(lang:ucfirst(topic) .. ' local importance_cell = mw.html.create('th') :attr('colspan' , #cfg.importance_classes+1) :wikitext('Importance') local top_row = mw.html.create('tr') :node(corner_cell) :node(importance_cell) local importance_row = mw.html.create('tr') for _, importance in ipairs(cfg.importance_classes) do importance_row:node(template('Importance', importance, topic, 'articles')) end local importance_cell = mw.html.create('th'):wikitext('Total') importance_row:node(importance_cell) local quality_cells = function(row, class) local total = 0 local typ = pagetype(class) row:node(template('Class', class, topic, typ)) for _, importance in ipairs(cfg.importance_classes) do if typ=='pages' and importance=='Unknown' then importance = 'NA' -- use NA-importance on non-articles end local cat_name = form :gsub('_C_', class_suffix(class, unassessed_suffix)) :gsub('_I_', importance .. '-importance') :gsub('_T_', topic .. ' ' .. typ) local pages = mw.site.stats.pagesInCategory(cat_name, 'pages') total = total + pages if totals[importance] then totals[importance] = totals[importance] + pages else totals[importance] = pages end row:node(col_num(pages, ':Category:' .. cat_name)) end row:node(col_num(total, ':Category:' .. class_suffix(class) .. ' ' .. topic .. ' ' .. typ)) grand_total = grand_total + total end local tab = mw.html.create('table') :addClass(args.format or 'wikitable') :addClass('toccolours'):addClass('nomobile') :css('table-layout', 'fixed') :css('margin', '1em auto') :node(top_row) :node(importance_row) local quality_column = mw.html.create('th') :attr('rowspan', #cfg.quality_classes+1) :wikitext('Quality') for n, _class in ipairs(cfg.quality_classes) do local row = mw.html.create('tr') if n==1 then row:node(quality_column) end quality_cells(row, cfg.quality_classes[n]) tab:node(row) end local total_row = mw.html.create('tr') :node(importance_cell) for _, importance in ipairs(cfg.importance_classes) do local cat_name = importance .. '-importance ' .. topic .. ' ' .. 'articles' total_row:node(col_num(totals[importance] or 0, ':Category:' .. cat_name)) end total_row:node(col_num(grand_total)) tab:node(total_row) return tostring(tab) .. table.concat(cats) end p.quality = function() return create_table{ pattern = '^(%a+)-Class (.+) (%a+)$', pattern2 = '^(Unassessed) (.+) (%a+)$', -- match unassessed category qualimp = 'quality', classes = {'FA', 'A', 'GA', 'B', 'C', 'Start', 'Stub', 'FL', 'AL', 'BL', 'CL', 'List', 'SIA', 'Future', 'Category', 'Disambig', 'Draft', 'FM', 'File', 'Portal', 'Project', 'Redirect', 'Template', 'User', 'NA'}, template_name = 'Class', suffix = 'Class', custom = {name = 'Unassessed', category = 'Unassessed %s articles'} } end p.importance = function() return create_table{ pattern = '^(%a+)-importance (.+) (%a+)$', qualimp = 'importance', classes = {'Top', 'High', 'Mid', 'Low', 'Bottom', 'NA', 'Unknown'}, template_name = 'Importance', suffix = 'importance' } end return p
articles')