Módulo:Edition

Wikisource, a biblioteca livre
Documentação do módulo[ver] [editar] [histórico] [purgar]

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[editar]

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

Used by {{author-list}}.

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

Method: badge[editar]

Display Wikidata badges for an edition.

Edition Wikitext Output
A Camp in the Adirondacks {{#invoke:Edition|badge|wikidata=Q16325556}} validado
The Great Secret {{#invoke:Edition|badge|wikidata=Q75047127}} revisto
The Riverside song book/The Open Window {{#invoke:Edition|badge|wikidata=Q59364480}} documento digitalproblemático
Douglas Adams (no badge) {{#invoke:Edition|badge|wikidata=Q42}}

Method: inline[editar]

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}} A Pair of Blue Eyes (1873) ()Wikidata books task force logo

Method: authority_control[editar]

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[editar]

--------------------------------------------------------------------------------
-- 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'
topicsMainWikimediaPortalProp = 'P1151';

--------------------------------------------------------------------------------
-- 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

--------------------------------------------------------------------------------
-- For the given author item, find the Wikisource sitelink. If there isn't one,
-- check to see if there the author has a topicsMainWikimediaPortal statement,
-- and then see if that portal has a sitelink instead.
function get_author_sitelink( authorItem )
	local siteLink = authorItem:getSitelink( mw.language.getContentLanguage().code .. 'wikisource' )
	if ( siteLink ~= nil ) then
		return siteLink
	end
	portalStatements = authorItem:getBestStatements( topicsMainWikimediaPortalProp )
	for _, mainPortal in pairs( portalStatements ) do
		local mainPortalId = mainPortal['mainsnak']['datavalue']['value']['id']
		local mainPortalItem = mw.wikibase.getEntity( mainPortalId )
		siteLink = mainPortalItem:getSitelink( mw.language.getContentLanguage().code .. 'wikisource' )
	end
	return siteLink
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 = get_author_sitelink( authorItem )
		local authorName = authorItem:getLabel()
		if siteLink ~= nil then
			authorName = mw.title.new( siteLink ).text
		end
		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

--------------------------------------------------------------------------------
-- Get the schema.org URL for the itemtype of the given item.
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 = getItem( args )
	local outHtml = mw.html.create()
	mw.logObject(args)
	mw.logObject(item)
	if ( item == nil ) then
		outHtml:wikitext( '<span class="error">Unable to determine the Wikidata item to use</span>' )
		return tostring( outHtml )
	end

	-- Make sure it's an edition.
	local editionOrTranslationOfStmts = item:getBestStatements( editionOrTranslationOfProp )
	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. Get wikitext for displaying an edition's badges from Wikidata.
-- To get an indicator, pass args.indicator = true
-- Testing: =p.badge({args={wikidata='Q75043199'}})
--
function badge( args )
	local item = getItem( args )
	if not ( item and item.sitelinks and item.sitelinks.enwikisource and item.sitelinks.enwikisource.badges ) then
		return ''
	end
	local badges = item.sitelinks.enwikisource.badges
	local out = ''
	for _, badge in pairs( badges ) do
		local badgeOut = ''
		local badgeItem = mw.wikibase.getEntity( badge )
		local badgeName = ''
		local wikisourceBadgeClass = 'Q75042035'
		if badgeItem.claims.P31[1].mainsnak.datavalue.value.id == wikisourceBadgeClass and badgeItem.claims.P18 ~= nil then
			local imageName = badgeItem.claims.P18[1].mainsnak.datavalue.value
			if mw.wikibase.getLabel( badge ) ~= nil then
				badgeName = mw.wikibase.getLabel( badge )
			end
			badgeOut = '<span class="indicator-badge">[[File:' .. imageName .. '|16px|link=Help:Text status|' .. badgeName .. ']]</span>'
			if args.indicator ~= nil then
				badgeOut = '<indicator name="wikisource-badge-' .. badgeName .. '">' .. badgeOut .. '</indicator>'
			end
			if args.category ~= nil and badgeItem.claims.P910 ~= nil then
				local categoryQid = badgeItem.claims.P910[1].mainsnak.datavalue.value.id
				local category = mw.wikibase.getEntity( categoryQid )
				badgeOut = badgeOut .. '[[' .. category.sitelinks.enwikisource.title .. ']]'
			end
			out = out .. badgeOut
		end
	end
	return mw.getCurrentFrame():preprocess( out )
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 an appropriate element, use it.
	if type( args ) == 'table' then
		if args.wikidata ~= '' and args.wikidata ~= nil then
			id = args.wikidata
		elseif args.wikidata_id ~= '' and args.wikidata_id ~= nil then
			id = args.wikidata_id
		elseif args.page ~= '' and args.page ~= nil then
			local title = mw.title.new( args.page )
			id = mw.wikibase.getEntityIdForTitle( title.nsText .. title.text )
			-- If no entity for this page, maybe it's a subpage and we should look for the root page's entity.
			if id == nil then
				id = mw.wikibase.getEntityIdForTitle( title.nsText .. title.rootText )
			end
		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 ~= nil and propItem.aliases.en[1].value then
					propLabel = propItem.aliases.en[1].value
				end
				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;
}