Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

Zelda Wiki
Advertisement

Lua error in package.lua at line 80: module 'Module:UtilsCode' not found.


local p = {}
local h = {}
local cargo = mw.ext.cargo
local utilsCode = require("Module:UtilsCode")
local utilsGame = require("Module:UtilsGame")
local utilsLayout = require("Module:UtilsLayout")
local utilsTable = require("Module:UtilsTable")

-- See the module for documentation about subcategories.
local SUBCATEGORIES = require("Module:Categories/Subcategories")
local PER_GAME_CATEGORIES = {
	{parameter = "bosses", category = "Bosses"},
	{parameter = "characters", category = "Characters"},
	{parameter = "dungeons", category = "Dungeons"},
	{parameter = "enemies", category = "Enemies"},
	{parameter = "items", category = "Items"},
	{parameter = "levels", category = "Levels"},
	{parameter = "objects", category = "Objects"},
	{parameter = "places", category = "Places"},
	{parameter = "playable", category = "Playable Characters"},
	{parameter = "songs", category = "Songs"},
	{parameter = "stages", category = "Stages"},
	{parameter = "sub-bosses", category = "Sub-Bosses"},
}
local MAX_NAV_LINKS = 100

function p._CategorizeEntries(frame)
	local args = frame:getParent().args
	return p.CategorizeEntries(frame.args["plain"], args)
end

function p.CategorizeEntries(plain, lists)
	local result = ""
	result = result .. p.PlainToNavboxes(plain)
	result = result .. p.PlainToCategories(plain)
	result = result .. p.GamesToCategories(lists)
	return result
end

function p.PlainToNavboxes(plain)
	result = ""
	local plaintable = mw.text.split(plain, '%s*,%s*')
	
	local navboxTitle = ""
	local rows = {}
	local rowDisplayName = ""
	local notCategories = ""
	local notParentCategories = ""
	local dplQuery = ""
	local dplParameters = '|namespace=|includesubpages=false|skipthispage=no|mode=userformat|format=,%PAGE%,;,|ordermethod=titlewithoutnamespace|noresultsheader=emptyCategory}}'
	
	-- For every category entered in the template
	for key, category in ipairs(plaintable) do
		rows = {}
		if not utilsCode.IsEmpty(category) then
			if tonumber(mw.getCurrentFrame():callParserFunction{name = 'PAGESINCATEGORY', args = {category, "R", "pages"}}) <= MAX_NAV_LINKS then
				-- Sets the title, which is "[[:Category:X|X]] in {{TLoZ|Series}}"
				navboxTitle = "[[:Category:" .. category .. "|" .. category .. "]] in " .. mw.getCurrentFrame():expandTemplate{ title = "TLoZ", args = { "Series" } }
				
	    		-- If subcategories exist, handles that
				if not utilsCode.IsEmpty(SUBCATEGORIES[category]) then
					notCategories = ""
					for key2, subCategory in ipairs(SUBCATEGORIES[category]) do
						notParentCategories = ""
						notCategories = notCategories .. "|notcategory=" .. subCategory["category"]
						if not utilsCode.IsEmpty(subCategory["parents"]) then
							for key3, parentCategory in ipairs(subCategory["parents"]) do
								notParentCategories = notParentCategories .. "|notcategory=" .. parentCategory
							end
						end
						dplQuery = h.dplToExternalLinks(mw.getCurrentFrame():preprocess("{{#dpl:|category=" .. category .. "|category=" .. subCategory["category"] .. notParentCategories .. dplParameters))
						
						if not (dplQuery == "emptyCategory") then
							if utilsCode.IsEmpty(subCategory["display"]) then
								rowDisplayName = subCategory["category"]
							else
								rowDisplayName = subCategory["display"]
							end
							table.insert(rows, {title = rowDisplayName, content = dplQuery})
						end
					end
					
					-- Other(s) row
					dplQuery = h.dplToExternalLinks(mw.getCurrentFrame():preprocess("{{#dpl:|category=" .. category .. notCategories .. dplParameters))
					if not (dplQuery == "emptyCategory") then
						table.insert(rows, {title = "Other(s)", content = dplQuery})
					end
					result = result .. utilsLayout.CreateRowNavbox(rows, navboxTitle)
					
				-- else just outputs everything
				else
					dplQuery = h.dplToExternalLinks(mw.getCurrentFrame():preprocess("{{#dpl:|category=" .. category .. dplParameters))
					if not (dplQuery == "emptyCategory") then
						table.insert(rows, {title = "All", content = dplQuery})
						result = result .. utilsLayout.CreateRowNavbox(rows, navboxTitle)
					end
				end
			end
		end
	end
	return tostring(result)
end

function h.dplToExternalLinks(dplResult)
	local result = ""
	local firstLink = true
	dplResult = mw.text.split(dplResult, '%s*;%s*')
	-- Removing the last entry in the table since it's "empty" due to how DPL
	-- adds a ";" at the end of each entry instead of just in-between entries
	table.remove(dplResult)
	for key, link in ipairs(dplResult) do
		if firstLink == true then
			firstLink = false
		else
			result = result .. ' <b>·</b> '
		end
		result = result .. '<span class="plainlinks">[https://zelda.gamepedia.com/' .. mw.getCurrentFrame():callParserFunction{name = 'urlencode', args = {link, "WIKI"}} .. ' ' .. link .. ']</span>'
	end
	return result
end

function p.PlainToCategories(plain)
	result = ""
	local plaintable = mw.text.split(plain, '%s*,%s*')
	for key, category in ipairs(plaintable) do
		if not utilsCode.IsEmpty(category) then
			result = result .. "[[Category:" .. category .. "]]"
		end
	end
	return result
end

function p.GamesToCategories(lists)
	local result = ""
	local categories = {}

	for key, list in ipairs(PER_GAME_CATEGORIES) do
		if not (utilsCode.IsEmpty(lists[list["parameter"]])) then
			for key2, entry in ipairs(mw.text.split(lists[list["parameter"]], '%s*,%s*')) do
				table.insert(categories, {list.category, entry})
			end
		end
	end
	
	for _, game in ipairs(utilsGame.GetSortOrder("canon")) do
		for _2, category in ipairs(categories) do
			if game == category[2] then
				result = result .. "[[Category:" .. category[1] .. " in " .. utilsGame.AbbToGame(category[2], "true") .. "]]"
			end
		end
	end
	
	
	return result
end

local params = {}
local paramOrder = {}
for _, perGameCategory in ipairs(PER_GAME_CATEGORIES) do
	params[perGameCategory.parameter] = {
		type = "string",
		desc = string.format("Comma-separated list of [[Data:Franchise|codes]] representing the games or other titles in which the given article subject is one of the [[:Category:%s|%s]].", perGameCategory.category, perGameCategory.category),
		split = true,
		trim = true,
		nilIfEmpty = true,
	}
	table.insert(paramOrder, perGameCategory.parameter)
end

p.Templates = {
	Categories = {
		purpose = "Adding categories to pages. For each category, a navbox is generated with links between the pages in the category.",
		format = "block",
		paramOrder = utilsTable.concat({1}, paramOrder),
		params = utilsTable.merge(params, {
			[1] = {
				name = "categories",
				type = "string",
				desc = "Comma separated list of categories which are not subcategorized by game. Examples of these include [[:Category:Animals|Animals]], [[:Category:Forests|Forests]], [[:Category:Fire-Related Enemies|Fire-Related Enemies]], and so on.",
				split = true,
				trim = true,
				nilIfEmpty = true,
			}
		}),
		examples = {
			vertical = true,
			{
				desc = "[[Ice Keese]]",
				args = {
					[1] = "Keese, Ice-Related Enemies",
					["enemies"] = "OoT, OoT3D, MM, MM3D, TP, TPHD, PH, ST, TFH, BotW",
					["sub-bosses"] = "ST",
				}
			},
			{
				desc = "[[Yuga]]",
				args = {
					[1] = "Demons, Loruleans, Sorcerers",
					["bosses"] = "TLoZ, ALttP, OoT, OoT3D, OoS, OoA, FSA, TP, TPHD, TFoE, TWoG, ZA, BSTLoZ, AST, HW, HWL, HWDE",
					["characters"] = "ALBW, HW",
					["playable"] = "HW",
				},
			},
			{
				desc = "[[Blue Fire]]",
				args = {
					[1] = "Ancient Technology",
					["items"] = "OoT, OoT3D",
					["objects"] = "BotW"
				}
			},
			{
				desc = "[[Desert Temple]]",
				args = {
					["dungeons"] = "OoT, OoT3D",
					["levels"] = "TFH",
					["places"] = "OoT, OoT3D",
				},
			},
			{
				desc = "[[Eldin Caves]]",
				args = {
					["stages"] = "HW, HWL, HWDE",
				},
			},
			{
				desc = "[[Song of Healing]]",
				args = {
					["songs"] = "MM, MM3D, TP, TPHD, ST",
				},
			},
			{
				desc = string.format("Navboxes are not generated for categories with %s+ links.", MAX_NAV_LINKS),
				args = {
					[1] = "Hylians, Swords",
				},
			},
			{
				desc = "Duplicates and improperly ordered entries are handled appropriately.",
				args = {
					characters = "TP, TP, OoT, OoT",
				},
			},
		},
	},
}

return p
Advertisement