Module:LangSwitcher: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
mNo edit summary
mNo edit summary
Line 1: Line 1:
local p = {}
local p = {}


local function trim(s)
local function trim(s) return (s or ""):gsub("^%s+",""):gsub("%s+$","") end
    return (s or ""):gsub("^%s+", ""):gsub("%s+$", "")
end
 
local function splitCSV(s)
    local t = {}
    if not s or s == "" then
        return t
    end
    for part in s:gmatch("([^,]+)") do
        local v = trim(part):lower()
        if v ~= "" then
            table.insert(t, v)
        end
    end
    return t
end
 
local function parseKVList(s)
    local out = {}
    if not s or s == "" then
        return out
    end
    for pair in s:gmatch("([^,]+)") do
        local k, v = pair:match("^%s*([^=]+)%s*=%s*(.-)%s*$")
        if k and v then
            out[trim(k):lower()] = trim(v)
        end
    end
    return out
end


local function getTitleParts()
local function getTitleParts()
Line 47: Line 17:


local function makeTarget(baseFullText, code, defaultLang)
local function makeTarget(baseFullText, code, defaultLang)
     if code == defaultLang then
     if code == defaultLang then return baseFullText end
        return baseFullText
    end
     local baseTitle = mw.title.new(baseFullText)
     local baseTitle = mw.title.new(baseFullText)
     if not baseTitle then
     if not baseTitle then return baseFullText .. "/" .. code end
        return baseFullText .. "/" .. code
    end
     local targetTitle = mw.title.new(baseTitle.fullText .. "/" .. code, baseTitle.namespace)
     local targetTitle = mw.title.new(baseTitle.fullText .. "/" .. code, baseTitle.namespace)
     return (targetTitle and targetTitle.fullText) or (baseFullText .. "/" .. code)
     return (targetTitle and targetTitle.fullText) or (baseFullText .. "/" .. code)
end
end


local function pageExists(fullTitleText)
local function exists(fullTitleText)
     local t = mw.title.new(fullTitleText)
     local t = mw.title.new(fullTitleText)
     return t and t.exists
     return t and t.exists
Line 68: Line 34:


local builtinNames = {
local builtinNames = {
     en = "English",
     en="English", sv="Svenska", da="Dansk",
    sv = "Svenska",
     de="Deutsch", fr="Français", es="Español", fi="Suomi",
    da = "Dansk",
     it="Italiano", nl="Nederlands", pl="Polski", pt="Português",
     nb = "Norsk bokmål",
     ["pt-br"]="Português (Brasil)", ru="Русский", ja="日本語",
    nn = "Nynorsk",
     zh="中文", ["zh-hans"]="中文(简体)", ["zh-hant"]="中文(繁體)", ko="한국어",
    no = "Norsk",
    fi = "Suomi",
     de = "Deutsch",
    fr = "Français",
    es = "Español",
    pt = "Português",
     ["pt-br"] = "Português (Brasil)",
    it = "Italiano",
    nl = "Nederlands",
    pl = "Polski",
    ru = "Русский",
    ja = "日本語",
     zh = "中文",
    ["zh-hans"] = "中文(简体)",
    ["zh-hant"] = "中文(繁體)",
    ko = "한국어",
}
}


function p.render(frame)
function p.render(frame)
     local args = frame:getParent() and frame:getParent().args or frame.args
     local args = frame:getParent() and frame:getParent().args or frame.args
    -- Set debug=yes in your invoke to print raw parameters
    local debug = (args.debug or ""):lower() == "yes"
    if debug then
        return 'DIAG langs=' .. tostring(args.langs) .. ' | default=' .. tostring(args.default)
    end
    local langs = splitCSV(args.langs or args.languages or "en")
    local labels = parseKVList(args.labels or "")
    local showMissing = (args.show_missing or ""):lower() == "yes"
     local icon = args.icon or ""
     local icon = args.icon or ""
    local defaultLang = trim((args.default or "en")):lower()


     local base, currentLang = getTitleParts()
     local base, currentLang = getTitleParts()
    local defaultLang = trim(args.default or (langs[1] or "en")):lower()


     local function labelFor(code)
    -- Candidate codes to auto-scan; add/remove as you need
         code = (code or ""):lower()
     local candidates = {
        return labels[code] or builtinNames[code] or code
         "en","sv","da","de","fr","es","fi","it","nl","pl","pt","pt-br","ru","ja","zh","zh-hans","zh-hant","ko"
     end
     }


     -- Order: default first, then others (unique)
     -- Order: default first, then others that exist
     local seen, ordered = {}, {}
     local seen, ordered = {}, {}
     local function add(code)
     local function add(code)
Line 123: Line 63:
     end
     end
     add(defaultLang)
     add(defaultLang)
     for _, code in ipairs(langs) do
     for _, code in ipairs(candidates) do
         add(code)
         if code ~= defaultLang then
            local target = makeTarget(base, code, defaultLang)
            if exists(target) then
                add(code)
            end
        end
     end
     end


Line 131: Line 76:
     for _, code in ipairs(ordered) do
     for _, code in ipairs(ordered) do
         local target = makeTarget(base, code, defaultLang)
         local target = makeTarget(base, code, defaultLang)
         local exists = pageExists(target)
         local label = builtinNames[code] or code
         if exists or showMissing then
         local link = wikilink(target, label)
            local link = wikilink(target, labelFor(code))
        local isActive = currentLang and (currentLang == code) or (code == defaultLang)
            local isActive = currentLang and (currentLang == code) or (code == defaultLang)
        if isActive then link = "'''" .. link .. "'''" end
            if isActive then
        table.insert(links, link)
                link = "'''" .. link .. "'''"
            end
            table.insert(links, link)
        end
     end
     end


     if #links == 0 then
     if #links == 0 then return "" end
        return ""
    end


     local pieces = {}
     local out = {}
     if icon ~= "" then
     if icon ~= "" then table.insert(out, "''" .. icon .. "'' ") end
        table.insert(pieces, "''" .. icon .. "'' ")
     table.insert(out, table.concat(links, " • "))
    end
     return table.concat(out)
     table.insert(pieces, table.concat(links, " • "))
     return table.concat(pieces)
end
end


return p
return p

Revision as of 13:29, 30 October 2025

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

local p = {}

local function trim(s) return (s or ""):gsub("^%s+",""):gsub("%s+$","") end

local function getTitleParts()
    local title = mw.title.getCurrentTitle()
    if title.subpageText ~= title.text then
        local last = title.subpageText
        local code = last:match("^([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$")
        if code then
            local baseTitle = mw.title.new(title.baseText, title.namespace)
            return baseTitle.fullText, code:lower(), title
        end
    end
    return title.fullText, nil, title
end

local function makeTarget(baseFullText, code, defaultLang)
    if code == defaultLang then return baseFullText end
    local baseTitle = mw.title.new(baseFullText)
    if not baseTitle then return baseFullText .. "/" .. code end
    local targetTitle = mw.title.new(baseTitle.fullText .. "/" .. code, baseTitle.namespace)
    return (targetTitle and targetTitle.fullText) or (baseFullText .. "/" .. code)
end

local function exists(fullTitleText)
    local t = mw.title.new(fullTitleText)
    return t and t.exists
end

local function wikilink(page, label)
    return string.format('[[%s|%s]]', page, label)
end

local builtinNames = {
    en="English", sv="Svenska", da="Dansk",
    de="Deutsch", fr="Français", es="Español", fi="Suomi",
    it="Italiano", nl="Nederlands", pl="Polski", pt="Português",
    ["pt-br"]="Português (Brasil)", ru="Русский", ja="日本語",
    zh="中文", ["zh-hans"]="中文(简体)", ["zh-hant"]="中文(繁體)", ko="한국어",
}

function p.render(frame)
    local args = frame:getParent() and frame:getParent().args or frame.args
    local icon = args.icon or ""
    local defaultLang = trim((args.default or "en")):lower()

    local base, currentLang = getTitleParts()

    -- Candidate codes to auto-scan; add/remove as you need
    local candidates = {
        "en","sv","da","de","fr","es","fi","it","nl","pl","pt","pt-br","ru","ja","zh","zh-hans","zh-hant","ko"
    }

    -- Order: default first, then others that exist
    local seen, ordered = {}, {}
    local function add(code)
        code = (code or ""):lower()
        if code ~= "" and not seen[code] then
            table.insert(ordered, code)
            seen[code] = true
        end
    end
    add(defaultLang)
    for _, code in ipairs(candidates) do
        if code ~= defaultLang then
            local target = makeTarget(base, code, defaultLang)
            if exists(target) then
                add(code)
            end
        end
    end

    -- Build links
    local links = {}
    for _, code in ipairs(ordered) do
        local target = makeTarget(base, code, defaultLang)
        local label = builtinNames[code] or code
        local link = wikilink(target, label)
        local isActive = currentLang and (currentLang == code) or (code == defaultLang)
        if isActive then link = "'''" .. link .. "'''" end
        table.insert(links, link)
    end

    if #links == 0 then return "" end

    local out = {}
    if icon ~= "" then table.insert(out, "''" .. icon .. "'' ") end
    table.insert(out, table.concat(links, " • "))
    return table.concat(out)
end

return p