Module:Infobox

From Call of Duty Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here.

To make a new infobox module, subclass this.


-- <nowiki>
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_html = require('Module:HtmlUtil')
local util_map = require("Module:MapUtil")
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_vars = require("Module:VarsUtil")
local i18n = require('Module:I18nUtil')
local lang = mw.getLanguage('en')
local social = require('Module:Infobox/Social')
local LCS = require('Module:LuaClassSystem').class
local CLASSES = {
	title = 'infobox-title',
	notice = 'infobox-notice'
}

local DEFAULT_IMAGE_SIZE = '220px'

local h = {}
local p = LCS.abstract()

p.LAYOUT = {
	sections = {  },
	contents = {
		{  },
	},
	i18n = {}
}

p.NOIMAGE = 'Unknown Infobox Image - Player.png'

function p:init(args)
	i18n.init('Infobox/' .. self.type)
	self:validateArgs(args)
	self:castArgs(args)
	local processed = self:getProcessed(args)
	
	self.display = self:getDisplay(args, processed)
	self.serializedSections = {}
	self.cargo = self:getCargo(args, processed)
	self.settings = self:getSettings(args, processed)
	self.categories = self:getCategories(args, processed)
	self.variables = self:getVariables(args, processed)
	self.layout = self.LAYOUT -- hmm.....
end

function p:validateArgs(args) end

function p:castArgs(args) end

function p:getProcessed(args)
	local tbl = {
		pagename = mw.title.getCurrentTitle().text,
		lc = args.name and lang:lcfirst(args.name) == args.name,
		isLowContent = util_args.castAsBool(args.low_content),
	}
	return tbl
end

function p:getSettings(args, processed)
	local ret = {
		lc = processed.lc,
		nocargo = mw.title.getCurrentTitle().nsText ~= '' or args.nocargo,
		nocat = mw.title.getCurrentTitle().nsText ~= '' or args['no-cat'],
	}
	return ret
end

function p:getDisplay(args, processed)
	local social = social.makeSocialSection(args)
	local argsCopy = mw.clone(args)
	local tbl = {
		title = args.name or processed.pagename,
		social = next(social) and tostring(util_html.blockBox(social)),
		imagesize = DEFAULT_IMAGE_SIZE,
	}
	return util_table.merge(argsCopy, tbl)
end

function p:getCargo(args, processed)
	local name = args._title or processed.title or mw.title.getCurrentTitle().text
	local page = mw.title.getCurrentTitle().text
	local isLowercase = lang:lcfirst(name) == name
	local entity = isLowercase and page or util_text.lcfirst(page)
	local tbl = {
		{
			_table = 'Entities',
			Entity = entity,
			EntityName = name,
			EntityPage = page,
			EntityType = self.type,
			IsLowercase = isLowercase,
			DisambigSentence = self:getDisambigSentence(args, processed),
		}
	}
	return tbl
end

function p:getDisambigSentence(args, processed)
	return ('%s (%s)'):format(
		util_text.intLinkOrText(mw.title.getCurrentTitle().text, args._title or processed.title),
		self.type
	)
end

function p:getCategories(args, processed)
	local tbl = {
		processed.isLowContent and 'LowContent',
	}
	return tbl
end

function p:getVariables(args, processed)
	local tbl = {
		isLowContent = args.low_content,
		hasInfobox = 'Yes',
	}
	return tbl
end

-- @staticmethod
function p.mergeDisplay(display, tbl)
	tbl.names = util_table.merge(display.names, tbl.names)
	tbl.footnotes = util_table.merge(display.footnotes, tbl.footnotes)
	util_table.merge(display, tbl)
	return display
end

function p:run()
	self:setLowercase()
	self:setVariables()
	self:storeCargo()
	self:mergeDynamicDisplayValuesIntoStatic()
	self.serializedSections = self:prepDisplayDataForPrinting()
	local output = {
		h.makeTabs(self.layout.tabs),
		tostring(self:makeInfobox()),
		h.getCategories(self.categories, self.settings.nocat)
	}
	return table.concat(output,'')
end

function p:setLowercase()
	if not self.settings.lc then return end
	local title = mw.title.getCurrentTitle().text
	mw.getCurrentFrame():callParserFunction{
		name = 'DISPLAYTITLE',
		args = h.getDisplayTitleArgs(title),
	}
end

function p:setVariables()
	if not self.variables then return end
	util_table.removeFalseEntries(self.variables)
	for k, v in pairs(self.variables) do
		util_vars.setVar(k, tostring(v))
	end
end

function p:storeCargo(nocargo, data)
	if self.settings.nocargo or not self.cargo then return end
	util_map.rowsInPlace(self.cargo, util_cargo.store)
end

-- build infobox

function p:mergeDynamicDisplayValuesIntoStatic()
	if not self.layout.classes then self.layout.classes = {} end
	if not self.layout.i18n then self.layout.i18n = {} end
	util_table.merge(self.layout.classes, self.display.classes)
	util_table.merge(self.layout.i18n, self.display.names)
	self.display.names = self.layout.i18n
end

function p:prepDisplayDataForPrinting()
	local serializedSections = {}
	for _, key in ipairs(self:getListOfNonemptySectionIndices()) do
		serializedSections[#serializedSections+1] = {
			name = self.layout.sections[key],
			lines = self:getSectionContentsAndValues(self.layout.contents[key]),
			class = self.layout.classes[key]
		}
	end
	return serializedSections
end

function p:getListOfNonemptySectionIndices()
	local ret = {}
	for k, _ in ipairs(self.layout.sections) do
		if self:doesSectionExist(self.layout.contents[k]) then
			ret[#ret+1] = k
		end
	end
	return ret
end

function p:doesSectionExist(contents)
	for k, v in ipairs(contents) do
		if self.display[v] then
			return true
		end
	end
	return false
end

function p:getSectionContentsAndValues(contents)
	local ret = {}
	for _, paramName in ipairs(contents) do
		ret[#ret+1] = self:getOneSectionContentsAndValues(contents, paramName)
	end
	return ret
end

function p:getOneSectionContentsAndValues(contents, paramName)
	if not self.display[paramName] then return nil end
	return {
		name = self.display.names[paramName] or i18n.print(paramName) or paramName,
		value = self.display[paramName],
		class = self.layout.classes[paramName],
		celltype = contents[paramName]
	}
end

-- print stuff
function h.makeTabs(tabsTemplateTitle)
	if not tabsTemplateTitle then return '' end
	return mw.getCurrentFrame():expandTemplate{title = tabsTemplateTitle }
end

function p:makeInfobox()
	local tbl = self:initializeTable()
	h.printHeadingI18n(tbl, self.display.notice, 'notice')
	h.printHeading(tbl, self.display.title, 'title')
	h.printImage(tbl, self.display)
	for k, section in ipairs(self.serializedSections) do
		h.printHeadingI18n(tbl, section.name, section.class)
		for _, line in ipairs(section.lines) do
			h.printRow(tbl, line)
		end
	end
	return tbl
end

function p:initializeTable()
	local tbl = mw.html.create('table')
		:addClass('infobox')
		:addClass(self.display.class)
		:addClass('Infobox' .. self.type)
		:attr('id', 'infobox' .. self.type)
	return tbl
end

function h.printHeading(tbl, content, class)
	if not content then return end
	tbl:tag('tr')
		:tag('th')
			:attr('colspan','2')
			:addClass(class and CLASSES[class] or class)
			:wikitext(content)
end

function h.printHeadingI18n(tbl, content, class)
	h.printHeading(tbl, i18n.print(content) or content, class)
end

function h.printImage(tbl, data)
	if not data.image then return end
	local imageText = ('[[File:%s|center|%s]]'):format(data.image, data.imagesize)
	h.printWideRow(tbl, imageText, 'infobox-image')
	h.printWideRow(tbl, data.imagecaption, 'infobox-image-caption')
end

function h.printRow(tbl, line)
	local tr = tbl:tag('tr')
		:addClass(line.class)
	if line.celltype == 'wide' then
		h.printWideRow(tr, line.value)
	else
		h.printNormalRow(tr, line.name, line.value)
	end
end

function h.printWideRow(tr, content)
	if not content then return end
	tr:tag('td')
		:attr('colspan','2')
		:addClass('infobox-wide')
		:wikitext(content)
	return
end

function h.printNormalRow(tr, label, content)
	if not content then return end
	tr:tag('td')
		:addClass('infobox-label')
		:wikitext(label)
	:done()
	:tag('td')
		:wikitext(content)
	:done()
	return
end

function h.getKeyForHeading(contents, display)
	for k, v in ipairs(contents) do
		if display[v] then
			return k
		end
	end
end

function h.getDisplayTitleArgs(title)
	if mw.title.getCurrentTitle().nsText ~= '' then
		return ('%s:%s'):format(
			mw.title.getCurrentTitle().nsText,
			lang:lcfirst(title)
		)
	end
	return lang:lcfirst(title)
end

function h.getCategories(categories, nocat)
	if nocat then return '' end
	if not categories then return '' end
	local tbl = {}
	for _, v in pairs(categories) do
		if v then
			tbl[#tbl+1] = ("[[Category:%s]]"):format(v)
		end
	end
	return table.concat(tbl, '')
end

return p
-- </nowiki>