Модуль:Сущность/data: различия между версиями
Pok (обсуждение | вклад) Новая страница: «local p = {} local getArgs = require('Module:Arguments').getArgs local BASE_USER = "IanComradeBot/" local moduleDataCache = {} local switchModeRegistry = {} local switchModeOrder = {} local function trim(s) if not s then return s end return (s:gsub("^%s*(.-)%s*$", "%1")) end local function load_module_data(page) local moduleName = "Module:" .. BASE_USER .. page .. "/data" if moduleDataCache[moduleName] ~= nil then return moduleDataC...» |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показаны 4 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
local p = {} | local p = {} | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local | local JsonPaths = require('Module:JsonPaths') | ||
local moduleDataCache = {} | local moduleDataCache = {} | ||
local templateContentCache = {} | |||
local templateMetaCache = {} | |||
local templateArgCache = {} | |||
local flattenExtraCache = {} | |||
local switchModeRegistry = {} | local switchModeRegistry = {} | ||
local switchModeOrder = {} | local switchModeOrder = {} | ||
| Строка 12: | Строка 17: | ||
local function load_module_data(page) | local function load_module_data(page) | ||
local moduleName = | local moduleName = JsonPaths.get(page) | ||
if moduleDataCache[moduleName] ~= nil then | if moduleDataCache[moduleName] ~= nil then | ||
return moduleDataCache[moduleName] | return moduleDataCache[moduleName] | ||
end | end | ||
local ok, data = pcall(mw.loadData, moduleName) | local ok, data = pcall(mw.loadData, moduleName) | ||
if not ok then | if not ok then | ||
| Строка 21: | Строка 28: | ||
return nil | return nil | ||
end | end | ||
moduleDataCache[moduleName] = data | moduleDataCache[moduleName] = data | ||
return data | return data | ||
| Строка 26: | Строка 34: | ||
local function load_template_content(path) | local function load_template_content(path) | ||
if templateContentCache[path] ~= nil then | |||
return templateContentCache[path] or nil | |||
end | |||
local title = mw.title.new("Template:" .. path) | local title = mw.title.new("Template:" .. path) | ||
if not title then return nil end | if not title then | ||
templateContentCache[path] = false | |||
return nil | |||
end | |||
local ok, content = pcall(function() return title:getContent() end) | local ok, content = pcall(function() return title:getContent() end) | ||
if not ok then return nil end | if not ok then | ||
templateContentCache[path] = false | |||
return nil | |||
end | |||
templateContentCache[path] = content or false | |||
return content | return content | ||
end | end | ||
| Строка 44: | Строка 64: | ||
tplStr = tplStr .. "}}" | tplStr = tplStr .. "}}" | ||
return tplStr | return tplStr | ||
end | |||
local function add_template_param(params, seen, raw) | |||
local param = trim(raw or "") | |||
if param == "" or param == "id" or param:match("^%d+$") then | |||
return | |||
end | |||
if not seen[param] then | |||
seen[param] = true | |||
params[#params + 1] = param | |||
end | |||
end | |||
local function collect_template_params(content) | |||
local params = {} | |||
local seen = {} | |||
if not content or content == "" then | |||
return params | |||
end | |||
for param in content:gmatch("{{{%s*([^|}]+)%s*|") do | |||
add_template_param(params, seen, param) | |||
end | |||
for param in content:gmatch("{{{%s*([^|}]+)%s*}}") do | |||
add_template_param(params, seen, param) | |||
end | |||
return params | |||
end | |||
local function get_template_params(tplPath, content) | |||
local cached = templateArgCache[tplPath] | |||
if cached ~= nil then | |||
return cached | |||
end | |||
local params = collect_template_params(content) | |||
templateArgCache[tplPath] = params | |||
return params | |||
end | end | ||
| Строка 109: | Строка 169: | ||
end | end | ||
local function renderTitleBlock(key, tplCalls, sources, includeHeader, frame) | local function renderTitleBlock(key, tplCalls, sources, includeHeader, frame, showSource) | ||
local parts = {} | local parts = {} | ||
if tplCalls and #tplCalls > 0 then | if tplCalls and #tplCalls > 0 then | ||
| Строка 120: | Строка 180: | ||
if add then | if add then | ||
local src = sources and sources[i] | local src = sources and sources[i] | ||
local line = '<div>' .. tpl .. '</div><div class="ts-Сущность-field">' .. makeSourceLink(src) .. '</div>' | local line = '<div>' .. tpl .. '</div>' | ||
if showSource and src then | |||
line = line .. '<div class="ts-Сущность-field">' .. makeSourceLink(src) .. '</div>' | |||
end | |||
table.insert(parts, '<div class="ts-Сущность">' .. line .. '</div>') | table.insert(parts, '<div class="ts-Сущность">' .. line .. '</div>') | ||
end | end | ||
| Строка 137: | Строка 200: | ||
local parts = {} | local parts = {} | ||
if entityId and entityId ~= "" then | if entityId and entityId ~= "" then | ||
parts[#parts + 1] = "id=" .. mw.text.encode(entityId) | parts[#parts + 1] = "id=" .. mw.text.encode(entityId) | ||
end | end | ||
if merged.tags and #merged.tags > 0 then | if merged.tags and #merged.tags > 0 then | ||
table.sort(merged.tags) | table.sort(merged.tags) | ||
| Строка 148: | Строка 209: | ||
end | end | ||
if merged.sections and #merged.sections > 0 then | if merged.sections and #merged.sections > 0 then | ||
table.sort(merged.sections, function(a, b) | table.sort(merged.sections, function(a, b) | ||
| Строка 168: | Строка 228: | ||
end | end | ||
for compositeKey, displayLabel in pairs(merged.labelOverrides or {}) do | for compositeKey, displayLabel in pairs(merged.labelOverrides or {}) do | ||
if displayLabel and displayLabel ~= "" then | if displayLabel and displayLabel ~= "" then | ||
| Строка 322: | Строка 381: | ||
} | } | ||
end, | end, | ||
render_key = function(frame, key, entries, noHeaders) | render_key = function(frame, key, entries, noHeaders, showSource) | ||
local tplCalls, sources = collect_tpl_calls(entries) | local tplCalls, sources = collect_tpl_calls(entries) | ||
return renderTitleBlock(key, tplCalls, sources, not noHeaders, frame) | return renderTitleBlock(key, tplCalls, sources, not noHeaders, frame, showSource) | ||
end | end | ||
}) | }) | ||
local function getTemplateMeta(frame, tplPath) | local function getTemplateMeta(frame, tplPath) | ||
if templateMetaCache[tplPath] ~= nil then | |||
return templateMetaCache[tplPath] or "" | |||
end | |||
local expanded = frame:expandTemplate { | local expanded = frame:expandTemplate { | ||
title = tplPath, | title = tplPath, | ||
| Строка 336: | Строка 399: | ||
local ok, data = pcall(mw.text.jsonDecode, expanded) | local ok, data = pcall(mw.text.jsonDecode, expanded) | ||
if not ok or type(data) ~= "table" then | if not ok or type(data) ~= "table" then | ||
templateMetaCache[tplPath] = false | |||
return "" | return "" | ||
end | end | ||
| Строка 355: | Строка 419: | ||
end | end | ||
templateMetaCache[tplPath] = data | |||
return data | return data | ||
end | end | ||
| Строка 447: | Строка 512: | ||
end | end | ||
return basePriority | return basePriority | ||
end | |||
local function get_selective_extra(dp, id, dataPage, paramNames) | |||
if not dp or type(dp.flattenFieldSelective) ~= "function" then | |||
return "" | |||
end | |||
if type(paramNames) ~= "table" or #paramNames == 0 then | |||
return "" | |||
end | |||
local okJson, keysJson = pcall(mw.text.jsonEncode, paramNames) | |||
if not okJson or not keysJson or keysJson == "" then | |||
return "" | |||
end | |||
local cacheKey = dataPage .. "\31" .. id .. "\31" .. keysJson | |||
if flattenExtraCache[cacheKey] ~= nil then | |||
return flattenExtraCache[cacheKey] | |||
end | |||
local extra = dp.flattenFieldSelective({ args = { id, dataPage, keysJson } }) or "" | |||
flattenExtraCache[cacheKey] = extra | |||
return extra | |||
end | end | ||
| Строка 490: | Строка 578: | ||
end | end | ||
local function renderBlocks(frame, state, noHeaders, entityId) | local function renderBlocks(frame, state, noHeaders, entityId, showSource) | ||
local outLocal = {} | local outLocal = {} | ||
for _, sw in ipairs(switchModeOrder) do | for _, sw in ipairs(switchModeOrder) do | ||
| Строка 505: | Строка 593: | ||
local entries = state.keyToTemplates[sw][key] or {} | local entries = state.keyToTemplates[sw][key] or {} | ||
if type(mode.render_key) == "function" then | if type(mode.render_key) == "function" then | ||
local outStr = mode.render_key(frame, key, entries, noHeaders) | local outStr = mode.render_key(frame, key, entries, noHeaders, showSource) | ||
if outStr and outStr ~= "" then table.insert(outLocal, outStr) end | if outStr and outStr ~= "" then table.insert(outLocal, outStr) end | ||
end | end | ||
| Строка 518: | Строка 606: | ||
local id = args[1] or "" | local id = args[1] or "" | ||
if id == "" then return "" end | if id == "" then return "" end | ||
local showSource = trim(args.showSource or "") == "" | |||
local filter = build_key_filter(args) | local filter = build_key_filter(args) | ||
| Строка 526: | Строка 616: | ||
local componentDefs = load_module_data("component.json") | local componentDefs = load_module_data("component.json") | ||
local prototypeStoreDefs = load_module_data("prototype_store.json") | local prototypeStoreDefs = load_module_data("prototype_store.json") | ||
if not componentDefs or not prototypeStoreDefs then return "" end | |||
if not componentDefs or not prototypeStoreDefs | |||
local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents, | local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents, | ||
| Строка 558: | Строка 647: | ||
local extra = "" | local extra = "" | ||
if ok and dp | local paramNames = get_template_params(tplPath, content) | ||
if ok and dp then | |||
local dataPage = tplPath .. ".json" | local dataPage = tplPath .. ".json" | ||
extra = dp | extra = get_selective_extra(dp, id, dataPage, paramNames) | ||
end | end | ||
| Строка 579: | Строка 669: | ||
end | end | ||
local componentStoreDefs = load_module_data("component_store.json") | |||
if type(componentStoreDefs) == "table" then | if type(componentStoreDefs) == "table" then | ||
local compStore = componentStoreDefs[id] | local compStore = componentStoreDefs[id] | ||
| Строка 603: | Строка 694: | ||
end | end | ||
local blocks = renderBlocks(frame, state, filter.hasWhitelist, id) | local blocks = renderBlocks(frame, state, filter.hasWhitelist, id, showSource) | ||
for _, b in ipairs(blocks) do | for _, b in ipairs(blocks) do | ||
table.insert(out, b) | table.insert(out, b) | ||
| Строка 615: | Строка 706: | ||
local tplPath = args[1] or "" | local tplPath = args[1] or "" | ||
if tplPath == "" then return "" end | if tplPath == "" then return "" end | ||
local showSource = trim(args.nosource or "") == "" | |||
local content = load_template_content(tplPath) | local content = load_template_content(tplPath) | ||
| Строка 639: | Строка 732: | ||
local out = {} | local out = {} | ||
local blocks = renderBlocks(frame, state, hasWhitelist, "") | local blocks = renderBlocks(frame, state, hasWhitelist, "", showSource) | ||
for _, b in ipairs(blocks) do | for _, b in ipairs(blocks) do | ||
table.insert(out, b) | table.insert(out, b) | ||