end
end  
function Blurb:_makeProtectionLevelParameter
local protectionLevels = self._cfg.protectionLevels
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionLevels[action][level] then
msg = protectionLevels[action][level]
elseif protectionLevels[action].default then
msg = protectionLevels[action].default
elseif protectionLevels.edit.default then
msg = protectionLevels.edit.default
else
error('no protection level defined for protectionLevels.edit.default', 8)
end
return self:_substituteParameters(msg)
end  
function Blurb:_makeProtectionLogParameter
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'autoreview' then
-- We need the pending changes log.
return makeFullUrl(
'Special:Log',
{type = 'stable', page = pagename},
self:_getExpandedMessage('pc-log-display')
else
-- We need the protection log.
return makeFullUrl(
'Special:Log',
{type = 'protect', page = pagename},
self:_getExpandedMessage('protection-log-display')
end
end  
function Blurb:_makeTalkPageParameter
return string.format(
'%s',
mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
self._protectionObj.title.text,
self._args.section or 'top',
self:_getExpandedMessage('talk-page-link-display')
end  
function Blurb:_makeTooltipBlurbParameter
if self._protectionObj:isTemporary then
return self:_getExpandedMessage('tooltip-blurb-expiry')
else
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
end
end  
function Blurb:_makeTooltipFragmentParameter
if self._protectionObj:isTemporary then
return self:_getExpandedMessage('tooltip-fragment-expiry')
else
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
end
end  
function Blurb:_makeVandalTemplateParameter
return mw.getCurrentFrame:expandTemplate{
title="vandal-m",
args={self._args.user or self._protectionObj.title.baseText}
}
end  
-- Public methods --  
function Blurb:makeBannerText(key)
-- Validate input.
if not key or not Blurb.bannerTextFields[key] then
error(string.format(
'"%s" is not a valid banner config field',
tostring(key)
), 2)
end  
-- Generate the text.
local msg = self._protectionObj.bannerConfig[key]
if type(msg) == 'string' then
return self:_substituteParameters(msg)
elseif type(msg) == 'function' then
msg = msg(self._protectionObj, self._args)
if type(msg) ~= 'string' then
error(string.format(
'bad output from banner config function with key "%s"'
.. ' (expected string, got %s)',
tostring(key),
type(msg)
), 4)
end
return self:_substituteParameters(msg)
end
end  
---
-- BannerTemplate class
---  
local BannerTemplate = {}
BannerTemplate.__index = BannerTemplate  
function BannerTemplate.new(protectionObj, cfg)
local obj = {}
obj._cfg = cfg  
-- Set the image filename.
local imageFilename = protectionObj.bannerConfig.image
if imageFilename then
obj._imageFilename = imageFilename
else
-- If an image filename isn't specified explicitly in the banner config,
-- generate it from the protection status and the namespace.
local action = protectionObj.action
local level = protectionObj.level
local namespace = protectionObj.title.namespace
local reason = protectionObj.reason  
-- Deal with special cases first.
if (
namespace == 10
or namespace == 828
or reason and obj._cfg.indefImageReasons[reason]
and action == 'edit'
and level == 'sysop'
and not protectionObj:isTemporary
then
-- Fully protected modules and templates get the special red "indef"
-- padlock.
obj._imageFilename = obj._cfg.msg['image-filename-indef']
else
-- Deal with regular protection types.
local images = obj._cfg.images
if images[action] then
if images[action][level] then
obj._imageFilename = images[action][level]
elseif images[action].default then
obj._imageFilename = images[action].default
end
end
end
end
return setmetatable(obj, BannerTemplate)
end  
function BannerTemplate:renderImage
local filename = self._imageFilename
or self._cfg.msg['image-filename-default']
or 'Transparent.gif'
return makeFileLink{
file = filename,
size = (self.imageWidth or 20) .. 'px',
alt = self._imageAlt,
link = self._imageLink,
caption = self.imageCaption
}
end  
---
-- Banner class
---  
local Banner = setmetatable({}, BannerTemplate)
Banner.__index = Banner  
function Banner.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 40
obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip.
obj._reasonText = blurbObj:makeBannerText('text')
obj._explanationText = blurbObj:makeBannerText('explanation')
obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing.
return setmetatable(obj, Banner)
end  
function Banner:__tostring
-- Renders the banner.
makeMessageBox = makeMessageBox or require('Module:Message box').main
local reasonText = self._reasonText or error('no reason text set', 2)
local explanationText = self._explanationText
local mbargs = {
page = self._page,
type = 'protection',
image = self:renderImage,
text = string.format(
"**%s**%s",
reasonText,
explanationText and '
' .. explanationText or ''
}
return makeMessageBox('mbox', mbargs)
end  
---
-- Padlock class
---  
local Padlock = setmetatable({}, BannerTemplate)
Padlock.__index = Padlock  
function Padlock.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 20
obj.imageCaption = blurbObj:makeBannerText('tooltip')
obj._imageAlt = blurbObj:makeBannerText('alt')
obj._imageLink = blurbObj:makeBannerText('link')
obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action]
or cfg.padlockIndicatorNames.default
or 'pp-default'
return setmetatable(obj, Padlock)
end  
function Padlock:__tostring
local = mw.getCurrentFrame
-- The nowiki tag helps prevent whitespace at the top of articles.
return :extensionTag{name = 'nowiki'} .. :extensionTag{
name = 'indicator',
args = {name = self._indicatorName},
content = self:renderImage
}
end  
---
-- Exports
---  
local p = {}  
function p._exportClasses
-- This is used for testing purposes.
return {
Protection = Protection,
Blurb = Blurb,
BannerTemplate = BannerTemplate,
Banner = Banner,
Padlock = Padlock,
}
end  
function p._main(args, cfg, title)
args = args or {}
cfg = cfg or require(CONFIG_MODULE)  
local protectionObj = Protection.new(args, cfg, title)  
local ret = {}  
-- If a page's edit protection is equally or more restrictive than its
-- protection from some other action, then don't bother displaying anything
-- for the other action (except categories).
if not yesno(args.catonly) and (protectionObj.action == 'edit' or
args.demolevel or
not getReachableNodes(
cfg.hierarchy,
protectionObj.level
)[effectiveProtectionLevel('edit', protectionObj.title)])
then
-- Initialise the blurb object
local blurbObj = Blurb.new(protectionObj, args, cfg)  
-- Render the banner
if protectionObj:shouldShowLock then
ret[#ret + 1] = tostring(
(yesno(args.small) and Padlock or Banner)
.new(protectionObj, blurbObj, cfg)
end
end  
-- Render the categories
if yesno(args.category) ~= false then
ret[#ret + 1] = protectionObj:makeCategoryLinks
end  
-- For arbitration enforcement, flagging WP:PIA pages to enable Special:AbuseFilter/1339 to flag edits to them
if protectionObj.level == "extendedconfirmed" then
if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then
ret[#ret + 1] = "<p title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>"
end
end  
return table.concat(ret)
end  
function p.main(, cfg)
cfg = cfg or require(CONFIG_MODULE)  
-- Find default args, if any.
local parent = .getParent and :getParent
local defaultArgs = parent and cfg.wrappers[parent:getTitle:gsub('/sandbox$', '')]  
-- Find user args, and use the parent if we are being called from a