Editing Module:Icon

Jump to navigation Jump to search
Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
local p = {}
local p = {}


local iconDataRaw = mw.loadJsonData("Data:ResourceLookup.json")
-- Load language codes
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 linkOverrides = table_data.linkOverrides
-- Cache for compiled icon data (persists during page render)
local legacyItems = table_data.legacyItems
local iconDataCache = nil
local missingImageOverrides = table_data.missingImageOverrides
local cachedLangCode, cachedLangData
local aliases = table_data.aliases
local renames = table_data.renames


local function getLangCode()
-- Build unified lookup table from bot-uploaded JSONs
     if cachedLangCode then
local function buildIconData()
         return cachedLangCode
     if iconDataCache then
         return iconDataCache
     end
     end
 
   
     local title = mw.title.getCurrentTitle().fullText
     local lookup = {}
     local subpageLang = title:match("/([^/]+)$")
   
     local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en"
    -- Load bot data
 
    local heroData = mw.loadJsonData("Data:HeroData.json")
     cachedLangCode = langCode
     local abilityData = mw.loadJsonData("Data:AbilityData.json")
     return langCode
     local itemData = mw.loadJsonData("Data:ItemData.json")
end
   
 
    -- Track which hero owns which ability (for linking)
-- Infer image path from name, with override support for missing images
     local abilityToHero = {}
local function getImage(iconInfo, args)
      
    local lowerName = iconInfo.name:lower()
    -- Process Heroes
 
    for heroKey, hero in pairs(heroData) do
    if args.image then
        if type(hero) == "table" and hero.Name then
         return args.image
            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
     end
 
   
     return missingImageOverrides[lowerName] or (iconInfo.name .. ".png")
     -- Process Abilities
end
    for abilityKey, ability in pairs(abilityData) do
 
        if type(ability) == "table" and ability.Name then
-- Get the translated name
            local name = ability.Name
local function getTranslatedName(iconInfo, langCode)
            local lowerName = name:lower()
    if langCode == "en" then
            local parentInfo = abilityToHero[abilityKey]
        return iconInfo.name
           
    end
            -- Determine link (fallback to ability name if no parent found)
 
            local link = parentInfo and parentInfo.heroName or name
    -- 1. Direct key
           
    if iconInfo.key and iconInfo.key ~= "" then
            lookup[lowerName] = {
        local translated = lang_module.get_string(iconInfo.key, langCode, iconInfo.name
                name = name,
        )
                key = abilityKey,
 
                link = link,
        if type(translated) == "string" then
                image = name .. ".png",
            return (translated:gsub("<[^>]+>", ""))
                type = "ability",
                class = "theme" -- Abilities get theme class by default
            }
         end
         end
        return iconInfo.name
     end
     end
 
   
     -- 2. Dictionary lookup
     -- Process Items
     if iconInfo.key_dictionary and iconInfo.key_dictionary ~= "" then
     for itemKey, item in pairs(itemData) do
        local entry = dictionary[iconInfo.key_dictionary]
        if type(item) == "table" and item.Name then
 
            local name = item.Name
        if type(entry) == "table" then
            local lowerName = name:lower()
             return entry[langCode]
              
                 or entry.en
            lookup[lowerName] = {
                 or iconInfo.name
                 name = name,
                key = itemKey,
                link = name,
                image = name .. ".png",
                 type = "item"
            }
         end
         end
     end
     end
 
   
     -- No valid key > fallback
     iconDataCache = lookup
     return iconInfo.name
     return lookup
end
end


-- Infer link from type and available fields
-- Get icon data by name (with alias support)
local function getLink(iconInfo, langCode)
local function getIconData(iconName)
     if iconInfo.type == "ability" then
     local data = buildIconData()
         local hero = iconInfo.hero_name or iconInfo.name
    local lowerName = iconName:lower()
       
   
        -- Get the translated name for the specific ability
    -- Check main lookup
         local abilityName = getTranslatedName(iconInfo, langCode)
    if data[lowerName] then
          
         return data[lowerName], nil
         -- Format for URL: replace spaces with underscores
    end
         local anchor = abilityName:gsub(" ", "_")
   
          
    -- Check aliases (for edge cases like "doorman" -> "the doorman")
         return hero .. "#" .. anchor
    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 linkOverrides[iconInfo.name] or iconInfo.name
     return nil, string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", iconName)
end
end


-- Returns the canonical display name for a given user input
-- Language handling
-- Used by templates to store the correct casing in data attributes
local function getLangData()
-- Normalizes casing so exact string matches work reliably in Lua modules
     if cachedLangData then
function p.getCanonicalName(frame)
         return cachedLangCode, cachedLangData
    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
     end


     local iconInfo = iconData[lowerName] or legacyItems[lowerName]
     local title = mw.title.getCurrentTitle().fullText
    local subpageLang = title:match("/([^/]+)$")
    local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en"


     -- If unknown, return original input
     local langData = {}
    if not iconInfo then
    if langCode ~= "en" then
         return name
        local success, data = pcall(function()
            return mw.loadJsonData("Data:Lang " .. langCode .. ".json")
        end)
        if success and type(data) == "table" then
            langData = data
         end
     end
     end


-- Quick hack: ability names are used by MediaWiki:Gadget-infobox-tooltip.js and expected to be localized
    cachedLangCode = langCode
     local langCode = getLangCode()
     cachedLangData = langData


     if iconInfo.type == "ability" then
     return langCode, langData
        return getTranslatedName(iconInfo, langCode)
    end
 
    return iconInfo.name
end
end


local function render(name, args)
-- Main render function
     local originalName = name
function p.render(frame)
    local lowerName = name:lower()
     local args = frame:getParent().args
    args = args or {}
     local name = args[1] or ""
 
     local customText = args.l1 or ""
    if renames[lowerName] then
      
        lowerName = renames[lowerName]
    -- Set Defaults
    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"


    -- 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
                 iconOnly = true
                 iconOnly = true
             elseif val == "no-link" then
             elseif val == "no-link" then
                 noLink = true
                 noLink = true
             elseif val:match("^%d+px$") then
             elseif val:match("^%d+px$") then  
                 size = val
                 size = val
             end
             end
Line 170: Line 172:
     end
     end


     local langCode = getLangCode()
    -- Get icon data automatically from JSON
     local iconData, err = getIconData(name)
    if not iconData then
        return "Error: " .. err
    end


     local displayName
    local langCode, langData = getLangData()
     if customText then
   
    -- Determine display name
     local displayName = ""
     if customText ~= "" then
         displayName = customText
         displayName = customText
     elseif renames[name:lower()] then
     elseif iconData.key and langData[iconData.key] then
        -- Preserve original if renamed
         displayName = langData[iconData.key]
         displayName = originalName
     else
     else
         displayName = getTranslatedName(iconInfo, langCode)
         displayName = iconData.name
    end
 
    local baseLink = customLink or getLink(iconInfo, langCode)
    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
     end


     local link = baseLink
    -- Localize link if on translated subpage
    local baseLink = iconData.link or ""
     local link = (langCode ~= "en" and baseLink ~= "") and (baseLink .. "/" .. langCode) or baseLink


     if not customLink and langCode ~= "en" and baseLink ~= "" then
     -- Style logic (only abilities get theme class by default)
        link = baseLink .. "/" .. langCode
    local class = iconData.class or ""
    end
     local extra = (class:find("invert", 1, true) and " filter:invert(1);" or "")
 
    -- Reattach fragment at the end
     link = link .. fragment
 
    -- Add CSS class for abilities
     local style
     local style
     if iconInfo.type == "ability" then
     if class:find("theme", 1, true) then
         style = 'class="module-icon-ability" style="position:relative; bottom:2px;"'
         style = 'class="module-icon-ability" style="position:relative; bottom:2px;' .. extra .. '"'
     else
     else
         style = 'class="c-icon" style="position:relative; bottom:2px;"'
         style = 'style="position:relative; bottom:2px;' .. extra .. '"'
     end
     end


    -- Generate icon HTML
     local imageLink = noLink and "" or link
     local imageLink = noLink and "" or link
     local iconHtml = ""
     local iconHtml = string.format('<span %s>[[File:%s|%s|link=%s]]</span>', style, iconData.image, size, imageLink)
 
    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 222: Line 213:


     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
 
-- Template entrypoint
function p.render(frame)
    local args = frame:getParent().args
    local name = args[1] or ""
 
    return render(name, args)
end
 
-- Module entrypoint
function p._render(name, args)
    return render(name, args)
end
end


return p
return p
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template

Pages included on this page: