Модуль:GetField: различия между версиями

Нет описания правки
Нет описания правки
Строка 72: Строка 72:
end
end


function p.findInPrototype(frame)
local function deep_copy(src)
    local dst = {}
    for k, v in pairs(src) do
        if type(v) == "table" then
            dst[k] = deep_copy(v)
        else
            dst[k] = v
        end
    end
    return dst
end
 
local function deep_merge(dst, src)
    for k, v in pairs(src) do
        if type(v) == "table" and type(dst[k]) == "table" then
            deep_merge(dst[k], v)
        elseif type(v) == "table" then
            dst[k] = deep_copy(v)
        else
            dst[k] = v
        end
    end
end
 
function p.findInProto(frame)
     local args = frame.args or {}
     local args = frame.args or {}
     local searchId = args[1] or ""
     local protoKey = args[1] or ""
     local protoId = args[2] or ""
     local fieldId = args[2] or ""


     if searchId == "" or protoId == "" then
     if protoKey == "" or fieldId == "" then
         return "[]"
         return "[]"
     end
     end
Строка 93: Строка 117:
     end
     end


     local proto = data[protoId]
     local proto = data[protoKey]
     if type(proto) ~= "table" then
     if type(proto) ~= "table" then
         return "[]"
         return "[]"
     end
     end


     local foundFields = {}
     local value = proto[fieldId]
     for fieldName, value in pairs(proto) do
     if value == nil then
        local matched = false
         return "[]"
        local t = type(value)
    end
        if t == "string" then
            if value == searchId then
                matched = true
            end
         elseif t == "table" then
            for _, v in ipairs(value) do
                if v == searchId then
                    matched = true
                    break
                end
            end
        end


        if matched then
    local out = {}
            table.insert(foundFields, fieldName)
    local t = type(value)
    if t == "table" then
        for _, v in ipairs(value) do
            out[#out + 1] = v
         end
         end
    else
        out[1] = value
     end
     end


     return mw.text.jsonEncode(foundFields)
     return mw.text.jsonEncode(out)
end
end


Строка 140: Строка 157:
     end
     end


     local entry = data[id] or data["default"] or {}
     local entry = data[id]
 
    if entry == nil then
        local idsTable = data.id
        if type(idsTable) == "table" then
            local specific = idsTable[id]
            if type(specific) == "table" then
                local base = data["default"]
                if type(base) == "table" then
                    local merged = deep_copy(base)
                    deep_merge(merged, specific)
                    entry = merged
                else
                    entry = deep_copy(specific)
                end
            end
        end
    end
 
    if entry == nil then
        local base = data["default"]
        if type(base) == "table" then
            entry = deep_copy(base)
        else
            entry = {}
        end
    end
 
     if type(entry) ~= "table" then return "" end
     if type(entry) ~= "table" then return "" end


Строка 223: Строка 267:
     local searchId = args[1] or ""
     local searchId = args[1] or ""
     local protoId = args[2] or ""
     local protoId = args[2] or ""
     local tplPath = args[4] or ""
     local tplPath = args[3] or ""
    local pagePath = "prototype/" .. protoId .. ".json"


     if searchId == "" or protoId == "" or tplPath == "" then
     if searchId == "" or protoId == "" or tplPath == "" then
Строка 229: Строка 274:
     end
     end


     local fieldsJson = p.findInPrototype({ args = { searchId, protoId } })
     local idsJson = p.findInProto({ args = { searchId, protoId } })
     local ok, fields = pcall(mw.text.jsonDecode, fieldsJson or "")
     local ok, ids = pcall(mw.text.jsonDecode, idsJson or "")
     if not ok or type(fields) ~= "table" or #fields == 0 then
     if not ok or type(ids) ~= "table" or #ids == 0 then
         return ""
         return ""
     end
     end


     local out = {}
     local out = {}
     for _ = 1, #fields do
     for _, id in ipairs(ids) do
         local tpl = p.getTpl({ args = { searchId, protoId, tplPath } })
         local tpl = p.getTpl({ args = { id, pagePath, tplPath } })
         if tpl ~= "" then
         if tpl ~= "" then
             out[#out + 1] = tpl
             out[#out + 1] = tpl