Jump to content

Module:ⴰⵙⴰⵔⵎ/Aksel Tinfat

ⵙⴳ ⵡⵉⴽⵉⴱⵉⴷⵢⴰ
local p = {}

local function trimWhitespace(s)
	if type(s) ~= 'string' then return nil end
	s = s:match('^%s*(.-)%s*$')
	if s == '' then return nil end
	return s
end

local function addEditIcon(entityId, propertyId)
	if not entityId or not propertyId then return '' end
	return ' [[ⴰⴼⴰⵢⵍⵓ:Edit-icon.svg|15px|link=https://www.wikidata.org/wiki/' .. entityId .. '#' .. propertyId .. '|ⵙⵏⴼⵍ ⴳ ⵡⵉⴽⵉⴷⴰⵜⴰ]]'
end

local function getArgs(frame)
	local args = {}
	local parent = frame:getParent()
	if parent and parent.args then
		for k, v in pairs(parent.args) do
			args[k] = trimWhitespace(v)
		end
	end
	for k, v in pairs(frame.args) do
		args[k] = trimWhitespace(v)
	end
	return args
end

local function getEntity(entityId)
	if not mw.wikibase then return nil end
	if entityId == '' then entityId = nil end
	entityId = entityId or mw.wikibase.getEntityIdForCurrentPage()
	if not entityId or entityId == '' then return nil end

	local success, entity = pcall(function() return mw.wikibase.getEntity(entityId) end)
	if success and entity then
		entity.getBestStatements = function(self, propertyId)
			if not self.claims or not self.claims[propertyId] then return {} end
			local statements = {}
			for _, claim in pairs(self.claims[propertyId]) do
				if claim.mainsnak.snaktype == 'value' then
					table.insert(statements, claim)
				end
			end
			return statements
		end
		return entity
	end
	return nil
end

local function makeRequest(entityId, property)
	local entity = getEntity(entityId)
	if not entity then return nil, false end
	
	if property == 'P18' or property == 'P3383' then
		local images = entity:getBestStatements(property)
		if #images > 0 then
			return images[1].mainsnak.datavalue.value, true
		end
		return nil, false
	end

	local statements = entity:getBestStatements(property)
	if #statements > 0 then
		local valuesWithLinks = {}
		local limit = (property == 'P161') and 5 or 10 
		
		for i, statement in ipairs(statements) do
			if i > limit then break end
			
			local datavalue = statement.mainsnak.datavalue
			local valueToAdd = nil

			if datavalue.type == 'string' then
				valueToAdd = datavalue.value
			elseif datavalue.type == 'wikibase-entityid' then
				local targetEntityId = datavalue.value.id
				local label = mw.wikibase.getLabel(targetEntityId)
				
				if not label then
					local targetEntity = mw.wikibase.getEntity(targetEntityId)
					if targetEntity and targetEntity.labels then
						if targetEntity.labels.en then label = targetEntity.labels.en.value
						elseif targetEntity.labels.fr then label = targetEntity.labels.fr.value end
					end
				end
				
				label = label or targetEntityId
				local sitelink = mw.wikibase.getSitelink(targetEntityId)

				if sitelink then
					valueToAdd = string.format("[[%s|%s]]", sitelink, label)
				else
					valueToAdd = string.format("[[:d:%s|%s]]", targetEntityId, label)
				end

			elseif datavalue.type == 'quantity' then
				local amount = tonumber(datavalue.value.amount)
				local lang = mw.getContentLanguage()
				valueToAdd = amount and lang:formatNum(amount) or datavalue.value.amount
				
			elseif datavalue.type == 'time' then
				local timestamp = datavalue.value.time
				local year = string.match(timestamp, "^[%+%-](%d+)")
				valueToAdd = year
			elseif datavalue.type == 'monolingualtext' then
				valueToAdd = datavalue.value.text
			end

			if valueToAdd then
				table.insert(valuesWithLinks, valueToAdd)
			end
		end
		
		if #valuesWithLinks > 0 then
			local separator = (property == 'P161' or property == 'P57' or property == 'P272') and "<br />" or "، "
			return table.concat(valuesWithLinks, separator), true
		end
	end
	return nil, false
end

local function getValueOrWikidata(args, paramName, propertyId)
	local value = args[paramName]
	local fromWikidata = false
	
	if value then 
		value = trimWhitespace(value) 
	end
	
	if not value then
		if propertyId and args.qid ~= '' then
			value, fromWikidata = makeRequest(args.qid, propertyId)
		end
	end
	return value, fromWikidata
end

function p.main(frame)
	local args = getArgs(frame)
	local entityId = args.qid 
	if entityId == '' then entityId = nil end
	entityId = entityId or mw.wikibase.getEntityIdForCurrentPage()
	local entity = getEntity(entityId)

	frame:extensionTag('templatestyles', '', {src = 'ⴰⵍⴱⵓⴹ:ⵜⴰⴼⵍⵓⵖⵎⵉⵙⵜ ⴰⴼⵉⵍⵎ/styles.css'})

	local infobox = mw.html.create('table')
	infobox:addClass('infobox vcard')
	infobox:css({
		['border'] = '1px solid #a2a9b1',
		['background-color'] = '#f9f9f9',
		['color'] = 'black',
		['margin'] = '0.5em 0 0.5em 1em',
		['float'] = 'right',
		['clear'] = 'right',
		['font-size'] = '90%',
		['width'] = '20em',
		['border-spacing'] = '2px',
	})

	local headerValue = args['ⴰⵣⵡⵍ'] or args['title']
	if not headerValue and entityId then
		headerValue = mw.wikibase.getLabel(entityId)
	end
	headerValue = headerValue or mw.title.getCurrentTitle().text

	local headerRow = infobox:tag('tr')
	local headerCell = headerRow:tag('th')
		:attr('colspan', 2)
		:css({
			['background-color'] = '#09c8bd',
			['color'] = '#ffffff',
			['padding'] = '0.4em',
			['text-align'] = 'center',
			['font-weight'] = 'bold',
			['font-size'] = '125%',
			['position'] = 'relative'
		})

	local headerContainer = mw.html.create('div')
		:css({
			['padding-right'] = '50px', 
			['padding-left'] = '50px',  
		})
		:wikitext(headerValue)
	headerCell:node(headerContainer)

	local iconContainer = mw.html.create('div')
		:css({
			['position'] = 'absolute',
			['top'] = '0.4px',
			['right'] = '1px',
		})
		:wikitext('[[ⴰⴼⴰⵢⵍⵓ:Picto_infobox_cinema.png|172px|alt=Cinema|link=]]')
	headerCell:node(iconContainer)

	local originalTitle, _ = getValueOrWikidata(args, 'ⴰⵣⵡⵍ ⴰⵥⵓⵕⴰⵏ', 'P1476')
	if originalTitle then
		infobox:tag('tr'):tag('td')
			:attr('colspan', 2)
			:css({['text-align'] = 'center', ['font-weight'] = 'bold', ['font-style'] = 'italic'})
			:wikitext(originalTitle)
	end

	local imageVal, _ = getValueOrWikidata(args, 'ⵜⴰⵡⵍⴰⴼⵜ', 'P3383')
	if not imageVal then imageVal, _ = getValueOrWikidata(args, 'ⵜⴰⵡⵍⴰⴼⵜ', 'P18') end
	
	if imageVal then
		local caption = args['ⴰⴳⵍⴰⵎ ⵏ ⵜⵡⵍⴰⴼⵜ'] or ''
		infobox:tag('tr'):tag('td')
			:attr('colspan', 2)
			:css('text-align', 'center')
			:wikitext('[[ⴰⴼⴰⵢⵍⵓ:' .. imageVal .. '|220px|frameless]]')
			:tag('div')
			:css({['padding-top'] = '3px', ['font-size'] = '90%'})
			:wikitext(caption)
	end

	local sectionHeaderStyle = {
		['background-color'] = '#09c8bd',
		['color'] = '#ffffff',
		['text-align'] = 'center',
		['font-weight'] = 'normal',
		['padding'] = '2px',
	}

	local sections = {
		{
			title = 'ⵓⵎⵍⴰⵏ ⵉⵎⴰⵜⴰⵢⵏ',
			properties = {
				{ 'ⴰⵏⴰⵡ', 'ⴰⵏⴰⵡ', 'P31' },
				{ 'ⵉⵎⵔⵙⵉ', 'ⵉⵎⵔⵙⵉ', 'P921' },
				{ 'ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⴼⵓⵖ', 'ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⴼⵓⵖ', 'P577' },
				{ 'ⵜⴰⵣⵣⵉⴳⵣⵜ', 'ⵜⴰⵣⵣⵉⴳⵣⵜ', 'P2047' },
				{ 'ⵜⵓⵜⵍⴰⵢⵜ', 'ⵜⵓⵜⵍⴰⵢⵜ', 'P364' },
				{ 'ⵜⴰⵎⵓⵔⵜ', 'ⵜⴰⵎⵓⵔⵜ', 'P495' },
				{ 'ⵉⴷⵖⴰⵔⵏ ⵏ ⵓⵙⵓⵍⴼ', 'ⵉⴷⵖⴰⵔⵏ ⵏ ⵓⵙⵓⵍⴼ', 'P915' },
			}
		},
		{
			title = 'ⴰⴳⴰⵍⵓⴼ',
			properties = {
				{ 'ⴰⵎⵙⵙⵓⴼⵖ', 'ⴰⵎⵙⵙⵓⴼⵖ', 'P57' },
				{ 'ⴰⵙⵉⵏⴰⵔⵢⵓ', 'ⴰⵙⵉⵏⴰⵔⵢⵓ', 'P58' },
				{ 'ⵜⴰⵏⵇⵇⵉⵙⵜ', 'ⵜⴰⵏⵇⵇⵉⵙⵜ', 'P3275' },
				{ 'ⵉⵎⵙⵎⴷⴰⵢⵏ', 'ⵉⵎⵙⵎⴷⴰⵢⵏ', 'P161' },
				{ 'ⴰⵥⴰⵡⴰⵏ', 'ⴰⵥⴰⵡⴰⵏ', 'P86' },
				{ 'ⴰⵙⵏⴰⵢ', 'ⴰⵙⵏⴰⵢ', 'P1040' },
				{ 'ⵜⵉⵎⵍⵙⴰ', 'ⵜⵉⵎⵍⵙⴰ', 'P2515' },
			}
		},
		{
			title = 'ⵜⴰⵎⴳⵓⵔⵉ ⵏ ⵙⵙⵉⵏⵉⵎⴰ',
			properties = {
				{ 'ⵜⴰⵎⵙⵙⵓⵔⵜ ⵏ ⵓⴼⴰⵔⵙ', 'ⵜⴰⵎⵙⵙⵓⵔⵜ', 'P272' },
				{ 'ⴰⵎⴼⴰⵔⵙ', 'ⴰⵎⴼⴰⵔⵙ', 'P162' },
				{ 'ⴰⵎⵣⵓⵣⵣⵔ', 'ⴰⵎⵣⵓⵣⵣⵔ', 'P750' },
				{ 'ⵜⴰⵎⵥⵍⴰⵢⵜ', 'ⵜⴰⵎⵥⵍⴰⵢⵜ', 'P2130' },
				{ 'ⵜⵉⵢⴰⴼⵓⵜⵉⵏ', 'ⵜⵉⵢⴰⴼⵓⵜⵉⵏ', 'P2142' },
			}
		},
		{
			title = 'ⵜⴰⵙⴷⴷⵉⵜ',
			properties = {
				{ 'ⵜⴰⵙⴷⴷⵉⵜ', 'ⵜⴰⵙⴷⴷⵉⵜ', 'P179' },
				{ 'ⵉⵣⵡⴰⵔ ⵜ', 'ⵉⵣⵡⴰⵔ ⵜ', 'P155' },
				{ 'ⵉⴹⴼⴰⵕ ⵜ', 'ⵉⴹⴼⴰⵕ ⵜ', 'P156' },
			}
		}
	}

	for _, section in ipairs(sections) do
		local sectionContent = mw.html.create('')
		local hasData = false

		for _, prop in ipairs(section.properties) do
			local label, param, pid = unpack(prop)
			local value, fromWikidata = getValueOrWikidata(args, param, pid)

			if value then
				hasData = true
				local row = sectionContent:tag('tr')
				row:tag('th')
					:wikitext(label)
					:css({
						['text-align'] = 'left',
						['width'] = '40%',
						['padding-right'] = '10px',
						['font-weight'] = 'normal',
						['background-color'] = '#F0F8FF',
						['vertical-align'] = 'top'
					})
				
				local cell = row:tag('td'):css({['padding'] = '2px', ['width'] = '60%'})
				
				if param == 'ⵜⴰⵣⵣⵉⴳⵣⵜ' and tonumber(value) then
					value = value .. ' ⵜⵓⵙⴷⵉⴷⵉⵏ'
				end
				
				if fromWikidata and pid and entityId then
					cell:wikitext(value .. addEditIcon(entityId, pid))
				else
					cell:wikitext(value)
				end
			end
		end

		if hasData then
			infobox:tag('tr'):tag('th')
				:attr('colspan', 2)
				:css(sectionHeaderStyle)
				:wikitext(section.title)
			infobox:node(sectionContent)
		end
	end

	local separatorRow = infobox:tag('tr')
	local separatorCell = separatorRow:tag('td')
		:attr('colspan', 2)
		:css({
			['padding'] = '0',
			['border-top'] = '2px dashed #09c8bd',
		})
	separatorCell:tag('div'):css({['height'] = '1px', ['background-color'] = 'transparent'})

	local currentTitle = mw.title.getCurrentTitle()
	local editSourceUrl = currentTitle:fullUrl({action='edit', section='0'})
	local editVisualUrl = currentTitle:fullUrl({veaction='edit'})
	local templateDocUrl = mw.title.new('ⴰⵍⴱⵓⴹ:ⵜⴰⴼⵍⵓⵖⵎⵉⵙⵜ ⴰⴼⵉⵍⵎ'):fullUrl()

	local footerRow = infobox:tag('tr')
	local footerCell = footerRow:tag('td')
		:attr('colspan', 2)
		:css({
			['padding'] = '0.2em',
			['font-size'] = '85%',
			['text-align'] = 'left',
			['background-color'] = '#f8f8f8',
		})

	local footerContainer = mw.html.create('div')
		:css({
			['display'] = 'flex',
			['justify-content'] = 'space-between',
			['align-items'] = 'center',
		})

	local editLinksSpan = footerContainer:tag('span'):addClass('plainlinks')
	if entityId and entityId ~= '' then
		local wikidataUrl = 'https://www.wikidata.org/wiki/Special:EntityPage/' .. entityId
		editLinksSpan:wikitext('[' .. editSourceUrl .. ' <span style="color:#002bb8;">ⵙⵏⴼⵍ ⴰⵙⴰⴳⵎ</span>] - [' ..
			editVisualUrl .. ' <span style="color:#002bb8;">ⵙⵏⴼⵍ</span>] - [' ..
			wikidataUrl .. ' <span style="color:#002bb8;">ⵡⵉⴽⵉⴷⴰⵜⴰ</span>]')
	else
		editLinksSpan:wikitext('[' .. editSourceUrl .. ' <span style="color:#002bb8;">ⵙⵏⴼⵍ ⴰⵙⴰⴳⵎ</span>] - [' ..
			editVisualUrl .. ' <span style="color:#002bb8;">ⵙⵏⴼⵍ</span>]')
	end

	footerContainer:tag('span')
		:css({['float'] = 'right', ['margin-left'] = '5px'})
		:wikitext('[[ⴰⴼⴰⵢⵍⵓ:Info Simple.svg|18px|ⵥⵕ ⵓⴳⴳⴰⵔ ⵅⴼ ⵡⴰⵍⴱⵓⴹ ⴰⴷ |link=' .. templateDocUrl .. ']]')

	footerCell:node(footerContainer)

	return tostring(infobox)
end

return p