Module:Infobox Person

From the Tesseract Wiki, the wiki for all things Marvel Cinematic Universe
Jump to navigation Jump to search

Documentation for this module may be created at Module:Infobox Person/doc

--------------------------
-- Module for [[Template:Infobox Person]]
--------------------------
local p = {}

-- "imports"
local onmain = require('Module:Mainonly').on_main
local yesno = require('Module:Yesno')
local paramtest = require('Module:Paramtest')
local infobox = require('Module:Infobox')
local cleanimg = require('Module:Clean image').clean
local editbutton = require('Module:Edit button')
local edit = editbutton("'''?''' (edit)")

function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)

	ret:defineParams{
		{ name = 'name', func = 'name' },
		{ name = 'image', func = imgarg },
		{ name = 'date_of_birth', func = 'has_content' },
		{ name = 'place_of_birth', func = 'has_content' },
		{ name = 'date_of_death', func = 'has_content' },
		{ name = 'place_of_death', func = 'has_content' },
		{ name = 'occupation', func = 'has_content' },
		{ name = 'website', func = 'has_content' },
		{ name = 'employed', func = 'has_content' },
		{ name = 'left', func = 'has_content' },
		{ name = 'employment_dates', func = { name = employmentDates, params = { 'employed', 'left' }, flag = { 'd', 'd' } } },
		{ name = 'twitter', func = { name = twitter, params = { 'twitter' }, flag = { 'd' } } },
		{ name = 'reddit', func = { name = reddit, params = { 'reddit' }, flag = { 'd' } } },
		{ name = 'artstation', func = { name = artstation, params = { 'artstation' }, flag = { 'd' } } },
		{ name = 'sketchfab', func = { name = sketchfab, params = { 'sketchfab' }, flag = { 'd' } } },
		{ name = 'twitch', func = { name = twitch, params = { 'twitch' }, flag = { 'd' } } },
		{ name = 'has_social', func = { name = hasSocial, params = { 'twitter', 'reddit', 'artstation', 'sketchfab', 'twitch' }, flag = { 'd', 'd', 'd', 'd', 'd' } } },
		{ name = 'SMWarg', func = { name = SMWarg, params = {
				'name', 'image'
			}, flag = 'd' } }
	}

	ret:useSMW({
		SMWarg = 'Person JSON',
	})

	ret:setMaxButtons(4)	
	ret:create()
	ret:cleanParams()
	ret:customButtonPlacement(true)
	
	ret:defineLinks({ links = {{ 'Template:%s', 'Infobox' },
		{ 'Template_talk:%s', 'Talk page' }}, colspan = '2' })

	ret:defineName('Infobox Person')
	ret:addClass('rsw-infobox plainlinks')

	ret:addButtonsCaption()

	-- PARAMETER: image
	ret:addRow{
		{ tag = 'argd', content = 'image', class = 'infobox-image infobox-full-width-content', colspan = '2' }
	}

	ret:addRow{
		{ tag = 'argh', content = 'name', class='infobox-header', colspan = '2' }
	}

	-- PARAMETER: date_of_birth
	if ret:paramDefined('date_of_birth') then
		ret:addRow{
			{ tag = 'th', content = 'Born' },
			{ tag = 'argd', content = 'date_of_birth' }
		}
	end

	-- PARAMETER: place_of_birth
	if ret:paramDefined('place_of_birth') then
		ret:addRow{
			{ tag = 'th', content = 'Place of Birth' },
			{ tag = 'argd', content = 'place_of_birth' }
		}
	end

	-- PARAMETER: date_of_death
	if ret:paramDefined('date_of_death') then
		ret:addRow{
			{ tag = 'th', content = 'Death' },
			{ tag = 'argd', content = 'date_of_death' }
		}
	end
	
	-- PARAMETER: place_of_death
	if ret:paramDefined('place_of_death') then
		ret:addRow{
			{ tag = 'th', content = 'Place of Death' },
			{ tag = 'argd', content = 'place_of_death' }
		}
	end
	
	-- PARAMETER: occupation
	if ret:paramDefined('occupation') then
		ret:addRow{
			{ tag = 'th', content = 'Occupation' },
			{ tag = 'argd', content = 'occupation' }
		}
	end
	
	-- PARAMETER: website
	if ret:paramDefined('website') then
		ret:addRow{
			{ tag = 'th', content = 'Website' },
			{ tag = 'argd', content = 'website' }
		}
	end

	-- PARAMETER: employment_dates
	if ret:paramDefined('employed') then
		ret:addRow{
			{ tag = 'th', content = 'Employed' },
			{ tag = 'argd', content = 'employment_dates' }
		}
	end
	
	if ret:paramGrep('has_social', true) then
		ret:addRow{
			{ tag = 'th', content = 'Social', class='infobox-subheader', colspan = '2' }
		}
		
		-- PARAMETER: twitter
		if ret:paramDefined('twitter') then
			ret:addRow{
				{ tag = 'th', content = 'Twitter' },
				{ tag = 'argd', content = 'twitter' }
			}
		end
		
		-- PARAMETER: reddit
		if ret:paramDefined('reddit') then
			ret:addRow{
				{ tag = 'th', content = 'Reddit' },
				{ tag = 'argd', content = 'reddit' }
			}
		end
		
		-- PARAMETER: artstation
		if ret:paramDefined('artstation') then
			ret:addRow{
				{ tag = 'th', content = 'ArtStation' },
				{ tag = 'argd', content = 'artstation' }
			}
		end
		
		-- PARAMETER: sketchfab
		if ret:paramDefined('sketchfab') then
			ret:addRow{
				{ tag = 'th', content = 'Sketchfab' },
				{ tag = 'argd', content = 'sketchfab' }
			}
		end
		
		-- PARAMETER: twitch
		if ret:paramDefined('twitch') then
			ret:addRow{
				{ tag = 'th', content = 'Twitch' },
				{ tag = 'argd', content = 'twitch' }
			}
		end
	end

	ret:finish()
	if onmain() then
		local a1 = ret:param('all')
		local a2 = ret:categoryData()
		ret:wikitext(addcategories(a1, a2))
	end
	return ret:tostring()
end

function imgarg(arg)
	if infobox.isDefined(arg) then
		return cleanimg{ file = arg, width = 300, height = 300 }
	end
	return nil
end

function name(arg)
	return string.match(arg or '','%S') and arg or nil
end

function lookuparg(t, c, y)
	local arg = t[string.lower(c or '')]
	if arg then
		if y ~= nil and y ~= '' then
			return arg[y]
		else
			return arg
		end
	end
	return nil
end

function lookupmultiarg(t, c, y, r)
	r = r or false
	local out = {}
	if not infobox.isDefined(c) then
		return nil
	end
	c = string.lower(c)
	for i in mw.text.gsplit(c, ',') do
		local arg = t[mw.text.trim(i)]
		if arg then
			table.insert(out, arg[y])	
		end
	end
	if #out == 0 then
		return nil
	end
	if r then 
		return out	
	end
	return table.concat(out, '<br>')
end

function employmentDates(employed, left)
	if not infobox.isDefined(employed) and not infobox.isDefined(left) then
		return edit	
	end
	
	local out = {}
	local dates = getEmploymentDates(employed, left)
	local maxArgs = math.max(#dates.employed, #dates.left)
	for i = 1, maxArgs, 1 do
		local e = dates.employed[i] or 'Unknown'
		local l = dates.left[i]
		local separator = ' ─ '
		
		-- If this is the latest set of dates don't set to left to unknown
		if i == maxArgs and infobox.isDefined(e) and not infobox.isDefined(l) then
			l = ''
			separator = ''
		end
    	table.insert(out, e..separator..l )
	end
	return table.concat(out, '<br>')
end

function getEmploymentDates(employed, left)
	local out = {
		employed = {},
		left = {}
	}
	for i in mw.text.gsplit(employed, ',') do
		table.insert(out.employed, mw.text.trim(i))
	end
	for i in mw.text.gsplit(left, ',') do
		table.insert(out.left, mw.text.trim(i))
	end
	return out
end

function hasSocial(twitter, reddit, artstation, sketchfab, twitch)
	if infobox.isDefined(twitter) or infobox.isDefined(reddit) or infobox.isDefined(artstation) or infobox.isDefined(sketchfab) or infobox.isDefined(twitch) then
		return true
	end
	return false
end

function twitter(arg)
	if infobox.isDefined(arg) then
		return '[https://www.twitter.com/'..arg..' @'..arg..']'
	end
	return nil
end

function reddit(arg)
	if infobox.isDefined(arg) then
		return '[https://www.reddit.com/u/'..arg..' /u/'..arg..']'
	end
	return nil
end

function artstation(arg)
	if infobox.isDefined(arg) then
		return '[https://www.artstation.com/'..arg..' '..arg..']'
	end
	return nil
end

function sketchfab(arg)
	if infobox.isDefined(arg) then
		return '[https://sketchfab.com/'..arg..' '..arg..']'
	end
	return nil
end

function twitch(arg)
	if infobox.isDefined(arg) then
		return '[https://www.twitch.tv/'..arg..' '..arg..']'
	end
	return nil
end

-- SMW JSON
function SMWarg(name, image)
	local toJSON = {
		name = name,
		image = image
	}

	for k,v in pairs(toJSON) do
		if v == '' or (type(v) == 'string' and string.find(v,'action=edit')) then
			toJSON[k] = nil
		end
	end

	return mw.text.jsonEncode(toJSON)
end

function addcategories(args, catargs)
	local ret = { 'People' }
	
	local cat_map = {
		-- Added if the parameter has content
		defined = {

		},
		-- Added if the parameter has no content
		notdefined = {
			image = 'Needs person image',
		},
	}
	
	local title = mw.title.getCurrentTitle().fullText

	-- Add the associated category based on employment dates
	if args['employed'] or args['left'] then
		local dates = getEmploymentDates(args['employed'].d or '', args['left'].d or '')
		if args['employed'].d:find('%?action=edit') and args['left'].d:find('%?action=edit') then
			table.insert(ret, 'Needs Marvel Studios employee employment dates|'..title)
		elseif args['left'].d:find('%?action=edit') then
			table.insert(ret, 'Current Marvel Studios employees|'..title)
		elseif #dates.employed > #dates.left then
			table.insert(ret, 'Current Marvel Studios employees|'..title)
		else
			table.insert(ret, 'Former Marvel Studios employees|'..title)
		end
	end

	-- Run and add mapped categories
	for n, v in pairs(cat_map.defined) do
		if catargs[n] and catargs[n].one_defined then
			table.insert(ret,v)
		end
	end
	for n, v in pairs(cat_map.notdefined) do
		if catargs[n] and catargs[n].all_defined == false then
			table.insert(ret,v)
		end
	end
	
	-- combine table and format category wikicode
	for i, v in ipairs(ret) do
		if (v ~= '') then
			ret[i] = string.format('[[Category:%s]]', v)
		end
	end

	return table.concat(ret, '')
end

return p