Модуль:GetField
Для документации этого модуля может быть создана страница Модуль:GetField/doc
local p = {}
local cache = {}
local entryCache = {}
local function parse_indexed_part(part)
local key, idx = string.match(part, "^(.-)%[(%d+)%]$")
if key then
return key, tonumber(idx)
end
local num = tonumber(part)
if num then
return nil, num
end
return part, nil
end
local function get_by_path(tbl, path)
if not tbl or path == "" then return nil end
local cur = tbl
for part in string.gmatch(path, "([^%.]+)") do
local key, idx = parse_indexed_part(part)
if key and key ~= "" then
if type(cur) ~= "table" then return nil end
local nextCur = cur[key]
if nextCur == nil then
nextCur = cur["!type:" .. key]
end
cur = nextCur
end
if idx then
if type(cur) ~= "table" then return nil end
cur = cur[idx]
end
if cur == nil then return nil end
end
return cur
end
local function is_array(t)
if type(t) ~= "table" then return false end
local max = 0
local count = 0
for k in pairs(t) do
if type(k) ~= "number" then
return false
end
count = count + 1
if k > max then max = k end
end
return max > 0
end
local function format_value(v)
if v == nil then return "" end
local t = type(v)
if t == "string" or t == "number" or t == "boolean" then
return tostring(v)
elseif t == "table" then
local max = 0
local hasNonNumber = false
for k in pairs(v) do
if type(k) ~= "number" then
hasNonNumber = true
break
else
if k > max then max = k end
end
end
if not hasNonNumber and max > 0 then
local out = {}
for i = 1, max do
out[#out+1] = format_value(v[i])
end
return table.concat(out, ", ")
else
local out = {}
for k, val in pairs(v) do
out[#out+1] = tostring(k) .. ": " .. format_value(val)
end
return table.concat(out, ", ")
end
else
return tostring(v)
end
end
function p.get(frame)
local args = frame.args or {}
local id = args[1] or ""
local pagePath = args[2] or ""
local keyPath = args[3] or ""
if pagePath == "" then return "" end
local baseUser = "IanComradeBot/"
local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
local data = cache[moduleName]
if not data then
local ok, loaded = pcall(mw.loadData, moduleName)
if not ok or not loaded then return "" end
data = loaded
cache[moduleName] = data
end
local entryKey = moduleName .. "|" .. (id ~= "" and id or "default")
local entry = entryCache[entryKey]
if not entry then
if id ~= "" then entry = data[id] end
if entry == nil then entry = data["default"] end
entryCache[entryKey] = entry
end
if entry == nil then return "" end
if keyPath == "" then
return format_value(entry)
end
local value = get_by_path(entry, keyPath)
return format_value(value)
end
function p.flattenField(frame)
local args = frame.args or {}
local id = args[1] or ""
local pagePath = args[2] or ""
if id == "" or pagePath == "" then return "" end
local baseUser = "IanComradeBot/"
local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
local data = cache[moduleName]
if not data then
local ok, loaded = pcall(mw.loadData, moduleName)
if not ok or not loaded then return "" end
data = loaded
cache[moduleName] = data
end
local entry = data[id] or data["default"] or {}
if type(entry) ~= "table" then return "" end
local parts = {}
local function walk(tbl, prefix)
local keys = {}
for k in pairs(tbl) do keys[#keys+1] = k end
table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
for _, k in ipairs(keys) do
local v = tbl[k]
local key = (prefix == "" and tostring(k) or prefix .. "." .. tostring(k))
if type(v) == "table" then
walk(v, key)
else
parts[#parts+1] = key .. "=" .. tostring(v)
end
end
end
walk(entry, "")
return table.concat(parts, "|")
end
return p