Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:WikiProjectBanner/Banner
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
------------------------------------------------------------------------------- -- Banner class -- -- This module contains the Banner class used in Module:WikiProjectBanner. -- -- It is used to generate the banner HTML and categories. -- ------------------------------------------------------------------------------- -- Load required modules. local yesno = require('Module:Yesno') local mShared = require('Module:WikiProjectBanner/shared') -- Lazily load modules we might not need. local Grade local Banner = {} Banner.__index = Banner Banner.rowModules = { quality = 'Module:WikiProjectBanner/AssessmentRow', importance = 'Module:WikiProjectBanner/AssessmentRow', taskForces = 'Module:WikiProjectBanner/TaskForce', requests = 'Module:WikiProjectBanner/Note', notices = 'Module:WikiProjectBanner/Note' } -- Define the classes table. This loads modules containing the row classes -- on demand; if it is not indexed, the class is not loaded. Banner.rowClasses = setmetatable({}, { __index = function (t, key) local module = Banner.rowModules[key] if module then module = require(module) Banner.rowClasses[key] = module return module end end }) function Banner.new(bannerName, args, cfg, bannerCfg) -- Set data we were passed. local obj, data = {}, {} data.bannerName = bannerName obj.args = args obj.cfg = cfg -- Set title objects. data.currentTitle = mw.title.getCurrentTitle() data.subjectTitle = data.currentTitle.subjectPageTitle -- Set banner config. -- We use a metatable to make it read-only, to try and limit hook -- interaction. bannerCfg = bannerCfg or mShared.maybeRequire( 'Module:WikiProjectBanner/banners/' .. data.bannerName ) if not bannerCfg then error( 'banner data page [[Module:WikiProjectBanner/banners/' .. bannerName .. ']] does not exist', 0 ) end bannerCfg.hooks = bannerCfg.hooks or {} obj.bannerCfg = setmetatable({}, { __index = bannerCfg, __newindex = function () error('the banner config is read-only', 2) end, __pairs = function () return pairs(bannerCfg) end, __ipairs = function () return ipairs(bannerCfg) end }) -- Set banner data. do -- Find if we are in demo mode. local currentPage = data.currentTitle.prefixedText local template = mw.site.namespaces[10].name .. ':' .. data.bannerName if currentPage == template or currentPage == template .. '/sandbox' then data.isDemo = true end end data.pageType = require('Module:Pagetype')._main{} data.project = bannerCfg.project or bannerName:gsub('^WikiProject ', '') data.projectLink = bannerCfg.projectLink or 'Wikipedia:WikiProject ' .. data.project data.projectName = bannerCfg.projectName or 'WikiProject ' .. data.project data.projectScope = bannerCfg.projectScope or '[[' .. data.project .. ']]' data.projectLinkTalk = mw.title.new(data.projectLink).talkPageTitle.prefixedText data.isSmall = yesno(args.small) -- Assessment link if bannerCfg.assessmentLink ~= nil then -- Custom link or false for no link data.assessmentLink = bannerCfg.assessmentLink else local assessmentPage = data.projectLink .. '/Assessment' local assessmentTitle = mw.title.new(assessmentPage) data.assessmentLink = assessmentTitle and assessmentTitle.exists and assessmentTitle.prefixedText end -- Create the HTML fragments. do local fragmentKeys = { 'headerName', 'headerRating', 'blurbImageLeft', 'blurbText', 'blurbImageRight', } local html = {} local create = mw.html.create for _, key in ipairs(fragmentKeys) do html[key] = create() end obj.html = html end -- Define the rest of the object structure. data.grades = {} obj.data = data obj.categories = {} obj.rows = { quality = {}, importance = {}, taskForces = {}, requests = {}, notices = {} } return setmetatable(obj, Banner) end function Banner:addRow(key, isActiveByDefault, rowCfg, ...) -- This function adds one row object to the banner object's rows subtable. if not key or not Banner.rowModules[key] then error(string.format( "'%s' is not a valid key for Banner:addRow", key ), 2) end local isActive = isActiveByDefault or mShared.isActiveRow( self.args, self.data, self.cfg, rowCfg ) if isActive then -- Create the object and add it to the banner's rows table. local aClass = Banner.rowClasses[key] local obj = aClass.new(self.args, self.data, self.cfg, rowCfg, ...) table.insert(self.rows[key], obj) -- Add the categories to the banner object's categories table. for i, category in ipairs(obj:exportCategories()) do table.insert(self.categories, category) end end end function Banner:addRows() local bannerCfg = self.bannerCfg -- Quality if bannerCfg.quality ~= false then Grade = Grade or require('Module:WikiProjectBanner/Grade') local gradeCfg = {} local gradeObj = Grade.new( 'quality', self.args, self.data, self.cfg, gradeCfg ) for i, category in ipairs(gradeObj:exportCategories()) do table.insert(self.categories, category) end local rowCfg = bannerCfg.quality or {} self:addRow('quality', true, rowCfg, gradeObj) self.data.grades.quality = gradeObj end -- Importance if bannerCfg.importance ~= false then Grade = Grade or require('Module:WikiProjectBanner/Grade') local gradeCfg = {} local qualityGrade = self.data.grades.quality if qualityGrade then gradeCfg.forceGrade = qualityGrade:exportData().forceImportance end local gradeObj = Grade.new( 'importance', self.args, self.data, self.cfg, gradeCfg ) for i, category in ipairs(gradeObj:exportCategories()) do table.insert(self.categories, category) end local rowCfg = bannerCfg.importance or {} if gradeObj:exportData().short ~= 'NA' then self:addRow('importance', true, rowCfg, gradeObj) end end -- Task forces, requests, and notices for i, key in ipairs{'taskForces', 'requests', 'notices'} do for j, rowCfg in ipairs(bannerCfg[key] or {}) do self:addRow(key, false, rowCfg) end end -- Count the requests and notices. local nNotes = #self.rows.requests + #self.rows.notices if nNotes > (bannerCfg.collapsed or self.cfg.collapsed or 3) then self.data.isCollapsed = true end end function Banner:callHook(key) local hookFunc = self.bannerCfg.hooks[key] if type(hookFunc) == 'function' then return hookFunc{ categories = self.categories, data = self.data, args = self.args, cfg = self.cfg, bannerCfg = self.bannerCfg } end end function Banner:renderBlurb() self:renderImage('Left') if self.bannerCfg.portal and not self.data.isSmall then local portal = mShared.makePortal(self.bannerCfg.portal) self.html.blurbText:wikitext(portal) end self:renderBlurbText() self:renderImage('Right') end function Banner:renderImage(position) -- Valid positions are "Left" and "Right". They must be capitalised. local filename = self.bannerCfg['image' .. position] if filename then local size = self.data.isSmall and (self.bannerCfg['image' .. position .. 'Small'] or "40px") or (self.bannerCfg['image' .. position .. 'Large'] or "80px") local fileLink = string.format('[[File:%s|%s]]', filename, size) self.html['blurbImage' .. position]:wikitext(fileLink) end end function Banner:renderBlurbText() local blurbText = self:callHook('blurb') or self.bannerCfg.blurb if blurbText then self.html.blurbText:wikitext(blurbText) else local data = self.data local msg if data.isSmall then msg = "This $5 is within the scope of '''[[$2|$1]]''', a collaborative effort " .. "to improve the coverage of $3 on Wikipedia." else msg = "This $5 is within the scope of '''[[$2|$1]]''', a collaborative effort " .. "to improve the coverage of $3 on Wikipedia. If you would like to participate, " .. "please visit the project page, where you can join the [[$4|discussion]] and " .. "see a list of open tasks." end msg = mShared.substituteParams( msg, data.projectName, data.projectLink, data.projectScope, data.projectLinkTalk, data.pageType ) self.html.blurbText:wikitext(msg) end end function Banner:getRowHtml(rowType) -- Render the rows. local rowHtml = mw.html.create() for i, obj in ipairs(self.rows[rowType] or {}) do rowHtml:node(obj:exportHtml()) end return rowHtml end function Banner:renderCategories() local sortKey = self.args.listas local ret = {} if yesno(self.args.category) ~= false then local categoryNsText = mw.site.namespaces[14].name for _, category in ipairs(self.categories) do if sortKey then ret[#ret + 1] = string.format( '[[%s:%s|%s]]', categoryNsText, category, sortKey ) else ret[#ret + 1] = string.format( '[[%s:%s]]', categoryNsText, category ) end end end return table.concat(ret) end function Banner:bindHtmlFragments() local html = self.html local root = mw.html.create() local wrapper = root :node(self:callHook('preWrapper')) :tag('table') :addClass('tmbox tmbox-notice collapsible innercollapse wpb') :addClass(self.data.isSmall and 'mbox-small' or nil) wrapper :tag('tr') :addClass('wpb-header') :tag('td') :css('text-align', 'right') :css('padding', '0.3em 1em 0.3em 0.3em') :css('width', '50%') :css('font-weight', 'bold') :node(self:callHook('headerName')) :done() :tag('th') :css('text-align', 'left') :css('width', '50%') :css('padding', '0.3em 0.3em 0.3em 0') :node(self:callHook('headerRating')) local content = wrapper :tag('tr') :tag('td') :addClass('mbox-text') :css('padding', '3px 0 3px 5px') :attr('colspan', '2') :tag('table') :css('background', 'transparent') :css('border', 'none') :css('padding', '0') :css('width', '100%') :attr('cellspacing', '0') content :node(self:callHook('preBlurb')) local blurbRow = content:tag('tr') -- blurb image left if self.bannerCfg.imageLeft then blurbRow:tag('td') :addClass('mbox-image') :node(html.blurbImageLeft) end -- blurb text do local colspan = (self.bannerCfg.imageLeft and 1 or 0) + (self.bannerCfg.imageRight and 1 or 0) + 1 colspan = colspan > 1 and colspan or nil blurbRow:tag('td') :addClass('mbox-text') :attr('colspan', colspan) :node(html.blurbText) end -- blurb image right if self.bannerCfg.imageRight then blurbRow:tag('td') :addClass('mbox-imageright') :node(html.blurbImageRight) end content :node(self:callHook('postBlurb')) :node(self:getRowHtml('quality')) :node(self:callHook('postQuality')) :node(self:getRowHtml('importance')) :node(self:callHook('postImportance')) :node(self:getRowHtml('taskForces')) :node(self:callHook('postTaskForces')) if self.data.isCollapsed then -- We are collapsing requests and notices, so define the collapsible -- table and add the requests and notices to it. content :tag('tr') :tag('td') :attr('colspan', '3') :css('padding', '0') :tag('table') :addClass('collapsible collapsed') :css('width', '100%') :css('background', 'transparent') :tag('tr') :tag('th') :attr('colspan', '3') :css('text-align', 'left') :css('padding', '0.2em 2px 0.2em 0') :wikitext( self.bannerCfg.moreHeader or 'More information' ) :done() :done() :node(self:callHook('preCollapsedContent')) :node(self:getRowHtml('requests')) :node(self:callHook('postRequests')) :node(self:getRowHtml('notices')) :node(self:callHook('postNotices')) else -- We aren't collapsing requests and notices, so add them to the normal -- content node. content :node(self:getRowHtml('requests')) :node(self:callHook('postRequests')) :node(self:getRowHtml('notices')) :node(self:callHook('postNotices')) end content :node(self:callHook('postContent')) root :wikitext(self:renderCategories()) :node(self:callHook('postWrapper')) html.root = root end function Banner:__tostring() self:addRows() self:callHook() self:renderBlurb() self:bindHtmlFragments() local root = self.html.root or mw.html.create() return tostring(root) end return Banner
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:WikiProjectBanner/Banner/doc
(
edit
)