Module:ElementNavigation: Difference between revisions
// via Wikitext Extension for VSCode |
// via Wikitext Extension for VSCode |
||
| (8 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
--[[ | --[[ | ||
* Name: ElementNavigation | |||
* Author: Mark W. Datysgeld | |||
* Description: Element module that provides navigation detection and rendering for sequential content in Blueprint templates | |||
* Notes: Automatic detection of previous/next pages based on naming patterns; supports series+number and series+year patterns; configurable field names and styling; designed as Blueprint template system block | |||
]] | ]] | ||
| Line 30: | Line 21: | ||
prevLabel = "← Previous", | prevLabel = "← Previous", | ||
nextLabel = "Next →", | nextLabel = "Next →", | ||
classPrefix = nil, | |||
rowHeight = "40" | rowHeight = "40" | ||
} | } | ||
| Line 38: | Line 30: | ||
-- ========== Navigation Detection ========== | -- ========== Navigation Detection ========== | ||
-- Detect navigation links based on patterns | -- Detect navigation links based on a list of patterns | ||
-- @param pageName string The current page name | -- @param pageName string The current page name | ||
-- @param patterns table | -- @param patterns table A list of patterns to try | ||
-- @return table Navigation result with prev and next properties | -- @return table Navigation result with prev and next properties, or nil | ||
function p.detectNavigation(pageName, patterns) | function p.detectNavigation(pageName, patterns) | ||
local cacheKey = pageName | local cacheKey = pageName | ||
if navigationCache[cacheKey] ~= nil then | if navigationCache[cacheKey] ~= nil then | ||
return navigationCache[cacheKey] | return navigationCache[cacheKey] | ||
end | end | ||
local result = nil | local result = nil | ||
for _, pattern in ipairs(patterns) do | |||
local series, numberStr = pageName:match(pattern) | |||
if series and numberStr then | |||
local number = tonumber(numberStr) | |||
if number then | |||
local prevName = (number > 1) and string.format("%s %d", series, number - 1) or nil | |||
local nextName = string.format("%s %d", series, number + 1) | |||
local prevPage = prevName and mw.title.new(prevName) | |||
local nextPage = mw.title.new(nextName) | |||
result = { | |||
prev = (prevPage and prevPage.exists) and prevName or nil, | |||
next = (nextPage and nextPage.exists) and nextName or nil, | |||
} | |||
break -- Stop after the first successful match | |||
end | |||
end | end | ||
end | end | ||
navigationCache[cacheKey] = result | navigationCache[cacheKey] = result | ||
return result | return result | ||
| Line 93: | Line 66: | ||
-- ========== Blueprint Integration ========== | -- ========== Blueprint Integration ========== | ||
-- Helper function to merge two tables. The custom table's values override the base table's. | |||
local function mergeConfigs(base, custom) | |||
local merged = {} | |||
for k, v in pairs(base) do | |||
merged[k] = v | |||
end | |||
for k, v in pairs(custom) do | |||
merged[k] = v | |||
end | |||
return merged | |||
end | |||
-- Create a navigation block for Blueprint | -- Create a navigation block for Blueprint | ||
| Line 117: | Line 102: | ||
return execute(function() | return execute(function() | ||
-- | -- Merge default and template-specific configurations | ||
local config = template.config.navigation or {} | local config = mergeConfigs(p.defaultConfig, template.config.navigation or {}) | ||
-- | -- Automatic navigation detection | ||
local pageName = mw.title.getCurrentTitle().text | local autoNavigation | ||
if config.autoDetect then | |||
local pageName = mw.title.getCurrentTitle().text | |||
-- The patterns are now expected to be an indexed table for ipairs | |||
local patterns = {config.patterns.seriesNumber, config.patterns.seriesYear} | |||
autoNavigation = p.detectNavigation(pageName, | autoNavigation = p.detectNavigation(pageName, patterns) or {} | ||
else | |||
autoNavigation = {} | |||
end | end | ||
-- | -- Determine final previous and next page links | ||
local | local prevPage = args[config.prevField] or autoNavigation.prev | ||
local nextPage = args[config.nextField] or autoNavigation.next | |||
-- Exit if no navigation links are found | |||
local | if not prevPage and not nextPage then | ||
-- | |||
if | |||
return "" | return "" | ||
end | end | ||
-- | -- Helper to create a navigation link | ||
local function createNavLink(page, label, class) | |||
local | if not page then return '' end | ||
local linkLabel = label:find("%%s") and string.format(label, page) or label | |||
return string.format('<div class="%s">[[%s|%s]]</div>', class, page, linkLabel) | |||
end | end | ||
-- Build the navigation container | |||
-- | |||
local output = { | local output = { | ||
'|-', | '|-', | ||
'| colspan="2" height="' | string.format('| colspan="2" height="%s" valign="middle" |', config.rowHeight), | ||
'<div class="element-navigation-container">' | |||
} | } | ||
local prevLink = createNavLink(prevPage, config.prevLabel, config.prevClass) | |||
local nextLink = createNavLink(nextPage, config.nextLabel, config.nextClass) | |||
table.insert(output, prevLink) | |||
table.insert(output, nextLink) | |||
table.insert(output, '</div>') | table.insert(output, '</div>') | ||
return table.concat(output, | |||
return table.concat(output, '\n') | |||
end) | end) | ||
end | end | ||