Module:UserLinks: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
Content added Content deleted
(add function for generating tracking categories, enable lower-case project parameter name)
(automatically detect project and language values from the project argument input)
Line 1: Line 1:
local ToolbarBuilder = require('Module:Toolbar')
local ToolbarBuilder = require('Module:Toolbar')
local interwikiTable = mw.loadData("Module:InterwikiTable")

local u = {} -- Table for user-data helper strings.
local u = {} -- Table for user-data helper strings.
local demo
local demo


-- Define a custom error message for this module.
-- Define a custom error message for this module.
local function err(msg, cat)
local function err(msg)
return '<span class="error">[[Module:UserLinks]] error: ' .. msg .. '.</span>[[Category:UserLinks transclusions with errors]]'
if cat and not demo then
cat = '[[Category:' .. cat .. ']]'
else
cat = ''
end
return '<span class="error">[[Module:UserLinks]] error: ' .. msg .. '.</span>' .. cat
end
end


--------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
-- Below are the helper strings available for writing user link functions. --
-- Below are the helper strings available for writing user link functions. --
-- If the project name has not been specified, all the project strings will be --
-- --
-- the blank string, ''. If the username is not specified, the module outputs an error. --
-- u.username The plain username. If the username is not present then the --
-- Either way, there is no need to worry about escaping nil values when using the --
-- module returns an error. --
-- u.usernameHtml The username html-encoded. Spaces are encoded with plus signs. --
-- helper strings. --
-- --
-- u.project The project name. Nil if not specified. --
-- u.username The plain username --
-- u.lang The language code. Nil if not specified. --
-- u.usernameHtml The username html-encoded. Spaces are encoded with plus signs. --
-- u.interwiki The interwiki prefix, consisting of the project and language --
-- --
-- values, separated by colons, e.g. ":wikt:es:". If no project --
-- u.project The plain project name. --
-- or language values are found, this is the blank string, "". --
-- --
-- u.projectColon The project name with two colons surrounding it, i.e. ":project:" --
-- --
-- If you want more strings, you can define them in the generateUserDataStrings --
-- If you want more strings, you can define them in the generateUserDataStrings --
-- function below. --
----------------------------------------------------------------------------------------------
-- function below. --
--------------------------------------------------------------------------------------------------


local function makeUserLink()
local function makeUserLink()
return '[[' .. u.projectColon .. 'User:' .. u.username .. '|' .. u.username .. ']]'
return '[[' .. u.interwiki .. 'User:' .. u.username .. '|' .. u.username .. ']]'
end
end


local function makeTalkLink()
local function makeTalkLink()
return '[[' .. u.projectColon .. 'User talk:' .. u.username .. '|talk]]'
return '[[' .. u.interwiki .. 'User talk:' .. u.username .. '|talk]]'
end
end


local function makeContribsLink()
local function makeContribsLink()
return '[[' .. u.projectColon .. 'Special:Contributions/' .. u.username .. '|contribs]]'
return '[[' .. u.interwiki .. 'Special:Contributions/' .. u.username .. '|contribs]]'
end
end


Line 47: Line 43:


local function makeMovesLink()
local function makeMovesLink()
return '[[' .. u.projectColon .. 'Special:Log/move/' .. u.username .. '|page&nbsp;moves]]'
return '[[' .. u.interwiki .. 'Special:Log/move/' .. u.username .. '|page&nbsp;moves]]'
end
end


local function makeLogsLink()
local function makeLogsLink()
return '[[' .. u.projectColon .. 'Special:Log/' .. u.username .. '|logs]]'
return '[[' .. u.interwiki .. 'Special:Log/' .. u.username .. '|logs]]'
end
end


Line 60: Line 56:


local function makeBlocksLink()
local function makeBlocksLink()
return '[[' .. u.projectColon .. 'Special:Log/block/' .. u.username .. '|blocks]]'
return '[[' .. u.interwiki .. 'Special:Log/block/' .. u.username .. '|blocks]]'
end
end


local function makeBlockUserLink()
local function makeBlockUserLink()
return '[[' .. u.projectColon .. 'Special:Block/' .. u.username .. '|block&nbsp;user]]'
return '[[' .. u.interwiki .. 'Special:Block/' .. u.username .. '|block&nbsp;user]]'
end
end


local function makeCentralAuthLink()
local function makeCentralAuthLink()
return '[[' .. u.projectColon .. 'Special:CentralAuth/' .. u.username .. '|central&nbsp;auth]]'
return '[[' .. u.interwiki .. 'Special:CentralAuth/' .. u.username .. '|central&nbsp;auth]]'
end
end


local function makeDeletedContribsLink()
local function makeDeletedContribsLink()
return '[[' .. u.projectColon .. 'Special:DeletedContributions/' .. u.username .. '|deleted&nbsp;contribs]]'
return '[[' .. u.interwiki .. 'Special:DeletedContributions/' .. u.username .. '|deleted&nbsp;contribs]]'
end
end


local function makeEmailLink()
local function makeEmailLink()
return '[[' .. u.projectColon .. 'Special:Emailuser/' .. u.username .. '|email]]'
return '[[' .. u.interwiki .. 'Special:Emailuser/' .. u.username .. '|email]]'
end
end


Line 84: Line 80:


local function makeDeletionsLink()
local function makeDeletionsLink()
return '[[' .. u.projectColon .. 'Special:Log/delete/' .. u.username .. '|deletions]]'
return '[[' .. u.interwiki .. 'Special:Log/delete/' .. u.username .. '|deletions]]'
end
end


Line 107: Line 103:


local function makeProtectionsLink()
local function makeProtectionsLink()
return '[[' .. u.projectColon .. 'Special:Log/protect/' .. u.username .. '|protections]]'
return '[[' .. u.interwiki .. 'Special:Log/protect/' .. u.username .. '|protections]]'
end
end


local function makeRightsLink()
local function makeRightsLink()
return '[[' .. u.projectColon .. 'Special:Log/rights/' .. u.username .. '|rights]]'
return '[[' .. u.interwiki .. 'Special:Log/rights/' .. u.username .. '|rights]]'
end
end


local function makeRenamesLink()
local function makeRenamesLink()
return '[[' .. u.projectColon .. 'Special:Log/renameuser/' .. u.username .. '|renames]]'
return '[[' .. u.interwiki .. 'Special:Log/renameuser/' .. u.username .. '|renames]]'
end
end


Line 147: Line 143:
}
}
if not linktypes[linktype] then
if not linktypes[linktype] then
return err('"' .. linktype .. '" is not a valid link code', 'UserLinks transclusions with invalid link types')
return err('"' .. linktype .. '" is not a valid link code')
end
end
return linktypes[linktype]()
return linktypes[linktype]()
Line 169: Line 165:
return ToolbarBuilder.main(targs)
return ToolbarBuilder.main(targs)
end
end
end

local function isKnownProject(prefix)
for projectKey, projectVal in pairs(interwikiTable) do
for _, iwCode in ipairs(projectVal.iw_prefix) do
if iwCode == prefix then
return true
end
end
end
return false
end
end


local function generateUserDataStrings(args)
local function generateUserDataStrings(args)
-- If the username is absent or blank, return an error and a tracking category.
-- Username helper strings.
u.username = args.user or args.User
if args.user == '' or (not args.user and (not args.User or args.User == '')) then
return err('no username detected')
u.usernameHtml = mw.uri.encode(u.username) -- Html-encoded username. Spaces are encoded as pluses.
else
-- Project helper strings.
u.username = args.user or args.User
end
-- Get other basic user data strings.
u.project = args.Project or args.project
u.project = args.Project or args.project
u.lang = args.lang or args.Lang
u.projectColon = (u.project and (':' .. u.project .. ':')) or '' -- Project value plus colons, for escaping interwiki links.
u.project = u.project or '' -- Control for nil values of args.Project.
-- Process the project value if it is present.
if u.project then
-- If u.project is a known project, we don't need to do anything. 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".
if not isKnownProject(u.project) then
if mw.language.isKnownLanguageTag(u.project) then
u.lang = u.project
u.project = nil
else
-- Guess
local pref1, pref2 = mw.ustring.match( u.project, '(%w+):(%w+)' )
if pref1 and pref2 then
if isKnownProject(pref1) and mw.language.isKnownLanguageTag(pref2) then
u.project = pref1
u.lang = pref2
elseif isKnownProject(pref2) and mw.language.isKnownLanguageTag(pref1) then
u.project = pref2
u.lang = pref1
else
return err('"' .. u.project .. '" is not a valid interwiki prefix')
end
else
return err('"' .. u.project .. '" is 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.
u.usernameHtml = mw.uri.encode(u.username) -- Html-encoded username. Spaces are encoded as pluses.
end
end


Line 192: Line 248:
local linktype = args[1]
local linktype = args[1]
if not linktype then
if not linktype then
return err('no link type specified', 'UserLinks transclusions with invalid link types')
return err('no link type specified')
end
end
local result = getLink(linktype)
local result = getLink(linktype)
Line 241: Line 297:
end
end
end
end
demo = args.demo -- Set the demo variable.
demo = args.demo -- Set the demo variable.
-- If the username is absent or blank, return an error and a tracking category.
-- Generate the user data strings and return any errors.
local dataStringError = generateUserDataStrings(args)
if args.user == '' or (not args.user and (not args.User or args.User == '')) then
if dataStringError then
return err('no username detected', 'UserLinks transclusions without usernames')
return dataStringError
end
end
-- Generate the user data strings.
generateUserDataStrings(args)
return func(args)
return func(args)
end
end

Revision as of 10:07, June 16, 2013

Documentation for this module may be created at Module:UserLinks/doc

local ToolbarBuilder = require('Module:Toolbar')
local interwikiTable = mw.loadData("Module:InterwikiTable")

local u = {} -- Table for user-data helper strings.
local demo

-- Define a custom error message for this module.
local function err(msg)
    return '<span class="error">[[Module:UserLinks]] error: ' .. msg .. '.</span>[[Category:UserLinks transclusions with errors]]'
end

----------------------------------------------------------------------------------------------
--      Below are the helper strings available for writing user link functions.             --
--                                                                                          --
--      u.username          The plain username. If the username is not present then the     --
--                          module returns an error.                                        --
--      u.usernameHtml      The username html-encoded. Spaces are encoded with plus signs.  --
--      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, "".     --
--                                                                                          --
--      If you want more strings, you can define them in the generateUserDataStrings        --
--      function below.                                                                     --
----------------------------------------------------------------------------------------------

local function makeUserLink()
    return '[[' .. u.interwiki .. 'User:' .. u.username .. '|' .. u.username .. ']]'
end

local function makeTalkLink()
    return '[[' .. u.interwiki .. 'User talk:' .. u.username .. '|talk]]'
end

local function makeContribsLink()
    return '[[' .. u.interwiki .. 'Special:Contributions/' .. u.username .. '|contribs]]'
end

local function makeCountLink()
    return '[//tools.wmflabs.org/xtools/pcount/index.php?name=' .. u.usernameHtml .. '&lang=en&wiki=wikipedia count]'
end

local function makeMovesLink()
    return '[[' .. u.interwiki .. 'Special:Log/move/' .. u.username .. '|page&nbsp;moves]]'
end

local function makeLogsLink()
    return '[[' .. u.interwiki .. 'Special:Log/' .. u.username .. '|logs]]'
end

local function makeBlockLogLink()
    local url = mw.uri.fullUrl('Special:Log/block', 'page=User:' .. u.usernameHtml)
    return '[' .. tostring(url) .. ' block&nbsp;log]'
end

local function makeBlocksLink()
    return '[[' .. u.interwiki .. 'Special:Log/block/' .. u.username .. '|blocks]]'
end

local function makeBlockUserLink()
    return '[[' .. u.interwiki .. 'Special:Block/' .. u.username .. '|block&nbsp;user]]'
end

local function makeCentralAuthLink()
    return '[[' .. u.interwiki .. 'Special:CentralAuth/' .. u.username .. '|central&nbsp;auth]]'
end

local function makeDeletedContribsLink()
    return '[[' .. u.interwiki .. 'Special:DeletedContributions/' .. u.username .. '|deleted&nbsp;contribs]]'
end

local function makeEmailLink()
    return '[[' .. u.interwiki .. 'Special:Emailuser/' .. u.username .. '|email]]'
end

local function makeEditSummariesLink()
    return '[http://toolserver.org/~tparis/editsummary/index.php?name=' .. u.usernameHtml .. '&lang=en&wiki=wikipedia edit summaries]'
end

local function makeDeletionsLink()
    return '[[' .. u.interwiki .. 'Special:Log/delete/' .. u.username .. '|deletions]]'
end

local function makeListUserLink()
    local url = mw.uri.fullUrl('Special:ListUsers', 'limit=1&username=' .. u.usernameHtml)
    return '[' .. tostring(url) .. ' list&nbsp;user]'
end

local function makeSulLink()
    return '[[sulutil:' .. u.username .. '|global&nbsp;contribs]]'
end

local function makeTargetLogsLink()
    local url = mw.uri.fullUrl('Special:Log', 'page=User:' .. u.usernameHtml)
    return '[' .. tostring(url) .. ' target&nbsp;logs]'
end

local function makeEditFilterLogLink()
    local url = mw.uri.fullUrl('Special:AbuseLog', 'wpSearchUser=' .. u.usernameHtml)
    return '[' .. tostring(url) .. ' edit&nbsp;filter&nbsp;log]'
end

local function makeProtectionsLink()
    return '[[' .. u.interwiki .. 'Special:Log/protect/' .. u.username .. '|protections]]'
end

local function makeRightsLink()
    return '[[' .. u.interwiki .. 'Special:Log/rights/' .. u.username .. '|rights]]'
end

local function makeRenamesLink()
    return '[[' .. u.interwiki .. 'Special:Log/renameuser/' .. u.username .. '|renames]]'
end

local function makeRfaLink()
    return '[[Special:PrefixIndex/Wikipedia:Requests for adminship/' .. u.username .. '|RfA]]'
end

local function getLink(linktype)
    local linktypes = {
        t   = makeTalkLink,
        c   = makeContribsLink,
        ct  = makeCountLink,
        m   = makeMovesLink,
        l   = makeLogsLink,
        bl  = makeBlockLogLink,
        bls = makeBlocksLink,
        bu  = makeBlockUserLink,
        ca  = makeCentralAuthLink,
        dc  = makeDeletedContribsLink,
        e   = makeEmailLink,
        es  = makeEditSummariesLink,
        del = makeDeletionsLink,
        lu  = makeListUserLink,
        sul = makeSulLink,
        tl  = makeTargetLogsLink,
        efl = makeEditFilterLogLink,
        pr  = makeProtectionsLink,
        rl  = makeRightsLink,
        ren = makeRenamesLink,
        rfa = makeRfaLink
    }
    if not linktypes[linktype] then
        return err('"' .. linktype .. '" is not a valid link code')
    end
    return linktypes[linktype]()
end

local function makeToolbar(args)
    local targs = {}
    local numArgsExist = false
    for k, v in pairs(args) do
        if type(k) == 'number' then
            numArgsExist = true
            targs[k] = getLink(v)
        end
    end
    targs.style = args.small and 'font-size: 90%;'
    targs.separator = args.separator or 'dot'
    
    if numArgsExist == false then
        return -- Don't return a toolbar if no numeric arguments exist.
    else
        return ToolbarBuilder.main(targs)
    end
end

local function isKnownProject(prefix)
    for projectKey, projectVal in pairs(interwikiTable) do
        for _, iwCode in ipairs(projectVal.iw_prefix) do
            if iwCode == prefix then
                return true
            end
        end
    end
    return false
end

local function generateUserDataStrings(args)
    -- If the username is absent or blank, return an error and a tracking category.
    if args.user == '' or (not args.user and (not args.User or args.User == '')) then
        return err('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
    
    -- Process the project value if it is present.
    if u.project then
        -- If u.project is a known project, we don't need to do anything. 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".
        if not isKnownProject(u.project) then
            if mw.language.isKnownLanguageTag(u.project) then
                u.lang = u.project
                u.project = nil
            else
                -- Guess
                local pref1, pref2 = mw.ustring.match( u.project, '(%w+):(%w+)' )
                if pref1 and pref2 then
                    if isKnownProject(pref1) and mw.language.isKnownLanguageTag(pref2) then
                        u.project = pref1
                        u.lang = pref2
                    elseif isKnownProject(pref2) and mw.language.isKnownLanguageTag(pref1) then
                        u.project = pref2
                        u.lang = pref1
                    else
                        return err('"' .. u.project .. '" is not a valid interwiki prefix')
                    end
                else
                    return err('"' .. u.project .. '" is 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.
    u.usernameHtml = mw.uri.encode(u.username) -- Html-encoded username. Spaces are encoded as pluses.
end

local function generateTrackingCategories(args)
    local ret = ''
    if (args.Project or args.project) and not demo then
        ret = ret .. '[[Category:UserLinks transclusions with project parameters]]'
    end
    return ret
end

local function getSingleLink(args)
    local linktype = args[1]
    if not linktype then 
        return err('no link type specified')
    end
    local result = getLink(linktype)
    result = result .. generateTrackingCategories(args)
    return result
end

local function getLinks(args)
    -- Build the template output.
    local result = makeToolbar(args) -- Get the toolbar contents.
    if result then
        if args.sup then
            result = '<sup>' .. result .. '</sup>'
        end
        result = '&nbsp;' .. result
    else
        result = '' -- If there are no links specified, don't return the toolbar at all.
    end
    result = '<span>' .. makeUserLink() .. result .. '</span>'
    result = result .. generateTrackingCategories(args)
    
    return result
end    

local function makeWrapper(func)
    return function (frame)
        -- If called via #invoke, use the args passed into the invoking template.
        -- Otherwise, for testing purposes, assume args are being passed directly in.
        local origArgs
        if frame == mw.getCurrentFrame() then
            origArgs = frame:getParent().args
            for k, v in pairs(frame.args) do
                origArgs = frame.args
                break
            end
        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
    
        demo = args.demo -- Set the demo variable.
        -- Generate the user data strings and return any errors.
        local dataStringError = generateUserDataStrings(args)
        if dataStringError then
            return dataStringError
        end
        
        return func(args)
    end
end

return {
    main = makeWrapper(getLinks),
    single = makeWrapper(getSingleLink)
}