<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mindpowe.red/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AUserLinks</id>
	<title>Module:UserLinks - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mindpowe.red/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AUserLinks"/>
	<link rel="alternate" type="text/html" href="https://mindpowe.red/wiki/index.php?title=Module:UserLinks&amp;action=history"/>
	<updated>2026-04-06T03:49:10Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://mindpowe.red/wiki/index.php?title=Module:UserLinks&amp;diff=2873&amp;oldid=prev</id>
		<title>imported&gt;Xaosflux: Changed protection level for &quot;Module:UserLinks&quot;: no longer in interface ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))</title>
		<link rel="alternate" type="text/html" href="https://mindpowe.red/wiki/index.php?title=Module:UserLinks&amp;diff=2873&amp;oldid=prev"/>
		<updated>2020-08-08T01:02:18Z</updated>

		<summary type="html">&lt;p&gt;Changed protection level for &amp;quot;&lt;a href=&quot;/wiki/index.php/Module:UserLinks&quot; title=&quot;Module:UserLinks&quot;&gt;Module:UserLinks&lt;/a&gt;&amp;quot;: no longer in interface ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite))&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                                 UserLinks                                  --&lt;br /&gt;
-- This module creates a list of links about a given user. It can be used on  --&lt;br /&gt;
-- its own or from a template. See the /doc page for more documentation.      --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Require necessary modules&lt;br /&gt;
local yesno = require('Module:Yesno')&lt;br /&gt;
&lt;br /&gt;
-- Lazily initialise modules that we might or might not need&lt;br /&gt;
local mExtra -- [[Module:UserLinks/extra]]&lt;br /&gt;
local mArguments -- [[Module:Arguments]]&lt;br /&gt;
local mToolbar -- [[Module:Toolbar]]&lt;br /&gt;
local mCategoryHandler -- [[Module:Category handler]]&lt;br /&gt;
local mTableTools -- [[Module:TableTools]]&lt;br /&gt;
local interwikiTable -- [[Module:InterwikiTable]], loaded with mw.loadData&lt;br /&gt;
&lt;br /&gt;
-- Load shared helper functions&lt;br /&gt;
local mShared = require('Module:UserLinks/shared')&lt;br /&gt;
local raiseError = mShared.raiseError&lt;br /&gt;
local maybeLoadModule = mShared.maybeLoadModule&lt;br /&gt;
local makeWikitextError = mShared.makeWikitextError&lt;br /&gt;
local makeWikilink = mShared.makeWikilink&lt;br /&gt;
local makeUrlLink = mShared.makeUrlLink&lt;br /&gt;
local makeFullUrlLink = mShared.makeFullUrlLink&lt;br /&gt;
local message = mShared.message&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Link table&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function p.getLinks(snippets)&lt;br /&gt;
	--[=[&lt;br /&gt;
	-- Get a table of links that can be indexed with link codes. The table&lt;br /&gt;
	-- returned is blank, but links are added to it on demand when it is&lt;br /&gt;
	-- indexed. This is made possible by the metatable and by the various link&lt;br /&gt;
	-- functions, some of which are defined here, and some of which are defined&lt;br /&gt;
	-- at [[Module:UserLinks/extra]].&lt;br /&gt;
	--]=]&lt;br /&gt;
	local links, linkFunctions = {}, {}&lt;br /&gt;
&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
	-- Link functions&lt;br /&gt;
	--&lt;br /&gt;
	-- The following functions make the links from the link codes and the user&lt;br /&gt;
	-- data snippets. New link functions should be added below the existing&lt;br /&gt;
	-- functions.&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.u(snippets)&lt;br /&gt;
		-- User page&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			2,&lt;br /&gt;
			snippets.username,&lt;br /&gt;
			snippets.username&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.t(snippets)&lt;br /&gt;
		-- User talk page&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			3,&lt;br /&gt;
			snippets.username,&lt;br /&gt;
			message('display-talk')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.c(snippets)&lt;br /&gt;
		-- Contributions&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Contribs/' .. snippets.username,&lt;br /&gt;
			message('display-contributions')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function linkFunctions.c64(snippets)&lt;br /&gt;
		-- Contributions&lt;br /&gt;
		local first64 = snippets.username:match('^%x+:%x+:%x+:%x+:')&lt;br /&gt;
			or snippets.username:match('^%x+:%x+:%x+:')&lt;br /&gt;
			or snippets.username:match('^%x+:%x+:')&lt;br /&gt;
			or snippets.username:match('^%x+:')&lt;br /&gt;
		return first64 and makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Contribs/' .. first64 .. ':/64',&lt;br /&gt;
			'(/64)'&lt;br /&gt;
		) or ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.ct(snippets)&lt;br /&gt;
		-- Edit count&lt;br /&gt;
		return makeUrlLink(&lt;br /&gt;
			{&lt;br /&gt;
				host = 'xtools.wmflabs.org',&lt;br /&gt;
				path = '/ec/',&lt;br /&gt;
				query = {&lt;br /&gt;
					username = snippets.username,&lt;br /&gt;
					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			message('display-count')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.m(snippets)&lt;br /&gt;
		-- Page moves&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/move/' .. snippets.username,&lt;br /&gt;
			message('display-moves')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.l(snippets)&lt;br /&gt;
		-- Logs&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/' .. snippets.username,&lt;br /&gt;
			message('display-logs')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.ae(snippets)&lt;br /&gt;
		-- Automated edits (and non-automated contributions).&lt;br /&gt;
		return makeUrlLink(&lt;br /&gt;
			{&lt;br /&gt;
				host = 'xtools.wmflabs.org',&lt;br /&gt;
				path = '/autoedits/',&lt;br /&gt;
				query = {&lt;br /&gt;
					username = snippets.username,&lt;br /&gt;
					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			message('display-autoedits')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.bl(snippets)&lt;br /&gt;
		-- Block log&lt;br /&gt;
		return makeFullUrlLink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/block',&lt;br /&gt;
			{page = 'User:' .. snippets.username},&lt;br /&gt;
			message('display-blocklog')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.bls(snippets)&lt;br /&gt;
		-- Blocks&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/block/' .. snippets.username,&lt;br /&gt;
			message('display-blocks')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.bu(snippets)&lt;br /&gt;
		-- Block user&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Block/' .. snippets.username,&lt;br /&gt;
			message('display-blockuser')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.ca(snippets)&lt;br /&gt;
		-- Central auth&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'CentralAuth/' .. snippets.username,&lt;br /&gt;
			message('display-centralauth')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.dc(snippets)&lt;br /&gt;
		-- Deleted contribs&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'DeletedContributions/' .. snippets.username,&lt;br /&gt;
			message('display-deletedcontributions')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.e(snippets)&lt;br /&gt;
		-- Email&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'EmailUser/' .. snippets.username,&lt;br /&gt;
			message('display-email')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.es(snippets)&lt;br /&gt;
		-- Edit summaries&lt;br /&gt;
		return makeUrlLink(&lt;br /&gt;
			{&lt;br /&gt;
				host = 'xtools.wmflabs.org',&lt;br /&gt;
				path = '/editsummary/',&lt;br /&gt;
				query = {&lt;br /&gt;
					username = snippets.username,&lt;br /&gt;
					project = snippets.toolLang .. '.' .. snippets.projectLong .. '.org'&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			message('display-editsummaries')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.del(snippets)&lt;br /&gt;
		-- Deletions&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/delete/' .. snippets.username,&lt;br /&gt;
			message('display-deletions')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.lu(snippets)&lt;br /&gt;
		-- List user&lt;br /&gt;
		return makeFullUrlLink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'ListUsers',&lt;br /&gt;
			{limit = 1, username = snippets.username},&lt;br /&gt;
			message('display-listuser')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.sul(snippets)&lt;br /&gt;
		-- SUL&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			nil,&lt;br /&gt;
			nil,&lt;br /&gt;
			'sulutil:' .. snippets.username,&lt;br /&gt;
			message('display-sul')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.tl(snippets)&lt;br /&gt;
		-- Target logs&lt;br /&gt;
		return makeFullUrlLink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log',&lt;br /&gt;
			{page = mw.site.namespaces[2].name .. ':' .. snippets.username},&lt;br /&gt;
			message('display-targetlogs')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.efl(snippets)&lt;br /&gt;
		-- Edit filter log&lt;br /&gt;
		return makeFullUrlLink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'AbuseLog',&lt;br /&gt;
			{wpSearchUser = snippets.username},&lt;br /&gt;
			message('display-abuselog')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.pr(snippets)&lt;br /&gt;
		-- Protections&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/protect/' .. snippets.username,&lt;br /&gt;
			message('display-protections')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.rl(snippets)&lt;br /&gt;
		-- User rights&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/rights/' .. snippets.username,&lt;br /&gt;
			message('display-rights')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.ren(snippets)&lt;br /&gt;
		-- Renames&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'Log/renameuser/' .. snippets.username,&lt;br /&gt;
			message('display-renames')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.rfa(snippets)&lt;br /&gt;
		-- Requests for adminship&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			nil,&lt;br /&gt;
			-1,&lt;br /&gt;
			'PrefixIndex/' .. message('page-rfa') .. '/' .. snippets.username,&lt;br /&gt;
			message('display-rfa')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.api(snippets)&lt;br /&gt;
		-- API user data&lt;br /&gt;
		return makeUrlLink(&lt;br /&gt;
			{&lt;br /&gt;
				host = snippets.fullDomain,&lt;br /&gt;
				path = '/w/api.php',&lt;br /&gt;
				query = {&lt;br /&gt;
					action = 'query',&lt;br /&gt;
					list = 'users',&lt;br /&gt;
					usprop = 'groups|editcount',&lt;br /&gt;
					ususers = snippets.username&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
			message('display-api')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function linkFunctions.up(snippets)&lt;br /&gt;
		-- Uploads&lt;br /&gt;
		return makeWikilink(&lt;br /&gt;
			snippets.interwiki,&lt;br /&gt;
			-1,&lt;br /&gt;
			'ListFiles/' .. snippets.username,&lt;br /&gt;
			message('display-uploads')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
	-- End of link functions&lt;br /&gt;
	----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	-- Define the metatable that memoizes the link functions, and fetches link&lt;br /&gt;
	-- functions from [[Module:UserLinks/extra]] if necessary.&lt;br /&gt;
&lt;br /&gt;
	-- Lazily initialise the extraLinkFunctions table. We only want to load&lt;br /&gt;
	-- [[Module:UserLinks/extra]] as necessary, so it has a low transclusion&lt;br /&gt;
	-- count.&lt;br /&gt;
	local extraLinkFunctions&lt;br /&gt;
&lt;br /&gt;
	-- Define functions for shared code in the metatable.&lt;br /&gt;
	local function validateCode(code)&lt;br /&gt;
		-- Checks whether code is a valid link code - i.e. checks that it is a&lt;br /&gt;
		-- string and that it is not the blank string. Returns the code if&lt;br /&gt;
		-- the check passes, and nil if not.&lt;br /&gt;
		if type(code) == 'string' and code ~= '' then&lt;br /&gt;
			return code&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getExtraLinkFunctions()&lt;br /&gt;
		-- Loads the table of extra link functions from the /extra module.&lt;br /&gt;
		-- If there is a problem with loading it, return false. We use the&lt;br /&gt;
		-- distinction between false and nil to record whether we have already&lt;br /&gt;
		-- tried to load it.&lt;br /&gt;
		if extraLinkFunctions ~= nil then&lt;br /&gt;
			return extraLinkFunctions&lt;br /&gt;
		end&lt;br /&gt;
		if mExtra == nil then&lt;br /&gt;
			-- If loading the module fails, maybeLoadModule returns false.&lt;br /&gt;
			-- Here we use the distinction between false and nil to record&lt;br /&gt;
			-- whether we have already tried to load the /extra module.&lt;br /&gt;
			mExtra = maybeLoadModule('Module:UserLinks/extra')&lt;br /&gt;
		end&lt;br /&gt;
		if type(mExtra) == 'table'&lt;br /&gt;
			and type(mExtra.linkFunctions) == 'table'&lt;br /&gt;
		then&lt;br /&gt;
			extraLinkFunctions = mExtra.linkFunctions&lt;br /&gt;
		else&lt;br /&gt;
			extraLinkFunctions = false&lt;br /&gt;
		end&lt;br /&gt;
		return extraLinkFunctions&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function memoizeExtraLink(code, func)&lt;br /&gt;
		local success, link = pcall(func, snippets)&lt;br /&gt;
		if success and type(link) == 'string' then&lt;br /&gt;
			links[code] = link&lt;br /&gt;
			return link&lt;br /&gt;
		end&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Define the metatable.&lt;br /&gt;
	setmetatable(links, {&lt;br /&gt;
		__index = function (t, key)&lt;br /&gt;
			local code = validateCode(key)&lt;br /&gt;
			if not code then&lt;br /&gt;
				raiseError(&lt;br /&gt;
					message('error-malformedlinkcode'),&lt;br /&gt;
					message('error-malformedlinkcode-section')&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
			local linkFunction = linkFunctions[code]&lt;br /&gt;
			local link&lt;br /&gt;
			if linkFunction then&lt;br /&gt;
				link = linkFunction(snippets)&lt;br /&gt;
				links[code] = link&lt;br /&gt;
			else&lt;br /&gt;
				extraLinkFunctions = getExtraLinkFunctions()&lt;br /&gt;
				if extraLinkFunctions then&lt;br /&gt;
					local extraLinkFunction = extraLinkFunctions[code]&lt;br /&gt;
					if type(extraLinkFunction) == 'function' then&lt;br /&gt;
						link = memoizeExtraLink(code, extraLinkFunction)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if link then&lt;br /&gt;
				return link&lt;br /&gt;
			else&lt;br /&gt;
				raiseError(&lt;br /&gt;
					message('error-invalidlinkcode', code),&lt;br /&gt;
					message('error-invalidlinkcode-section')&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
		end,&lt;br /&gt;
		__pairs = function ()&lt;br /&gt;
			extraLinkFunctions = getExtraLinkFunctions()&lt;br /&gt;
			if extraLinkFunctions then&lt;br /&gt;
				for code, func in pairs(extraLinkFunctions) do&lt;br /&gt;
					if validateCode(code) and type(func) == 'function' then&lt;br /&gt;
						memoizeExtraLink(code, func)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			-- Allow built-in functions to overwrite extra functions.&lt;br /&gt;
			for code, func in pairs(linkFunctions) do&lt;br /&gt;
				local link = func(snippets)&lt;br /&gt;
				links[code] = link&lt;br /&gt;
			end&lt;br /&gt;
			return function (t, key)&lt;br /&gt;
				return next(links, key)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
	return links&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- User data snippets&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function p.getSnippets(args)&lt;br /&gt;
	--[=[&lt;br /&gt;
	-- This function gets user data snippets from the arguments, and from&lt;br /&gt;
	-- [[Module:InterwikiTable]]. The data is loaded as necessary and memoized&lt;br /&gt;
	-- in the snippets table for performance. &lt;br /&gt;
	--&lt;br /&gt;
	-- Snippets default to the blank string, '', so they can be used in&lt;br /&gt;
	-- concatenation operations without coders having to worry about raising&lt;br /&gt;
	-- errors. Because of this, the local functions snippetExists and&lt;br /&gt;
	-- getSnippet have been written to aid people writing new snippets. These&lt;br /&gt;
	-- functions treat the blank string as false. It is not necessary to return&lt;br /&gt;
	-- the blank string from a snippet function, as nil and false values are&lt;br /&gt;
	-- automatically converted into the blank string by the metatable.&lt;br /&gt;
	--&lt;br /&gt;
	-- If you add a new snippet, please document it at&lt;br /&gt;
	-- [[Module:UserLinks#Adding new links]].&lt;br /&gt;
	--]=]&lt;br /&gt;
	local snippets, snippetFunctions = {}, {}&lt;br /&gt;
	setmetatable(snippets, {&lt;br /&gt;
		__index = function (t, key)&lt;br /&gt;
			local snippetFunction = snippetFunctions[key]&lt;br /&gt;
			if snippetFunction then&lt;br /&gt;
				snippets[key] = snippetFunction() or ''&lt;br /&gt;
				return snippets[key]&lt;br /&gt;
			else&lt;br /&gt;
				raiseError(&lt;br /&gt;
					message('error-nosnippet', key),&lt;br /&gt;
					message('error-nosnippet-section')&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	-- Define helper functions for writting the snippet functions.&lt;br /&gt;
	local function snippetExists(key)&lt;br /&gt;
		-- We have set the metatable up to make snippets default to '', so we&lt;br /&gt;
		-- don't have to test for false or nil.&lt;br /&gt;
		return snippets[key] ~= ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getSnippet(key)&lt;br /&gt;
		local ret = snippets[key]&lt;br /&gt;
		if ret == '' then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return ret&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Start snippet functions.&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.username()&lt;br /&gt;
		-- The username.&lt;br /&gt;
		local username = args.user or args.User&lt;br /&gt;
		return username or raiseError(&lt;br /&gt;
			message('error-nousername'),&lt;br /&gt;
			message('error-nousername-section')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.usernameHtml()&lt;br /&gt;
		-- The username html-encoded. Spaces are encoded as pluses.&lt;br /&gt;
		return mw.uri.encode(snippets.username)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.project()&lt;br /&gt;
		-- The project name.&lt;br /&gt;
		-- Also does the work for snippetFunctions.interwikiTableKey, and adds&lt;br /&gt;
		-- the project value to snippets.lang if it is a valid language code.&lt;br /&gt;
		local project = args.Project or args.project&lt;br /&gt;
		if not project then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		local projectValidated, interwikiTableKey = p.validateProjectCode(project)&lt;br /&gt;
		if not projectValidated then&lt;br /&gt;
			if mw.language.isKnownLanguageTag(project) then&lt;br /&gt;
				if not snippetExists('lang') then&lt;br /&gt;
					snippets.lang = project&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				raiseError(&lt;br /&gt;
					message('error-invalidproject', project),&lt;br /&gt;
					message('error-invalidproject-section')&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		snippets.interwikiTableKey = interwikiTableKey&lt;br /&gt;
		return project&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.interwikiTableKey()&lt;br /&gt;
		-- The key for the project in Module:InterwikiTable.&lt;br /&gt;
		-- Relies on snippetFunctions.project to do the real work.&lt;br /&gt;
		local temp = snippets.project -- required; puts key in snippets table&lt;br /&gt;
		return rawget(snippets, 'interwikiTableKey')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.toolProject()&lt;br /&gt;
		-- The short project code for use with toolserver or labs. It is always&lt;br /&gt;
		-- present, even if the &amp;quot;project&amp;quot; argument is absent. The default value&lt;br /&gt;
		-- is the &amp;quot;snippet-project-default&amp;quot; message.&lt;br /&gt;
		local project = getSnippet('project')&lt;br /&gt;
		if not project then&lt;br /&gt;
			return message('snippet-project-default')&lt;br /&gt;
		else&lt;br /&gt;
			return project&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.projectLong()&lt;br /&gt;
		-- The long form of the project name, e.g. &amp;quot;wikipedia&amp;quot; or &amp;quot;wikibooks&amp;quot;.&lt;br /&gt;
		local key = getSnippet('interwikiTableKey')&lt;br /&gt;
		if not key then&lt;br /&gt;
			return message('snippet-projectlong-default')&lt;br /&gt;
		end&lt;br /&gt;
		interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')&lt;br /&gt;
		local prefixes = interwikiTable[key].iw_prefix&lt;br /&gt;
		-- Using prefixes[2] is a bit of a hack, but should find the long name&lt;br /&gt;
		-- most of the time.&lt;br /&gt;
		return prefixes[2] or prefixes[1] &lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.lang()&lt;br /&gt;
		-- The language code.&lt;br /&gt;
		local lang = args.lang or args.Lang&lt;br /&gt;
		if not lang then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		if mw.language.isKnownLanguageTag(lang) then&lt;br /&gt;
			return lang&lt;br /&gt;
		else&lt;br /&gt;
			raiseError(&lt;br /&gt;
				message('error-invalidlanguage', lang),&lt;br /&gt;
				message('error-invalidlanguage-section')&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.toolLang()&lt;br /&gt;
		-- The language code for use with toolserver or labs tools. It is always&lt;br /&gt;
		-- present, even if the &amp;quot;lang&amp;quot; argument is absent. The default value is&lt;br /&gt;
		-- the &amp;quot;snippet-lang-default&amp;quot; message. &lt;br /&gt;
		return getSnippet('lang') or message('snippet-lang-default')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.interwiki()&lt;br /&gt;
		-- The interwiki prefix, consisting of the project and language values,&lt;br /&gt;
		-- separated by colons, e.g. &amp;quot;:wikt:es:&amp;quot;.&lt;br /&gt;
		local project = getSnippet('project')&lt;br /&gt;
		local lang = getSnippet('lang')&lt;br /&gt;
		if not project and not lang then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		ret[#ret + 1] = project&lt;br /&gt;
		ret[#ret + 1] = lang&lt;br /&gt;
		return table.concat(ret, ':')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	function snippetFunctions.fullDomain()&lt;br /&gt;
		-- The full domain name of the site, e.g. www.mediawiki.org,&lt;br /&gt;
		-- en.wikpedia.org, or ja.wikibooks.org.&lt;br /&gt;
		local fullDomain&lt;br /&gt;
		local lang = getSnippet('toolLang')&lt;br /&gt;
		local key = getSnippet('interwikiTableKey')&lt;br /&gt;
		if key then&lt;br /&gt;
			interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')&lt;br /&gt;
			local domain = interwikiTable[key].domain&lt;br /&gt;
			local takesLangPrefix = interwikiTable[key].takes_lang_prefix&lt;br /&gt;
			if takesLangPrefix then&lt;br /&gt;
				fullDomain = lang .. '.' .. domain&lt;br /&gt;
			else&lt;br /&gt;
				fullDomain = domain&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			fullDomain = lang .. '.wikipedia.org'&lt;br /&gt;
		end&lt;br /&gt;
		return fullDomain&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- End snippet functions. If you add a new snippet function, please&lt;br /&gt;
	-- document it at [[Module:UserLinks#Adding new links]].&lt;br /&gt;
&lt;br /&gt;
	return snippets&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
function p.validateProjectCode(s)&lt;br /&gt;
	-- Validates a project code, by seeing whether it is present in&lt;br /&gt;
	-- [[Module:InterwikiTable]]. If it is present, returns the code and the&lt;br /&gt;
	-- InterwikiTable key for the corresponding site. If not present,&lt;br /&gt;
	-- returns nil for both.&lt;br /&gt;
	interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')&lt;br /&gt;
	for key, t in pairs(interwikiTable) do&lt;br /&gt;
		for i, prefix in ipairs(t.iw_prefix) do&lt;br /&gt;
			if s == prefix then&lt;br /&gt;
				return s, key&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Main functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function makeInvokeFunction(funcName)&lt;br /&gt;
	-- Makes a function that can be accessed from #invoke. This is only required&lt;br /&gt;
	-- for functions that need to access arguments.&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		mArguments = require('Module:Arguments')&lt;br /&gt;
		local args = mArguments.getArgs(frame)&lt;br /&gt;
		return p[funcName](args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.main = makeInvokeFunction('_main')&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	-- The main function. This is the one called from [[Template:User-multi]],&lt;br /&gt;
	-- via p.main.&lt;br /&gt;
	local options = p.getOptions(args)&lt;br /&gt;
	local snippets = p.getSnippets(args)&lt;br /&gt;
	local codes = p.getCodes(args)&lt;br /&gt;
	local links = p.getLinks(snippets)&lt;br /&gt;
	-- Overload the built-in Lua error function to generate wikitext errors&lt;br /&gt;
	-- meant for end users to see. This makes things harder to debug when&lt;br /&gt;
	-- real errors occur, but it is the only realistic way to show wikitext&lt;br /&gt;
	-- errors and and still have sane code when using metatables, etc.&lt;br /&gt;
	local success, result = pcall(p.export, codes, links, options)&lt;br /&gt;
	if success then&lt;br /&gt;
		return result&lt;br /&gt;
	else&lt;br /&gt;
		return makeWikitextError(result, options.isDemo)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getOptions(args)&lt;br /&gt;
	-- Gets the options from the args table, so that we don't have to pass&lt;br /&gt;
	-- around the whole args table all the time.&lt;br /&gt;
	local options = {}&lt;br /&gt;
	options.isDemo = yesno(args.demo) or false&lt;br /&gt;
	options.toolbarStyle = yesno(args.small) and 'font-size: 90%;' or nil&lt;br /&gt;
	options.sup = yesno(args.sup, true)&lt;br /&gt;
	options.separator = args.separator&lt;br /&gt;
	options.span = args.span&lt;br /&gt;
	return options&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getCodes(args)&lt;br /&gt;
	-- Gets the link codes from the arguments. The codes aren't validated&lt;br /&gt;
	-- at this point.&lt;br /&gt;
	mTableTools = maybeLoadModule('Module:TableTools')&lt;br /&gt;
	local codes&lt;br /&gt;
	if mTableTools then&lt;br /&gt;
		codes = mTableTools.compressSparseArray(args)&lt;br /&gt;
	else&lt;br /&gt;
		codes = {}&lt;br /&gt;
		for i, code in ipairs(args) do&lt;br /&gt;
			codes[i] = code&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return codes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.export(codes, links, options)&lt;br /&gt;
	-- Make the user link.&lt;br /&gt;
	local userLink = links.u&lt;br /&gt;
&lt;br /&gt;
	-- If we weren't passed any link codes, just return the user link.&lt;br /&gt;
	if #codes &amp;lt; 1 then&lt;br /&gt;
		return userLink&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Make the toolbar.&lt;br /&gt;
	mToolbar = require('Module:Toolbar')&lt;br /&gt;
	local toolbarArgs = {}&lt;br /&gt;
	for i, code in ipairs(codes) do&lt;br /&gt;
		local link = links[code]&lt;br /&gt;
		toolbarArgs[#toolbarArgs + 1] = link&lt;br /&gt;
	end&lt;br /&gt;
	toolbarArgs.style = options.toolbarStyle&lt;br /&gt;
	toolbarArgs.separator = options.separator or 'dot'&lt;br /&gt;
	toolbarArgs.span = options.span&lt;br /&gt;
	local toolbar = mToolbar.main(toolbarArgs)&lt;br /&gt;
&lt;br /&gt;
	-- Apply the sup option.&lt;br /&gt;
	if options.sup then&lt;br /&gt;
		toolbar = '&amp;lt;sup&amp;gt;' .. toolbar .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If we are transcluding, add a non-breaking space, but if we are substing&lt;br /&gt;
	-- just use a normal space&lt;br /&gt;
	local space = mw.isSubsting() and ' ' or '&amp;amp;nbsp;'&lt;br /&gt;
	&lt;br /&gt;
	return userLink .. space .. toolbar&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Single link function&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
p.single = makeInvokeFunction('_single')&lt;br /&gt;
&lt;br /&gt;
function p._single(args)&lt;br /&gt;
	-- Fetches a single link from the link table.&lt;br /&gt;
	local options = p.getOptions(args)&lt;br /&gt;
	local snippets = p.getSnippets(args)&lt;br /&gt;
	local links = p.getLinks(snippets)&lt;br /&gt;
	local code = args[1]&lt;br /&gt;
	local success, link = pcall(p.exportSingle, links, code)&lt;br /&gt;
	if success then&lt;br /&gt;
		return link&lt;br /&gt;
	else&lt;br /&gt;
		return makeWikitextError(link, options.isDemo)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.exportSingle(links, code)&lt;br /&gt;
	-- If any errors occur, they will probably occur here. This function&lt;br /&gt;
	-- exists purely so that all the errors that will occur in p._single can&lt;br /&gt;
	-- be handled using a single pcall.&lt;br /&gt;
	if not code then&lt;br /&gt;
		raiseError(&lt;br /&gt;
			message('error-nolinkcode'),&lt;br /&gt;
			message('error-nolinkcode-section')&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	return links[code]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Link table&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function p.linktable()&lt;br /&gt;
	-- Returns a wikitext table of link codes, with an example link for each&lt;br /&gt;
	-- one. This function doesn't take any arguments, so it can be accessed&lt;br /&gt;
	-- directly from wiki pages without using makeInvokeFunction.&lt;br /&gt;
	local args = {user = 'Example'}&lt;br /&gt;
	local snippets = p.getSnippets(args)&lt;br /&gt;
	local links = p.getLinks(snippets)&lt;br /&gt;
&lt;br /&gt;
	-- Assemble the codes and links in order&lt;br /&gt;
	local firstCodes = {'u', 't', 'c'}&lt;br /&gt;
	local firstLinks, firstCodesKeys = {}, {}&lt;br /&gt;
	for i, code in ipairs(firstCodes) do&lt;br /&gt;
		firstCodesKeys[code] = true&lt;br /&gt;
		firstLinks[#firstLinks + 1] = {code, links[code]}&lt;br /&gt;
	end&lt;br /&gt;
	local secondLinks = {}&lt;br /&gt;
	for code, link in pairs(links) do&lt;br /&gt;
		if not firstCodesKeys[code] then&lt;br /&gt;
			secondLinks[#secondLinks + 1] = {code, link}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(secondLinks, function(t1, t2)&lt;br /&gt;
		return t1[1] &amp;lt; t2[1]&lt;br /&gt;
	end)&lt;br /&gt;
	local links = {}&lt;br /&gt;
	for i, t in ipairs(firstLinks) do&lt;br /&gt;
		links[#links + 1] = t&lt;br /&gt;
	end&lt;br /&gt;
	for i, t in ipairs(secondLinks) do&lt;br /&gt;
		links[#links + 1] = t&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Output the code table in table format&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	ret[#ret + 1] = '{| class=&amp;quot;wikitable plainlinks sortable&amp;quot;'&lt;br /&gt;
	ret[#ret + 1] = '|-'&lt;br /&gt;
	ret[#ret + 1] = '! ' .. message('linktable-codeheader')&lt;br /&gt;
	ret[#ret + 1] = '! ' .. message('linktable-previewheader')&lt;br /&gt;
	for i, t in ipairs(links) do&lt;br /&gt;
		local code = t[1]&lt;br /&gt;
		local link = t[2]&lt;br /&gt;
		ret[#ret + 1] = '|-'&lt;br /&gt;
		ret[#ret + 1] = &amp;quot;| '''&amp;quot; .. code .. &amp;quot;'''&amp;quot; &lt;br /&gt;
		ret[#ret + 1] = '| ' .. link&lt;br /&gt;
	end&lt;br /&gt;
	ret[#ret + 1] = '|}'&lt;br /&gt;
	return table.concat(ret, '\n')&lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Xaosflux</name></author>
		
	</entry>
</feed>