Module:Icon: Difference between revisionsGive feedback
Added localized icon names based on page language |
mNo edit summary |
||
| (11 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local | local iconDataRaw = mw.loadJsonData("Data:ResourceLookup.json") | ||
local | local iconData2 = mw.loadJsonData("Data:ResourceLookup2.json") | ||
local | local dictionary = mw.loadJsonData("Data:Dictionary") | ||
local | local iconData = {} | ||
for k, v in pairs(iconDataRaw) do | |||
iconData[k] = v | |||
[ | end | ||
for k, v in pairs(iconData2) do | |||
iconData[k] = v | |||
[ | end | ||
local | local lang_codes = mw.loadJsonData("Data:LangCodes.json") | ||
local lang_module = require("Module:Lang") | |||
local table_data = require("Module:Icon/data") | |||
local | local cachedLangCode | ||
local linkOverrides = table_data.linkOverrides | |||
local legacyItems = table_data.legacyItems | |||
local missingImageOverrides = table_data.missingImageOverrides | |||
local aliases = table_data.aliases | |||
local renames = table_data.renames | |||
local function getLangCode() | local function getLangCode() | ||
| Line 64: | Line 41: | ||
-- Infer image path from name, with override support for missing images | -- Infer image path from name, with override support for missing images | ||
local function getImage(iconInfo) | local function getImage(iconInfo, args) | ||
local lowerName = iconInfo.name:lower() | local lowerName = iconInfo.name:lower() | ||
if args.image then | |||
return args.image | |||
end | |||
return missingImageOverrides[lowerName] or (iconInfo.name .. ".png") | return missingImageOverrides[lowerName] or (iconInfo.name .. ".png") | ||
end | |||
-- Get the translated name | |||
local function getTranslatedName(iconInfo, langCode) | |||
if langCode == "en" then | |||
return iconInfo.name | |||
end | |||
-- 1. Direct key | |||
if iconInfo.key and iconInfo.key ~= "" then | |||
local translated = lang_module.get_string(iconInfo.key, langCode, iconInfo.name | |||
) | |||
if type(translated) == "string" then | |||
return (translated:gsub("<[^>]+>", "")) | |||
end | |||
return iconInfo.name | |||
end | |||
-- 2. Dictionary lookup | |||
if iconInfo.key_dictionary and iconInfo.key_dictionary ~= "" then | |||
local entry = dictionary[iconInfo.key_dictionary] | |||
if type(entry) == "table" then | |||
return entry[langCode] | |||
or entry.en | |||
or iconInfo.name | |||
end | |||
end | |||
-- No valid key > fallback | |||
return iconInfo.name | |||
end | end | ||
-- Infer link from type and available fields | -- Infer link from type and available fields | ||
local function getLink(iconInfo) | local function getLink(iconInfo, langCode) | ||
if iconInfo.type == "ability" then | if iconInfo.type == "ability" then | ||
local hero = iconInfo.hero_name or iconInfo.name | local hero = iconInfo.hero_name or iconInfo.name | ||
return hero .. "# | |||
-- Get the translated name for the specific ability | |||
local abilityName = getTranslatedName(iconInfo, langCode) | |||
-- Format for URL: replace spaces with underscores | |||
local anchor = abilityName:gsub(" ", "_") | |||
return hero .. "#" .. anchor | |||
end | end | ||
return linkOverrides[iconInfo.name] or iconInfo.name | return linkOverrides[iconInfo.name] or iconInfo.name | ||
end | end | ||
-- Returns the canonical display name for a given user input | |||
-- Returns the canonical display name for a given user input | |||
-- Used by templates to store the correct casing in data attributes | -- Used by templates to store the correct casing in data attributes | ||
-- so | -- Normalizes casing so exact string matches work reliably in Lua modules | ||
function p.getCanonicalName(frame) | function p.getCanonicalName(frame) | ||
local name = frame.args[1] or "" | local name = frame.args[1] or "" | ||
local lowerName = name:lower() | local lowerName = name:lower() | ||
if aliases[lowerName] then | if renames[lowerName] then | ||
lowerName = renames[lowerName] | |||
elseif aliases[lowerName] then | |||
lowerName = aliases[lowerName] | lowerName = aliases[lowerName] | ||
end | end | ||
local iconInfo = iconData[lowerName] | local iconInfo = iconData[lowerName] or legacyItems[lowerName] | ||
-- If unknown, return original input | |||
if not iconInfo then | if not iconInfo then | ||
return name | |||
end | end | ||
if | -- Quick hack: ability names are used by MediaWiki:Gadget-infobox-tooltip.js and expected to be localized | ||
return | local langCode = getLangCode() | ||
if iconInfo.type == "ability" then | |||
return getTranslatedName(iconInfo, langCode) | |||
end | end | ||
| Line 116: | Line 132: | ||
local function render(name, args) | local function render(name, args) | ||
local originalName = name | |||
local lowerName = name:lower() | local lowerName = name:lower() | ||
args = args or {} | args = args or {} | ||
if aliases[lowerName] then | if renames[lowerName] then | ||
lowerName = renames[lowerName] | |||
elseif aliases[lowerName] then | |||
lowerName = aliases[lowerName] | lowerName = aliases[lowerName] | ||
end | end | ||
-- | -- Lookup live data > legacy fallback | ||
local iconInfo = iconData[lowerName] | local iconInfo = iconData[lowerName] or legacyItems[lowerName] | ||
-- | -- Throw error if not found | ||
if not iconInfo then | if not iconInfo then | ||
return string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", name) | return string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", name) | ||
end | end | ||
local customText = args.l1 or | local customText = args.l1 ~= "" and args.l1 or nil | ||
local customLink = args.link ~= "" and args.link or nil | |||
local size = args.size or "20px" | local size = args.size or "20px" | ||
local noLink = args["no-link"] == "true" | local noLink = args["no-link"] == "true" | ||
local noFile = args["no-file"] == "true" | |||
local iconOnly = args["icon-only"] == "true" | local iconOnly = args["icon-only"] == "true" | ||
| Line 144: | Line 160: | ||
if type(k) == "number" and k > 1 then | if type(k) == "number" and k > 1 then | ||
local val = mw.text.trim(v) | local val = mw.text.trim(v) | ||
if val == "icon-only" then iconOnly = true | if val == "icon-only" then | ||
elseif val == "no-link" then noLink = true | iconOnly = true | ||
elseif val:match("^%d+px$") then size = val end | elseif val == "no-link" then | ||
noLink = true | |||
elseif val:match("^%d+px$") then | |||
size = val | |||
end | |||
end | end | ||
end | end | ||
| Line 152: | Line 172: | ||
local langCode = getLangCode() | local langCode = getLangCode() | ||
local displayName = customText | local displayName | ||
if displayName = | if customText then | ||
displayName = customText | |||
elseif renames[name:lower()] then | |||
-- Preserve original if renamed | |||
displayName = originalName | |||
else | |||
displayName = getTranslatedName(iconInfo, langCode) | displayName = getTranslatedName(iconInfo, langCode) | ||
end | end | ||
local baseLink = getLink(iconInfo) | local baseLink = customLink or getLink(iconInfo, langCode) | ||
local fragment = "" | local fragment = "" | ||
| Line 168: | Line 193: | ||
local link = baseLink | local link = baseLink | ||
if langCode ~= "en" and baseLink ~= "" then | |||
if not customLink and langCode ~= "en" and baseLink ~= "" then | |||
link = baseLink .. "/" .. langCode | link = baseLink .. "/" .. langCode | ||
end | end | ||
-- | -- Reattach fragment at the end | ||
link = link .. fragment | link = link .. fragment | ||
-- | -- Add CSS class for abilities | ||
local style | local style | ||
if iconInfo.type == "ability" then | if iconInfo.type == "ability" then | ||
style = 'class="module-icon-ability" style="position:relative; bottom:2px;"' | style = 'class="module-icon-ability" style="position:relative; bottom:2px;"' | ||
else | else | ||
style = 'style="position:relative; bottom:2px;"' | style = 'class="c-icon" style="position:relative; bottom:2px;"' | ||
end | end | ||
local imageLink = noLink and "" or link | local imageLink = noLink and "" or link | ||
local iconHtml = string.format('<span %s>[[File:%s|%s|link=%s]]</span>', style, image, size, imageLink) | local iconHtml = "" | ||
if not noFile then | |||
local image = getImage(iconInfo, args) | |||
iconHtml = string.format('<span %s>[[File:%s|%s|link=%s]]</span>', style, image, size, imageLink) | |||
end | |||
if iconOnly or displayName == "" then | if iconOnly or displayName == "" then | ||
| Line 192: | Line 222: | ||
local textHtml = (noLink or link == "") and displayName or string.format('[[%s|%s]]', link, displayName) | local textHtml = (noLink or link == "") and displayName or string.format('[[%s|%s]]', link, displayName) | ||
return '<span style="white-space:nowrap;">' .. iconHtml .. " " .. textHtml .. '</span>' | |||
if iconHtml ~= "" then | |||
return '<span style="white-space:nowrap;">' .. iconHtml .. " " .. textHtml .. '</span>' | |||
else | |||
return textHtml | |||
end | |||
end | end | ||
| Line 205: | Line 240: | ||
-- Module entrypoint | -- Module entrypoint | ||
function p._render(name, args) | function p._render(name, args) | ||
return render(name, args) | |||
end | end | ||
return p | return p | ||