Module:LangSwitcher: Difference between revisions
From Heroes of Might and Magic: Olden Era Official Wiki
m Protected "Module:LangSwitcher" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) |
test |
||
| Line 3: | Line 3: | ||
local function trim(s) return (s or ""):gsub("^%s+",""):gsub("%s+$","") end | local function trim(s) return (s or ""):gsub("^%s+",""):gsub("%s+$","") end | ||
local function getTitleParts() | local function getTitleParts() | ||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
if title.subpageText ~= title.text then | if title.subpageText ~= title.text then | ||
local last = title.subpageText | local last = title.subpageText | ||
local code = last:match("^([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$") | local code = last:match("^([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$") | ||
if code then | if code then | ||
| Line 19: | Line 15: | ||
end | end | ||
end | end | ||
local full = title.fullText | local full = title.fullText | ||
local base, code = full:match("^(.*)/([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$") | local base, code = full:match("^(.*)/([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$") | ||
| Line 29: | Line 23: | ||
end | end | ||
end | end | ||
return title.fullText, nil, title | return title.fullText, nil, title | ||
end | end | ||
local function makeTarget(baseFullText, code, defaultLang) | local function makeTarget(baseFullText, code, defaultLang) | ||
code = (code or ""):lower() | code = (code or ""):lower() | ||
| Line 46: | Line 37: | ||
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 | ||
| Line 57: | Line 43: | ||
end | end | ||
local builtinNames = { | local builtinNames = { | ||
en="English", sv="Svenska", da="Dansk", | en="English", sv="Svenska", da="Dansk", | ||
| Line 66: | Line 51: | ||
} | } | ||
-- Render function (kept for explicit calls if desired) | |||
function p.render(frame) | function p.render(frame) | ||
local args = frame:getParent() and frame:getParent().args | return p._main(frame) | ||
end | |||
-- Main entrypoint: used for direct invocation {{#invoke:LangSwitcher|Some Title}} or with named args. | |||
function p._main(frame) | |||
local args = frame.args or {} | |||
-- If invoked positionally, first positional param is the display title. | |||
local displayTitle = nil | |||
if frame.args[1] and trim(frame.args[1]) ~= "" then | |||
displayTitle = trim(frame.args[1]) | |||
elseif frame:getParent() and frame:getParent().args and frame:getParent().args[1] and trim(frame:getParent().args[1]) ~= "" then | |||
displayTitle = trim(frame:getParent().args[1]) | |||
end | |||
-- Also accept named param displaytitle | |||
if not displayTitle and args.displaytitle and trim(args.displaytitle) ~= "" then | |||
displayTitle = trim(args.displaytitle) | |||
end | |||
local defaultLang = "en" -- fixed to English | |||
local defaultLang = | |||
local icon = args.icon or "" | local icon = args.icon or "" | ||
local base, currentLang = getTitleParts() | local base, currentLang = getTitleParts() | ||
-- | -- Configure languages to always show here: | ||
local candidates = { | local candidates = { | ||
"en","sv","da","de","fr","es","fi","it","nl","pl","pt","pt-br","ru","ja","zh","zh-hans","zh-hant","ko" | "en","sv","da","de","fr","es","fi","it","nl","pl","pt","pt-br","ru","ja","zh","zh-hans","zh-hant","ko" | ||
} | } | ||
local seen, ordered = {}, {} | local seen, ordered = {}, {} | ||
local function add(code) | local function add(code) | ||
| Line 91: | Line 90: | ||
end | end | ||
add(defaultLang) | add(defaultLang) | ||
for _, code in ipairs(candidates) do | for _, code in ipairs(candidates) do | ||
if code ~= defaultLang then | if code:lower() ~= defaultLang then | ||
add(code) | |||
end | end | ||
end | end | ||
local links = {} | local links = {} | ||
for _, code in ipairs(ordered) do | for _, code in ipairs(ordered) do | ||
| Line 108: | Line 101: | ||
local label = builtinNames[code] or code | local label = builtinNames[code] or code | ||
local link = wikilink(target, label) | local link = wikilink(target, label) | ||
local isActive = currentLang and (currentLang == code) or (code == defaultLang) | local isActive = (currentLang and (currentLang == code)) or (code == defaultLang and not currentLang) | ||
if isActive then | if isActive then | ||
link = "'''" .. link .. "'''" | link = "'''" .. link .. "'''" | ||
end | end | ||
table.insert(links, link) | table.insert(links, link) | ||
end | end | ||
| Line 124: | Line 113: | ||
end | end | ||
table.insert(out, table.concat(links, " • ")) | table.insert(out, table.concat(links, " • ")) | ||
-- Set display title if requested. | |||
if displayTitle and displayTitle ~= "" then | |||
-- Prefer API via mw.title.setDisplayTitle (if available in this MW build). | |||
if mw.title.setDisplayTitle then | |||
-- setDisplayTitle expects only the title string. | |||
pcall(function() mw.title.setDisplayTitle(displayTitle) end) | |||
else | |||
-- Fallback: emit raw wikitext that sets DISPLAYTITLE (will be output on page). | |||
table.insert(out, 1, "{{DISPLAYTITLE:" .. displayTitle .. "}}\n") | |||
end | |||
end | |||
return table.concat(out) | return table.concat(out) | ||
end | end | ||
return p | return p | ||
Revision as of 14:28, 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)
if baseTitle then
return baseTitle.fullText, code:lower(), title
end
end
end
local full = title.fullText
local base, code = full:match("^(.*)/([A-Za-z%-][A-Za-z%-][A-Za-z%-]*)$")
if base and code then
local baseTitle = mw.title.new(base, title.namespace)
if baseTitle then
return baseTitle.fullText, code:lower(), title
end
end
return title.fullText, nil, title
end
local function makeTarget(baseFullText, code, defaultLang)
code = (code or ""):lower()
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 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="한국어",
}
-- Render function (kept for explicit calls if desired)
function p.render(frame)
return p._main(frame)
end
-- Main entrypoint: used for direct invocation {{#invoke:LangSwitcher|Some Title}} or with named args.
function p._main(frame)
local args = frame.args or {}
-- If invoked positionally, first positional param is the display title.
local displayTitle = nil
if frame.args[1] and trim(frame.args[1]) ~= "" then
displayTitle = trim(frame.args[1])
elseif frame:getParent() and frame:getParent().args and frame:getParent().args[1] and trim(frame:getParent().args[1]) ~= "" then
displayTitle = trim(frame:getParent().args[1])
end
-- Also accept named param displaytitle
if not displayTitle and args.displaytitle and trim(args.displaytitle) ~= "" then
displayTitle = trim(args.displaytitle)
end
local defaultLang = "en" -- fixed to English
local icon = args.icon or ""
local base, currentLang = getTitleParts()
-- Configure languages to always show here:
local candidates = {
"en","sv","da","de","fr","es","fi","it","nl","pl","pt","pt-br","ru","ja","zh","zh-hans","zh-hant","ko"
}
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:lower() ~= defaultLang then
add(code)
end
end
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 and not currentLang)
if isActive then
link = "'''" .. link .. "'''"
end
table.insert(links, link)
end
local out = {}
if icon ~= "" then
table.insert(out, "''" .. icon .. "'' ")
end
table.insert(out, table.concat(links, " • "))
-- Set display title if requested.
if displayTitle and displayTitle ~= "" then
-- Prefer API via mw.title.setDisplayTitle (if available in this MW build).
if mw.title.setDisplayTitle then
-- setDisplayTitle expects only the title string.
pcall(function() mw.title.setDisplayTitle(displayTitle) end)
else
-- Fallback: emit raw wikitext that sets DISPLAYTITLE (will be output on page).
table.insert(out, 1, "{{DISPLAYTITLE:" .. displayTitle .. "}}\n")
end
end
return table.concat(out)
end
return p


