Module:Navlists
Module:Navlists
This module generates lists of page links from one or more categories, optionally including subcategories (recursively).
Functions
listFromCategory
- Returns a dot-separated list of pages from a category.
1
– Category name (without theCategory:
prefix).separator
(optional) – String used to separate items. Default:•
.
Basic usage
{{#invoke:Navlists|listFromCategory|Characters}}
Returns all pages in Category:Characters and its subcategories.
Custom separator
{{#invoke:Navlists|listFromCategory|Characters|separator=, }}
Notes
- Redirects are excluded.
- The function detects and avoids category loops.
- Subcategories are detected recursively.
- You can create wrapper templates (e.g.,
Template:NavlistMainCast
) for use in navboxes.
See also
local p = {}
-- Build absolute API URL for this wiki
local function apiEndpoint()
-- Works on standard setups; adjust if you serve from a subdir
return (mw.site.server or "") .. (mw.site.scriptPath or "") .. "/api.php"
end
-- GET wrapper with JSON decode
local function apiQuery(params)
params.format = "json"
local url = apiEndpoint() .. "?" .. mw.uri.buildQueryString(params)
local res = mw.http.fetch(url)
if not res or res.status ~= 200 then
error("Navlists: API HTTP error " .. tostring(res and res.status))
end
return mw.text.jsonDecode(res.body)
end
-- Recursively gather pages from a category and its subcategories
local function gather(catTitle, visited, out)
visited = visited or {}
out = out or {}
if visited[catTitle] then return out end
visited[catTitle] = true
local cont = nil
repeat
local params = {
action = "query",
list = "categorymembers",
cmtitle = catTitle, -- e.g. "Category:Characters"
cmtype = "page|subcat",
cmlimit = "500",
}
if cont then params.cmcontinue = cont end
local data = apiQuery(params)
local members = (data.query and data.query.categorymembers) or {}
for _, m in ipairs(members) do
if m.ns == 14 then
-- Category (ns 14): recurse into it
gather(m.title, visited, out)
else
-- Regular page
table.insert(out, string.format("[[%s]]", m.title))
end
end
cont = data.continue and data.continue.cmcontinue
until not cont
return out
end
-- Public: {{#invoke:Navlists|listFromCategory|CategoryName|separator= • }}
function p.listFromCategory(frame)
local cat = frame.args[1] or frame:getParent().args[1]
if not cat or cat == "" then return "" end
-- Accept "Characters" or "Category:Characters"
if not cat:match("^[Cc]ategory:") then
cat = "Category:" .. cat
end
local sep = frame.args.separator or frame:getParent().args.separator or " • "
local links = gather(cat, {}, {})
table.sort(links, function(a, b)
-- sort on display title without brackets
return mw.ustring.lower(a:gsub("[%[%]]", "")) < mw.ustring.lower(b:gsub("[%[%]]", ""))
end)
return table.concat(links, sep)
end
return p