Module:PageContext
Documentation for this module may be created at Module:PageContext/doc
-- Module:PageContext
-- Centralized EDFM page section resolver for Article header eyebrows.
-- Keep page-specific overrides small; prefer structured datasets and family rules.
local p = {}
local config = mw.loadData('Module:Data/PageSections')
local cache = {}
local function trim(value)
return mw.text.trim(tostring(value or ''))
end
local function isNonEmpty(value)
return value ~= nil and trim(value) ~= ''
end
local function normalizeTitle(pageName)
if isNonEmpty(pageName) then
local t = mw.title.new(trim(pageName))
return t and t.text or trim(pageName)
end
return mw.title.getCurrentTitle().text
end
local function loadLuaData(title)
local ok, data = pcall(mw.loadData, title)
if ok and type(data) == 'table' then return data end
return nil
end
local function loadJsonPage(titleText)
local title = mw.title.new(titleText)
local content = title and title:getContent()
if not content then return nil end
local ok, data = pcall(mw.text.jsonDecode, content)
if ok and type(data) == 'table' then return data end
return nil
end
local function listContains(list, title)
if type(list) ~= 'table' then return false end
for _, value in ipairs(list) do
if value == title then return true end
end
return false
end
local function pageInEngineers(title)
local index = loadJsonPage('Module:Data/Engineers/index')
return listContains(index, title)
end
local function pageInShipModules(title)
local index = loadLuaData('Module:Data/ShipModules/index')
return listContains(index, title)
end
local function pageInModulesJson(title)
local index = loadJsonPage('Module:Data/Modules/index')
if type(index) ~= 'table' or type(index.modules) ~= 'table' then return false end
for _, record in pairs(index.modules) do
if type(record) == 'table' and (record.page == title or record.name == title) then
return true
end
end
return false
end
local function pageInMiningDataset(title, dataTitle, field)
local data = loadLuaData(dataTitle)
if type(data) ~= 'table' then return false end
for _, record in ipairs(data) do
if type(record) == 'table' and (record[field or 'page'] == title or record.page == title or record.label == title or record.title == title) then
return true
end
end
return false
end
local function guardianLike(title)
return title:find('Guardian', 1, true) ~= nil or title:find('Nanite Torpedo', 1, true) ~= nil
end
local function thargoidLike(title)
return title:find('Thargoid', 1, true) ~= nil or title:find('Xeno', 1, true) ~= nil or title:find('AX ', 1, true) ~= nil or title:find('Caustic', 1, true) ~= nil
end
local function startsWith(value, prefix)
return value:sub(1, #prefix) == prefix
end
local function typeToSection(pageType)
return config.typeToSection and config.typeToSection[pageType]
end
function p.getPageTypeValue(pageName)
local title = normalizeTitle(pageName)
if cache['type:' .. title] then return cache['type:' .. title] end
local pageType = nil
if pageInEngineers(title) then
pageType = 'engineer'
elseif pageInMiningDataset(title, 'Module:Data/Mining/Methods') then
pageType = 'mining_method'
elseif pageInMiningDataset(title, 'Module:Data/Mining/Equipment') then
pageType = 'mining_equipment'
elseif pageInMiningDataset(title, 'Module:Data/Mining/Locations') then
pageType = 'mining_location'
elseif pageInMiningDataset(title, 'Module:Data/Mining/Commodities') then
pageType = 'mining_commodity'
elseif pageInMiningDataset(title, 'Module:Data/Procedures/Mining', 'page') then
pageType = 'field_procedure'
elseif pageInShipModules(title) or pageInModulesJson(title) then
if guardianLike(title) then
pageType = 'guardian_module'
elseif thargoidLike(title) then
pageType = 'thargoid_module'
else
pageType = 'ship_module'
end
end
cache['type:' .. title] = pageType or ''
return pageType
end
function p.getSectionValue(pageName, override)
local title = normalizeTitle(pageName)
if isNonEmpty(override) then return trim(override) end
local key = 'section:' .. title
if cache[key] then return cache[key] end
local section = nil
local exact = config.exactSections or {}
if exact[title] then
section = exact[title]
else
local pageType = p.getPageTypeValue(title)
section = typeToSection(pageType)
end
if not section then
for _, rule in ipairs(config.familyRules or {}) do
if rule.prefix and startsWith(title, rule.prefix) then
section = rule.section
break
end
end
end
if not section then
for _, rule in ipairs(config.titleContainsRules or {}) do
if rule.text and title:find(rule.text, 1, true) then
section = rule.section
break
end
end
end
section = section or config.fallback or 'Reference'
cache[key] = section
return section
end
function p.getPageType(frame)
local args = frame.args or {}
return p.getPageTypeValue(args.page or args[1]) or ''
end
function p.getSection(frame)
local args = frame.args or {}
return p.getSectionValue(args.page or args[1], args.section or args.override)
end
function p.eyebrow(frame)
local args = frame.args or {}
return 'EDFM // ' .. p.getSectionValue(args.page or args[1], args.section or args.override)
end
return p