Module:Edition

From Wikisource
Jump to: navigation, search
Documentation icon Module documentation[view] [edit] [history] [purge]

The Edition module is responsible for retrieving and displaying various bits of data about editions on Wikisource.

For all of the methods below, the wikidata parameter can be left out and the item ID of the page on which it is invoked will be used.

Method: author_list[edit]

Get a list of authors. These will be linked to their author pages where they exist.

Wikitext Output
{{#invoke:Edition|author_list|wikidata=Q28913867}}

Method: badge[edit]

Display Wikidata badges for an edition.

Challenges and opportunities for digital history is a digital document, and is badged as such:

Wikitext Output
{{#invoke:Edition|badge|wikidata=Q28020002}} Digital Electronics Icon.svg

Method: inline[edit]

The 'inline summary' of an edition can be used on an author's page, for example, to show the basic details about the edition and work.

Wikitext Output
{{#invoke:Edition|inline|wikidata_id=Q28913867}} Lua error at line 129: bad argument #1 to 'getBestStatements' (string expected, got nil).

Method: authority_control[edit]

For editions, you can list all available authority controlled identifiers with:

Wikitext Output
{{#invoke:Edition|authority_control|wikidata=Q28020002}}

And if you want to list all for the parent work of the edition, use:

Wikitext Output
{{#invoke:Edition|authority_control|wikidata=Q28020002|show_work=yes}}

See also[edit]

--------------------------------------------------------------------------------
-- Organisation of this module: the exports are listed at the bottom; their
-- direct functions are just above there, and supporting functions are higher
-- up.
--
-- Please add testcases before modifying anything.
--
--------------------------------------------------------------------------------

instanceOfProp = 'P31'
authorProp = 'P50'
editionOrTranslationOfProp = 'P629'
equivalentClassProp = 'P1709'

--------------------------------------------------------------------------------
-- Insert a value into a table, but not if it's already there.
function tableInsertUnique( theTable, value )
	for _, item in pairs( theTable ) do
		if item == value then
			-- Already present
			return
		end
	end
	-- Otherwise, add the new value.
	table.insert( theTable, value )
end

--------------------------------------------------------------------------------
-- Create the HTML (including wikitext link) for all provided authors,
-- and add it to the given authorLinks table (for later concatenation).
function process_authors( authorLinks, authors )
	if authors == nil or #authors == 0 then
		return
	end
	for _, author in pairs( authors ) do
		local authorId = author['mainsnak']['datavalue']['value']['id']
		local authorItem =  mw.wikibase.getEntity( authorId )
		local siteLink = authorItem:getSitelink( mw.language.getContentLanguage().code .. 'wikisource' )
		local authorName = authorItem:getLabel()
		local authorHtml = mw.html.create('span')
			:attr('itemprop', 'author')
			:attr('itemscope', '')
			:attr('itemtype', getSchemaorgItemtype( authorItem ) )
		local authorNameHtml = authorHtml:tag( 'span' )
		authorNameHtml:attr( 'itemprop', 'name' )
			:wikitext( authorName )
		local authorHtmlStr = tostring( authorHtml )
		if siteLink == nil then
			tableInsertUnique( authorLinks, authorHtmlStr )
		else
			tableInsertUnique( authorLinks, '[[' .. siteLink .. '|' .. authorHtmlStr .. ']]' )
		end
	end
end

function getSchemaorgItemtype( item )
	local schemaPrefix = 'http://schema.org/'
	for _, instanceOf in pairs( item:getBestStatements( instanceOfProp ) ) do
		local instanceOfId = instanceOf['mainsnak']['datavalue']['value']['id']
		local instanceOfItem = mw.wikibase.getEntity( instanceOfId )
		-- Now go through each of the instance-of item's class statements,
		-- seeing if we can find a matching schema.org URL.
		for _, equivClass in pairs( instanceOfItem:getBestStatements( equivalentClassProp ) ) do
			local val = equivClass['mainsnak']['datavalue']['value']
			if string.sub( val, 1, #schemaPrefix ) == schemaPrefix then
				-- This is a schema.org URL.
				return val
			end
		end
	end
	-- If we've not figured it out by now, give up with the default.
	return schemaPrefix .. 'Thing'
end

--------------------------------------------------------------------------------
-- Exported method.
--
function author_list( args )
	local item = getItem( args )
	if item == nil then
		return ''
	end
	local authorLinks = {}

	-- Collect the authors of this item.
	local authors = item:getBestStatements( authorProp )
	process_authors( authorLinks, authors )

	-- Also collect the authors of the parent work.
	local works = item:getBestStatements( editionOrTranslationOfProp )
	for _, work in pairs( works ) do
		local workId = work['mainsnak']['datavalue']['value']['id']
		local workItem = mw.wikibase.getEntity( workId )
		authors = workItem:getBestStatements( authorProp )
		if #authors > 0 then
			process_authors( authorLinks, authors )
		end
	end

	-- Output the final list of links.
	local outHtml = mw.html.create()
	local separator = args.separator or ', '
	local last_separator = args.last_separator or ', and '
	local i = 1
	for _, link in pairs( authorLinks ) do
		outHtml:wikitext( link )
		if i == ( #authorLinks - 1 ) then
			outHtml:wikitext( last_separator )
		elseif #authorLinks > 1 and i ~= #authorLinks then
			outHtml:wikitext( separator )
		end
		i = i + 1
	end
	return tostring( outHtml )
end

--------------------------------------------------------------------------------
-- Exported method.
--
function inline( args )
	local item = mw.wikibase.getEntity()
	if args.wikidata_id ~= nil and args.wikidata_id ~= '' then
		-- This check required because getEntity can't copy with empty strings.
		item = mw.wikibase.getEntity( args.wikidata_id )
	end
	local outHtml = mw.html.create()

	-- Make sure it's an edition.
	local editionOrTranslationOfStmts = item:getBestStatements( editionOrTranslationOf )
	if #editionOrTranslationOfStmts == 0 then
		outHtml:wikitext( '<span class="error">' .. item.id .. ' is not an edition or translation of a work (missing P629)</span>' )
		return tostring( outHtml )
	end


	-- Title/label.
	local title = item:getSitelink( 'enwikisource' )
	local label = item:getLabel( 'en' )
	local hasWikisourcePage = false
	if title == nil or title == '' then
		title = label
	else
		hasWikisourcePage = true
		title = '[[' .. title .. '|' .. label .. ']]'
	end
	outHtml:wikitext( title .. ' ' );


	-- Publication date
	local publicationDate = item:formatPropertyValues( 'P577' )
	outHtml:wikitext( '(' .. publicationDate.value .. ') ' )


	-- Scanned file on Wikimedia Commons.
	if not hasWikisourcePage then
		-- Add links to Index page or Commons file.
		local hasIndexOrCommonsLink = false
		local scannedFileOnWikimediaCommons = 'P996'
		local scannedFileOnWikimediaCommonsStmts = item:getBestStatements( scannedFileOnWikimediaCommons )
		for _, stmt in pairs( scannedFileOnWikimediaCommonsStmts ) do
			local commonsFilename = stmt['mainsnak']['datavalue']['value']
			outHtml:wikitext( ' ' .. mw.getCurrentFrame():expandTemplate{ title = 'Small scan link', args = { commonsFilename } } )
			hasIndexOrCommonsLink = true;
		end
		-- Add link to the IA item if no links were added above.
		if not hasIndexOrCommonsLink then
			local internetArchiveIdProp = 'P724'
			local internetArchiveIdStmts = item:getBestStatements( internetArchiveIdProp )
			for _, stmt in pairs( internetArchiveIdStmts ) do
				local internetArchiveId = stmt['mainsnak']['datavalue']['value']
				outHtml:wikitext( ' ' .. mw.getCurrentFrame():expandTemplate{ title = 'IA small link', args = { internetArchiveId } } )
			end
		end
	end


	-- Wikidata and Wikipedia links.
	local img = '[[File:Wikidata-books-task-force-logo.svg|20px|alt=Wikidata books task force logo|link=d:' .. item.id .. '|View on Wikidata]]'
	outHtml:wikitext( img )

	return tostring( outHtml )
end

--------------------------------------------------------------------------------
-- Exported method.
--
function badge( args )
	local item = getItem( args )
	if item.sitelinks and item.sitelinks.enwikisource and item.sitelinks.enwikisource.badges then
		local badges = item.sitelinks.enwikisource.badges
		for _, badge in pairs( badges ) do
			if badge == 'Q28064618' then
				return '<span class="badge digital-document-badge Q28064618">[[File:Digital Electronics Icon.svg|16px|link=d:' .. item.id .. ']]</span>'
			end
		end
	end
end

--------------------------------------------------------------------------------
-- Get an Item based on what's passed in the 'wikidata' or 'page' parameters of
-- the args, or the current page's ID otherwise.
function getItem( args )
	local id = nil
	-- If args is a table with a wikidata element, use it.
	if type( args ) == 'table' then
		if args.wikidata ~= '' and args.wikidata ~= nil then
			id = args.wikidata
		elseif args.page ~= '' and args.page ~= nil then
			id = mw.wikibase.getEntityIdForTitle( args.page )
		end
	end
	if type( args ) == 'string' and args ~= '' then
		id = args
	end
	return mw.wikibase.getEntity( id )
end

--------------------------------------------------------------------------------
-- Exported method.
function authority_control( args )
	local item = getItem( args )
	-- Gather every 'external-id' statement.
	local out = mw.html.create( '' )
	for propertyId,claims in pairs( item.claims) do
		local propItem = getItem( propertyId )
		for _,claim in pairs( claims ) do
			if claim.mainsnak.datatype == 'external-id' then
				local propLabel = propertyId
				if propItem.aliases.en[1].value then
					propLabel = propItem.aliases.en[1].value
				end
				-- mw.logObject(propItem)
				out:wikitext( '* [[' .. propLabel .. ']]: ' .. claim.mainsnak.datavalue.value .. '\n' )
			end
		end
	end
	return tostring( out )
end

--------------------------------------------------------------------------------
-- Export all public functions.
return {
	-- =p.author_list({args={wikidata='Q28913867'}})
	author_list = function( frame ) return author_list( frame.args ) end;
	-- =p.inline({args={wikidata_id='Q28913867'}})
	inline = function( frame ) return inline( frame.args ) end;
	-- =p.badge({args={wikidata='Q28020002'}})
	badge = function( frame ) return badge( frame.args ) end;
	-- =p.authority_control({args={wikidata='Q19035838'}})
	authority_control = function( frame ) return authority_control( frame.args ) end;
}