Module:Progression rainbow
MyWikiBiz, Author Your Legacy — Friday November 15, 2024
Jump to navigationJump to searchTemplate:Module rating Template:Lua Template:Uses TemplateStyles
This module implements Template:Progression rainbow.
Usage
{{#invoke:Progression rainbow|main}}
--[[ This implements {{progression rainbow}} ]] require('Module:No globals') local p = {} -- rounding to first decimal, from http://lua-users.org/wiki/SimpleRound local function round(num) return math.floor(num * 10 + 0.5) / 10 end local function class_percent(param, total) -- These suck for i18n because the % is forced to the right without spacing, -- both in a required context (CSS) and unrequired (to-be-displayed text). -- I.e., there should be a separate version of this or a function parameter -- which takes a boolean. :( return tostring(round(100 * param / total)) .. '%' end local function percent_remaining(sum, total) local remaining = total - sum if remaining > 0 then return tostring(round(100 * remaining / total)) .. '%' else return nil end end local function category_count(category, project) return mw.site.stats.pagesInCategory( string.format('%s %s articles', category, project), 'pages' ) end -- This is only done once in this module, here for demonstration. -- Gist: Make it cleaner to initialize 'trivial' variables. local function arg_or_default(args, from_arg, default) if args[from_arg] and args[from_arg] ~= '' then return args[from_arg] else return default end end function p.main(frame) return p._main(require('Module:Arguments').getArgs(frame)) end function p._main(args) local classes = { {count = 0, class = 'List', category = 'List-Class'}, {count = 0, class = 'Stub', category = 'Stub-Class'}, {count = 0, class = 'Start', category = 'Start-Class'}, {count = 0, class = 'C', category = 'C-Class'}, {count = 0, class = 'B', category = 'B-Class'}, {count = 0, class = 'GA', category = 'GA-Class'}, {count = 0, class = 'A', category = 'A-Class'}, {count = 0, class = 'FA', category = 'FA-Class'} } local project_classes = { {count = 0, class = 'FL', category = 'FL-Class'}, {count = 0, class = 'Unassessed', category = 'Unassessed'} } local project = arg_or_default(args, "project", nil) local sum_classes = 0 if project then for _, class in ipairs(classes) do class.count = category_count(class.category, project) if class.class == 'FA' then class.count = class.count + category_count( project_classes[1].category, project ) end sum_classes = sum_classes + class.count end else for i, class in ipairs(classes) do -- 'or class.count' to keep us safe from a non-numeric value in args. class.count = tonumber(args[i]) or class.count sum_classes = sum_classes + class.count end end local total if project then -- It makes more sense to do this sum here rather than in the project -- loop above because total is initialized here in the non-project case total = sum_classes + category_count( project_classes[2].category, project ) else total = tonumber(args[9]) or 100 end local root = mw.html.create('ul') root:addClass('progression-rainbow') -- Don't care which frame it is if all I want to do is expand templates -- and extension tags local current_frame = mw.getCurrentFrame() for _, class in ipairs(classes) do if class.count ~= 0 then local percentage = class_percent(class.count, total) root:newline() -- sprinkled through to make the HTML easier to read root:tag('li') :css('background', current_frame:expandTemplate{ title = 'class/colour', args = { class.class } }) :css('width', percentage) :tag('span') :addClass('sr-only') :wikitext(string.format('%s %s', percentage, class.category)) :done() :done() end end root:newline() local remaining = percent_remaining(sum_classes, total) if remaining then root:tag('li') :addClass('remaining') :css('width', remaining) :tag('span') :addClass('sr-only') :wikitext(string.format('%s remaining', remaining)) :done() :done() :newline() end root:allDone() return current_frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Progression rainbow/styles.css'} } .. current_frame:extensionTag{ name = 'templatestyles', args = { src = 'Screen reader-only/styles.css'} } .. '\n' .. tostring(root) end return p