Module:Timeline

Lua
CodeDiscussionLinksLink count SubpagesDocumentationTestsResultsSandboxLive code All modules

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

Code

-- Creates a timeline for an item based on various properties

local p = {}
local wikidata = require('Module:Wikidata')
local usual = require('Module:Wikidata/usual')

local lang, item

-- language depedent typo-functions
local function colon(lang)
	return mw.message.newFallbackSequence( "colon" ):inLanguage(lang):plain()
end

-- properties used / formatting instructions
local props = {
	P26 = function(event, lang) return wikidata._getLabel('P26', lang) .. colon(lang) .. usual.showvalue(event, lang) end, -- spouse
	P39 = function(event, lang) return usual.showvalue(event, lang) end, -- function held
	P69 = function(event, lang) return usual.studies(event, lang) end, -- alma mater
	P108 = function(event, lang) return usual.worksfor(event, lang) end, -- employer
	P166 = function(event, lang) return usual.showvalue(event, lang) end, -- award
	P551 = function(event, lang) return usual.livesin(event, lang) end, -- residence
	P571 = function(event, lang) return wikidata._getLabel('P571', lang) end, --fondation date / any better label ?
	P569 = function(event, lang) return usual.birthfortimeline(item, lang) end, -- ridiculously intricate, replace by the following line if needed
--	P569 = function(event) return usual.eventinplace('Q3335327', wikidata.getClaims({property = 'P19', item = item}, {lang=lang})[1], lang) end, -- slightly dubious as it potentially conflates two conlficting sources
	P570 = function(event, lang) return usual.eventinplace('Q4', wikidata.getClaims({property = 'P20', item = item}, {lang=lang})[1], lang) end, -- slightly dubious as it potentially conflates two conlficting sources
	P793 = function(event, lang) return usual.showvalue(event, lang) end, -- key event 
}


local function makeLabel(event, property, lang)
	local propformat = props[property]
	if not propformat then
		return wikidata._getLabel(property,lang) .. colon(lang) .. ' ' .. wikidata.formatStatement(event, {lang=lang})
	end
	if type(propformat) == 'function' then
		return propformat(event, lang) 
	end
	if type(propformat) == 'string' then
		return wikidata._getLabel(propformat, lang)
	end
end


local function processevent(event, property, lang)
	if event.mainsnak.snaktype ~= 'value' then 
		return
	end
	local timedata = wikidata.getDate(event)
	if not timedata then
		return
	end
	local timetext = wikidata.getFormattedDate(event, {})
	local eventtext = makeLabel(event, property, lang)
	
	return {label = eventtext, timedata = timedata, timetext = timetext}
end

function p._timeline(entity, lang, query) 
	local eventtable = {}
	if type(entity) == 'string' then -- if an id was sent rather than a datatable
		entity = mw.wikibase.getEntityObject(item)
	end
	-- process request from the query parameter
	--same args as in wikidata.getClaims
	if not query then
		query = {}
	end

	query.entity = entity
	if not query.rank then
		query.rank = 'valid'
	end
	
	local properties = query.property
	if type(properties) == 'string' then
		properties = {properties}
	end
	if not properties then
		properties = entity:getProperties()
	end

	 
	-- create the event table, as a table {label=, timedata=}
	for i, j in pairs(properties) do
		query.property = j
		local newevents = wikidata.getClaims(query)
		if newevents then
			for k, l in pairs(newevents) do
				local newevent = processevent(l, j, lang)
				table.insert(eventtable, newevent )
			end
		end
	end
	
	local str = '' -- output string, or rather an html table ? 
	table.sort(eventtable, function(a,b) return a.timedata.timestamp < b.timedata.timestamp end)
	for i, j in pairs(eventtable) do
		local eventtext = j.label or '?'
		local datetext =  j.timetext or '?'
		str = str .. datetext .. colon(lang) .. (eventtext or 'fixme') .. '<br />' 
	end
	if str ~= '' then -- return nil rather than '', simpler for the calling module
		return str
	end
end

function p.timeline(frame)
	lang = frame.args['lang']
	local properties = frame.args.properties
	
	if not lang or lang == '' then 
		lang = frame:preprocess( "{{int:lang}}" )
	end
	if properties == '' then
		properties = nil
	end
	if properties then
		properties = mw.text.trim(properties)
		properties = mw.text.split(properties, ',')
	end
	item = string.upper(frame.args['item'])
	if not item or string.sub(item, 1, 1) ~= 'Q' then 
		return 'please provide a valid item ID" (should start with "Q")' 
	end
	return p._timeline(item, lang, {properties = properties})
end

return p