Module:InfoboxItem: Difference between revisions

From Evospace
Jump to navigation Jump to search
No edit summary
Tag: Reverted
Undo revision 5719 by Evospace (talk)
Tag: Undo
 
(One intermediate revision by the same user not shown)
Line 15: Line 15:
     local result = {}
     local result = {}
     if not tbl then return result end
     if not tbl then return result end
     for _, v in pairs(tbl) do
     for k, v in pairs(tbl) do
        -- Каждая строка тоже может быть ассоциативной таблицей
         if type(v) == "table" then
         if type(v) == "table" then
             local name = v[1] or v.name or v["1"]
             local name = v[1] or v.name or v["1"]
             local count = v[2] or v.count or v["2"] or 1
             local count = v[2] or v.count or v["2"] or 1
             if name and name ~= "" then
             table.insert(result, {name, count})
                table.insert(result, {name, count})
            end
         end
         end
     end
     end
Line 70: Line 69:
     local out = {}
     local out = {}
     table.insert(out, '{| class="infobox"')
     table.insert(out, '{| class="infobox"')
    -- Первая строка: объединённая ячейка, иконка + название со ссылками
     table.insert(out, '|-')
     table.insert(out, '|-')
     table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
     table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
         string.format('[[File:%s|64px|link=%s]] [[%s]]', imageName, pageName, pageName))
         string.format('[[File:%s|64px|link=%s]] [[%s]]',
            imageName, pageName, pageName))
 
    -- Остальные поля
     table.insert(out, '|-')
     table.insert(out, '|-')
     table.insert(out, '! Category')
     table.insert(out, '! Category')
Line 83: Line 87:
     table.insert(out, '| ' .. (data.StackSize or ''))
     table.insert(out, '| ' .. (data.StackSize or ''))
     table.insert(out, '|}')
     table.insert(out, '|}')
     return table.concat(out, '\n')
     return table.concat(out, '\n')
end
local function renderRecipeInput(recipe)
    local inputs = normalizeArray(recipe.input)
    local tableNode = mw.html.create("table")
        :addClass("recipe-table")
    local str = ''
    if #inputs > 0 then
        for _, ing in ipairs(inputs) do
            str = str .. string.format("[[File:T_%s.png|22px]]", ing[1]) .. string.format("[[%s]] × %s", splitCamelCase(ing[1]), tostring(ing[2])) .. "\n\n"
        end
    else
        str = str .. "—"
    end
    return str
end
end


Line 97: Line 117:
     end
     end


     local dictName = "Data/" .. itemModule .. "/InOutput"
     local dictName = "Data/"..itemModule.."/InOutput"
 
     local success, recipes = pcall(mw.loadData, "Module:" .. dictName)
     local success, recipes = pcall(mw.loadData, "Module:" .. dictName)
     if not success or type(recipes) ~= "table" or next(recipes) == nil then
     if not success or type(recipes) ~= "table" then
         return ""
         return ""
     end
     end
    -- Берём первый рецепт
    local firstRecipe = recipes[1]
    if not firstRecipe then
        for _, v in pairs(recipes) do
            firstRecipe = v
            break
        end
    end
    if type(firstRecipe) ~= "table" then
        return ""
    end
    local inputs = normalizeArray(firstRecipe.input)


     local pageName = splitCamelCase(itemModule)
     local pageName = splitCamelCase(itemModule)
Line 122: Line 129:
     local out = {}
     local out = {}
     table.insert(out, '{| class="infobox"')
     table.insert(out, '{| class="infobox"')
    -- Первая строка: объединённая ячейка, иконка + название со ссылками
     table.insert(out, '|-')
     table.insert(out, '|-')
     table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
     table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
         string.format('[[File:%s|64px|link=%s]] [[%s]]', imageName, pageName, pageName))
         string.format('[[File:%s|64px|link=%s]] [[%s]]',
    table.insert(out, '|-')
            imageName, pageName, pageName))
    table.insert(out, '! colspan="2" | Recipe input')


     if #inputs == 0 then
     -- Остальные поля
        table.insert(out, '|-')
        table.insert(out, '| colspan="2" style="text-align:center;" | —')
    else
        for _, ing in ipairs(inputs) do
            table.insert(out, '|-')
            table.insert(out, string.format('| [[File:T_%s.png|22px]] || [[%s]] × %s',
                ing[1],
                splitCamelCase(ing[1]),
                tostring(ing[2])
            ))
        end
    end


    table.insert(out, '|-')
    table.insert(out, '| colspan="2" style="text-align:center;" | ' .. renderRecipeInput(recipes[1]))
     table.insert(out, '|}')
     table.insert(out, '|}')
     return table.concat(out, '\n')
     return table.concat(out, '\n')
end
end


return p
return p

Latest revision as of 10:16, 2 August 2025

Documentation for this module may be created at Module:InfoboxItem/doc

-- Module:InfoboxItem
local p = {}

local function safeLoadData(name)
    local success, data = pcall(function()
        return mw.loadData('Module:Data/' .. name)
    end)
    if success and type(data) == "table" then
        return data
    end
    return nil
end

local function normalizeArray(tbl)
    local result = {}
    if not tbl then return result end
    for k, v in pairs(tbl) do
        -- Каждая строка тоже может быть ассоциативной таблицей
        if type(v) == "table" then
            local name = v[1] or v.name or v["1"]
            local count = v[2] or v.count or v["2"] or 1
            table.insert(result, {name, count})
        end
    end
    table.sort(result, function(a,b) return tostring(a[1]) < tostring(b[1]) end)
    return result
end

local function splitCamelCase(str)
    str = str:gsub("_", " ")
    str = str:gsub("(%l)(%u)", "%1 %2")
    str = str:gsub("(%a)(%d)", "%1 %2")
    str = str:gsub("(%d)(%a)", "%1 %2")
    return str
end

function p.show_inline(frame)
    local itemModule = frame.args[1]
    if not itemModule or itemModule == "" then
        return "❌ No data module provided"
    end
    
    local data = safeLoadData(itemModule)
    if not data then
        return ""
    end

    local pageName = splitCamelCase(itemModule)
    local imageName = (data.Image or "") .. ".png"

    return string.format("[[File:%s|32px|link=%s]] [[%s]]",
                         imageName, pageName, pageName);
end

function p.show(frame)
    local itemModule = frame.args[1]
    if not itemModule or itemModule == "" then
        return "❌ No data module provided"
    end
    
    local data = safeLoadData(itemModule)
    if not data then
        return ""
    end

    local pageName = splitCamelCase(itemModule)
    local imageName = (data.Image or "") .. ".png"

    local out = {}
    table.insert(out, '{| class="infobox"')

    -- Первая строка: объединённая ячейка, иконка + название со ссылками
    table.insert(out, '|-')
    table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
        string.format('[[File:%s|64px|link=%s]] [[%s]]',
            imageName, pageName, pageName))

    -- Остальные поля
    table.insert(out, '|-')
    table.insert(out, '! Category')
    table.insert(out, '| ' .. (data.Category or ''))
    table.insert(out, '|-')
    table.insert(out, '! Tier')
    table.insert(out, '| ' .. (data.Tier or ''))
    table.insert(out, '|-')
    table.insert(out, '! Stack size')
    table.insert(out, '| ' .. (data.StackSize or ''))
    table.insert(out, '|}')

    return table.concat(out, '\n')
end

local function renderRecipeInput(recipe)
    local inputs = normalizeArray(recipe.input)
    local tableNode = mw.html.create("table")
        :addClass("recipe-table")
    local str = ''
    if #inputs > 0 then
        for _, ing in ipairs(inputs) do
            str = str .. string.format("[[File:T_%s.png|22px]]", ing[1]) .. string.format("[[%s]] × %s", splitCamelCase(ing[1]), tostring(ing[2])) .. "\n\n"
        end
    else
        str = str .. "—"
    end
    return str
end

function p.show_recipe(frame)
    local itemModule = frame.args[1]
    if not itemModule or itemModule == "" then
        return "❌ No data module provided"
    end
    
    local data = safeLoadData(itemModule)
    if not data then
        return ""
    end

    local dictName = "Data/"..itemModule.."/InOutput"

    local success, recipes = pcall(mw.loadData, "Module:" .. dictName)
    if not success or type(recipes) ~= "table" then
        return ""
    end

    local pageName = splitCamelCase(itemModule)
    local imageName = (data.Image or "") .. ".png"

    local out = {}
    table.insert(out, '{| class="infobox"')

    -- Первая строка: объединённая ячейка, иконка + название со ссылками
    table.insert(out, '|-')
    table.insert(out, '| colspan="2" style="text-align:center;" | ' ..
        string.format('[[File:%s|64px|link=%s]] [[%s]]',
            imageName, pageName, pageName))

    -- Остальные поля

    table.insert(out, '|-')
    table.insert(out, '| colspan="2" style="text-align:center;" | ' .. renderRecipeInput(recipes[1]))
    table.insert(out, '|}')

    return table.concat(out, '\n')
end

return p