Module:Lockbox: Difference between revisions
Appearance
Content deleted Content added
m Protected "Module:Lockbox": High-risk Lua module ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) |
don't show warnings on pages transcluding a lockbox, and make page-name-processing logic more robust by using mw.title objects |
||
Line 2: | Line 2: | ||
-- XXX: OUTRAGEOUS ABUSE OF SCRIBUNTO API |
-- XXX: OUTRAGEOUS ABUSE OF SCRIBUNTO API |
||
-- |
-- Generates a transclusion without incrementing the "expensive function" count |
||
local generate_transclusion |
local generate_transclusion |
||
do |
do |
||
Line 8: | Line 8: | ||
local getContent = mock_title.getContent |
local getContent = mock_title.getContent |
||
function generate_transclusion(title) |
function generate_transclusion(title) |
||
local full_text = type(title) == 'table' and title.fullText or title |
|||
rawset(mock_title, 'fullText', |
rawset(mock_title, 'fullText', full_text) |
||
getContent(mock_title) |
getContent(mock_title) |
||
end |
end |
||
end |
|||
-- I can do the same thing without rawset. |
|||
local function make_wikitext_warning(msg) |
|||
return string.format('<strong class="warning">Warning: %s.</strong>', msg) |
|||
end |
end |
||
function export.lock(frame) |
function export.lock(frame) |
||
local |
local warnings, transclusion_list = {}, {} |
||
-- |
-- Check if the transcluding page is cascade-protected. |
||
-- |
|||
-- XXX: unfortunately there is no other way; title.protectionLevels does not report cascading protection status |
|||
-- Only pages transcluded from a cascade-protected page appear in |
|||
mw.title.getCurrentTitle():getContent() -- self-transclude; see [[mw:Extension:Scribunto/Lua reference manual#Title objects]] |
|||
-- CASCADINGSOURCES, so normally we would not be able to tell if the lockbox |
|||
-- itself is cascade-protected. To work around this, we generate a |
|||
output[#output + 1] = '<strong class="warning">Warning: this page (' .. mw.title.getCurrentTitle().fullText .. ') is not cascade-protected.</strong>\n' |
|||
-- transclusion from the lockbox to itself, so that it will have an entry |
|||
-- for itself in CASCADINGSOURCES. |
|||
-- |
|||
-- We cannot generate this transclusion using the title object for the |
|||
-- parent title (the lockbox), as if the lockbox is transcluded on another |
|||
-- page, we will generate a transclusion *from* the lockbox *to* that page |
|||
-- as well, and the page will be cascade-protected. Instead we generate it |
|||
-- with the title object for the current title. |
|||
-- |
|||
-- When the current title is the parent title (i.e. we are rendering the |
|||
-- lockbox page), this creates the required entry in the link table in the |
|||
-- database. When the current title is the grandparent title or up (i.e. we |
|||
-- are rendering a page transcluding the lockbox), transclusions are only |
|||
-- created from the page itself, not from the lockbox, and it is not |
|||
-- cascade-protected. |
|||
-- |
|||
-- This creates an extaneous self-transclusion for all pages using the |
|||
-- module, but we treat that as a necessary evil. |
|||
-- |
|||
-- XXX: there seems to be no way to check for cascading protection using a |
|||
-- Scribunto API, so we have to use frame:preprocess with the |
|||
-- CASCADINGSOURCES parser function. |
|||
do |
|||
mw.title.getCurrentTitle():getContent() -- Generate self-transclusion |
|||
local parent_title = frame:getParent():getTitle() |
|||
if frame:preprocess('{{CASCADINGSOURCES:' .. parent_title .. '}}') == '' then |
|||
warnings[#warnings + 1] = make_wikitext_warning(string.format( |
|||
'the page "%s" is not cascade-protected', |
|||
parent_title |
|||
)) |
|||
end |
|||
end |
end |
||
local match = string.match |
|||
-- Generate transclusions to the templates, and build the output list. |
|||
for |
for i, item in ipairs(frame.args) do |
||
item = mw.text.trim(item) |
item = mw.text.trim(item) |
||
local title = mw.title.new(item) |
|||
if title then |
|||
local ns, rest = match(item, "^(.-):(.*)") |
|||
local ns = title.namespace |
|||
if not ns or not mw.site.namespaces[ns] then |
|||
local prefixed_text = title.prefixedText |
|||
⚫ | |||
⚫ | |||
output[#output + 1] = '* [[Template:' .. item .. ']]' |
|||
-- The item had no namespace text. If the item starts with a |
|||
elseif (ns == "File") or (ns == "Image") then |
|||
-- colon, assume it is a mainspace page. Otherwise, assume it is |
|||
⚫ | |||
-- a template. |
|||
output[#output + 1] = '* [[:' .. item .. ']]' |
|||
if item:sub(1, 1) == ':' then |
|||
generate_transclusion( |
generate_transclusion(title) |
||
table.insert(transclusion_list, '* [[' .. prefixed_text .. ']]') |
|||
else |
|||
⚫ | |||
generate_transclusion( |
generate_transclusion('Template:' .. prefixed_text) |
||
table.insert(transclusion_list, '* [[Template:' .. prefixed_text .. ']]') |
|||
end |
|||
elseif ns == 6 or ns == 14 then -- File or Category namespace |
|||
⚫ | |||
table.insert(transclusion_list, '* [[:' .. prefixed_text .. ']]') |
|||
else |
|||
⚫ | |||
table.insert(transclusion_list, '* [[' .. prefixed_text .. ']]') |
|||
end |
|||
else |
|||
warnings[#warnings + 1] = make_wikitext_warning(string.format( |
|||
'invalid title "%s" in argument #%d', |
|||
item, |
|||
i |
|||
)) |
|||
end |
end |
||
end |
end |
||
if frame.args.silent then |
if frame.args.silent then |
||
return |
return '' |
||
else |
else |
||
-- If there were any warnings, show them at the top. Then show the list |
|||
⚫ | |||
-- of transcluded pages. |
|||
local ret = '' |
|||
if #warnings > 0 then |
|||
if #warnings > 1 then |
|||
for i, warning in ipairs(warnings) do |
|||
warnings[i] = '* ' .. warning |
|||
end |
|||
end |
|||
ret = ret .. table.concat(warnings, '\n') .. '\n\n' |
|||
end |
|||
⚫ | |||
end |
end |
||
end |
end |
Revision as of 03:39, 17 March 2017
![]() | This module can only be edited by administrators because it is transcluded onto one or more cascade-protected pages. |
This module transcludes templates whose names have been given as parameters in order to trigger cascade protection.
Usage
{{#invoke:lockbox|lock|silent=1 | X1 | X2 | X3 | ... }}
See also
local export = {}
-- XXX: OUTRAGEOUS ABUSE OF SCRIBUNTO API
-- Generates a transclusion without incrementing the "expensive function" count
local generate_transclusion
do
local mock_title = mw.title.new(mw.title.getCurrentTitle().id)
local getContent = mock_title.getContent
function generate_transclusion(title)
local full_text = type(title) == 'table' and title.fullText or title
rawset(mock_title, 'fullText', full_text)
getContent(mock_title)
end
end
local function make_wikitext_warning(msg)
return string.format('<strong class="warning">Warning: %s.</strong>', msg)
end
function export.lock(frame)
local warnings, transclusion_list = {}, {}
-- Check if the transcluding page is cascade-protected.
--
-- Only pages transcluded from a cascade-protected page appear in
-- CASCADINGSOURCES, so normally we would not be able to tell if the lockbox
-- itself is cascade-protected. To work around this, we generate a
-- transclusion from the lockbox to itself, so that it will have an entry
-- for itself in CASCADINGSOURCES.
--
-- We cannot generate this transclusion using the title object for the
-- parent title (the lockbox), as if the lockbox is transcluded on another
-- page, we will generate a transclusion *from* the lockbox *to* that page
-- as well, and the page will be cascade-protected. Instead we generate it
-- with the title object for the current title.
--
-- When the current title is the parent title (i.e. we are rendering the
-- lockbox page), this creates the required entry in the link table in the
-- database. When the current title is the grandparent title or up (i.e. we
-- are rendering a page transcluding the lockbox), transclusions are only
-- created from the page itself, not from the lockbox, and it is not
-- cascade-protected.
--
-- This creates an extaneous self-transclusion for all pages using the
-- module, but we treat that as a necessary evil.
--
-- XXX: there seems to be no way to check for cascading protection using a
-- Scribunto API, so we have to use frame:preprocess with the
-- CASCADINGSOURCES parser function.
do
mw.title.getCurrentTitle():getContent() -- Generate self-transclusion
local parent_title = frame:getParent():getTitle()
if frame:preprocess('{{CASCADINGSOURCES:' .. parent_title .. '}}') == '' then
warnings[#warnings + 1] = make_wikitext_warning(string.format(
'the page "%s" is not cascade-protected',
parent_title
))
end
end
-- Generate transclusions to the templates, and build the output list.
for i, item in ipairs(frame.args) do
item = mw.text.trim(item)
local title = mw.title.new(item)
if title then
local ns = title.namespace
local prefixed_text = title.prefixedText
if ns == 0 then
-- The item had no namespace text. If the item starts with a
-- colon, assume it is a mainspace page. Otherwise, assume it is
-- a template.
if item:sub(1, 1) == ':' then
generate_transclusion(title)
table.insert(transclusion_list, '* [[' .. prefixed_text .. ']]')
else
generate_transclusion('Template:' .. prefixed_text)
table.insert(transclusion_list, '* [[Template:' .. prefixed_text .. ']]')
end
elseif ns == 6 or ns == 14 then -- File or Category namespace
generate_transclusion(title)
table.insert(transclusion_list, '* [[:' .. prefixed_text .. ']]')
else
generate_transclusion(title)
table.insert(transclusion_list, '* [[' .. prefixed_text .. ']]')
end
else
warnings[#warnings + 1] = make_wikitext_warning(string.format(
'invalid title "%s" in argument #%d',
item,
i
))
end
end
if frame.args.silent then
return ''
else
-- If there were any warnings, show them at the top. Then show the list
-- of transcluded pages.
local ret = ''
if #warnings > 0 then
if #warnings > 1 then
for i, warning in ipairs(warnings) do
warnings[i] = '* ' .. warning
end
end
ret = ret .. table.concat(warnings, '\n') .. '\n\n'
end
return ret .. table.concat(transclusion_list, '\n')
end
end
return export