Module:Soyjak categorizer

From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search

This module automatically generates categorization for Soyjak variant and subvariant articles. It is designed to be called from within an infobox template (such as {{Infobox soyjak}}) and reads the template's parameters to seamlessly categorize the page without requiring manual category tags.

Place the following invoke string inside your infobox template's wikitext, wrapped in <includeonly> tags(evendoe it's already placed there):

<includeonly>{{#invoke:Soyjak categorizer|main}}</includeonly>

How it works

[edit source]

The module performs several automated checks to determine the correct categories to output.

1. Type Classification

[edit source]

The module reads the |type= parameter to determine the base category suffix:

  • If the field contains the word subvariant, it uses "subvariants".
  • If the field contains the word variant, or if the field is left empty/blank, it defaults to "variants".
  • If it contains something else entirely (e.g. "trend"), the module assumes the subject is neither a variant nor subvariant and will gracefully exit without generating any categories.

2. Origin Site Detection

[edit source]

The module reads the |origin= parameter and searches for known websites.

  • It ignores capitalization, spaces, dots, and hyphens, meaning inputs like "Soyjak.party", "soyjak party", or "soyjakparty" will all successfully match.
  • Based on the match, it will output a category such as [[Category:4chan variants]] or [[Category:SoyBooru subvariants]].

3. Year Detection

[edit source]

The module scans the |origin= parameter for isolated four-digit numbers representing years.

  • To prevent false positives, it only targets isolated 4-digit strings (ignoring longer numbers like 8-digit post IDs).
  • It restricts matches to a plausible timeframe (currently 2017–2035).
  • Outputs a category such as [[Category:2020 variants]].

4. Reference Stripping

[edit source]

Before checking the origin parameter for sites or years, the module completely strips out <ref>...</ref> tags. This ensures that citation URLs, archived timestamps, and reference IDs are not accidentally parsed as origin dates or sites.

Configuration

[edit source]

Wiki administrators and template maintainers can easily tweak the module's behavior by editing the configuration variables at the very top of the Lua script. You do not need to touch the core logic to update these:

  • SITES: A table of recognized origin sites. You can add new sites by defining their search key (lowercase, alphanumeric only) and their category label.
  • MIN_YEAR / MAX_YEAR: Defines the acceptable range for date detection (e.g., 2017 to 2035).
  • EMIT_BASE_CATEGORY: A true/false toggle. If set to true, the module will also append the base [[Category:Soyjak variants]] or [[Category:Soyjak subvariants]] to the page.

local p = {}

local SITES = {
	{ key = '4chan',       label = '4chan' },
	{ key = 'soybooru',    label = 'SoyBooru' },
	{ key = 'soyjakparty', label = 'Soyjak.party' },
}
local MIN_YEAR = 2017
local MAX_YEAR = 2035

local EMIT_BASE_CATEGORY = false

local function classify(typeField)
	if typeField == nil or mw.text.trim(typeField) == '' then
		return 'variant'
	end
	local lowered = mw.ustring.lower(typeField)
	if mw.ustring.find(lowered, 'subvariant', 1, true) then
		return 'subvariant'
	elseif mw.ustring.find(lowered, 'variant', 1, true) then
		return 'variant'
	end
	return nil
end

local function stripRefs(text)
	text = mw.ustring.gsub(text, '<ref[^>]*>.-</ref>', '')
	text = mw.ustring.gsub(text, '<ref[^>]*/>', '')
	return text
end

local function findSites(origin)
	local cleaned = stripRefs(origin)
	local normalized = mw.ustring.lower(cleaned)
	normalized = mw.ustring.gsub(normalized, '[%.%s%-]', '')

	local found = {}
	for _, site in ipairs(SITES) do
		if mw.ustring.find(normalized, site.key, 1, true) then
			table.insert(found, site.label)
		end
	end
	return found
end

local function findYear(origin)
	local cleaned = stripRefs(origin)
	for year in mw.ustring.gmatch(cleaned, '%f[%d]%d%d%d%d%f[%D]') do
		local y = tonumber(year)
		if y and y >= MIN_YEAR and y <= MAX_YEAR then
			return year
		end
	end
	return nil
end


function p._main(args)
	local currentTitle = mw.title.getCurrentTitle()
    if currentTitle.namespace ~= 0 then
        return ''
    end
    
	local classification = classify(args.type)
	if not classification then
		return ''
	end
	local plural = classification .. 's'
	local origin = args.origin or ''

	local categories = {}

	if EMIT_BASE_CATEGORY then
		table.insert(categories, 'Soyjak ' .. plural)
	end

	for _, siteLabel in ipairs(findSites(origin)) do
		table.insert(categories, siteLabel .. ' ' .. plural)
	end

	local year = findYear(origin)
	if year then
        table.insert(categories, year .. ' ' .. plural)
    else
        table.insert(categories, 'Undated ' .. plural)
    end

	local out = {}
	for _, cat in ipairs(categories) do
		table.insert(out, '[[Category:' .. cat .. ']]')
	end
	return table.concat(out)
end

function p.main(frame)
	local args = frame:getParent().args
	return p._main(args)
end

return p