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

Новая страница: «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...»
 
Нет описания правки
 
(не показаны 4 промежуточные версии этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local BASE_USER = "IanComradeBot/"
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 = "Module:" .. BASE_USER .. page .. "/data"
     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 = {}


    -- 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)
Строка 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")
    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,
Строка 558: Строка 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


Строка 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)