Модуль:Сущность/data: различия между версиями

Нет описания правки
Нет описания правки
 
(не показаны 2 промежуточные версии этого же участника)
Строка 4: Строка 4:


local moduleDataCache = {}
local moduleDataCache = {}
local templateContentCache = {}
local templateMetaCache = {}
local templateArgCache = {}
local flattenExtraCache = {}
local switchModeRegistry = {}
local switchModeRegistry = {}
local switchModeOrder = {}
local switchModeOrder = {}
Строка 30: Строка 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
Строка 48: Строка 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


Строка 113: Строка 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
Строка 124: Строка 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
Строка 141: Строка 200:
     local parts = {}
     local parts = {}


    -- id сущности
     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)
Строка 152: Строка 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)
Строка 172: Строка 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
Строка 326: Строка 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,
Строка 340: Строка 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
Строка 359: Строка 419:
     end
     end


    templateMetaCache[tplPath] = data
     return data
     return data
end
end
Строка 451: Строка 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


Строка 494: Строка 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
Строка 509: Строка 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
Строка 522: Строка 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)
Строка 530: Строка 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")
    local componentStoreDefs = load_module_data("component_store.json")
     if not componentDefs or not prototypeStoreDefs then return "" end
     if not componentDefs or not prototypeStoreDefs or not componentStoreDefs then return "" end


     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents,
     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents,
Строка 562: Строка 647:


         local extra = ""
         local extra = ""
         if ok and dp and dp.flattenField then
        local paramNames = get_template_params(tplPath, content)
         if ok and dp then
             local dataPage = tplPath .. ".json"
             local dataPage = tplPath .. ".json"
             extra = dp.flattenField({ args = { id, dataPage } })
             extra = get_selective_extra(dp, id, dataPage, paramNames)
         end
         end


Строка 583: Строка 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]
Строка 607: Строка 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)
Строка 619: Строка 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)
Строка 643: Строка 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)