Module:UserLinks/shared: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(raise error if no namespace defined)
m (20 revisions imported)
 
(13 intermediate revisions by one other user not shown)
Line 5: Line 5:
local cfg = mw.loadData('Module:UserLinks/config')
local cfg = mw.loadData('Module:UserLinks/config')
local namespaces = mw.site.namespaces
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.
-- Define namespaces for which links need to be escaped with the colon trick.
Line 14: Line 17:


local p = {}
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)
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
if section then
message = message .. '|' .. section
message = message .. '|' .. section
Line 27: Line 45:
end
end


local localBlacklist = {
function p.makeWikitextError(encodedMessage, demo)
'/[sS]andbox$', -- Don't categorise sandboxes
local message, section = mw.ustring.match(encodedMessage, '^(.-)|(.*)$')
'/[tT]est ?cases$', -- Don't categorise test case pages
message = message or encodedMessage
}
if section then

section = ' ([[Template:User-multi#' .. section .. '|help]])'
local function currentTitleMatchesLocalBlacklist()
else
-- Return true if the current title matches any of the patterns in the
section = ''
-- 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
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
local category
if not demo then
if not demo then
category = '[[Category:UserLinks transclusions with errors]]'
category = string.format(
'[[%s:%s]]',
mCategoryHandler = require('Module:Category handler')
namespaces[14].name,
category = mCategoryHandler.main{
p.message('error-config-category')
all = category -- Categorise all namespaces, but not blacklisted pages.
}
)
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
end
category = category or ''
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(
return string.format(
'<strong class="error">[[Template:User-multi|User-multi]] error: %s%s.</strong>%s',
'<strong class="error">%s</strong>%s',
formattedError,
message, section, category
category
)
)
end
end


local function formatPage(interwiki, namespace, page)
local function formatPage(interwiki, namespace, page)
-- Formats an interwiki, a namespace and a page into a wikilink-ready
namespace = namespace or error('no namespace defined', 2)
-- 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 = {}
local ret = {}
interwiki = interwiki or ''
interwiki = interwiki or ''
Line 61: Line 123:
ret[#ret + 1] = ':'
ret[#ret + 1] = ':'
end
end
if namespace then
ret[#ret + 1] = namespaces[namespace].name
local nsTable = namespaces[namespace]
if namespace ~= 0 then
if not nsTable then
ret[#ret + 1] = ':'
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
end
ret[#ret + 1] = page
ret[#ret + 1] = page
return table.concat(ret)
return table.concat(ret)
end

local function formatDisplay(s)
-- Replaces spaces in a string with "&nbsp;" to make sure they don't wrap.
-- Don't replace anything if we are substing, as we generally don't want
-- to use "&nbsp;" in that case.
if mw.isSubsting() then
return s
else
return s:gsub(' ', '&nbsp;')
end
end
end


function p.makeWikilink(interwiki, namespace, page, display)
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)
local formattedPage = formatPage(interwiki, namespace, page)
if display then
if display then
display = display:gsub(' ', '&nbsp;')
display = formatDisplay(display)
return string.format('[[%s|%s]]', formattedPage, display)
return string.format('[[%s|%s]]', formattedPage, display)
else
else
Line 79: Line 161:
end
end


function p.makeUrlLink(interwiki, namespace, page, query, display)
local function formatUrlLink(url, display)
-- Formats a URL link with an optional display parameter.
local formattedPage = formatPage(interwiki, namespace, page)
query = query or {}
local url = mw.uri.fullUrl(formattedPage, query)
url = tostring(url)
if display then
if display then
display = display:gsub(' ', '&nbsp;')
display = formatDisplay(display)
return string.format('[%s %s]', url, display)
return string.format('[%s %s]', url, display)
else
else
Line 92: Line 171:
end
end


function p.message(key)
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]
local msg = cfg[key]
if not msg then
return msg or p.raiseError(
p.raiseError(
'No message found with key "' .. tostring(key) .. '"',
'No message found',
'No message found with key "' .. tostring(key) .. '"',
'No message found',
2
2
)
)
end
local noArgs = select('#', ...)
if noArgs < 1 then
return msg
else
local msg = mw.message.newRawMessage(msg, ...)
return msg:plain()
end
end
end



Latest revision as of 17:25, January 24, 2022

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 "&nbsp;" to make sure they don't wrap.
	-- Don't replace anything if we are substing, as we generally don't want
	-- to use "&nbsp;" in that case.
	if mw.isSubsting() then
		return s
	else
		return s:gsub(' ', '&nbsp;')
	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