<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://projectmailer.net/index.php?action=history&amp;feed=atom&amp;title=Module%3AUserLinks%2Fshared</id>
	<title>Module:UserLinks/shared - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://projectmailer.net/index.php?action=history&amp;feed=atom&amp;title=Module%3AUserLinks%2Fshared"/>
	<link rel="alternate" type="text/html" href="https://projectmailer.net/index.php?title=Module:UserLinks/shared&amp;action=history"/>
	<updated>2026-04-27T18:33:41Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>https://projectmailer.net/index.php?title=Module:UserLinks/shared&amp;diff=6598&amp;oldid=prev</id>
		<title>Grlucas: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://projectmailer.net/index.php?title=Module:UserLinks/shared&amp;diff=6598&amp;oldid=prev"/>
		<updated>2019-04-09T18:14:37Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:14, 9 April 2019&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key projectmailer-mw5w_:diff:1.41:old-6597:rev-6598 --&gt;
&lt;/table&gt;</summary>
		<author><name>Grlucas</name></author>
	</entry>
	<entry>
		<id>https://projectmailer.net/index.php?title=Module:UserLinks/shared&amp;diff=6597&amp;oldid=prev</id>
		<title>en&gt;Mr. Stradivarius: set up a local blacklist system so that we don&#039;t categorise sandboxes or test case pages</title>
		<link rel="alternate" type="text/html" href="https://projectmailer.net/index.php?title=Module:UserLinks/shared&amp;diff=6597&amp;oldid=prev"/>
		<updated>2016-12-30T15:21:53Z</updated>

		<summary type="html">&lt;p&gt;set up a local blacklist system so that we don&amp;#039;t categorise sandboxes or test case pages&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- This module stores functions that are shared between [[Module:UserLinks]]&lt;br /&gt;
-- and [[Module:UserLinks/extra]].&lt;br /&gt;
&lt;br /&gt;
-- Load data and define often-used variables&lt;br /&gt;
local cfg = mw.loadData(&amp;#039;Module:UserLinks/config&amp;#039;)&lt;br /&gt;
local namespaces = mw.site.namespaces&lt;br /&gt;
&lt;br /&gt;
-- Lazily initialise modules that we may or may not need&lt;br /&gt;
local mCategoryHandler&lt;br /&gt;
&lt;br /&gt;
-- Define namespaces for which links need to be escaped with the colon trick.&lt;br /&gt;
-- See [[w:en:Help:Colon trick]].&lt;br /&gt;
local colonNamespaces = {&lt;br /&gt;
	[6] = true, -- File&lt;br /&gt;
	[14] = true, -- Category&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.maybeLoadModule(s)&lt;br /&gt;
	-- Attempts to load the module s. If it succeeds, returns the module;&lt;br /&gt;
	-- otherwise, returns false.&lt;br /&gt;
	local success, mdl = pcall(require, s)&lt;br /&gt;
	if success then&lt;br /&gt;
		return mdl&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.raiseError(message, section, level)&lt;br /&gt;
	-- Raises an error using the Lua error function. The error message is&lt;br /&gt;
	-- designed to be caught with pcall and then passed to p.makeWikitextError.&lt;br /&gt;
	-- The section, if specified, is the section name on a help page that gives&lt;br /&gt;
	-- help to users about that particular error.&lt;br /&gt;
	if section then&lt;br /&gt;
		message = message .. &amp;#039;|&amp;#039; .. section&lt;br /&gt;
	end&lt;br /&gt;
	if not level or level == 0 then&lt;br /&gt;
		level = 0&lt;br /&gt;
	else&lt;br /&gt;
		level = level + 1&lt;br /&gt;
	end&lt;br /&gt;
	error(message, level)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local localBlacklist = {&lt;br /&gt;
	&amp;#039;/[sS]andbox$&amp;#039;, -- Don&amp;#039;t categorise sandboxes&lt;br /&gt;
	&amp;#039;/[tT]est ?cases$&amp;#039;, -- Don&amp;#039;t categorise test case pages&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function currentTitleMatchesLocalBlacklist()&lt;br /&gt;
	-- Return true if the current title matches any of the patterns in the&lt;br /&gt;
	-- local blacklist table. Otherwise return false.&lt;br /&gt;
	local title = mw.title.getCurrentTitle().prefixedText&lt;br /&gt;
	for i, pattern in ipairs(localBlacklist) do&lt;br /&gt;
		if title:find(pattern) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeWikitextError(encodedMessage, demo)&lt;br /&gt;
	local errorMessage, section = mw.ustring.match(encodedMessage, &amp;#039;^(.-)|(.*)$&amp;#039;)&lt;br /&gt;
	errorMessage = errorMessage or encodedMessage&lt;br /&gt;
	&lt;br /&gt;
	-- If not a demo, get the error category link and pass it through&lt;br /&gt;
	-- [[Module:Category handler]]&amp;#039;s blacklist.&lt;br /&gt;
	local category&lt;br /&gt;
	if not demo then&lt;br /&gt;
		category = string.format(&lt;br /&gt;
			&amp;#039;[[%s:%s]]&amp;#039;,&lt;br /&gt;
			namespaces[14].name,&lt;br /&gt;
			p.message(&amp;#039;error-config-category&amp;#039;)&lt;br /&gt;
		)&lt;br /&gt;
		mCategoryHandler = p.maybeLoadModule(&amp;#039;Module:Category handler&amp;#039;)&lt;br /&gt;
		if mCategoryHandler then&lt;br /&gt;
			-- Categorise all namespaces, but not blacklisted pages.&lt;br /&gt;
			category = mCategoryHandler.main{all = category}&lt;br /&gt;
		end&lt;br /&gt;
		if category and currentTitleMatchesLocalBlacklist() then&lt;br /&gt;
			category = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	category = category or &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	-- Format the error message and the section link.&lt;br /&gt;
	local formattedError&lt;br /&gt;
	if section then&lt;br /&gt;
		formattedError = p.message(&lt;br /&gt;
			&amp;#039;error-config-message-help&amp;#039;,&lt;br /&gt;
			errorMessage,&lt;br /&gt;
			section&lt;br /&gt;
		)&lt;br /&gt;
	else&lt;br /&gt;
		formattedError = p.message(&lt;br /&gt;
			&amp;#039;error-config-message-nohelp&amp;#039;,&lt;br /&gt;
			errorMessage&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Return the error message and the category inside html error tags.&lt;br /&gt;
	return string.format(&lt;br /&gt;
		&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/strong&amp;gt;%s&amp;#039;,&lt;br /&gt;
		formattedError,&lt;br /&gt;
		category&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatPage(interwiki, namespace, page)&lt;br /&gt;
	-- Formats an interwiki, a namespace and a page into a wikilink-ready&lt;br /&gt;
	-- string. The interwiki and namespace are optional. If a namespace is&lt;br /&gt;
	-- specified, it should be a valid key to mw.site.namespaces. The page&lt;br /&gt;
	-- parameter is required.&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	interwiki = interwiki or &amp;#039;&amp;#039;&lt;br /&gt;
	if interwiki ~= &amp;#039;&amp;#039; or colonNamespaces[namespace] then&lt;br /&gt;
		ret[#ret + 1] = &amp;#039;:&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	ret[#ret + 1] = interwiki&lt;br /&gt;
	if interwiki ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		ret[#ret + 1] = &amp;#039;:&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if namespace then&lt;br /&gt;
		local nsTable = namespaces[namespace]&lt;br /&gt;
		if not nsTable then&lt;br /&gt;
			error(&amp;#039;&amp;quot;&amp;#039; .. tostring(namespace) .. &amp;#039;&amp;quot; is not a valid namespace key&amp;#039;, 2)&lt;br /&gt;
		end&lt;br /&gt;
		ret[#ret + 1] = nsTable.name&lt;br /&gt;
		if namespace ~= 0 then&lt;br /&gt;
			ret[#ret + 1] = &amp;#039;:&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	ret[#ret + 1] = page&lt;br /&gt;
	return table.concat(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatDisplay(s)&lt;br /&gt;
	-- Replaces spaces in a string with &amp;quot;&amp;amp;nbsp;&amp;quot; to make sure they don&amp;#039;t wrap.&lt;br /&gt;
	-- Don&amp;#039;t replace anything if we are substing, as we generally don&amp;#039;t want&lt;br /&gt;
	-- to use &amp;quot;&amp;amp;nbsp;&amp;quot; in that case.&lt;br /&gt;
	if mw.isSubsting() then&lt;br /&gt;
		return s&lt;br /&gt;
	else&lt;br /&gt;
		return s:gsub(&amp;#039; &amp;#039;, &amp;#039;&amp;amp;nbsp;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeWikilink(interwiki, namespace, page, display)&lt;br /&gt;
	-- Creates a wikilink. The interwiki, namespace and display parameters are&lt;br /&gt;
	-- optional. If a namespace parameter is specified it must be a valid key&lt;br /&gt;
	-- to mw.site.namespaces.&lt;br /&gt;
	local formattedPage = formatPage(interwiki, namespace, page)&lt;br /&gt;
	if display then&lt;br /&gt;
		display = formatDisplay(display)&lt;br /&gt;
		return string.format(&amp;#039;[[%s|%s]]&amp;#039;, formattedPage, display)&lt;br /&gt;
	else&lt;br /&gt;
		return string.format(&amp;#039;[[%s]]&amp;#039;, formattedPage)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatUrlLink(url, display)&lt;br /&gt;
	-- Formats a URL link with an optional display parameter.&lt;br /&gt;
	if display then&lt;br /&gt;
		display = formatDisplay(display)&lt;br /&gt;
		return string.format(&amp;#039;[%s %s]&amp;#039;, url, display)&lt;br /&gt;
	else&lt;br /&gt;
		return string.format(&amp;#039;[%s]&amp;#039;, url)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeUrlLink(s, display)&lt;br /&gt;
	-- Makes a URL link with an optional display parameter. The first input&lt;br /&gt;
	-- may be any valid input to mw.uri.new.&lt;br /&gt;
	local url = mw.uri.new(s)&lt;br /&gt;
	url = tostring(url)&lt;br /&gt;
	return formatUrlLink(url, display)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.makeFullUrlLink(interwiki, namespace, page, query, display)&lt;br /&gt;
	-- Makes a link to the full URL of a page. The interwiki, namespace, query&lt;br /&gt;
	-- and display parameters are optional. If a namespace parameter is&lt;br /&gt;
	-- specified it must be a valid key to mw.site.namespaces. The query&lt;br /&gt;
	-- parameter can be a string or a table as specified in the mw.uri library.&lt;br /&gt;
	local formattedPage = formatPage(interwiki, namespace, page)&lt;br /&gt;
	local url = mw.uri.fullUrl(formattedPage, query)&lt;br /&gt;
	url = tostring(url)&lt;br /&gt;
	return formatUrlLink(url, display)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.message(key, ...)&lt;br /&gt;
	-- Returns the message with the given key from [[Module:UserLinks/config]].&lt;br /&gt;
	-- Extra parameters are substituted in the message for keys $1, $2, $3, etc.&lt;br /&gt;
	local msg = cfg[key]&lt;br /&gt;
	if not msg then&lt;br /&gt;
		p.raiseError(&lt;br /&gt;
			&amp;#039;No message found with key &amp;quot;&amp;#039; .. tostring(key) .. &amp;#039;&amp;quot;&amp;#039;,&lt;br /&gt;
			&amp;#039;No message found&amp;#039;,&lt;br /&gt;
			2&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	local noArgs = select(&amp;#039;#&amp;#039;, ...)&lt;br /&gt;
	if noArgs &amp;lt; 1 then&lt;br /&gt;
		return msg&lt;br /&gt;
	else&lt;br /&gt;
		local msg = mw.message.newRawMessage(msg, ...)&lt;br /&gt;
		return msg:plain()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>en&gt;Mr. Stradivarius</name></author>
	</entry>
</feed>