Module:Wikidata statements
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules
The Wikidata statements module provides a number of helper functions to access selected statements from Wikidata. It is intended to be used by other modules; calling these functions directly from Wikitext is not possible.
Usage
editlocal wdStatements = require "Module:Wikidata statements" values = getValueList(entityId, propertyId) items = getItemIdList(entityId, propertyId) value = getOneValue(entityId, propertyId) property = getOnePropertyId(entityId, propertyId) item = getOneItemId(entityId, propertyId)
Parameters
editAll public functions have the same two parameters:
- entityId
- The ID of the entity whose statements are queried. This can be any valid Wikidata entity ID, either an item ID (like "Q1") or a property ID (like "P373").
- propertyId
- The ID of the property of the statements which are queried. This can be any valid Wikidata property ID (like "P373").
For example, passing the parameters ("Q30", "P36") will query the property capital (P36) of the item United States of America (Q30).
Functions
editAll functions will discard the following statements before returning any result:
- All statements with a "deprecated" rank.
- All statements with a "normal" rank if there is at least one statement with a "preferred" rank.
- All statements with qualifiers P580 (start time) and/or P582 (end time) which indicate that the statement's validity has either not yet started or already expired at the time of the query.
- getValueList(itemId, propertyId)
- Return a Lua table of statements filtered according to the rules described above, each of them formatted as Wikitext.
- getItemIdList(itemId, propertyId)
- Return a Lua table of Wikidata item IDs for a property which is expected to actually hold references to other Wikidata items. If the property holds values other than references to other Wikidata items, an error is generated.
- getOneValue(itemId, propertyId)
- Return a single statement formatted as Wikitext. If the queried item has multiple statements for the given property (even after filtering according to the rules described above), an error is generated.
- getOnePropertyId(itemId, propertyId)
- Return a single Wikidata item ID for a property which is expected to actually hold references to Wikidata properties. If the property holds values other than such references, or the queried item has multiple statements for the given property (even after filtering according to the rules described above), an error is generated.
- getOneItemId(itemId, propertyId)
- Return a single Wikidata item ID for a property which is expected to actually hold references to other Wikidata items. If the property holds values other than such references, or the queried item has multiple statements for the given property (even after filtering according to the rules described above), an error is generated.
Code
-- =============================================================================
-- Routines for accessing statements from Wikidata
-- =============================================================================
local p = {}
-- -----------------------------------------------------------------------------
-- Return information about a statement, usable for error messages
-- -----------------------------------------------------------------------------
local function statementInfo(statement)
return (
"Item " .. string.match(statement.id, "^(.*)%$")
.. ", Property " .. statement.mainsnak.property
)
end
-- -----------------------------------------------------------------------------
-- Return the item id for a statement that points to a data item
-- -----------------------------------------------------------------------------
local function getAnyId(statement, datatype, entitytype)
assert(
statement.mainsnak.datatype == datatype,
statementInfo(statement) .. " is not of datatype " .. datatype
)
local datavalue = assert(
statement.mainsnak.datavalue,
statementInfo(statement) .. " has no datavalue"
)
assert(
datavalue.type == "wikibase-entityid",
statementInfo(statement) .. "'s value is not of type wikibase-entityid"
)
local value = assert(
datavalue.value,
statementInfo(statement) .. " has no value"
)
assert(
value["entity-type"] == entitytype,
statementInfo(statement) .. "'s value's entity-type is not " .. entitytype
)
return assert(
value.id,
statementInfo(statement) .. "'s value has no id field"
)
end
-- -----------------------------------------------------------------------------
-- Return the item id for a statement that points to a data item
-- -----------------------------------------------------------------------------
local function getItemId(statement)
return getAnyId(statement, "wikibase-item", "item")
end
-- -----------------------------------------------------------------------------
-- Return the property id for a statement that points to a property
-- -----------------------------------------------------------------------------
local function getPropertyId(statement)
return getAnyId(statement, "wikibase-property", "property")
end
-- -----------------------------------------------------------------------------
-- Return a list of statements for a property, filter out obsolete ones
-- -----------------------------------------------------------------------------
local function getStatementList(entityId, propertyId)
local result = {}
for index, statement in ipairs(mw.wikibase.getBestStatements(entityId, propertyId)) do
local useThis = true
-- Filter out statements with start time in the future
local startTime = statement.qualifiers and statement.qualifiers.P580
if startTime then
assert(#startTime == 1, statementInfo(statement) .. " has more than one start time")
-- FIXME: Is there a better way to check whether a time value is in the future?
local lang = mw.getContentLanguage()
if startTime[1].datavalue and tonumber(lang:formatDate("U", "now")) < tonumber(lang:formatDate("U", startTime[1].datavalue.value.time)) then
useThis = false
end
end
-- Filter out statements with end time in the past
local endTime = statement.qualifiers and statement.qualifiers.P582
if endTime then
assert(#endTime == 1, statementInfo(statement) .. " has more than one end time")
-- FIXME: Is there a better way to check whether a time value is in the past?
local lang = mw.getContentLanguage()
if endTime[1].datavalue and tonumber(lang:formatDate("U", "now")) > tonumber(lang:formatDate("U", endTime[1].datavalue.value.time)) then
useThis = false
end
end
if useThis then
table.insert(result, statement)
end
end
return result
end
-- -----------------------------------------------------------------------------
-- Return the rendered value of a single statement
-- -----------------------------------------------------------------------------
function p.getValueList(entityId, propertyId)
local result = {}
for index, statement in ipairs(getStatementList(entityId, propertyId)) do
local value = mw.wikibase.renderSnak(statement.mainsnak)
table.insert(result, value)
end
return result
end
-- -----------------------------------------------------------------------------
-- Return the item ids for statements that point to a data item
-- -----------------------------------------------------------------------------
function p.getItemIdList(entityId, propertyId)
local result = {}
for index, statement in ipairs(getStatementList(entityId, propertyId)) do
local itemId = getItemId(statement)
table.insert(result, itemId)
end
return result
end
-- -----------------------------------------------------------------------------
-- Return a single statement for a property, throw error if more than one
-- -----------------------------------------------------------------------------
local function getOneStatement(entityId, propertyId)
local statements = getStatementList(entityId, propertyId)
if #statements > 0 then
assert(#statements == 1, entityId .. " has more than one statement for " .. propertyId)
return statements[1]
else
return nil
end
end
-- -----------------------------------------------------------------------------
-- Return the rendered value of a single statement
-- -----------------------------------------------------------------------------
function p.getOneValue(entityId, propertyId)
local statement = getOneStatement(entityId, propertyId)
if statement then
return mw.wikibase.renderSnak(statement.mainsnak)
else
return nil
end
end
-- -----------------------------------------------------------------------------
-- Return the property id for a single statement that point to a property
-- -----------------------------------------------------------------------------
function p.getOnePropertyId(entityId, propertyId)
local statement = getOneStatement(entityId, propertyId)
if statement then
return getPropertyId(statement)
else
return nil
end
end
-- -----------------------------------------------------------------------------
-- Return the item id for a single statement that point to a data item
-- -----------------------------------------------------------------------------
function p.getOneItemId(entityId, propertyId)
local statement = getOneStatement(entityId, propertyId)
if statement then
return getItemId(statement)
else
return nil
end
end
-- =============================================================================
return p