Module:Icon: Difference between revisions

Put the "nowrap" around the icon and text – not just icon, it doesn't do anything that way
LVL (talk | contribs)
mNo edit summary
 
(40 intermediate revisions by 6 users not shown)
Line 1: Line 1:
local p = {}
local p = {}


-- Load icon data and language codes
local iconDataRaw = mw.loadJsonData("Data:ResourceLookup.json")
local iconData = require("Module:Icon/data")
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")


-- Per-page cache
local cachedLangCode
local cachedLangCode, cachedLangData


-- Get icon data by name
local linkOverrides = table_data.linkOverrides
local function getIconData(iconName)
local legacyItems = table_data.legacyItems
    local entry = iconData[iconName:lower()]
local missingImageOverrides = table_data.missingImageOverrides
    if entry then
local aliases = table_data.aliases
        return entry, nil
local renames = table_data.renames
    end
    return nil, string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", iconName)
end


-- Get cached or loaded language code and JSON data
local function getLangCode()
local function getLangData()
     if cachedLangCode then
     if cachedLangData then
         return cachedLangCode
         return cachedLangCode, cachedLangData
     end
     end


Line 27: Line 36:
     local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en"
     local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en"


     local langData = {}
     cachedLangCode = langCode
     if langCode ~= "en" then
     return langCode
        local success, data = pcall(function()
end
            return mw.loadJsonData("Data:Lang " .. langCode .. ".json")
 
         end)
-- Infer image path from name, with override support for missing images
         if success and type(data) == "table" then
local function getImage(iconInfo, args)
             langData = data
    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
     end


     cachedLangCode = langCode
     -- 2. Dictionary lookup
     cachedLangData = langData
    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
 
-- 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 langCode, langData
     return iconInfo.name
end
end


-- Main render function
local function render(name, args)
function p.render(frame)
     local originalName = name
     local args = frame:getParent().args
    local lowerName = name:lower()
     local name = args[1] or ""
    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 iconData, err = getIconData(name)
     for k, v in pairs(args) do
     if not iconData then
        if type(k) == "number" and k > 1 then
         return "Error: " .. err
            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 langCode, langData = getLangData()
     local baseLink = customLink or getLink(iconInfo, langCode)
     local hasOnlyImage = iconData.image and iconData.image ~= "" and not iconData.name and not iconData.key and (iconData.link == nil or iconData.link == "") and customText == ""
     local fragment = ""


     -- Use translation if available
     -- Split the fragment (#Abilities) from the base link
local displayName = (iconData.name or (not hasOnlyImage and name)) or ""
    if baseLink:find("#") then
if iconData.key and langData[iconData.key] then
        local parts = mw.text.split(baseLink, "#", true)
    displayName = langData[iconData.key]
        baseLink = parts[1]
end
        fragment = "#" .. (parts[2] or "")
    end


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


     -- Style logic
    if not customLink and langCode ~= "en" and baseLink ~= "" then
     local class = iconData.class or ""
        link = baseLink .. "/" .. langCode
     local style = 'style="position:relative; bottom:2px;"'
    end
     if class == "theme" then
 
     -- 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;"'
         style = 'class="module-icon-ability" style="position:relative; bottom:2px;"'
    else
        style = 'class="c-icon" style="position:relative; bottom:2px;"'
     end
     end


     local finalText = (customText ~= "") and customText or displayName
     local imageLink = noLink and "" or link
     local iconHtml = string.format('<span %s>[[File:%s|%s|link=]]</span>', style, iconData.image, size)
     local iconHtml = ""


if iconOnly or displayName == "" then
    if not noFile then
    return iconHtml
        local image = getImage(iconInfo, args)
end
        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


    local textHtml = (noLink or link == "") and finalText or string.format('[[%s|%s]]', link, finalText)
-- Module entrypoint
     return '<span style="white-space:nowrap;">' .. iconHtml .. " " .. textHtml .. '</span>'
function p._render(name, args)
     return render(name, args)
end
end


return p
return p