Jump to content

Module:SocialMedia: Difference between revisions

No edit summary
No edit summary
Line 1: Line 1:
-- Module:SocialMedia
-- Reusable social media component meant to be called from other modules
-- Reusable, single-row or multi-row social media footer that can be called from any other module or template.
-- This version includes:
--  - alt text for improved accessibility
--  - the ability to accept multiple parameter names (aliases) for “X (Twitter)”


local sf = {}
local sf = {}


--------------------------------------------------------------------------------
-- This section defines the social platforms; can be added or deleted without consequence
-- 1) Define the social platforms
-- param = handle for the platform; for "x", we also accept "twitter" for legacy pursposes
--
-- For most, 'param' is just a single string (e.g., "facebook").
-- For X/Twitter, we allow a table { "x", "twitter" }, so the user can supply
-- |x=SomeHandle OR |twitter=SomeHandle, and it will produce one icon link.
--
-- icon  = wiki file for the icon
-- icon  = wiki file for the icon
-- prefix = URL prefix
-- prefix = URL prefix
-- label  = used for alt text, so screen readers have a descriptive name
-- label  = used for alt text/screen readers
--------------------------------------------------------------------------------
local socialPlatforms = {
local socialPlatforms = {
     {
     {
Line 56: Line 46:
     },
     },
     {
     {
         -- Multiple aliases here: the user can supply |x=Handle OR |twitter=Handle
         -- Multiple aliases: the editor can supply "x" or "twitter"
         param  = { "x", "twitter" },
         param  = { "x", "twitter" },
         icon  = "File:TwitterIcon.png", -- or "File:XIcon.png"
         icon  = "File:XIcon.png",
         prefix = "https://x.com/",
         prefix = "https://x.com/",
         label  = "X (Twitter)"
         label  = "X (Twitter)"
Line 90: Line 80:
end
end


--------------------------------------------------------------------------------
-- Helper function to build a clickable icon link with alt text for accessibility using wikitext syntax: [[File:Something.png|16px|alt=ALT_TEXT|link=URL]]
-- 2) Helper function to build a clickable icon link with alt text for accessibility
--    Using wikitext syntax: [[File:Something.png|16px|alt=ALT_TEXT|link=URL]]
--------------------------------------------------------------------------------
local function buildIconLink(iconFile, altText, url)
local function buildIconLink(iconFile, altText, url)
     return string.format("[[%s|16px|alt=%s|link=%s]]", iconFile, altText, url)
     return string.format("[[%s|16px|alt=%s|link=%s]]", iconFile, altText, url)
end
end


--------------------------------------------------------------------------------
-- Main render function, takes a table of arguments (handles), returns wiki markup with social icons
-- 3) The main render function, called from another module or via #invoke.
--    Takes a table of arguments (handles), returns wiki markup with social icons.
--
--    - If the user supplies no social handles, we return an empty string (no row).
--    - Otherwise, we build a single row labeled "Social Media" containing icons.
--------------------------------------------------------------------------------
function sf.render(args)
function sf.render(args)
     local icons = {}
     local icons = {}


     for _, platform in ipairs(socialPlatforms) do
     for _, platform in ipairs(socialPlatforms) do
         -- Retrieve the user's handle from any of the defined param aliases
         -- Retrieve the handle from any of the defined param aliases
         local handle = getUserHandle(args, platform.param)
         local handle = getUserHandle(args, platform.param)
         if handle and handle ~= "" then
         if handle and handle ~= "" then
             local url
             local url


             -- Mastodon is special; user might type a full URL or just user@instance
             -- Mastodon is special; editor might type a full URL or just user@instance
             if type(platform.param) == "string" and platform.param == "mastodon"
             if type(platform.param) == "string" and platform.param == "mastodon"
               or type(platform.param) == "table" and table.concat(platform.param, ","):match("mastodon") then
               or type(platform.param) == "table" and table.concat(platform.param, ","):match("mastodon") then


                 -- If user typed a full URL (starting with http...)
                 -- If editor typed a full URL
                 if handle:match("^https?://") then
                 if handle:match("^https?://") then
                     url = handle
                     url = handle
Line 143: Line 124:
     end
     end


     -- Otherwise, return a table row (or any layout you want).
     -- Otherwise, return a table row
    -- Example: single row labeled "Social Media"
     local iconString = table.concat(icons, "   ")
     local iconString = table.concat(icons, "   ")
     local row = table.concat({
     local row = table.concat({
         "|-",
         "|-",
         "| ",  -- Label on the left
         "| ",  -- Label on the left
         "| " .. iconString       -- Icons on the right
         "| " .. iconString -- Icons on the right
     }, "\n")
     }, "\n")



Revision as of 13:10, 7 February 2025

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

-- Reusable social media component meant to be called from other modules

local sf = {}

-- This section defines the social platforms; can be added or deleted without consequence
-- param = handle for the platform; for "x", we also accept "twitter" for legacy pursposes
-- icon  = wiki file for the icon
-- prefix = URL prefix
-- label  = used for alt text/screen readers
local socialPlatforms = {
    {
        param  = "facebook",
        icon   = "File:FacebookIcon.png",
        prefix = "https://www.facebook.com/",
        label  = "Facebook"
    },
    {
        param  = "instagram",
        icon   = "File:InstagramIcon.png",
        prefix = "https://www.instagram.com/",
        label  = "Instagram"
    },
    {
        param  = "linkedin",
        icon   = "File:LinkedInIcon.png",
        prefix = "https://www.linkedin.com/",
        label  = "LinkedIn"
    },
    {
        param  = "mastodon",
        icon   = "File:MastodonIcon.png",
        prefix = "",
        label  = "Mastodon"
    },
    {
        param  = "threads",
        icon   = "File:ThreadsIcon.png",
        prefix = "https://www.threads.net/",
        label  = "Threads"
    },
    {
        param  = "tiktok",
        icon   = "File:TikTokIcon.png",
        prefix = "https://www.tiktok.com/",
        label  = "TikTok"
    },
    {
        -- Multiple aliases: the editor can supply "x" or "twitter"
        param  = { "x", "twitter" },
        icon   = "File:XIcon.png",
        prefix = "https://x.com/",
        label  = "X (Twitter)"
    },
    {
        param  = "youtube",
        icon   = "File:YouTubeIcon.png",
        prefix = "https://www.youtube.com/",
        label  = "YouTube"
    },
}

--------------------------------------------------------------------------------
-- Helper to find the first non-empty user handle from a param or table of params
-- If param is a single string (e.g. "facebook"), we do args["facebook"]
-- If it's a table like { "x", "twitter" }, we check args["x"] then args["twitter"]
--------------------------------------------------------------------------------
local function getUserHandle(args, param)
    if type(param) == "string" then
        return args[param]
    else
        -- param is a table of aliases
        for _, alias in ipairs(param) do
            local handle = args[alias]
            if handle and handle ~= "" then
                return handle
            end
        end
        return nil
    end
end

-- Helper function to build a clickable icon link with alt text for accessibility using wikitext syntax: [[File:Something.png|16px|alt=ALT_TEXT|link=URL]]
local function buildIconLink(iconFile, altText, url)
    return string.format("[[%s|16px|alt=%s|link=%s]]", iconFile, altText, url)
end

-- Main render function, takes a table of arguments (handles), returns wiki markup with social icons
function sf.render(args)
    local icons = {}

    for _, platform in ipairs(socialPlatforms) do
        -- Retrieve the handle from any of the defined param aliases
        local handle = getUserHandle(args, platform.param)
        if handle and handle ~= "" then
            local url

            -- Mastodon is special; editor might type a full URL or just user@instance
            if type(platform.param) == "string" and platform.param == "mastodon"
               or type(platform.param) == "table" and table.concat(platform.param, ","):match("mastodon") then

                -- If editor typed a full URL
                if handle:match("^https?://") then
                    url = handle
                else
                    -- parse e.g. "icann@mastodon.social"
                    local domain = handle:match("@([^@]+)$") or "mastodon.social"
                    local user   = handle:match("^(.-)@") or handle
                    url = "https://" .. domain .. "/@" .. user
                end
            else
                -- For all other platforms, just prefix + handle
                url = platform.prefix .. handle
            end

            -- Build an icon link, passing label as alt text
            local iconLink = buildIconLink(platform.icon, platform.label, url)
            table.insert(icons, iconLink)
        end
    end

    -- If no handles were provided, return nothing (empty string).
    if #icons == 0 then
        return ""
    end

    -- Otherwise, return a table row
    local iconString = table.concat(icons, "   ")
    local row = table.concat({
        "|-",
        "| ",  -- Label on the left
        "| " .. iconString -- Icons on the right
    }, "\n")

    return row
end

return sf