Module:Icon: Difference between revisionsGive feedback
m replaced to not break previous usage |
mNo edit summary |
||
| (45 intermediate revisions by 7 users not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local iconDataRaw = mw.loadJsonData("Data:ResourceLookup.json") | |||
local | local iconData2 = mw.loadJsonData("Data:ResourceLookup2.json") | ||
local dictionary = mw.loadJsonData("Data:Dictionary") | |||
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 lang_codes = mw.loadJsonData("Data:LangCodes.json") | local lang_codes = mw.loadJsonData("Data:LangCodes.json") | ||
local lang_module = require("Module:Lang") | |||
local table_data = require("Module:Icon/data") | |||
local cachedLangCode | |||
local cachedLangCode | |||
local linkOverrides = table_data.linkOverrides | |||
local | 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 | if cachedLangCode then | ||
if | return cachedLangCode | ||
return cachedLangCode | |||
end | end | ||
| Line 23: | Line 36: | ||
local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en" | local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en" | ||
cachedLangCode = langCode | |||
return langCode | |||
end | |||
-- Infer image path from name, with override support for missing images | |||
if | local function getImage(iconInfo, args) | ||
local lowerName = iconInfo.name:lower() | |||
if args.image then | |||
return args.image | |||
end | |||
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 | 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 | |||
-- Infer link from type and available fields | |||
local function getLink(iconInfo, langCode) | |||
if iconInfo.type == "ability" then | |||
local hero = iconInfo.hero_name or iconInfo.name | |||
-- 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 | |||
return linkOverrides[iconInfo.name] or iconInfo.name | |||
end | |||
-- Returns the canonical display name for a given user input | |||
-- Used by templates to store the correct casing in data attributes | |||
-- Normalizes casing so exact string matches work reliably in Lua modules | |||
function p.getCanonicalName(frame) | |||
local name = frame.args[1] or "" | |||
local lowerName = name:lower() | |||
if renames[lowerName] then | |||
lowerName = renames[lowerName] | |||
elseif aliases[lowerName] then | |||
lowerName = aliases[lowerName] | |||
end | |||
local iconInfo = iconData[lowerName] or legacyItems[lowerName] | |||
-- If unknown, return original input | |||
if not iconInfo then | |||
return name | |||
end | end | ||
-- Quick hack: ability names are used by MediaWiki:Gadget-infobox-tooltip.js and expected to be localized | |||
local langCode = getLangCode() | |||
if iconInfo.type == "ability" then | |||
return getTranslatedName(iconInfo, langCode) | |||
end | |||
return | return iconInfo.name | ||
end | end | ||
local function render(name, args) | |||
local originalName = name | |||
local | local lowerName = name:lower() | ||
local | args = args or {} | ||
local customText = args.l1 or "" | |||
if renames[lowerName] then | |||
lowerName = renames[lowerName] | |||
elseif aliases[lowerName] then | |||
lowerName = aliases[lowerName] | |||
end | |||
-- Lookup live data > legacy fallback | |||
local iconInfo = iconData[lowerName] or legacyItems[lowerName] | |||
-- Throw error if not found | |||
if not iconInfo then | |||
return string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", name) | |||
end | |||
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" | ||
local | for k, v in pairs(args) do | ||
if | if type(k) == "number" and k > 1 then | ||
local val = mw.text.trim(v) | |||
if val == "icon-only" then | |||
iconOnly = true | |||
elseif val == "no-link" then | |||
noLink = true | |||
elseif val:match("^%d+px$") then | |||
size = val | |||
end | |||
end | |||
end | |||
local langCode = getLangCode() | |||
local displayName | |||
if customText then | |||
displayName = customText | |||
elseif renames[name:lower()] then | |||
-- Preserve original if renamed | |||
displayName = originalName | |||
else | |||
displayName = getTranslatedName(iconInfo, langCode) | |||
end | end | ||
local | local baseLink = customLink or getLink(iconInfo, langCode) | ||
local | local fragment = "" | ||
-- | -- Split the fragment (#Abilities) from the base link | ||
if baseLink:find("#") then | |||
local parts = mw.text.split(baseLink, "#", true) | |||
baseLink = parts[1] | |||
fragment = "#" .. (parts[2] or "") | |||
end | |||
local link = baseLink | |||
local link = | |||
if not customLink and langCode ~= "en" and baseLink ~= "" then | |||
link = baseLink .. "/" .. langCode | |||
end | end | ||
-- Reattach fragment at the end | |||
link = link .. fragment | |||
-- Add CSS class for abilities | |||
local style | |||
if iconInfo.type == "ability" then | |||
style = 'class="module-icon-ability" style="position:relative; bottom:2px;"' | |||
else | |||
style = 'class="c-icon" style="position:relative; bottom:2px;"' | |||
end | |||
local imageLink = noLink and "" or link | |||
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 | |||
return iconHtml | |||
end | |||
local textHtml = (noLink or link == "") and displayName or string.format('[[%s|%s]]', link, displayName) | |||
if iconHtml ~= "" then | |||
return '<span style="white-space:nowrap;">' .. iconHtml .. " " .. textHtml .. '</span>' | |||
else | |||
return textHtml | |||
end | |||
end | |||
-- Template entrypoint | |||
function p.render(frame) | |||
local args = frame:getParent().args | |||
local name = args[1] or "" | |||
return render(name, args) | |||
end | |||
-- Module entrypoint | |||
return | function p._render(name, args) | ||
return render(name, args) | |||
end | end | ||
return p | return p | ||