Module:Progress box explained

local makePurgeLink = require('Module:Purge')._mainlocal lang = mw.language.getContentLanguagelocal CONFIG_MODULE = 'Module:Progress box/config'

--------------------------------------------------------------------------------- Message mixin-- -- This function is mixed into all of the other classes-------------------------------------------------------------------------------

local function message(self, key, ...) local msg = self._cfg[key] if not msg then error(string.format("no message found with key '%s'", tostring(key)), 2) end if select('#', ...) > 0 then return mw.message.newRawMessage(msg, ...):plain else return msg endend

--------------------------------------------------------------------------------- Category class-------------------------------------------------------------------------------

local Category = Category.__index = CategoryCategory.message = message

function Category.new(data) local self = setmetatable(Category) self._cfg = data.cfg self._whatToCount = data.whatToCount self:setCategory(data.category) return selfend

function Category:setCategory(category) self._category = categoryend

function Category:getCategory return self._categoryend

function Category:makeCategoryLink(display) local cat = self:getCategory display = display or cat return string.format('%s', cat, display)end

function Category:getCount if not self._count then local counts = mw.site.stats.pagesInCategory(self:getCategory, '*') self._count = counts[self._whatToCount or 'pages'] if not self._count then error("the count type must be one of 'pages', 'subcats', 'files' or 'all'") end end return self._countend

function Category:getFormattedCount return lang:formatNum(self:getCount)end

function Category:exists return mw.title.makeTitle(14, self:getCategory).existsend

--------------------------------------------------------------------------------- DatedCategory class-- Inherits from Category-------------------------------------------------------------------------------

local DatedCategory = DatedCategory.__index = DatedCategorysetmetatable(DatedCategory, Category)

function DatedCategory.new(data) local self = setmetatable(Category.new(data),) self._date = data.date self._dateFormat = data.dateFormat or self:message('date-format') self._formattedDate = self:formatDate(self._date) do local category = self:message('dated-category-format', data.baseCategory, self._formattedDate, data.from or self:message('dated-category-format-from'), data.suffix or ) category = category:match('^%s*(.-)%s*$') -- trim whitespace self:setCategory(category) end return selfend

function DatedCategory:formatDate(date) return lang:formatDate(self._dateFormat, date)end

function DatedCategory:getDate return self._dateend

function DatedCategory:getFormattedDate return self._formattedDateend

--------------------------------------------------------------------------------- ProgressBox class-------------------------------------------------------------------------------

local ProgressBox = ProgressBox.__index = ProgressBoxProgressBox.message = message

function ProgressBox.new(args, cfg, title) local self = setmetatable(ProgressBox)

-- Argument defaults args = args or self._cfg = cfg or mw.loadData(CONFIG_MODULE) self._title = title or mw.title.getCurrentTitle

-- Set data if not args.float or (args.float and (args.float

'left' or args.float

)) then self._float_class = 'maint-cat-progress-left' elseif args.float

'right' then self._float_class = 'maint-cat-progress-right' elseif args.float

'none' then -- 'none' is actually 'center'ed self._float_class = 'maint-cat-progress-center' end self._header = args[1] self._frame = mw.getCurrentFrame

-- Make the base category object if not args[1] then error('no base category specified', 3) end self._baseCategoryObj = Category.new

-- Make datedCategory objects self._datedCategories = do local cfg = self._cfg local baseCategory = args[2] or self._baseCategoryObj:getCategory local whatToCount = args.count local from = args.from or self:message('dated-category-format-from') local suffix = args.suffix local currentDate = lang:formatDate('Y-m') local date = self:findEarliestCategoryDate local dateFormat = self:message('date-format') while date <= currentDate do local datedCategoryObj = DatedCategory.new if datedCategoryObj:getCount > 0 then table.insert(self._datedCategories, datedCategoryObj) end date = ProgressBox.incrementDate(date) end end

-- Make all-article category object do local allCategory if args[3] then allCategory = args[3] else allCategory = self:message('all-articles-category-format', self._baseCategoryObj:getCategory ) allCategory = self._frame:preprocess(allCategory) end self._allCategoryObj = Category.new end

return selfend

-- Increments a date in the format YYYY-MMfunction ProgressBox.incrementDate(date) local year, month = date:match('^(%d%d%d%d)%-(%d%d)$') year = tonumber(year) month = tonumber(month) if not year or not month then error(string.format("error parsing date '%s'", tostring(date)), 2) end month = month + 1 if month > 12 then month = 1 year = year + 1 end return string.format('%04d-%02d', year, month)end

function ProgressBox:findEarliestCategoryDate return self:message('start-date')end

function ProgressBox:isCollapsed return self._title.namespace ~= 10 -- is not in template namespaceend

function ProgressBox:makeTotalLabel local display = self:message('all-articles-label') if self._allCategoryObj:exists then return self._allCategoryObj:makeCategoryLink(display) else return display endend

function ProgressBox:getTotalCount local count = 0 for i, obj in ipairs(self._datedCategories) do count = count + obj:getCount end count = count + self._baseCategoryObj:getCount return countend

function ProgressBox:getFormattedTotalCount return lang:formatNum(self:getTotalCount)end

function ProgressBox:__tostring data = data or local root = mw.html.create('div') -- Base classes and styles root :addClass('maint-cat-progress') :addClass(self._float_class)

-- Header row root:tag('div') :addClass('maint-cat-progress-header') :wikitext(self._header)

-- Refresh row root:tag('div') :addClass('maint-cat-progress-refresh') :wikitext(makePurgeLink)

-- Subtotals local subtotalTable = mw.html.create('table') subtotalTable :addClass('maint-cat-progress-subtotals mw-collapsible') :addClass(self:isCollapsed and 'mw-collapsed' or nil) :tag('caption') :wikitext(self:message('subtotal-heading')) for i, datedCategoryObj in ipairs(self._datedCategories) do subtotalTable :tag('tr') :tag('td') :wikitext(datedCategoryObj:makeCategoryLink(datedCategoryObj:getFormattedDate )) :done :tag('td') :wikitext(datedCategoryObj:getFormattedCount) end

-- Undated articles subtotalTable :tag('tr') :tag('td') :wikitext(self._baseCategoryObj:makeCategoryLink(self:message('undated-articles-label') )) :done :tag('td') :wikitext(self._baseCategoryObj:getFormattedCount) :allDone

-- Total root :node(subtotalTable) :tag('div') :addClass('maint-cat-progress-total-row') :tag('div') :addClass('maint-cat-progress-total-label') :wikitext(self:makeTotalLabel) :done :tag('div') :addClass('maint-cat-progress-total') :wikitext(self:getFormattedTotalCount)

return mw.getCurrentFrame:extensionTag .. tostring(root)end

--------------------------------------------------------------------------------- Exports-------------------------------------------------------------------------------

local p =

function p._exportClasses return end

function p._main(args, cfg, title) return tostring(ProgressBox.new(args, cfg, title))end

function p.main(frame) local args = require('Module:Arguments').getArgs(frame,) return p._main(args)end

return p