Difference between revisions of "Module:UserLinks/shared"

From blackwiki
Jump to navigation Jump to search
blackwiki>Mr. Stradivarius
(change name of p.makeUrlLink to p.makeFullUrlLink - will add a new URL function soon)
m (20 revisions imported)
 
(5 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 25: Line 43:
 
end
 
end
 
error(message, level)
 
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
 
end
  
 
function p.makeWikitextError(encodedMessage, demo)
 
function p.makeWikitextError(encodedMessage, demo)
local message, section = mw.ustring.match(encodedMessage, '^(.-)|(.*)$')
+
local errorMessage, section = mw.ustring.match(encodedMessage, '^(.-)|(.*)$')
message = message or encodedMessage
+
errorMessage = errorMessage or encodedMessage
if section then
+
section = ' ([[Template:User-multi#' .. section .. '|help]])'
+
-- If not a demo, get the error category link and pass it through
else
+
-- [[Module:Category handler]]'s blacklist.
section = ''
 
end
 
 
local category
 
local category
 
if not demo then
 
if not demo then
category = '[[Category:UserLinks transclusions with errors]]'
+
category = string.format(
mCategoryHandler = require('Module:Category handler')
+
'[[%s:%s]]',
category = mCategoryHandler.main{
+
namespaces[14].name,
all = category -- Categorise all namespaces, but not blacklisted pages.
+
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
 
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',
message, section, category
+
formattedError,
 +
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
 +
-- 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 72: Line 135:
 
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 84: Line 161:
 
end
 
end
  
function p.makeFullUrlLink(interwiki, namespace, page, query, display)
+
local function formatUrlLink(url, display)
-- Makes a wikitext link to the full URL of a page.
+
-- 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
 
return string.format('[%s]', url)
 
return string.format('[%s]', url)
 
end
 
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
 
end
  
 
function p.message(key, ...)
 
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
 
if not msg then

Latest revision as of 05:04, 30 September 2020

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