Module:Icon: Difference between revisionsGive feedback
Made icons have a link. |
Refactor to use HeroData.json, AbilityData.json, and ItemData.jsonm; no more need for hardcoded data table; auto-detect icon types |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
-- Load | -- Load language codes | ||
local lang_codes = mw.loadJsonData("Data:LangCodes.json") | local lang_codes = mw.loadJsonData("Data:LangCodes.json") | ||
-- | -- Cache for compiled icon data (persists during page render) | ||
local iconDataCache = nil | |||
local cachedLangCode, cachedLangData | local cachedLangCode, cachedLangData | ||
-- Get icon data by name | -- Build unified lookup table from bot-uploaded JSONs | ||
local function buildIconData() | |||
if iconDataCache then | |||
return iconDataCache | |||
end | |||
local lookup = {} | |||
-- Load bot data | |||
local heroData = mw.loadJsonData("Data:HeroData.json") | |||
local abilityData = mw.loadJsonData("Data:AbilityData.json") | |||
local itemData = mw.loadJsonData("Data:ItemData.json") | |||
-- Track which hero owns which ability (for linking) | |||
local abilityToHero = {} | |||
-- Process Heroes | |||
for heroKey, hero in pairs(heroData) do | |||
if type(hero) == "table" and hero.Name then | |||
local name = hero.Name | |||
local lowerName = name:lower() | |||
lookup[lowerName] = { | |||
name = name, | |||
key = heroKey, | |||
link = name, | |||
image = name .. ".png", | |||
type = "hero" | |||
} | |||
-- Map abilities to parent hero | |||
if hero.BoundAbilities then | |||
for slot, ability in pairs(hero.BoundAbilities) do | |||
if ability.Key then | |||
abilityToHero[ability.Key] = { | |||
heroName = name, | |||
abilityName = ability.Name -- Use name from hero data if available | |||
} | |||
end | |||
end | |||
end | |||
end | |||
end | |||
-- Process Abilities | |||
for abilityKey, ability in pairs(abilityData) do | |||
if type(ability) == "table" and ability.Name then | |||
local name = ability.Name | |||
local lowerName = name:lower() | |||
local parentInfo = abilityToHero[abilityKey] | |||
-- Determine link (fallback to ability name if no parent found) | |||
local link = parentInfo and parentInfo.heroName or name | |||
lookup[lowerName] = { | |||
name = name, | |||
key = abilityKey, | |||
link = link, | |||
image = name .. ".png", | |||
type = "ability", | |||
class = "theme" -- Abilities get theme class by default | |||
} | |||
end | |||
end | |||
-- Process Items | |||
for itemKey, item in pairs(itemData) do | |||
if type(item) == "table" and item.Name then | |||
local name = item.Name | |||
local lowerName = name:lower() | |||
lookup[lowerName] = { | |||
name = name, | |||
key = itemKey, | |||
link = name, | |||
image = name .. ".png", | |||
type = "item" | |||
} | |||
end | |||
end | |||
iconDataCache = lookup | |||
return lookup | |||
end | |||
-- Get icon data by name (with alias support) | |||
local function getIconData(iconName) | local function getIconData(iconName) | ||
local | local data = buildIconData() | ||
if | local lowerName = iconName:lower() | ||
return | |||
-- Check main lookup | |||
if data[lowerName] then | |||
return data[lowerName], nil | |||
end | |||
-- Check aliases (for edge cases like "doorman" -> "the doorman") | |||
local aliases = { | |||
["doorman"] = "the doorman", | |||
["mo and krill"] = "mo & krill", | |||
["mo"] = "mo & krill", | |||
["krill"] = "mo & krill", | |||
["curse"] = "cursed relic", | |||
["debuff remover"] = "dispel magic" | |||
} | |||
if aliases[lowerName] then | |||
return data[aliases[lowerName]], nil | |||
end | end | ||
return nil, string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", iconName) | return nil, string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", iconName) | ||
end | end | ||
-- | -- Language handling | ||
local function getLangData() | local function getLangData() | ||
if cachedLangData then | if cachedLangData then | ||
| Line 49: | Line 152: | ||
local customText = args.l1 or "" | local customText = args.l1 or "" | ||
-- | -- Set Defaults | ||
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 iconOnly = args["icon-only"] == "true" | local iconOnly = args["icon-only"] == "true" | ||
-- | -- Scan unnamed parameters | ||
for k, v in pairs(args) do | for k, v in pairs(args) do | ||
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 | if val == "icon-only" then | ||
| Line 65: | Line 167: | ||
noLink = true | noLink = true | ||
elseif val:match("^%d+px$") then | elseif val:match("^%d+px$") then | ||
size = val | size = val | ||
end | end | ||
| Line 71: | Line 172: | ||
end | end | ||
-- | -- Get icon data automatically from JSON | ||
local iconData, err = getIconData(name) | local iconData, err = getIconData(name) | ||
if not iconData then | if not iconData then | ||
| Line 79: | Line 180: | ||
local langCode, langData = getLangData() | local langCode, langData = getLangData() | ||
-- Determine display name | -- Determine display name | ||
local displayName = "" | local displayName = "" | ||
if customText ~= "" then | if customText ~= "" then | ||
| Line 85: | Line 186: | ||
elseif iconData.key and langData[iconData.key] then | elseif iconData.key and langData[iconData.key] then | ||
displayName = langData[iconData.key] | displayName = langData[iconData.key] | ||
else | |||
displayName = iconData.name | displayName = iconData.name | ||
end | end | ||
-- Localize link if on | -- Localize link if on translated subpage | ||
local baseLink = iconData.link or "" | local baseLink = iconData.link or "" | ||
local link = (langCode ~= "en" and baseLink ~= "") and (baseLink .. "/" .. langCode) or baseLink | local link = (langCode ~= "en" and baseLink ~= "") and (baseLink .. "/" .. langCode) or baseLink | ||
-- Style logic | -- Style logic (only abilities get theme class by default) | ||
local class = iconData.class or "" | local class = iconData.class or "" | ||
local extra = (class:find("invert", 1, true) and " filter:invert(1);" or "") | local extra = (class:find("invert", 1, true) and " filter:invert(1);" or "") | ||
| Line 107: | Line 204: | ||
end | end | ||
-- | -- Generate icon HTML | ||
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, iconData.image, size, imageLink) | local iconHtml = string.format('<span %s>[[File:%s|%s|link=%s]]</span>', style, iconData.image, size, imageLink) | ||