Module:Game Rating

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
This is the main module for the following templates:
local p = {}
local h = {}
local Data = mw.loadData('Module:Game Rating/Data')

local Region = require("Module:Region")
local utilsArg = require("Module:UtilsArg")
local utilsCargo = require("Module:UtilsCargo")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsTable = require("Module:UtilsTable")

function p.Main(frame)
	local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Game Rating"])
    if err then
    	return utilsMarkup.categories(err.categories)
    end
	h.store(args)
    return h.printRating(args.organization, args.code, args.release)
end

function p.Table(frame)
	local DataTable = require("Module:Data Table")
	
	local ratings = utilsCargo.query("GameRatings", "_pageName, regionName, organizationId, ratingCode, gameRelease", {
		limit = 9000,
	})
	local columnHeaders = {"Title [Rowspan]", "Region [Rowspan]", "Organization", "Rating"}
	local rows = utilsTable.map(ratings, function(rating)
		local ratingCode = rating.ratingCode
		if rating.gameRelease then
			ratingCode = ratingCode.." <small>("..rating.gameRelease..")</small>"
		end
		return {
			"[["..rating._pageName.."]]",
			rating.regionName,
			rating.organizationId,
			ratingCode,
		}
	end)
	local dataTable = DataTable.printTable(rows, {
		columns = columnHeaders,
		responsiveModeEnabled = false,
	})
	return dataTable
end

function h.store(args)
	local org = Data.organizations[args.organization]
	mw.getCurrentFrame():expandTemplate({
		title = "Game Rating/Store",
		args = {
			organizationId = args.organization,
			organizationName = org.fullName,
			regionCode = org.region,
			regionName = h.regionName(org.region),
			ratingCode = args.code,
			ratingName = h.ratingName(org, args.code),
			gameRelease = args.release
		}
	})
end
function h.regionName(regionCode)
	local region = Region.getRegion(regionCode)
	return region.name
end
function h.ratingName(organization, ratingCode)
	local ratings = organization.ratings
	local ratingName = utilsTable.keyOf(ratings, ratingCode) or utilsTable.find(ratings, {code = ratingCode}).full
	return ratingName
end

function h.printRating(orgCode, ratingCode, release)
	local org = Data.organizations[orgCode]
	local orgName = org.fullName
	
	local region = Region.getRegion(org.region)
	local regionName = region.name
	local flag = region.flags[1]
	
	local orgDisplay = mw.getCurrentFrame():expandTemplate({
		title= "Exp",
        args= {
            string.format("%s (%s)", orgName, regionName),
            orgCode,
        }
	})
    
    local result = string.format("%s %s: %s", flag, orgDisplay, ratingCode)

    if release then
    	local releaseText = tostring(
    		mw.html.create('span')
    			:css('font-size', 'smaller')
    			:wikitext(string.format("(%s)", release))
		)
        result = result .. ' ' .. releaseText
    end

    return result
end

function h.organizationsEnum()
	local organizations = utilsTable.keys(Data.organizations)
	organizations.reference = "[[Module:Game Rating/Data]]"
	return organizations
end

function h.ratingCodesEnum(organizationId)
	local organization = Data.organizations[organizationId]
	if not organization then
		return {}
	end
	local codes = {}
	for _, rating in ipairs(organization.ratings) do
		table.insert(codes, rating.code or rating)
	end
	codes.reference = "[[Module:Game Rating/Data]]"
	return codes
end

function p.Data()
	local utilsLayout = require("Module:UtilsLayout")

	local columnHeaders = {"ID", "Full Name", "Region"}
	local rows = {}
	for orgId, org in pairs(Data.organizations) do
		local region = Region.getRegion(org.region)
		table.insert(rows, {
			"<code>"..orgId.."</code>",
			org.fullName,
			{
				content = region.flags[1].." "..region.name,
				sortValue = region.name,	
			},
		})
	end
	rows = utilsTable.sortBy(rows, 1)
	local wikitable = utilsLayout.table({
		caption = "Content Rating Organizations",
		sortable = true,
		headers = columnHeaders,
		rows = rows,
	})

	return wikitable
end

function p.Schemas()
	return {
		Data = {
			type = "record",
			required = true,
			properties = {
				{
					name = "organizations",
					required = true,
					desc = "Information on video game rating organizations.",
					type = "map",
					keys = {
						type = "string"
					},
					values = {
						type = "record",
						properties = {
							{
								name = "fullName",
								required = true,
								type = "string",
								desc = "Full name of the rating organization.",
							},
							{
								name = "region",
								required = true,
								type = "string",
								desc = "A [[Module:Region/Data|region code]] representing the rating organization's jurisdiction.",
								enum = Region.enum(),
							},
							{
								name = "ratings",
								required = true,
								type = "array",
								items = {
									desc = "A collection of all the content ratings the organization has.",
									oneOf = {
										{
											type = "record",
											properties = {
												{
													name = "code",
													type = "string",
													required = true,
													desc = "The rating code.",
												},
												{
													name = "full",
													type = "string",
													required = true,
													desc = "What the the rating code stands for officially.",
												},
											},
										},
										{
											type = "string",
											desc = "The rating code just as a <code>string</code>.",
										},
									},
								},
							},
						},
					},
				}
			}
		}
	}
end

p.Templates = {
	["Game Rating"] = {
		purpose = "This template is used inside [[Template:Infobox Game]] to record a game's [[Content Ratings for The Legend of Zelda|content ratings]].",
		params = {
			[1] = {
				name = "organization",
				type = "string",
				required = true,
				enum = h.organizationsEnum(),
				desc = "Abbreviatied name of a game rating body.",
			},
			[2] = {
				name = "code",
				type = "string",
				required = true,
				enum = h.ratingCodesEnum,
				enumDependsOn = "organization",
				desc = "Rating code that is valid for the given organization."
			},
			release = {
				type = "string",
				canOmit = true,
				desc = "Used to specify ratings that apply to a specific version of a game.",
			},
		},
		paramOrder = {1, 2, "release"},
		format = "inline",
		boilerplate = {
			list = true,
		},
		examples = {
			{"ESRB", "E"},
			{"PEGI", "7", release = "Nintendo 3DS Virtual Console"},
			{"ESRB", "đŸ’©"},
			{"POOP"},
		}
	},
	["Game Rating Table"] = {},
}

return p