Module:Category handler: Difference between revisions

Ganaram inukshuk (talk | contribs)
No edit summary
Ganaram inukshuk (talk | contribs)
rollback to previously working code
Line 1: Line 1:
-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]]
-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]]
local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")
local yesno = require("Module:Yesno")


Line 7: Line 6:
-- Basic category handler, based on Wikipedia's category handler. It categorizes
-- Basic category handler, based on Wikipedia's category handler. It categorizes
-- pages, given a table of categories as input, and suppresses categorization if
-- pages, given a table of categories as input, and suppresses categorization if
-- the page is in the table of excluded namespaces.
-- the page is in the table of excluded namespaces, or table of excluded
-- suffixes (subpages).
-- The most common categorizing templates that have/require complex rules are:
-- The most common categorizing templates that have/require complex rules are:
-- - Infoboxes; these usually shouldn't categorize if they're outside the main
-- - Infoboxes; these usually shouldn't categorize if they're outside the main
Line 47: Line 47:
-- Helper function: check if current namespace is excluded
-- Helper function: check if current namespace is excluded
-- Accepts an optional table, containing or overriding other namespaces' rules
-- Accepts an optional table, containing or overriding other namespaces' rules
local function is_suppressed_namespace(title, ns_override)
local function is_suppressed_namespace(ns_override)
local ns_text
-- Get current namespace, as lowercase
 
local curr_ns = mw.ustring.lower(mw.title.getCurrentTitle().nsText or '')
if type(title) == "table" and title.nsText then
ns_text = mw.ustring.lower(title.nsText or '')
-- Build table of suppressed namespaces; start with default list
elseif type(title) == "string" then
ns_text = mw.ustring.lower(title)
else
ns_text = mw.ustring.lower(mw.title.getCurrentTitle().nsText or '')
end
 
local namespaces = {}
local namespaces = {}
for k, v in pairs(DEFAULT_SUPPRESSED_NAMESPACES) do
for k, v in pairs(DEFAULT_SUPPRESSED_NAMESPACES) do
Line 63: Line 57:
end
end


-- Then extend/override list using ns_override, if available
if type(ns_override) == "table" then
if type(ns_override) == "table" then
for k, v in pairs(ns_override) do
for k, v in pairs(ns_override) do
Line 69: Line 64:
end
end


return namespaces[ns_text] or false
-- Return; if no namespace found, default to false
return namespaces[curr_ns] or false
end
end


Line 76: Line 72:
-- Accepts an opiontal table, containing additional suffixes to suppress
-- Accepts an opiontal table, containing additional suffixes to suppress
-- Suffix and custom suffixes are lowercased to guarantee matching
-- Suffix and custom suffixes are lowercased to guarantee matching
local function has_suppressed_suffix(title, suffixes_override)
local function has_suppressed_suffix(suffixes_override)
local title_obj
local title = mw.title.getCurrentTitle()
local pagename = mw.ustring.lower(title.text)


if type(title) == "table" and title.text then
-- Build table of suppressed suffixes, start with default suffixes
title_obj = title
elseif type(title) == "string" then
title_obj = mw.title.new(title)
else
title_obj = mw.title.getCurrentTitle()
end
 
local pagename = mw.ustring.lower(title_obj.text or '')
local suffixes = {}
local suffixes = {}
-- Include default suppressed suffixes
for _, suffix in ipairs(DEFAULT_SUPPRESSED_SUFFIXES) do
for _, suffix in ipairs(DEFAULT_SUPPRESSED_SUFFIXES) do
table.insert(suffixes, suffix)
table.insert(suffixes, suffix)
end
end


-- Add custom overrides
-- Then append additional suffixes, if available (append, not replace)
if type(suffixes_override) == "table" then
if type(suffixes_override) == "table" then
for _, suffix in ipairs(suffixes_override) do
for _, suffix in ipairs(suffixes_override) do
Line 102: Line 89:
end
end


-- Check if the page name ends with any of the suffixes (as subpages)
-- Find and match suffix
for _, suffix in ipairs(suffixes) do
for _, suffix in ipairs(suffixes) do
suffix = mw.text.trim(mw.ustring.lower(suffix or ''))
suffix = mw.ustring.lower(mw.text.trim(suffix or '')) -- Also normalize
if suffix ~= '' then
if suffix ~= '' then
local pattern = '/' .. mw.ustring.gsub(suffix, '([%^%$%(%)%%%.%[%]%*%+%-%?])', '%%%1') .. '$'
local pattern = '/' .. mw.ustring.gsub(suffix, '([%^%$%(%)%%%.%[%]%*%+%-%?])', '%%%1') .. '$'
Line 114: Line 101:


return false
return false
end
-- Helper function: strips suffix from title
local function strip_suffix(title, suffix)
    local text = title.text
    if mw.ustring.sub(text, -mw.ustring.len(suffix)) == suffix then
        return mw.title.new(mw.ustring.sub(text, 1, -mw.ustring.len(suffix)-1), title.ns)
    end
    return title
end
end


Line 129: Line 107:
-- Disallows categories if it's in a suppressed namespace or the page has a
-- Disallows categories if it's in a suppressed namespace or the page has a
-- suppressed suffix (subpage)
-- suppressed suffix (subpage)
function p._category_handler(cats, ns_override, suffixes_override, is_debug)
function p._category_handler(cats, ns_override, suffixes, is_debug)
    cats = cats or {}
local cats = cats or {}
    is_debug = yesno(is_debug, false)
local is_debug = yesno(is_debug, false)
-- Test values; should be commented out for normal use
--local cats = cats or {"Abstract MOS patterns", "7-tone scales"}
--local ns_override = ns_override or { ["module"] = true }
-- If in a suppressed namespace/prefix, or in debug mode (suppresses ALL
-- categorization) don't bother
if is_suppressed_namespace(ns_override)
or has_suppressed_suffix(suffixes)
or is_debug then
return ''
end


    local frame = mw.getCurrentFrame()
-- Otherwise, categorize
    local parent_frame = frame:getParent()
local result = ''
    local parent_title = parent_frame and mw.title.new(parent_frame:getTitle()) or mw.title.getCurrentTitle()
for _, cat in ipairs(cats) do
cat = mw.text.trim(cat or '')
if cat ~= '' then
result = result .. string.format('[[Category:%s]]', cat)
end
end


    -- If parent page is a documentation subpage (e.g. ends with /doc), switch to base page
return result
    parent_title = strip_suffix(parent_title, "/doc")
end
 
    local suppressed_ns = is_suppressed_namespace(parent_title, ns_override)
    local suppressed_suffix = has_suppressed_suffix(parent_title, suffixes_override)
    local is_content = parent_title.isContentPage
 
    if is_debug or suppressed_ns or suppressed_suffix or not is_content then
        local reason = is_debug and "debug mode"
            or (suppressed_ns and "suppressed namespace")
            or (suppressed_suffix and "suppressed suffix")
            or (not is_content and "non-content page")
            or "unknown"
 
        -- Return a debug comment explaining why categorization was suppressed
        return string.format(
            "<!-- categorization suppressed: %s; is_debug=%s; suppressed_ns=%s; suppressed_suffix=%s; is_content=%s -->",
            reason,
            tostring(is_debug),
            tostring(suppressed_ns),
            tostring(suppressed_suffix),
            tostring(is_content)
        )
    end
 
    local result = ''
    for _, cat in ipairs(cats) do
        cat = mw.text.trim(cat or '')
        if cat ~= '' then
            result = result .. string.format('[[Category:%s]]', cat)
        end
    end


    return result
end


-- Wrapper for templates calling via #invoke
-- Wrapper for templates calling via #invoke
function p.category_handler(frame)
function p.category_handler(frame)
local args = getArgs(frame)
local args = frame:getParent().args
local cats_unparsed        = args["categories"] or ""
local cats_unparsed        = args["categories" ] or ""
local excluded_ns_unparsed = args["excluded_ns"] or ""
local excluded_ns_unparsed = args["excluded_ns"] or ""
local suffixes_unparsed    = args["suffixes"] or ""
local suffixes_unparsed    = args["suffixes"   ] or ""
local is_debug             = yesno(args["debug"], false)
local is_debug = yesno(args["debug"], false) -- Parse debug mode; setting this to TRUE disables all categories


-- Parse categories
-- Parse categories
Line 190: Line 153:
end
end


-- Parse excluded namespaces (added/overrides default)
-- Parse excluded namespaces
-- These are added in addition to the default list
-- This currently can't force-allow suppressed namespaces as template input,
-- only disallow additional namespaces
local ns_override = {}
local ns_override = {}
for ns in mw.text.gsplit(excluded_ns_unparsed, "[;\n]") do
for ns in mw.text.gsplit(excluded_ns_unparsed, "[;\n]") do