Module:Progress box
Appearance
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
This module implements Template:Progress box. Please see the template page for usage instructions.
-- This module implements [[Template:Progress box]]
local makePurgeLink = require('Module:Purge')._main
local lang = mw.language.getContentLanguage()
local 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
end
end
-------------------------------------------------------------------------------
-- Subtotal class
-------------------------------------------------------------------------------
local Subtotal = {}
Subtotal.__index = Subtotal
Subtotal.message = message
function Subtotal.new(data)
local self = setmetatable({}, Subtotal)
self._cfg = data.cfg
self._categoryBase = data.categoryBase
self._date = data.date
self._dateFormat = data.dateFormat or self:message('date-format')
self._formattedDate = self:formatDate(self._date)
self._category = self:message(
'category-format',
data.categoryBase,
self._formattedDate,
data.from or '',
data.suffix or ''
)
self._category = self._category:match('^%s*(.-)%s*$') -- trim whitespace
-- Using pagesInCategory is expensive, but we will have to do it every time
-- so it may as well go here.
self._subtotal = mw.site.stats.pagesInCategory(self._category, 'pages')
return self
end
function Subtotal:formatDate(date)
return lang:formatDate(self._dateFormat, date)
end
function Subtotal:getDate()
return self._date
end
function Subtotal:getFormattedDate()
return self._formattedDate
end
function Subtotal:getCategory()
return self._category
end
function Subtotal:makeCategoryLink(display)
local cat = self:getCategory()
display = display or cat
return string.format('[[:Category:%s|%s]]', cat, display)
end
function Subtotal:getSubtotal()
return self._subtotal
end
-------------------------------------------------------------------------------
-- ProgressBox class
-------------------------------------------------------------------------------
local ProgressBox = {}
ProgressBox.__index = ProgressBox
ProgressBox.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
self._float = args.float or 'left'
self._margin = args.float == 'none' and 'auto' or nil
self._header = args[1]
-- Make subtotal objects
self._subtotals = {}
do
local cfg = self._cfg
local categoryBase = args[2] or args[1]
if not categoryBase then
error('no category base specified', 3)
end
local from = args.from or self:message('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 subtotalObj = Subtotal.new{
cfg = cfg,
categoryBase = categoryBase,
from = from,
suffix = suffix,
date = date,
dateFormat = dateFormat,
}
if subtotalObj:getSubtotal() > 0 then
table.insert(self._subtotals, subtotalObj)
end
date = ProgressBox.incrementDate(date)
end
end
return self
end
-- Increments a date in the format YYYY-MM
function 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 namespace
end
function ProgressBox:makeTotalLabel()
-- @TODO
return 'Total label'
end
function ProgressBox:getTotalCount()
-- @TODO
return 7
end
function ProgressBox:__tostring()
data = data or {}
local root = mw.html.create('table')
-- Base classes and styles
root
:addClass('infobox')
:css('float', self._float)
:css('clear', self._float)
:css('margin', self._margin)
:css('width', '22em')
-- Header row
root:tag('tr'):tag('th')
:attr('colspan', 2)
:addClass('navbox-title')
:css('padding', '0.2em')
:css('font-size', '125%')
:wikitext(self._header)
-- Refresh row
root:tag('tr'):tag('th')
:attr('colspan', 2)
:css('text-align', 'center')
:wikitext(makePurgeLink{'(refresh)'})
-- Subtotals
local subtotalTable = root
:tag('tr')
:tag('th')
:attr('colspan', 2)
:css('padding', 0)
:tag('table')
:addClass('collapsible')
:addClass(self:isCollapsed() and 'collapsed' or nil)
:css('width', '100%')
:css('margin', 0)
for i, subtotalObj in ipairs(self._subtotals) do
subtotalTable
:tag('tr')
:tag('td')
:wikitext(subtotalObj:makeCategoryLink(subtotalObj:getFormattedDate()))
:done()
:tag('td')
:css('text-align', 'right')
:wikitext(subtotalObj:getSubtotal())
end
-- Total
root
:tag('tr')
:css('font-size', '110%')
:tag('th')
:wikitext(self:makeTotalLabel())
:done()
:tag('td')
:css('text-align', 'right')
:wikitext(string.format("'''%d'''", self:getTotalCount()))
return tostring(root)
end
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
local p = {}
function p._main(args)
return tostring(ProgressBox.new(args))
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:Progress box'
})
return p._main(args)
end
return p