Модуль:GetField: различия между версиями
Pok (обсуждение | вклад) Нет описания правки Метка: ручная отмена |
Pok (обсуждение | вклад) Нет описания правки |
||
| Строка 30: | Строка 30: | ||
end | end | ||
local function | local function parse_path(path) | ||
if not | 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 | for i = 1, #parsedPath do | ||
local key | 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 = | 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) | ||
data = data or load_cached_data(moduleName) | |||
if not data then | if not data then | ||
return "" | return "" | ||
| Строка 362: | Строка 423: | ||
local extra = flatten_entry(entry) | local extra = flatten_entry(entry) | ||
local tplStr = "{{" .. | 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 | local v = resolve_path_value(data, idKey, parsedPath) | ||
if type(v) == "table" and v[target] ~= nil then | |||
matches[#matches + 1] = idKey | |||
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 | ||
matches = find_matching_ids(idsTable, keyPath, searchValue) | |||
else | |||
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 | local v = resolve_path_value(data, idKey, parsedPath) | ||
if is_nonempty_value(v) then | |||
matches[#matches + 1] = idKey | |||
end | end | ||
end | end | ||
| Строка 578: | Строка 647: | ||
matches = {} | matches = {} | ||
for _, idKey in ipairs(ids) do | for _, idKey in ipairs(ids) do | ||
local | local v = resolve_path_value(data, idKey, parsedPath) | ||
if type( | if type(v) == "table" and v[target] ~= nil then | ||
local | matches[#matches + 1] = idKey | ||
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 | ||
else | |||
local target = tostring(searchValue) | |||
matches = {} | |||
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 | ||
| Строка 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 | local calls = {} | ||
local | 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 = { | local parts = { makeTemplatePrefix(), "id=" .. id } | ||
if type(obj) == "table" then | if type(obj) == "table" then | ||
local extra = p.flattenParams(obj) | |||
for i = 1, #extra do | |||
parts[#parts + 1] = extra[i] | |||
end | end | ||
elseif obj ~= nil then | elseif obj ~= nil then | ||