Module:Navbox Automatic Groups: Difference between revisions
Appearance
ReisuDesign (talk | contribs) Created page with "local p = {} local PREFIX = '__NAVBOX_AUTO_GROUPS__' local NOGROUP = '[nogroup]' -- Trim a value local function trim(value) return mw.text.trim(tostring(value or '')) end -- Split the groups parameter local function splitGroups(value) local result = {} for _, group in ipairs(mw.text.split(value, ';', true)) do group = trim(group) if group ~= '' then result[#result + 1] = group end end return result end -- Normalize a group name for override matching loc..." |
ReisuDesign (talk | contribs) No edit summary |
||
| (3 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
local PREFIX = '__NAVBOX_AUTO_GROUPS__' | local PREFIX = '__NAVBOX_AUTO_GROUPS__' | ||
local NOGROUP = '[nogroup]' | local NOGROUP = '[nogroup]' | ||
local CONTROL_ARGS = { | |||
groups = true, | |||
base = true, | |||
list = true, | |||
list_type = true, | |||
not_format = true, | |||
start = true | |||
} | |||
-- Trim a value | -- Trim a value | ||
| Line 12: | Line 20: | ||
local function splitGroups(value) | local function splitGroups(value) | ||
local result = {} | local result = {} | ||
for _, group in ipairs(mw.text.split(value, ';', true)) do | for _, group in ipairs(mw.text.split(value, ';', true)) do | ||
group = trim(group) | group = trim(group) | ||
if group ~= '' then | if group ~= '' then | ||
result[#result + 1] = group | result[#result + 1] = group | ||
end | end | ||
end | end | ||
return result | return result | ||
end | end | ||
| Line 34: | Line 45: | ||
end | end | ||
-- | -- Link a group name if the page exists | ||
local function | local function linkGroup(group) | ||
if # | local page = mw.text.decode(group or '') | ||
return '' | local frame = mw.getCurrentFrame() | ||
if page ~= '' | |||
and not page:match('[#<>%[%]{}]+') | |||
and frame:callParserFunction('PROTECTIONEXPIRY:edit', page) ~= '' then | |||
return '[[' .. group .. '|' .. group .. ']]' | |||
end | end | ||
return group | |||
end | end | ||
-- Find list_<group> overrides | -- Find list_<group> overrides | ||
local function getListOverrides( | local function getListOverrides(args) | ||
local overrides = {} | local overrides = {} | ||
for key, value in pairs( | |||
for key, value in pairs(args) do | |||
local groupName = tostring(key):match('^list_(.+)$') | local groupName = tostring(key):match('^list_(.+)$') | ||
if groupName then | if groupName then | ||
overrides[normalizeGroupName(groupName)] = tostring(value) | overrides[normalizeGroupName(groupName)] = tostring(value) | ||
end | end | ||
end | end | ||
return overrides | return overrides | ||
end | |||
-- Build DPL arguments | |||
local function getDplArgs(args, group, exclusions) | |||
local dplArgs = {} | |||
local notFormat = tostring(args.not_format or '%%group%%') | |||
for key, value in pairs(args) do | |||
key = tostring(key) | |||
if not CONTROL_ARGS[key] and not key:match('^list_.+$') then | |||
if type(value) == 'string' then | |||
dplArgs[key] = substituteGroup(value, group) | |||
else | |||
dplArgs[key] = value | |||
end | |||
end | |||
end | |||
-- Add automatically generated DPL exclusions | |||
for i, exclusion in ipairs(exclusions) do | |||
dplArgs['not' .. i] = substituteGroup(notFormat, exclusion) | |||
end | |||
return dplArgs | |||
end | |||
-- Expand Navbox DPL | |||
local function expandDpl(frame, args, group, exclusions) | |||
local dplArgs = getDplArgs(args, group, exclusions) | |||
return frame:expandTemplate{ | |||
title = 'Navbox DPL', | |||
args = dplArgs | |||
} | |||
end | |||
-- Check whether expanded content actually contains anything | |||
local function hasContent(value) | |||
return mw.text.trim(tostring(value or '')) ~= '' | |||
end | end | ||
-- Main | -- Main | ||
function p.main(frame) | function p.main(frame) | ||
local groupsArg = trim( | local args = {} | ||
local base = trim( | |||
local defaultList = tostring( | -- Get arguments passed directly to the module | ||
local start = tonumber(trim( | for key, value in pairs(frame.args) do | ||
args[key] = value | |||
end | |||
-- Get arguments passed through Template:Navbox Automatic Groups | |||
local parent = frame:getParent() | |||
if parent then | |||
for key, value in pairs(parent.args) do | |||
if args[key] == nil then | |||
args[key] = value | |||
end | |||
end | |||
end | |||
local groupsArg = trim(args.groups) | |||
local base = trim(args.base) | |||
local defaultList = tostring(args.list or '') | |||
local listType = mw.ustring.lower(trim(args.list_type)) | |||
local start = tonumber(trim(args.start)) or 1 | |||
if groupsArg == '' then | if groupsArg == '' then | ||
| Line 74: | Line 149: | ||
local groups = splitGroups(groupsArg) | local groups = splitGroups(groupsArg) | ||
local overrides = getListOverrides(args) | |||
local overrides = getListOverrides( | |||
local exclusions = {} | local exclusions = {} | ||
-- Build the list of named groups used for [nogroup] exclusions | |||
for _, group in ipairs(groups) do | for _, group in ipairs(groups) do | ||
if normalizeGroupName(group) ~= normalizeGroupName(NOGROUP) then | if normalizeGroupName(group) ~= normalizeGroupName(NOGROUP) then | ||
| Line 88: | Line 159: | ||
end | end | ||
local rows = {} | local rows = {} | ||
| Line 100: | Line 170: | ||
local overrideKey = normalizeGroupName(isNoGroup and 'nogroup' or group) | local overrideKey = normalizeGroupName(isNoGroup and 'nogroup' or group) | ||
local list = overrides[overrideKey] or defaultList | local list = overrides[overrideKey] | ||
if list == nil then | |||
if listType == 'dpl' then | |||
list = expandDpl( | |||
frame, | |||
args, | |||
targetGroup, | |||
isNoGroup and exclusions or {} | |||
) | |||
else | |||
list = substituteGroup(defaultList, targetGroup) | |||
list = list:gsub('%%%%not%%%%', '') | |||
end | |||
else | |||
list = substituteGroup(list, targetGroup) | |||
list = list:gsub('%%%%not%%%%', '') | |||
end | |||
list | -- Do not create a row when the generated list is empty | ||
if hasContent(list) then | |||
local row = { | |||
list = list | |||
} | |||
-- Link normal group names when the corresponding page exists | |||
if not isNoGroup then | |||
row.group = linkGroup(group) | |||
end | |||
rows[#rows + 1] = row | |||
row | |||
end | end | ||
end | end | ||
Latest revision as of 14:35, 3 September 2026
| Main | Documentation | Usage |
This module implements {{Navbox Automatic Groups}}.
local p = {}
local PREFIX = '__NAVBOX_AUTO_GROUPS__'
local NOGROUP = '[nogroup]'
local CONTROL_ARGS = {
groups = true,
base = true,
list = true,
list_type = true,
not_format = true,
start = true
}
-- Trim a value
local function trim(value)
return mw.text.trim(tostring(value or ''))
end
-- Split the groups parameter
local function splitGroups(value)
local result = {}
for _, group in ipairs(mw.text.split(value, ';', true)) do
group = trim(group)
if group ~= '' then
result[#result + 1] = group
end
end
return result
end
-- Normalize a group name for override matching
local function normalizeGroupName(value)
value = trim(value):gsub('%s+', ' ')
return mw.ustring.lower(value)
end
-- Replace the group placeholder
local function substituteGroup(value, group)
return tostring(value or ''):gsub('%%%%group%%%%', function()
return group
end)
end
-- Link a group name if the page exists
local function linkGroup(group)
local page = mw.text.decode(group or '')
local frame = mw.getCurrentFrame()
if page ~= ''
and not page:match('[#<>%[%]{}]+')
and frame:callParserFunction('PROTECTIONEXPIRY:edit', page) ~= '' then
return '[[' .. group .. '|' .. group .. ']]'
end
return group
end
-- Find list_<group> overrides
local function getListOverrides(args)
local overrides = {}
for key, value in pairs(args) do
local groupName = tostring(key):match('^list_(.+)$')
if groupName then
overrides[normalizeGroupName(groupName)] = tostring(value)
end
end
return overrides
end
-- Build DPL arguments
local function getDplArgs(args, group, exclusions)
local dplArgs = {}
local notFormat = tostring(args.not_format or '%%group%%')
for key, value in pairs(args) do
key = tostring(key)
if not CONTROL_ARGS[key] and not key:match('^list_.+$') then
if type(value) == 'string' then
dplArgs[key] = substituteGroup(value, group)
else
dplArgs[key] = value
end
end
end
-- Add automatically generated DPL exclusions
for i, exclusion in ipairs(exclusions) do
dplArgs['not' .. i] = substituteGroup(notFormat, exclusion)
end
return dplArgs
end
-- Expand Navbox DPL
local function expandDpl(frame, args, group, exclusions)
local dplArgs = getDplArgs(args, group, exclusions)
return frame:expandTemplate{
title = 'Navbox DPL',
args = dplArgs
}
end
-- Check whether expanded content actually contains anything
local function hasContent(value)
return mw.text.trim(tostring(value or '')) ~= ''
end
-- Main
function p.main(frame)
local args = {}
-- Get arguments passed directly to the module
for key, value in pairs(frame.args) do
args[key] = value
end
-- Get arguments passed through Template:Navbox Automatic Groups
local parent = frame:getParent()
if parent then
for key, value in pairs(parent.args) do
if args[key] == nil then
args[key] = value
end
end
end
local groupsArg = trim(args.groups)
local base = trim(args.base)
local defaultList = tostring(args.list or '')
local listType = mw.ustring.lower(trim(args.list_type))
local start = tonumber(trim(args.start)) or 1
if groupsArg == '' then
error('Navbox Automatic Groups: missing groups parameter.')
end
if start < 1 or start % 1 ~= 0 then
error('Navbox Automatic Groups: start must be a positive integer.')
end
local groups = splitGroups(groupsArg)
local overrides = getListOverrides(args)
local exclusions = {}
-- Build the list of named groups used for [nogroup] exclusions
for _, group in ipairs(groups) do
if normalizeGroupName(group) ~= normalizeGroupName(NOGROUP) then
exclusions[#exclusions + 1] = group
end
end
local rows = {}
for _, group in ipairs(groups) do
local isNoGroup = normalizeGroupName(group) == normalizeGroupName(NOGROUP)
local targetGroup = isNoGroup and base or group
if isNoGroup and base == '' then
error('Navbox Automatic Groups: [nogroup] requires a base parameter.')
end
local overrideKey = normalizeGroupName(isNoGroup and 'nogroup' or group)
local list = overrides[overrideKey]
if list == nil then
if listType == 'dpl' then
list = expandDpl(
frame,
args,
targetGroup,
isNoGroup and exclusions or {}
)
else
list = substituteGroup(defaultList, targetGroup)
list = list:gsub('%%%%not%%%%', '')
end
else
list = substituteGroup(list, targetGroup)
list = list:gsub('%%%%not%%%%', '')
end
-- Do not create a row when the generated list is empty
if hasContent(list) then
local row = {
list = list
}
-- Link normal group names when the corresponding page exists
if not isNoGroup then
row.group = linkGroup(group)
end
rows[#rows + 1] = row
end
end
return PREFIX .. mw.text.jsonEncode({
start = start,
rows = rows
})
end
return p