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

Нет описания правки
Метка: ручная отмена
Нет описания правки
Строка 30: Строка 30:
end
end


local function get_by_path(tbl, path)
local function parse_path(path)
if not tbl or path == "" then
if not path or path == "" then
return nil
end
 
local parsed = {}
for part in string.gmatch(path, "([^%.]+)") do
parsed[#parsed + 1] = { parse_indexed_part(part) }
end
 
return parsed
end
 
local function get_by_parsed_path(tbl, parsedPath)
if not tbl or not parsedPath then
return nil
return nil
end
end


local cur = tbl
local cur = tbl
for part in string.gmatch(path, "([^%.]+)") do
for i = 1, #parsedPath do
local key, idx = parse_indexed_part(part)
local token = parsedPath[i]
local key = token[1]
local idx = token[2]


if key and key ~= "" then
if key and key ~= "" then
Строка 64: Строка 79:


return cur
return cur
end
local function get_by_path(tbl, path)
return get_by_parsed_path(tbl, parse_path(path))
end
end


Строка 162: Строка 181:
if type(base) == "table" then
if type(base) == "table" then
return deep_copy(base)
return deep_copy(base)
end
return nil
end
local function resolve_path_value(data, id, parsedPath)
if type(data) ~= "table" or not parsedPath or not id or id == "" then
return nil
end
local direct = data[id]
if direct ~= nil then
local value = get_by_parsed_path(direct, parsedPath)
if value ~= nil then
return value
end
end
local idsTable = data.id
if type(idsTable) == "table" then
local specific = idsTable[id]
if type(specific) == "table" then
local value = get_by_parsed_path(specific, parsedPath)
if value ~= nil then
return value
end
end
end
local base = data["default"]
if type(base) == "table" then
return get_by_parsed_path(base, parsedPath)
end
end


Строка 224: Строка 275:


local function find_matching_ids(idsTable, keyPath, searchValue)
local function find_matching_ids(idsTable, keyPath, searchValue)
local parsedPath = parse_path(keyPath)
local target = tostring(searchValue)
local target = tostring(searchValue)
local matches = {}
local matches = {}
Строка 229: Строка 281:
for idKey, entry in pairs(idsTable) do
for idKey, entry in pairs(idsTable) do
if type(entry) == "table" then
if type(entry) == "table" then
local v = get_by_path(entry, keyPath)
local v = get_by_parsed_path(entry, parsedPath)
if v ~= nil and contains_target(v, target) then
if v ~= nil and contains_target(v, target) then
matches[#matches + 1] = idKey
matches[#matches + 1] = idKey
Строка 344: Строка 396:
end
end
return table.concat(parts, "|")
return table.concat(parts, "|")
end
local function resolve_template_path(tplPath)
local templatePath = tplPath
local project = JsonPaths.project()
if project ~= nil and project ~= "" then
templatePath = tplPath .. "/" .. project
templatePath = "{{#ifexist:Шаблон:" .. templatePath .. "|" .. templatePath .. "|" .. tplPath .. "}}"
end
return templatePath
end
end


Строка 352: Строка 415:


local moduleName = get_module_name(pagePath)
local moduleName = get_module_name(pagePath)
if not data then
data = data or load_cached_data(moduleName)
data = load_cached_data(moduleName)
end
if not data then
if not data then
return ""
return ""
Строка 362: Строка 423:
local extra = flatten_entry(entry)
local extra = flatten_entry(entry)


local tplStr = "{{" .. tostring(tplPath) .. "|id=" .. tostring(id)
local templatePath = resolve_template_path(tplPath)
 
local tplStr = "{{Шаблон:" .. templatePath .. "|id=" .. tostring(id)
if extra ~= "" then
if extra ~= "" then
tplStr = tplStr .. "|" .. extra
tplStr = tplStr .. "|" .. extra
Строка 481: Строка 544:
end
end


local parsedPath = parse_path(keyPath)
if not parsedPath then
return ""
end
local idsTable = type(data.id) == "table" and data.id or data
local ids = collect_id_keys(data)
local ids = collect_id_keys(data)
if #ids == 0 then
if #ids == 0 then
Строка 491: Строка 560:
matches = {}
matches = {}
for _, idKey in ipairs(ids) do
for _, idKey in ipairs(ids) do
local entry = resolve_entry(data, idKey)
local v = resolve_path_value(data, idKey, parsedPath)
if type(entry) == "table" then
if type(v) == "table" and v[target] ~= nil then
local v = get_by_path(entry, keyPath)
matches[#matches + 1] = idKey
if type(v) == "table" and v[target] ~= nil then
matches[#matches + 1] = idKey
end
end
end
end
end
Строка 502: Строка 568:
local target = tostring(searchValue)
local target = tostring(searchValue)
matches = {}
matches = {}
for _, idKey in ipairs(ids) do
if idsTable == data then
local entry = resolve_entry(data, idKey)
matches = find_matching_ids(idsTable, keyPath, searchValue)
if type(entry) == "table" then
else
local v = get_by_path(entry, keyPath)
for _, idKey in ipairs(ids) do
local v = resolve_path_value(data, idKey, parsedPath)
if v ~= nil and contains_target(v, target) then
if v ~= nil and contains_target(v, target) then
matches[#matches + 1] = idKey
matches[#matches + 1] = idKey
Строка 554: Строка 621:
local data = load_cached_data(moduleName)
local data = load_cached_data(moduleName)
if not data then
if not data then
return ""
end
local parsedPath = parse_path(keyPath)
if not parsedPath then
return ""
return ""
end
end
Строка 566: Строка 638:
matches = {}
matches = {}
for _, idKey in ipairs(ids) do
for _, idKey in ipairs(ids) do
local entry = resolve_entry(data, idKey)
local v = resolve_path_value(data, idKey, parsedPath)
if type(entry) == "table" then
if is_nonempty_value(v) then
local v = get_by_path(entry, keyPath)
matches[#matches + 1] = idKey
if is_nonempty_value(v) then
matches[#matches + 1] = idKey
end
end
end
end
end
Строка 578: Строка 647:
matches = {}
matches = {}
for _, idKey in ipairs(ids) do
for _, idKey in ipairs(ids) do
local entry = resolve_entry(data, idKey)
local v = resolve_path_value(data, idKey, parsedPath)
if type(entry) == "table" then
if type(v) == "table" and v[target] ~= nil then
local v = get_by_path(entry, keyPath)
matches[#matches + 1] = idKey
if type(v) == "table" and v[target] ~= nil then
end
end
else
local idsTable = data.id
if type(idsTable) == "table" then
local directMatches = find_matching_ids(idsTable, keyPath, searchValue)
local defaultValue = nil
local includeDefault = false
local base = data["default"]
if type(base) == "table" then
defaultValue = get_by_parsed_path(base, parsedPath)
includeDefault = defaultValue ~= nil and contains_target(defaultValue, tostring(searchValue))
end
 
if includeDefault and #directMatches < #ids then
local seen = {}
for i = 1, #directMatches do
seen[directMatches[i]] = true
end
 
matches = {}
for _, idKey in ipairs(directMatches) do
matches[#matches + 1] = idKey
matches[#matches + 1] = idKey
end
end
for _, idKey in ipairs(ids) do
if not seen[idKey] then
local specific = idsTable[idKey]
local specificValue = type(specific) == "table" and get_by_parsed_path(specific, parsedPath) or nil
if specificValue == nil then
matches[#matches + 1] = idKey
end
end
end
else
matches = directMatches
end
end
end
else
else
local target = tostring(searchValue)
local target = tostring(searchValue)
matches = {}
matches = {}
for _, idKey in ipairs(ids) do
for _, idKey in ipairs(ids) do
local v = resolve_path_value(data, idKey, parsedPath)
local entry = resolve_entry(data, idKey)
if type(entry) == "table" then
local v = get_by_path(entry, keyPath)
if v ~= nil and contains_target(v, target) then
if v ~= nil and contains_target(v, target) then
matches[#matches + 1] = idKey
matches[#matches + 1] = idKey
Строка 838: Строка 936:
local jsonStr = mw.text.unstripNoWiki(args[1] or args.json or "")
local jsonStr = mw.text.unstripNoWiki(args[1] or args.json or "")
local tplPath = mw.text.unstripNoWiki(args[2] or args.template or "")
local tplPath = mw.text.unstripNoWiki(args[2] or args.template or "")
if jsonStr == "" or tplPath == "" then
if jsonStr == "" or tplPath == "" then
return ""
return ""
Строка 847: Строка 946:
end
end


local okDp, dp = pcall(require, "Module:GetField")
local calls = {}


local calls = {}
local function makeTemplatePrefix()
return "{{Шаблон:" .. resolve_template_path(tplPath)
end


local function makeCall(id, obj)
local function makeCall(id, obj)
Строка 856: Строка 957:
end
end


local parts = { "{{" .. tplPath, "id=" .. id }
local parts = { makeTemplatePrefix(), "id=" .. id }


if type(obj) == "table" then
if type(obj) == "table" then
if okDp and dp and type(dp.flattenParams) == "function" then
local extra = p.flattenParams(obj)
local extra = dp.flattenParams(obj)
for i = 1, #extra do
for i = 1, #extra do
parts[#parts + 1] = extra[i]
parts[#parts + 1] = extra[i]
end
else
for k, v in pairs(obj) do
if v ~= nil then
parts[#parts + 1] = tostring(k) .. "=" .. tostring(v)
end
end
end
end
elseif obj ~= nil then
elseif obj ~= nil then