Module:UserLinks: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Undid revision 602835579 by Mr. Stradivarius (talk) revert for now, generated an unexpected script error
(Complete rewrite of the module, updated from sandbox. Now supports adding new link functions on Module:UserLinks/extra, and is configurable at Module:UserLinks/config.)
(Undid revision 602835579 by Mr. Stradivarius (talk) revert for now, generated an unexpected script error)
Line 1:
local ToolbarBuilder = require('Module:Toolbar')
--------------------------------------------------------------------------------
local interwikiTable = mw.loadData("Module:InterwikiTable")
-- UserLinks --
-- This module creates a list of links about a given user. It can be used on --
-- its own or from a template. See the /doc page for more documentation. --
--------------------------------------------------------------------------------
 
local u = {} -- Table for user-data helper strings.
-- Require necessary modules
local trackingCategories = {} -- Table for storing the tracking categories.
local yesno = require('Module:Yesno')
local demo
 
-- Define a custom error message for this module.
-- Lazily initialise modules that we might or might not need
local function err(msg, section)
local mExtra -- [[Module:UserLinks/extra]]
local help
local mArguments -- [[Module:Arguments]]
if section then
local mToolbar -- [[Module:Toolbar]]
help = ' ([[Template:User-multi#' .. section .. '|help]])'
local mCategoryHandler -- [[Module:Category handler]]
else
local mTableTools -- [[Module:TableTools]]
help = ''
local interwikiTable -- [[Module:InterwikiTable]], loaded with mw.loadData
end
local cat
if demo == 'yes' then
cat = ''
else
cat = '[[Category:UserLinks transclusions with errors]]'
end
return '<span class="error">[[Template:User-multi|User-multi]] error: ' .. msg
.. help .. '.</span>' .. cat
end
 
----------------------------------------------------------------------------------------------
-- Load shared helper functions
-- To add more link types, write a function that produces an individual link, and put --
local mShared = require('Module:UserLinks/shared')
-- it at the bottom of the list below. Then, add a link code for your function to the --
local raiseError = mShared.raiseError
-- "linktypes" table. Try and make the code three letters or less. There are a number --
local maybeLoadModule = mShared.maybeLoadModule
-- of helper strings available for writing the functions: --
local makeWikitextError = mShared.makeWikitextError
-- --
local makeWikilink = mShared.makeWikilink
-- u.username The plain username. If the username is not present then the --
local makeUrlLink = mShared.makeUrlLink
-- module returns an error. --
local makeFullUrlLink = mShared.makeFullUrlLink
-- u.usernameHtml The username html-encoded. Spaces are encoded with plus signs. --
local message = mShared.message
-- u.project The project name. Nil if not specified. --
-- u.lang The language code. Nil if not specified. --
-- u.interwiki The interwiki prefix, consisting of the project and language --
-- values, separated by colons, e.g. ":wikt:es:". If no project --
-- or language values are found, this is the blank string, "". --
-- u.projectCode If a valid project is specified, this is the code for that --
-- project in [[Module:InterwikiTable]]. Otherwise this is nil. --
-- u.projectLong The long project name, e.g. "wikipedia" or "wikibooks". If --
-- not specified the default is "wikipedia". --
-- u.toolLang The language code for use with toolserver or labs tools. The --
-- default is "en". --
-- --
-- If you want more helper strings, you can define them in the generateUserDataStrings --
-- function below. --
----------------------------------------------------------------------------------------------
 
----------------------------------------------------------------------------------------------
local p = {}
-- LINK FUNCTIONS START --
----------------------------------------------------------------------------------------------
 
local function makeUserLink()
--------------------------------------------------------------------------------
return '[[' .. u.interwiki .. 'User:' .. u.username .. '|' .. u.username .. ']]'
-- Link table
end
--------------------------------------------------------------------------------
 
local function p.getLinksmakeTalkLink(snippets)
return '[[' .. u.interwiki .. 'User talk:' .. u.username .. '|talk]]'
--[=[
end
-- Get a table of links that can be indexed with link codes. The table
-- returned is blank, but links are added to it on demand when it is
-- indexed. This is made possible by the metatable and by the various link
-- functions, some of which are defined here, and some of which are defined
-- at [[Module:UserLinks/extra]].
--]=]
local links, linkFunctions = {}, {}
 
local function makeContribsLink()
----------------------------------------------------------------------------
return '[[' .. u.interwiki .. 'Special:Contributions/' .. u.username .. '|contribs]]'
-- Link functions
end
--
-- The following functions make the links from the link codes and the user
-- data snippets. New link functions should be added below the existing
-- functions.
--
-- For documentation on how to add new link functions, please see
-- [[Module:UserLinks#Adding new links]].
----------------------------------------------------------------------------
 
local function linkFunctions.umakeCountLink(snippets)
return '[//tools.wmflabs.org/supercount/index.php?user=' .. u.usernameHtml
-- User page
.. '&project=' .. u.toolLang .. '.' .. u.projectLong
return makeWikilink(
.. ' count]'
snippets.interwiki,
end
2,
snippets.username,
snippets.username
)
end
 
local function linkFunctions.tmakeMovesLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/move/' .. u.username .. '|page&nbsp;moves]]'
-- User talk page
end
return makeWikilink(
snippets.interwiki,
3,
snippets.username,
message('display-talk')
)
end
 
local function linkFunctions.cmakeLogsLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/' .. u.username .. '|logs]]'
-- Contributions
end
return makeWikilink(
snippets.interwiki,
-1,
'Contributions/' .. snippets.username,
message('display-contributions')
)
end
 
local function linkFunctions.ctmakeBlockLogLink(snippets)
local url = mw.uri.fullUrl(u.interwiki .. 'Special:Log/block', 'page=User:' .. u.usernameHtml)
-- Edit count
return '[' .. tostring(url) .. ' block&nbsp;log]'
return makeUrlLink(
end
{
host = 'tools.wmflabs.org',
path = '/supercount/index.php',
query = {
user = snippets.username,
project = snippets.toolLang .. '.' .. snippets.projectLong
}
},
message('display-count')
)
end
 
local function linkFunctions.mmakeBlocksLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/block/' .. u.username .. '|blocks]]'
-- Page moves
end
return makeWikilink(
snippets.interwiki,
-1,
'Log/move/' .. snippets.username,
message('display-moves')
)
end
 
local function linkFunctions.lmakeBlockUserLink(snippets)
return '[[' .. u.interwiki .. 'Special:Block/' .. u.username .. '|block&nbsp;user]]'
-- Logs
end
return makeWikilink(
snippets.interwiki,
-1,
'Log/' .. snippets.username,
message('display-logs')
)
end
 
local function linkFunctions.blmakeCentralAuthLink(snippets)
return '[[' .. u.interwiki .. 'Special:CentralAuth/' .. u.username .. '|central&nbsp;auth]]'
-- Block log
end
return makeFullUrlLink(
snippets.interwiki,
-1,
'Log/block',
{page = 'User:' .. snippets.username},
message('display-blocklog')
)
end
 
local function linkFunctions.blsmakeDeletedContribsLink(snippets)
return '[[' .. u.interwiki .. 'Special:DeletedContributions/' .. u.username .. '|deleted&nbsp;contribs]]'
-- Blocks
end
return makeWikilink(
snippets.interwiki,
-1,
'Log/block/' .. snippets.username,
message('display-blocks')
)
end
 
local function linkFunctions.bumakeEmailLink(snippets)
return '[[' .. u.interwiki .. 'Special:Emailuser/' .. u.username .. '|email]]'
-- Block user
end
return makeWikilink(
snippets.interwiki,
-1,
'Block/' .. snippets.username,
message('display-blockuser')
)
end
 
local function linkFunctions.camakeEditSummariesLink(snippets)
return '[http://tools.wmflabs.org/xtools/editsummary/index.php?name=' .. u.usernameHtml
-- Central auth
.. '&lang=' .. u.toolLang
return makeWikilink(
.. '&wiki=' .. u.projectLong
snippets.interwiki,
.. ' edit&nbsp;summaries]'
-1,
end
'CentralAuth/' .. snippets.username,
message('display-centralauth')
)
end
 
local function linkFunctions.dcmakeDeletionsLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/delete/' .. u.username .. '|deletions]]'
-- Deleted contribs
end
return makeWikilink(
snippets.interwiki,
-1,
'DeletedContributions/' .. snippets.username,
message('display-deletedcontributions')
)
end
 
local function linkFunctions.emakeListUserLink(snippets)
local url = mw.uri.fullUrl(u.interwiki .. 'Special:ListUsers', 'limit=1&username=' .. u.usernameHtml)
-- Email
return '[' .. tostring(url) .. ' list&nbsp;user]'
return makeWikilink(
end
snippets.interwiki,
-1,
'EmailUser/' .. snippets.username,
message('display-email')
)
end
 
local function linkFunctions.esmakeSulLink(snippets)
return '[[sulutil:' .. u.username .. '|global&nbsp;contribs]]'
-- Edit summaries
end
return makeUrlLink(
{
host = 'tools.wmflabs.org',
path = '/xtools/editsummary/index.php',
query = {
name = snippets.username,
lang = snippets.toolLang,
wiki = snippets.projectLong
}
},
message('display-editsummaries')
)
end
 
local function linkFunctions.delmakeTargetLogsLink(snippets)
local url = mw.uri.fullUrl(u.interwiki .. 'Special:Log', 'page=User:' .. u.usernameHtml)
-- Deletions
return '[' .. tostring(url) .. ' target&nbsp;logs]'
return makeWikilink(
end
snippets.interwiki,
-1,
'Log/delete/' .. snippets.username,
message('display-deletions')
)
end
 
local function linkFunctions.lumakeEditFilterLogLink(snippets)
local url = mw.uri.fullUrl(u.interwiki .. 'Special:AbuseLog', 'wpSearchUser=' .. u.usernameHtml)
-- List user
return '[' .. tostring(url) .. ' edit&nbsp;filter&nbsp;log]'
return makeFullUrlLink(
end
snippets.interwiki,
-1,
'ListUsers',
{limit = 1, user = snippets.username},
message('display-listuser')
)
end
 
local function linkFunctions.sulmakeProtectionsLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/protect/' .. u.username .. '|protections]]'
-- SUL
end
return makeWikilink(
nil,
nil,
'sulutil:' .. snippets.username,
message('display-sul')
)
end
 
local function linkFunctions.tlmakeRightsLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/rights/' .. u.username .. '|rights]]'
-- Target logs
end
return makeFullUrlLink(
snippets.interwiki,
-1,
'Log',
{page = mw.site.namespaces[2].name .. ':' .. snippets.username},
message('display-targetlogs')
)
end
 
local function linkFunctions.eflmakeRenamesLink(snippets)
return '[[' .. u.interwiki .. 'Special:Log/renameuser/' .. u.username .. '|renames]]'
-- Edit filter log
end
return makeFullUrlLink(
snippets.interwiki,
-1,
'AbuseLog',
{wpSearchUser = snippets.username},
message('display-abuselog')
)
end
 
local function linkFunctions.prmakeRfaLink(snippets)
if u.project or u.lang then
-- Protections
table.insert( trackingCategories, '[[Category:UserLinks transclusions with unresolvable interwiki links]]' )
return makeWikilink(
end
snippets.interwiki,
return '[[Special:PrefixIndex/Wikipedia:Requests for adminship/' .. u.username .. '|RfA]]'
-1,
end
'Log/protect/' .. snippets.username,
message('display-protections')
)
end
 
local function linkFunctions.rlmakeApiLink(snippets)
-- Find the full domain, as the API can't be accessed through the interwiki system.
-- User rights
local fulldomain
return makeWikilink(
local lang = u.lang or 'en'
snippets.interwiki,
if u.projectCode then
-1,
local domain = interwikiTable[u.projectCode].domain
'Log/rights/' .. snippets.username,
local takesLangPrefix = interwikiTable[u.projectCode].takes_lang_prefix
message('display-rights')
if not takesLangPrefix then
)
fulldomain = domain
end
else
fulldomain = lang .. '.' .. domain
end
else
fulldomain = lang .. '.wikipedia.org'
end
-- Return the API link
return '[//' .. fulldomain .. '/w/api.php?action=query&list=users&usprop=editcount&ususers=' .. u.usernameHtml .. ' api]'
end
 
local function linkFunctions.renmakeUploadsLink(snippets)
return '[[' .. u.interwiki .. 'Special:ListFiles/' .. u.username .. '|uploads]]'
-- Renames
end
return makeWikilink(
snippets.interwiki,
-1,
'Log/renameuser/' .. snippets.username,
message('display-renames')
)
end
 
----------------------------------------------------------------------------------------------
function linkFunctions.rfa(snippets)
-- LINK FUNCTIONS END --
-- Requests for adminship
-- To enable new link functions, add the code to the "linktypes" table directly below. --
return makeWikilink(
----------------------------------------------------------------------------------------------
nil,
-1,
'PrefixIndex/' .. message('page-rfa') .. '/' .. snippets.username,
message('display-rfa')
)
end
 
local linktypes = {
function linkFunctions.api(snippets)
{'t' , makeTalkLink},
-- API user data
{'c' , makeContribsLink},
return makeUrlLink(
{'ct' , makeCountLink},
{
{'m' , makeMovesLink},
host = snippets.fullDomain,
{'l' , makeLogsLink},
path = '/w/api.php',
{'bl' , makeBlockLogLink},
query = {
{'bls' , makeBlocksLink},
action = 'query',
{'bu' , makeBlockUserLink},
list = 'users',
{'ca' , makeCentralAuthLink},
usprop = 'editcount',
{'dc' , makeDeletedContribsLink},
ususers = snippets.username
{'e' , makeEmailLink},
}
{'es' , makeEditSummariesLink},
},
{'del' , makeDeletionsLink},
message('display-api')
{'lu' , makeListUserLink},
)
{'sul' , makeSulLink},
end
{'tl' , makeTargetLogsLink},
{'efl' , makeEditFilterLogLink},
{'pr' , makeProtectionsLink},
{'rl' , makeRightsLink},
{'ren' , makeRenamesLink},
{'rfa' , makeRfaLink},
{'api' , makeApiLink},
{'up' , makeUploadsLink}
}
 
local function linkFunctions.upgetLink(snippetslinktype)
local linkNumber
-- Uploads
for i, value in ipairs(linktypes) do
return makeWikilink(
if value[1] == linktype then
snippets.interwiki,
linkNumber = i
-1,
break
'ListFiles/' .. snippets.username,
end
message('display-uploads')
end
)
if not linkNumber then
end
return err('"' .. linktype .. '" is not a valid link code', 'Not a valid link code')
end
----------------------------------------------------------------------------
local result = linktypes[linkNumber][2]()
-- End of link functions
if type(result) ~= 'string' then
----------------------------------------------------------------------------
return err(
 
'the function for code "' .. linktype .. '" did not return a string value',
-- Define the metatable that memoizes the link functions, and fetches link
'Function did not return a string value'
-- functions from [[Module:UserLinks/extra]] if necessary.
)
 
end
-- Lazily initialise the extraLinkFunctions table. We only want to load
return result
-- [[Module:UserLinks/extra]] as necessary, so it has a low transclusion
end
-- count.
local extraLinkFunctions
 
local function makeToolbar(args)
-- Define functions for shared code in the metatable.
local targs = {}
local function validateCode(code)
local numArgsExist = false
-- Checks whether code is a valid link code - i.e. checks that it is a
for k, v in pairs(args) do
-- string and that it is not the blank string. Returns the code if
if type(k) == 'number' then
-- the check passes, and nil if not.
numArgsExist = true
if type(code) == 'string' and code ~= '' then
targs[k] = getLink(v)
return code
end
else
end
return nil
targs.style = args.small and 'font-size: 90%;'
end
targs.separator = args.separator or 'dot'
end
 
if numArgsExist == false then
local function getExtraLinkFunctions()
return nil -- Don't return a toolbar if no numeric arguments exist.
-- Loads the table of extra link functions from the /extra module.
else
-- If there is a problem with loading it, return false. We use the
return ToolbarBuilder.main(targs)
-- distinction between false and nil to record whether we have already
end
-- tried to load it.
if extraLinkFunctions ~= nil then
return extraLinkFunctions
end
if mExtra == nil then
-- If loading the module fails, maybeLoadModule returns false.
-- Here we use the distinction between false and nil to record
-- whether we have already tried to load the /extra module.
mExtra = maybeLoadModule('Module:UserLinks/extra')
end
if type(mExtra) == 'table'
and type(mExtra.linkFunctions) == 'table'
then
extraLinkFunctions = mExtra.linkFunctions
else
extraLinkFunctions = false
end
return extraLinkFunctions
end
 
local function memoizeExtraLink(code, func)
local success, link = pcall(func, snippets)
if success and type(link) == 'string' then
links[code] = link
return link
end
return nil
end
 
-- Define the metatable.
setmetatable(links, {
__index = function (t, key)
local code = validateCode(key)
if not code then
raiseError(
message('error-malformedlinkcode'),
message('error-malformedlinkcode-section')
)
end
local linkFunction = linkFunctions[code]
local link
if linkFunction then
link = linkFunction(snippets)
links[code] = link
else
extraLinkFunctions = getExtraLinkFunctions()
if extraLinkFunctions then
local extraLinkFunction = extraLinkFunctions[code]
if type(extraLinkFunction) == 'function' then
link = memoizeExtraLink(code, extraLinkFunction)
end
end
end
if link then
return link
else
raiseError(
message('error-invalidlinkcode', code),
message('error-invalidlinkcode-section')
)
end
end,
__pairs = function ()
extraLinkFunctions = getExtraLinkFunctions()
if extraLinkFunctions then
for code, func in pairs(extraLinkFunctions) do
if validateCode(code) and type(func) == 'function' then
memoizeExtraLink(code, func)
end
end
end
-- Allow built-in functions to overwrite extra functions.
for code, func in pairs(linkFunctions) do
local link = func(snippets)
links[code] = link
end
return function (t, key)
return next(links, key)
end
end
})
return links
end
 
-- This function finds whether a string is a valid interwiki project prefix.
--------------------------------------------------------------------------------
-- If the string is valid, the function outputs two values: true, and the site code
-- User data snippets
-- used in [[Module:InterwikiTable]]. If the string is valid, the function outputs
--------------------------------------------------------------------------------
-- false and nil.
 
local function p.getSnippetsisKnownProject(argsprefix)
for projectCode, projectVal in pairs(interwikiTable) do
--[=[
for _, iwCode in ipairs(projectVal.iw_prefix) do
-- This function gets user data snippets from the arguments, and from
if iwCode == prefix then
-- [[Module:InterwikiTable]]. The data is loaded as necessary and memoized
return true, projectCode
-- in the snippets table for performance.
--
-- Snippets default to the blank string, '', so they can be used in
-- concatenation operations without coders having to worry about raising
-- errors. Because of this, the local functions snippetExists and
-- getSnippet have been written to aid people writing new snippets. These
-- functions treat the blank string as false. It is not necessary to return
-- the blank string from a snippet function, as nil and false values are
-- automatically converted into the blank string by the metatable.
--
-- If you add a new snippet, please document it at
-- [[Module:UserLinks#Adding new links]].
--]=]
local snippets, snippetFunctions = {}, {}
setmetatable(snippets, {
__index = function (t, key)
local snippetFunction = snippetFunctions[key]
if snippetFunction then
snippets[key] = snippetFunction() or ''
return snippets[key]
else
raiseError(
message('error-nosnippet', key),
message('error-nosnippet-section')
)
end
end
})
 
-- Define helper functions for writting the snippet functions.
local function snippetExists(key)
-- We have set the metatable up to make snippets default to '', so we
-- don't have to test for false or nil.
return snippets[key] ~= ''
end
 
local function getSnippet(key)
local ret = snippets[key]
if ret == '' then
return nil
else
return ret
end
end
 
-- Start snippet functions.
 
function snippetFunctions.username()
-- The username.
local username = args.user or args.User
return username or raiseError(
message('error-nousername'),
message('error-nousername-section')
)
end
 
function snippetFunctions.usernameHtml()
-- The username html-encoded. Spaces are encoded as pluses.
return mw.uri.encode(snippets.username)
end
 
function snippetFunctions.project()
-- The project name.
-- Also does the work for snippetFunctions.interwikiTableKey, and adds
-- the project value to snippets.lang if it is a valid language code.
local project = args.Project or args.project
if not project then
return nil
end
local projectValidated, interwikiTableKey = p.validateProjectCode(project)
if not projectValidated then
if mw.language.isKnownLanguageTag(project) then
if not snippetExists('lang') then
snippets.lang = project
end
else
raiseError(
message('error-invalidproject', project),
message('error-invalidproject-section')
)
end
end
snippets.interwikiTableKey = interwikiTableKey
return project
end
 
function snippetFunctions.interwikiTableKey()
-- The key for the project in Module:InterwikiTable.
-- Relies on snippetFunctions.project to do the real work.
local temp = snippets.project -- required; puts key in snippets table
return rawget(snippets, 'interwikiTableKey')
end
 
function snippetFunctions.toolProject()
-- The short project code for use with toolserver or labs. It is always
-- present, even if the "project" argument is absent. The default value
-- is the "snippet-project-default" message.
local project = getSnippet('project')
if not project then
return message('snippet-project-default')
else
return project
end
end
 
function snippetFunctions.projectLong()
-- The long form of the project name, e.g. "wikipedia" or "wikibooks".
local key = getSnippet('interwikiTableKey')
if not key then
return message('snippet-projectlong-default')
end
interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
local prefixes = interwikiTable[key].iw_prefix
-- Using prefixes[2] is a bit of a hack, but should find the long name
-- most of the time.
return prefixes[2] or prefixes[1]
end
 
function snippetFunctions.lang()
-- The language code.
local lang = args.lang or args.Lang
if not lang then
return nil
end
if mw.language.isKnownLanguageTag(lang) then
return lang
else
raiseError(
message('error-invalidlanguage', lang),
message('error-invalidlanguage-section')
)
end
end
 
function snippetFunctions.toolLang()
-- The language code for use with toolserver or labs tools. It is always
-- present, even if the "lang" argument is absent. The default value is
-- the "snippet-lang-default" message.
return getSnippet('lang') or message('snippet-lang-default')
end
 
function snippetFunctions.interwiki()
-- The interwiki prefix, consisting of the project and language values,
-- separated by colons, e.g. ":wikt:es:".
local project = getSnippet('project')
local lang = getSnippet('lang')
if not project and not lang then
return nil
end
local ret = {}
ret[#ret + 1] = project
ret[#ret + 1] = lang
return table.concat(ret, ':')
end
 
function snippetFunctions.fullDomain()
-- The full domain name of the site, e.g. www.mediawiki.org,
-- en.wikpedia.org, or ja.wikibooks.org.
local fullDomain
local lang = getSnippet('toolLang')
local key = getSnippet('interwikiTableKey')
if key then
interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
local domain = interwikiTable[key].domain
local takesLangPrefix = interwikiTable[key].takes_lang_prefix
if takesLangPrefix then
fullDomain = lang .. '.' .. domain
else
fullDomain = domain
end
else
fullDomain = lang .. '.wikipedia.org'
end
return fullDomain
end
 
-- End snippet functions. If you add a new snippet function, please
-- document it at [[Module:UserLinks#Adding new links]].
 
return snippets
end
 
function p.validateProjectCode(s)
-- Validates a project code, by seeing whether it is present in
-- [[Module:InterwikiTable]]. If it is present, returns the code and the
-- InterwikiTable key for the corresponding site. If not present,
-- returns nil for both.
interwikiTable = interwikiTable or mw.loadData('Module:InterwikiTable')
for key, t in pairs(interwikiTable) do
for i, prefix in ipairs(t.iw_prefix) do
if s == prefix then
return s, key
end
end
end
return nilfalse, nil
end
 
local function generateUserDataStrings(args)
--------------------------------------------------------------------------------
-- If the username is absent or blank, return an error and a tracking category.
-- Main functions
if args.user == '' or (not args.user and (not args.User or args.User == '')) then
--------------------------------------------------------------------------------
return err('no username detected', 'No username detected')
else
u.username = args.user or args.User
end
-- Get other basic user data strings.
u.project = args.Project or args.project
u.lang = args.lang or args.Lang
if u.lang then
if mw.language.isKnownLanguageTag(u.lang) then
table.insert(trackingCategories, '[[Category:UserLinks transclusions with language parameters]]')
else
return err('"' .. u.lang .. '" is not a valid language code', 'Not a valid language code')
end
end
-- Process the project value if it is present.
if u.project then
table.insert( trackingCategories, '[[Category:UserLinks transclusions with project parameters]]' )
-- If u.project is a known project, we only need to get the project code. If the project
-- isn't known, first check whether it is a valid language code, and if not then see if it's
-- an interwiki code separated by colons, e.g. "wikt:es".
local uprojectIsKnownProject, uprojectProjectCode = isKnownProject(u.project)
if uprojectIsKnownProject then
u.projectCode = uprojectProjectCode
else
if mw.language.isKnownLanguageTag(u.project) then
u.lang = u.project
u.project = nil
else
local pref1, pref2 = mw.ustring.match( u.project, '^(%w+):(%w+)$' )
if pref1 and pref2 then
local pref1IsKnownProject, pref1ProjectCode = isKnownProject(pref1)
local pref2IsKnownProject, pref2ProjectCode = isKnownProject(pref2)
if pref1IsKnownProject
and mw.language.isKnownLanguageTag(pref2)
and interwikiTable[pref1ProjectCode].takes_lang_prefix then
u.project = pref1
u.lang = pref2
u.projectCode = pref1ProjectCode
table.insert(
trackingCategories,
'[[Category:UserLinks transclusions with project parameters containing language codes]]'
)
elseif pref2IsKnownProject
and mw.language.isKnownLanguageTag(pref1)
and interwikiTable[pref2ProjectCode].takes_lang_prefix then
u.project = pref2
u.lang = pref1
u.projectCode = pref2ProjectCode
table.insert(
trackingCategories,
'[[Category:UserLinks transclusions with project parameters containing language codes]]'
)
else
return err(
'"' .. u.project .. '" is not a valid interwiki prefix',
'Not a valid interwiki prefix'
)
end
else
return err(
'"' .. u.project .. '" is not a valid interwiki prefix',
'Not a valid interwiki prefix'
)
end
end
end
end
-- Generate the interwiki prefix. This includes colons.
if u.project or u.lang then
u.interwiki = ''
if u.project then
u.interwiki = u.interwiki .. ':' .. u.project
end
if u.lang then
u.interwiki = u.interwiki .. ':' .. u.lang
end
u.interwiki = u.interwiki .. ':'
else
u.interwiki = ''
end
 
-- Generate the other helper strings.
local function makeInvokeFunction(funcName)
u.usernameHtml = mw.uri.encode(u.username) -- Html-encoded username. Spaces are encoded as pluses.
-- Makes a function that can be accessed from #invoke. This is only required
if u.project then
-- for functions that need to access arguments.
local prefixes = interwikiTable[u.projectCode].iw_prefix
return function (frame)
u.projectLong = prefixes[2] or prefixes[1] -- A bit of a hack, but should find the long prefix name most of the time.
mArguments = require('Module:Arguments')
else
local args = mArguments.getArgs(frame)
u.projectLong = 'wikipedia'
return p[funcName](args)
end
u.toolLang = u.lang or 'en' -- set the default language for tools on the toolserver or labs.
end
 
local function generateTrackingCategories()
p.main = makeInvokeFunction('_main')
if demo == 'yes' then
 
return ''
function p._main(args)
else
-- The main function. This is the one called from [[Template:User-multi]],
return table.concat(trackingCategories)
-- via p.main.
end
local options = p.getOptions(args)
local snippets = p.getSnippets(args)
local codes = p.getCodes(args)
local links = p.getLinks(snippets)
-- Overload the built-in Lua error function to generate wikitext errors
-- meant for end users to see. This makes things harder to debug when
-- real errors occur, but it is the only realistic way to show wikitext
-- errors and and still have sane code when using metatables, etc.
local success, result = pcall(p.export, codes, links, options)
if success then
return result
else
return makeWikitextError(result, options.isDemo)
end
end
 
-- This function generates a table of all available link types, with their previews.
function p.getOptions(args)
-- It is used in the module documentation.
-- Gets the options from the args table, so that we don't have to pass
local function getLinkTable(args)
-- around the whole args table all the time.
demo = args.demo -- Set the demo variable.
local options = {}
-- Generate the user data strings and return any errors.
options.isDemo = yesno(args.demo) or false
local dataStringError = generateUserDataStrings(args)
options.toolbarStyle = yesno(args.small) and 'font-size: 90%;' or nil
if dataStringError then
options.sup = yesno(args.sup, true)
return dataStringError
options.separator = args.separator
end
options.span = args.span
return options
-- Build a table of all of the links.
local result = '<table class="wikitable plainlinks sortable">'
.. '\n<tr><th>Code</th><th>Preview</th></tr>'
for i, value in ipairs(linktypes) do
local code = value[1]
result = result .. "\n<tr><td>'''" .. code .. "'''</td><td>" .. getLink(code) .. '</td></tr>'
end
result = result .. '\n</table>'
return result
end
 
local function p.getCodesgetSingleLink(args)
demo = args.demo -- Set the demo variable.
-- Gets the link codes from the arguments. The codes aren't validated
-- Generate the user data strings and return any errors.
-- at this point.
local dataStringError = generateUserDataStrings(args)
mTableTools = maybeLoadModule('Module:TableTools')
if dataStringError then
local codes
return dataStringError
if mTableTools then
end
codes = mTableTools.compressSparseArray(args)
else
local linktype = args[1]
codes = {}
if not linktype then
for i, code in ipairs(args) do
return err('no link type specified')
codes[i] = code
end
local result = getLink(linktype)
end
result = result .. generateTrackingCategories()
return codes
return result
end
 
local function p.exportgetLinks(codes, links, optionsargs)
demo = args.demo -- MakeSet the userdemo linkvariable.
-- Generate the user data strings and return any errors.
local userLink = links.u
local dataStringError = generateUserDataStrings(args)
 
if dataStringError then
-- If we weren't passed any link codes, just return the user link.
return dataStringError
if #codes < 1 then
end
return userLink
end
-- Build the template output.
 
local result = makeToolbar(args) -- MakeGet the toolbar contents.
if result then
mToolbar = require('Module:Toolbar')
if args.sup then
local toolbarArgs = {}
result = '<sup>' .. result .. '</sup>'
for i, code in ipairs(codes) do
end
local link = links[code]
result = '&nbsp;' .. result
toolbarArgs[#toolbarArgs + 1] = link
else
end
result = '' -- If there are no links specified, don't return the toolbar at all.
toolbarArgs.style = options.toolbarStyle
end
toolbarArgs.separator = options.separator or 'dot'
result = '<span>' .. makeUserLink() .. result .. '</span>'
toolbarArgs.span = options.span
result = result .. generateTrackingCategories()
local toolbar = mToolbar.main(toolbarArgs)
 
-- Apply the sup option and return the result.
if options.sup then
toolbar = '<sup>' .. toolbar .. '</sup>'
end
return userLink .. '&nbsp;' .. toolbar
end
 
local function getExampleLinks(args)
--------------------------------------------------------------------------------
-- This function enables example output without having to specify any
-- Single link function
-- parameters to #invoke.
--------------------------------------------------------------------------------
args.demo = 'yes'
 
args.user = 'Example'
p.single = makeInvokeFunction('_single')
args.User = nil
 
function p._single return getLinks(args)
-- Fetches a single link from the link table.
local options = p.getOptions(args)
local snippets = p.getSnippets(args)
local links = p.getLinks(snippets)
local code = args[1]
local success, link = pcall(p.exportSingle, links, code)
if success then
return link
else
return makeWikitextError(link, options.isDemo)
end
end
 
local function p.exportSinglemakeWrapper(links, codefunc)
return function (frame)
-- If any errors occur, they will probably occur here. This function
-- If called via #invoke, use the args passed into the invoking template.
-- exists purely so that all the errors that will occur in p._single can
-- Otherwise, for testing purposes, assume args are being passed directly in.
-- be handled using a single pcall.
local origArgs
if not code then
if frame == mw.getCurrentFrame() then
raiseError(
origArgs = frame:getParent().args
message('error-nolinkcode'),
for k, v in pairs(frame.args) do
message('error-nolinkcode-section')
origArgs = frame.args
)
break
end
end
return links[code]
else
origArgs = frame
end
-- Strip whitespace, and treat blank arguments as nil.
-- 'user', 'User', and 'separator' have different behaviour depending on
-- whether they are blank or nil, so keep them as they are.
local args = {}
for k, v in pairs(origArgs) do
v = mw.text.trim(v)
if v ~= '' or k == 'user' or k == 'User' or k == 'separator' then
args[k] = v
end
end
return func(args)
end
end
 
return {
--------------------------------------------------------------------------------
main = makeWrapper(getLinks),
-- Link table
single = makeWrapper(getSingleLink),
--------------------------------------------------------------------------------
linktable = makeWrapper(getLinkTable),
 
example = makeWrapper(getExampleLinks)
function p.linktable()
}
-- Returns a wikitext table of link codes, with an example link for each
-- one. This function doesn't take any arguments, so it can be accessed
-- directly from wiki pages without using makeInvokeFunction.
local args = {user = 'Example'}
local snippets = p.getSnippets(args)
local links = p.getLinks(snippets)
 
-- Assemble the codes and links in order
local firstCodes = {'u', 't', 'c'}
local firstLinks, firstCodesKeys = {}, {}
for i, code in ipairs(firstCodes) do
firstCodesKeys[code] = true
firstLinks[#firstLinks + 1] = {code, links[code]}
end
local secondLinks = {}
for code, link in pairs(links) do
if not firstCodesKeys[code] then
secondLinks[#secondLinks + 1] = {code, link}
end
end
table.sort(secondLinks, function(t1, t2)
return t1[1] < t2[1]
end)
local links = {}
for i, t in ipairs(firstLinks) do
links[#links + 1] = t
end
for i, t in ipairs(secondLinks) do
links[#links + 1] = t
end
 
-- Output the code table in table format
local ret = {}
ret[#ret + 1] = '{| class="wikitable plainlinks sortable"'
ret[#ret + 1] = '|-'
ret[#ret + 1] = '! ' .. message('linktable-codeheader')
ret[#ret + 1] = '! ' .. message('linktable-previewheader')
for i, t in ipairs(links) do
local code = t[1]
local link = t[2]
ret[#ret + 1] = '|-'
ret[#ret + 1] = "| '''" .. code .. "'''"
ret[#ret + 1] = '| ' .. link
end
ret[#ret + 1] = '|}'
return table.concat(ret, '\n')
end
 
return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu