Module:UserLinks/shared
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This Lua module is used in system messages. Changes to it can cause immediate changes to the Wikipedia user interface. To avoid major disruption, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Please discuss changes on the talk page before implementing them. |
This module stores functions that are shared between Module:UserLinks and Module:UserLinks/extra.
-- This module stores functions that are shared between [[Module:UserLinks]]
-- and [[Module:UserLinks/extra]].
-- Load data and define often-used variables
local cfg = mw.loadData('Module:UserLinks/config')
local namespaces = mw.site.namespaces
-- Lazily initialise modules that we may or may not need
local mCategoryHandler
-- Define namespaces for which links need to be escaped with the colon trick.
-- See [[w:en:Help:Colon trick]].
local colonNamespaces = {
[6] = true, -- File
[14] = true, -- Category
}
local p = {}
function p.maybeLoadModule(s)
-- Attempts to load the module s. If it succeeds, returns the module;
-- otherwise, returns false.
local success, mdl = pcall(require, s)
if success then
return mdl
else
return false
end
end
function p.raiseError(message, section, level)
-- Raises an error using the Lua error function. The error message is
-- designed to be caught with pcall and then passed to p.makeWikitextError.
-- The section, if specified, is the section name on a help page that gives
-- help to users about that particular error.
if section then
message = message .. '|' .. section
end
if not level or level == 0 then
level = 0
else
level = level + 1
end
error(message, level)
end
local localBlacklist = {
'/[sS]andbox$', -- Don't categorise sandboxes
'/[tT]est ?cases$', -- Don't categorise test case pages
}
local function currentTitleMatchesLocalBlacklist()
-- Return true if the current title matches any of the patterns in the
-- local blacklist table. Otherwise return false.
local title = mw.title.getCurrentTitle().prefixedText
for i, pattern in ipairs(localBlacklist) do
if title:find(pattern) then
return true
end
end
return false
end
function p.makeWikitextError(encodedMessage, demo)
local errorMessage, section = mw.ustring.match(encodedMessage, '^(.-)|(.*)$')
errorMessage = errorMessage or encodedMessage
-- If not a demo, get the error category link and pass it through
-- [[Module:Category handler]]'s blacklist.
local category
if not demo then
category = string.format(
'[[%s:%s]]',
namespaces[14].name,
p.message('error-config-category')
)
mCategoryHandler = p.maybeLoadModule('Module:Category handler')
if mCategoryHandler then
-- Categorise all namespaces, but not blacklisted pages.
category = mCategoryHandler.main{all = category}
end
if category and currentTitleMatchesLocalBlacklist() then
category = nil
end
end
category = category or ''
-- Format the error message and the section link.
local formattedError
if section then
formattedError = p.message(
'error-config-message-help',
errorMessage,
section
)
else
formattedError = p.message(
'error-config-message-nohelp',
errorMessage
)
end
-- Return the error message and the category inside html error tags.
return string.format(
'<strong class="error">%s</strong>%s',
formattedError,
category
)
end
local function formatPage(interwiki, namespace, page)
-- Formats an interwiki, a namespace and a page into a wikilink-ready
-- string. The interwiki and namespace are optional. If a namespace is
-- specified, it should be a valid key to mw.site.namespaces. The page
-- parameter is required.
local ret = {}
interwiki = interwiki or ''
if interwiki ~= '' or colonNamespaces[namespace] then
ret[#ret + 1] = ':'
end
ret[#ret + 1] = interwiki
if interwiki ~= '' then
ret[#ret + 1] = ':'
end
if namespace then
local nsTable = namespaces[namespace]
if not nsTable then
error('"' .. tostring(namespace) .. '" is not a valid namespace key', 2)
end
ret[#ret + 1] = nsTable.name
if namespace ~= 0 then
ret[#ret + 1] = ':'
end
end
ret[#ret + 1] = page
return table.concat(ret)
end
local function formatDisplay(s)
-- Replaces spaces in a string with " " to make sure they don't wrap.
-- Don't replace anything if we are substing, as we generally don't want
-- to use " " in that case.
if mw.isSubsting() then
return s
else
return s:gsub(' ', ' ')
end
end
function p.makeWikilink(interwiki, namespace, page, display)
-- Creates a wikilink. The interwiki, namespace and display parameters are
-- optional. If a namespace parameter is specified it must be a valid key
-- to mw.site.namespaces.
local formattedPage = formatPage(interwiki, namespace, page)
if display then
display = formatDisplay(display)
return string.format('[[%s|%s]]', formattedPage, display)
else
return string.format('[[%s]]', formattedPage)
end
end
local function formatUrlLink(url, display)
-- Formats a URL link with an optional display parameter.
if display then
display = formatDisplay(display)
return string.format('[%s %s]', url, display)
else
return string.format('[%s]', url)
end
end
function p.makeUrlLink(s, display)
-- Makes a URL link with an optional display parameter. The first input
-- may be any valid input to mw.uri.new.
local url = mw.uri.new(s)
url = tostring(url)
return formatUrlLink(url, display)
end
function p.makeFullUrlLink(interwiki, namespace, page, query, display)
-- Makes a link to the full URL of a page. The interwiki, namespace, query
-- and display parameters are optional. If a namespace parameter is
-- specified it must be a valid key to mw.site.namespaces. The query
-- parameter can be a string or a table as specified in the mw.uri library.
local formattedPage = formatPage(interwiki, namespace, page)
local url = mw.uri.fullUrl(formattedPage, query)
url = tostring(url)
return formatUrlLink(url, display)
end
function p.message(key, ...)
-- Returns the message with the given key from [[Module:UserLinks/config]].
-- Extra parameters are substituted in the message for keys $1, $2, $3, etc.
local msg = cfg[key]
if not msg then
p.raiseError(
'No message found with key "' .. tostring(key) .. '"',
'No message found',
2
)
end
local noArgs = select('#', ...)
if noArgs < 1 then
return msg
else
local msg = mw.message.newRawMessage(msg, ...)
return msg:plain()
end
end
return p