Přeskočit na obsah

Modul:Wikidata: Porovnání verzí

Z Wikipedie, otevřené encyklopedie
Smazaný obsah Přidaný obsah
m sup
Řádek 3: Řádek 3:
local p = {}
local p = {}


local i18n = {
local lib = require "Modul:Wikidata/lib"
local i18n = mw.loadData("Modul:Wikidata/i18n")
errors = {
["entity-not-found"] = "Entita nenalezena",
["invalid-datatype"] = "Nesprávný datový typ vlastnosti „%s“: „%s“; vyžadován „%s“",
["invalid-date"] = "Neplatné datum „%s“",
["invalid-field"] = "Neplatné pole „%s“",
["invalid-sort"] = "Neplatný způsob řazení „%s“",
["param-not-provided"] = "Nezadán parametr „%s“",
["unknown-claim-type"] = "Neznámý typ tvrzení: %s",
["unknown-datavalue-type"] = "Neznámý typ datové hodnoty: %s",
["unknown-entity-type"] = "Neznámý typ entity: %s",
["unknown-snak-type"] = "Neznámý typ snaku: %s",
["unknown-value-module"] = "Musíte nastavit oba parametry „value-module“ i „value-function“",
["value-function-not-found"] = "Funkce „%s“ odkazovaná parametrem „value-function“ nenalezena",
["value-module-not-found"] = "Modul „%s“ odkazovaný parametrem „value-module“ nenalezen"
},
lang = mw.language.getContentLanguage(),
more = "… více na [[d:%s#%s|Wikidatech]]",
novalue = "''bez hodnoty''",
somevalue = "''neznámá hodnota''"
}

local props = {
begin = { 'P569', 'P580' },
ending = { 'P570', 'P582' },
lang = { 'P407' },
point = { 'P571', 'P577', 'P585' },
}

local function formatError(key, ...)
return error(mw.ustring.format(i18n.errors[key], ...), 3)
end


local function getEntityFromId(id)
local function getEntityFromId(id)
return mw.wikibase.getEntityObject(id)
return mw.wikibase.getEntityObject(id)
end

function p.getEntityIdFromValue(value)
local entityType = value['entity-type']
if entityType == 'item' then
return 'Q' .. value['numeric-id']
elseif entityType == 'property' then
return 'P' .. value['numeric-id']
else
return formatError( 'unknown-entity-type', entityType )
end
end

-- move to submodule
local function filterStatements(entity, options)
if not options.property or options.property == '' then
return formatError( 'param-not-provided', 'property' )
else
options.property = options.property:upper()
end
if not (entity and entity.claims and entity.claims[options.property]) then
return {}
end
local Statements, oldStatements = entity.claims[options.property], {}
-- apply filter by rank
if not options.rank or options.rank ~= "all" then
oldStatements, Statements = Statements, {}
if not options.rank or options.rank == "best" or options.rank == "valid" then
if options.rank == "best" then
for _, statement in pairs(oldStatements) do
if statement.rank == "preferred" then
table.insert(Statements, statement)
end
end
if #Statements == 0 then
for _, statement in pairs(oldStatements) do
if statement.rank == "normal" then
table.insert(Statements, statement)
end
end
end
else
for _, statement in pairs(oldStatements) do
if statement.rank ~= "deprecated" then
table.insert(Statements, statement)
end
end
end
else
for _, statement in pairs(oldStatements) do
if statement.rank == options.rank then
table.insert(Statements, statement)
end
end
end
if #Statements == 0 then return {} end
end
-- apply filter by source
if options.ref and options.ref == '#any' then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.references then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by snak type
if not options.showspecial or tostring(options.showspecial) ~= "true" then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.mainsnak.snaktype == "value" then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by qualifier property
if options.withqualifier and options.withqualifier ~= '' then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.qualifiers and statement.qualifiers[options.withqualifier:upper()] then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by class
if options.class and options.class ~= '' then
local datatype = Statements[1].mainsnak.datatype
if datatype == 'wikibase-item' or datatype == 'wikibase-property' then
local class = options.class:upper()
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.mainsnak.snaktype == "value" then
local function IsInClass(id)
local entity = getEntityFromId(id)
local Classes = entity:getBestStatements('P279')
if Classes then
for _, class in pairs(Classes) do
if class.mainsnak.snaktype == 'value' then
local id = p.getEntityIdFromValue(class.mainsnak.datavalue.value)
if class == id or IsInClass(id) then
return true
end
end
end
end
return false
end
local entity = getEntityFromId(p.getEntityIdFromValue(statement.mainsnak.datavalue.value))
local Instances = entity:getBestStatements('P31')
if Instances then
for _, instance in pairs(Instances) do
if instance.mainsnak.snaktype == 'value' then
local id = p.getEntityIdFromValue(instance.mainsnak.datavalue.value)
if class == id or IsInClass(id) then
table.insert(Statements, statement)
break
end
end
end
end
end
end
if #Statements == 0 then return {} end
else
return formatError('invalid-datatype', options.property, datatype, 'wikibase-item/wikibase-property')
end
end
-- apply filter by language
if options.withlang and options.withlang ~= '' then
local datatype = Statements[1].mainsnak.datatype
if datatype == 'monolingualtext' then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.mainsnak.snaktype == "value" then
if statement.mainsnak.datavalue.value.language == options.withlang then
table.insert(Statements, statement)
end
end
end
if #Statements == 0 then return {} end
else
return formatError('invalid-datatype', options.property, datatype, 'monolingualtext')
end
end
-- apply filter by time
if options.date and options.date ~= '' then
local date
local Time = require 'Modul:Time'
if type(options.date) == 'table' then
date = options.date
-- elseif mw.ustring.find(options.date, '^[Pp][1-9]%d-$') then
elseif options.date == '#now' then
date = Time.new( os.date('!*t') )
else
date = Time.newFromIso8601( options.date )
end
if date then
oldStatements, Statements = Statements, {}
local temp_value
local Date = require 'Modul:Wikidata/datum'
for _, statement in pairs(oldStatements) do
if statement.qualifiers then
local Values = {}
for key, array in pairs(props) do
for _, prop in pairs(array) do
if statement.qualifiers[prop] then
for _, qualData in pairs(statement.qualifiers[prop]) do
if qualData.snaktype == "value" then
Values[key] = Time.newFromWikidataValue(qualData.datavalue.value)
break
end
end
end
end
end
if Values.point then
if not Date.IsSecondLaterThanFirst(date, Values.point) then
if not temp_value then
Statements = { statement }
temp_value = Values.point
else
if Date.IsSecondLaterThanFirst(Values.point, temp_value) then
Statements = { statement }
temp_value = Values.point
elseif Date.IsSecondSameAsFirst(temp_value, Values.point) then
table.insert(Statements, statement)
end
end
end
else
if Values.begin then
if Date.IsSecondLaterThanFirst(Values.begin, date) then
if not Values.ending then
table.insert(Statements, statement)
elseif Date.IsSecondLaterThanFirst(date, Values.ending) then
table.insert(Statements, statement)
end
end
elseif Values.ending then
if Date.IsSecondLaterThanFirst(date, Values.ending) then
if not Values.begin then
table.insert(Statements, statement)
elseif Date.IsSecondLaterThanFirst(Values.begin, date) then
table.insert(Statements, statement)
end
end
end
end
end
end
if #Statements == 0 then return {} end
else
return formatError('invalid-date', options.date)
end
end
-- sort statements if needed
if options.sort and options.sort ~= '' then
local function checkInvert(value)
if options.invert and tostring(options.invert) == 'true' then
return not value
end
return value and true
end
if options.sort == 'rank' then
table.sort(Statements, function(first, second)
if first.rank == 'preferred' and second.rank ~= 'preferred' then
return checkInvert(true)
elseif first.rank == 'normal' and second.rank == 'deprecated' then
return checkInvert(true)
end
return checkInvert(false)
end)
elseif options.sort == 'date' then
table.sort(Statements, function(first, second)
local FirstValues, SecondValues
local Date = require 'Modul:Wikidata/datum'
if first and first.qualifiers then
FirstValues = {}
local Time = require 'Modul:Time'
for key, array in pairs(props) do
for _, prop in pairs(array) do
if first.qualifiers[prop] then
for _, qualData in pairs(first.qualifiers[prop]) do
if qualData.snaktype == "value" then
FirstValues[key] = Time.newFromWikidataValue(qualData.datavalue.value)
break
end
end
end
end
end
end
if second and second.qualifiers then
SecondValues = {}
local Time = require 'Modul:Time'
for key, array in pairs(props) do
for _, prop in pairs(array) do
if second.qualifiers[prop] then
for _, qualData in pairs(second.qualifiers[prop]) do
if qualData.snaktype == "value" then
SecondValues[key] = Time.newFromWikidataValue(qualData.datavalue.value)
break
end
end
end
end
end
end
if not FirstValues or not SecondValues then
if not FirstValues and not SecondValues then
return checkInvert(false)
else
return checkInvert(not SecondValues)
end
end
if FirstValues.point or SecondValues.point then
if FirstValues.point and SecondValues.point then
return checkInvert(Date.IsSecondLaterThanFirst(FirstValues.point, SecondValues.point))
else
return checkInvert(not FirstValues.point)
end
else
if FirstValues.begin or SecondValues.begin then
if FirstValues.begin and SecondValues.begin then
return checkInvert(Date.IsSecondLaterThanFirst(FirstValues.begin, SecondValues.begin))
else
return checkInvert(not FirstValues.begin)
end
elseif FirstValues.ending or SecondValues.ending then
if FirstValues.ending and SecondValues.ending then
return checkInvert(Date.IsSecondLaterThanFirst(FirstValues.ending, SecondValues.ending))
else
return checkInvert(not FirstValues.ending)
end
end
end
return checkInvert(false)
end)
elseif options.sort == 'alfa' then
if Statements[1].mainsnak.datatype == 'wikibase-item' or Statements[1].mainsnak.datatype == 'wikibase-property' then
table.sort(Statements, function(first, second)
if not (first and second) then
return checkInvert(second)
end
if not (first.mainsnak.snaktype == "value" and second.mainsnak.snaktype == "value") then
return checkInvert(second.mainsnak.snaktype == "value")
end
local first_label = mw.wikibase.label(p.getEntityIdFromValue(first.mainsnak.datavalue.value))
local second_label = mw.wikibase.label(p.getEntityIdFromValue(second.mainsnak.datavalue.value))
if not (first_label and second_label) then
return checkInvert(second_label)
end
local min_length = mw.ustring.len(first_label)
if mw.ustring.len(second_label) < mw.ustring.len(first_label) then
min_length = mw.ustring.len(second_label)
end
local chars = ' -0123456789aábcčdďeéěfghiíjklmnňoópqrřsštťuúůvwxyýzž'
local function charValue(char)
return mw.ustring.match(chars, '()' .. char) or (mw.ustring.len(chars) + 1)
end
local i = 1
while i <= min_length do
local first_char = mw.ustring.sub(mw.ustring.lower(first_label), i, i)
local second_char = mw.ustring.sub(mw.ustring.lower(second_label), i, i)
if charValue(first_char) ~= charValue(second_char) then
return checkInvert(charValue(first_char) < charValue(second_char))
end
i = i + 1
end
return checkInvert(mw.ustring.len(second_label) == min_length)
end)
end
elseif options.sort == 'number' then
if Statements[1].mainsnak.datatype == 'quantity' then
table.sort(Statements, function(first, second)
if not (first and second) then
return checkInvert(second)
end
if not (first.mainsnak.snaktype == "value" and second.mainsnak.snaktype == "value") then
return checkInvert(second.mainsnak.snaktype == "value")
end
local first_quantity = tonumber(first.mainsnak.datavalue.value.amount)
local second_quantity = tonumber(second.mainsnak.datavalue.value.amount)
return checkInvert(first_quantity > second_quantity)
end)
end
else
return formatError('invalid-sort', options.sort)
end
end
-- apply filter by limit
local limit = options.limit
if limit then
while #Statements > limit do
table.remove(Statements)
end
end
return Statements
end
end


Řádek 419: Řádek 28:
if options.of and options.of ~= '' then
if options.of and options.of ~= '' then
if entity then
if entity then
local Statements = filterStatements(entity, { property = options.of, rank = 'best' })
local Statements = entity:getBestStatements(options.of)
for _, statement in pairs(Statements) do
for _, statement in pairs(Statements) do
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
local id = p.getEntityIdFromValue(statement.mainsnak.datavalue.value)
local id = lib.getEntityIdFromValue(statement.mainsnak.datavalue.value)
entity = getEntityFromId(id)
entity = getEntityFromId(id)
if entity and entity.id ~= id then
if entity and entity.id ~= id then
Řádek 429: Řádek 38:
return entity
return entity
else
else
return formatError('invalid-datatype', options.of:upper(), statement.mainsnak.datatype, 'wikibase-item/wikibase-property')
return error(lib.formatError('invalid-datatype', options.of:upper(), statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
end
end
end
end
Řádek 436: Řádek 45:
end
end
return entity
return entity
end

local function formatFromPattern( str, options )
return mw.ustring.gsub( options.pattern, '$1', str ) .. '' --Hack to get only the first result of the function
end
end


local function getSitelink(options)
local function getSitelink(options)
local options = lib.common.cleanArgs(options)
local site
if options.site and options.site ~= '' then
site = options.site
elseif options[1] and options[1] ~= '' then
site = mw.text.trim(options[1])
end


local entity = findEntity(options)
local entity = findEntity(options)

if not entity or not entity.sitelinks then
if not entity or not entity.sitelinks then
return nil
return nil
end
end

local site = options.site or options[1]


local sitelink = entity:getSitelink(site)
local sitelink = entity:getSitelink(site)

if not sitelink then
if not sitelink then
return nil
return nil
end
end

if options.pattern and options.pattern ~= '' then
if options.pattern then
sitelink = formatFromPattern(sitelink, options)
sitelink = lib.formatFromPattern(sitelink, options.pattern)
end
end
return sitelink
return sitelink
end
end


-- @deprecated
local function fastConvertDdToDms(ddValue)
local dmsArr = {
degrees = 0,
minutes = 0,
seconds = 0.0
}

if ddValue then
dmsArr["degrees"] = math.floor(tonumber(ddValue))
dmsArr["minutes"] = math.floor((tonumber(ddValue) - dmsArr["degrees"]) * 60)
dmsArr["seconds"] = (tonumber(ddValue) - dmsArr["degrees"] - dmsArr["minutes"]/60) * 3600
end

return dmsArr
end

local function formatCoordinateValue(datavalue, typeOfValue, field)
-- type bude nepovinny - tj. "nil"
-- priklad pouze -- je tam asi X chyb (mimo jine N vs S a podobne)
local value = ""
local latdmsText, londmsText
if typeOfValue == 'dms' then
local latDms = fastConvertDdToDms(datavalue.value.latitude)
local lonDms = fastConvertDdToDms(datavalue.value.longitude)
latdmsText = "N " .. latDms["degrees"] .. "° " .. latDms["minutes"] .. "' " .. latDms["seconds"] .. '"'
londmsText = "E " .. lonDms["degrees"] .. "° " .. lonDms["minutes"] .. "' " .. lonDms["seconds"] .. '"'
if field then
if field == 'latitude' then
value = latdmsText
elseif field == 'longitude' then
value = londmsText
end
else
value = latdmsText .. " " .. londmsText
end
elseif typeOfValue == 'dd' then
latdmsText = tonumber(datavalue.value.latitude)
londmsText = tonumber(datavalue.value.longitude)
if field then
if field == 'latitude' then
value = latdmsText
elseif field == 'longitude' then
value = londmsText
end
else
value = latdmsText .. " " .. londmsText
end
else
value = datavalue.value.latitude .. ' / ' .. datavalue.value.longitude .. ' (přesnost: ' .. datavalue.value.precision .. ')'
end

return value
end

local function formatEntityId(entityId, options)
local function formatEntityId(entityId, options)
local formatter = require 'Modul:Wikidata/item'
local formatter = require 'Modul:Wikidata/item'
Řádek 526: Řádek 74:
end
end


local function findPattern(property)
local function formatStatement(statement, options)
if not statement.type or statement.type ~= 'statement' then
local entity = getEntityFromId(property:upper())
return error(lib.formatError('unknown-claim-type', statement.type))
if entity then
local Statements = filterStatements(entity, { limit = 1, property = 'P1630', rank = 'best' })
if Statements[1] then
return Statements[1].mainsnak.datavalue.value
end
end
end
return nil
end


local function formatDatavalue( datavalue, options )
local options = lib.common.cleanArgs(options)
local Filterers = require 'Modul:Wikidata/Filterers'
--Use the customize handler if provided
local Formatters = require 'Modul:Wikidata/Formatters'
if options['value-module'] or options['value-function'] then
if not options['value-module'] or not options['value-function'] then
return formatError( 'unknown-value-module' )
end
local formatter = require ('Module:' .. options['value-module'])
if not formatter then
return formatError( 'value-module-not-found', options['value-module'] )
end
local fun = formatter[options['value-function']]
if not fun then
return formatError( 'value-function-not-found', options['value-function'] )
end
return fun( datavalue.value, options )
end


local mainsnak, qualifiers, targetdata, references
--Default formatters
if not lib.IsOptionTrue(options, 'qualifiersOnly') then
if datavalue.type == 'wikibase-entityid' then
return formatEntityId(p.getEntityIdFromValue(datavalue.value), options)
mainsnak = Formatters.getFormattedValue(statement.mainsnak, options)
elseif datavalue.type == 'string' then
if options.pattern and options.pattern ~= '' then
return formatFromPattern( datavalue.value, options )
elseif options.autoformat and tostring(options.autoformat) == 'true' then
local pattern = findPattern(options.property)
if pattern then
return formatFromPattern( datavalue.value, { pattern = '[' .. pattern .. ' $1]' } )
end
else
return datavalue.value
end
elseif datavalue.type == 'time' then
local Time = require 'Modul:Time'
return Time.newFromWikidataValue( datavalue.value ):toString()
elseif datavalue.type == 'globecoordinate' then
if not options.field or options.field == '' then
-- return formatError( 'param-not-provided', 'field' )
return formatCoordinateValue(datavalue, 'dms')
elseif options.field == "latitude" or options.field == "longitude" then
return formatCoordinateValue(datavalue, options.typeOfCoordinates, options.field)
elseif options.field == "precision" or options.field == "globe" then
return datavalue.value[options.field]
else
return formatError( 'invalid-field', options.field )
end
elseif datavalue.type == 'monolingualtext' then
return '<span lang="' .. datavalue.value.language .. '">' .. datavalue.value.text .. '</span>'
elseif datavalue.type == 'quantity' then
local value = tonumber(datavalue.value.amount)
local margin
if tostring(options.showmargin) == 'true' then
margin = value - tonumber(datavalue.value.lowerBound)
if margin == 0 then
margin = nil
end
end
local prefix
if value < 0 then
value = tonumber(mw.ustring.sub(value, 2))
prefix = '−'
end
if tostring(options.formatted) == 'true' then
local function formatNumber(number)
local integer, decimal
if mw.ustring.find(number, '%.') then
integer, decimal = mw.ustring.match(number, '^(.+)%.(.+)$')
else
integer = number
end
local length = mw.ustring.len(integer)
local i = length % 3
if i == 0 then
i = 3
end
local formatted_num = mw.ustring.sub(integer, 1, i)
while i < length do
formatted_num = formatted_num .. '&nbsp;' .. mw.ustring.sub(integer, i + 1, i + 3)
i = i + 3
end
if decimal then
local length = mw.ustring.len(decimal)
local i = 3
formatted_num = formatted_num .. ',' .. mw.ustring.sub(decimal, 1, 3)
while i < length do
formatted_num = formatted_num .. '&nbsp;' .. mw.ustring.sub(decimal, i + 1, i + 3)
i = i + 3
end
end
return formatted_num
end
value = formatNumber(value)
if margin then
margin = formatNumber(margin)
end
end
if margin then
value = value .. '±' .. margin
end
if prefix then
value = prefix .. value
end
local unit = datavalue.value.unit
if unit ~= '1' and tostring(options.showunit) ~= 'false' then
unit = mw.ustring.match(unit, '(Q%d+)')
unit = formatEntityId(unit, {})
value = value .. '&nbsp;' .. unit
end
return value
else
return formatError( 'unknown-datavalue-type', datavalue.type )
end
end
if statement.qualifiers and options.showqualifier then
end
local PropList = lib.textToTable(options.showqualifier)

local function formatSnak( snak, options )
if snak.snaktype == 'value' then
return formatDatavalue( snak.datavalue, options )
elseif snak.snaktype == 'somevalue' or snak.snaktype == 'novalue' then
return i18n[snak.snaktype]
else
return formatError( 'unknown-snak-type', snak.snaktype )
end
end

local function formatStatement( statement, options )
if not statement.type or statement.type ~= 'statement' then
return formatError( 'unknown-claim-type', statement.type )
end
local mainsnak = formatSnak(statement.mainsnak, options)
local qualifiers, targetdata, references
if statement.qualifiers and options.showqualifier and options.showqualifier ~= '' then
local Snaks = {}
local Snaks = {}
local PropList = {}
if type(options.showqualifier) == "table" then
PropList = options.showqualifier
else
PropList = mw.text.split(tostring(options.showqualifier):upper(), "%s*,%s*")
end
for _, property in pairs(PropList) do
for _, property in pairs(PropList) do
local Values = {}
local Values = {}
local options = {
local property = mw.ustring.upper(property)
local format_options = {
autoformat = true,
autoformat = true,
entity = options.entity,
precision = 9,
property = property
property = property,
}
}
if statement.qualifiers[property] then
if statement.qualifiers[property] then
for _, snakData in pairs(statement.qualifiers[property]) do
local Qualifiers = Filterers.filterQualifiers(statement.qualifiers[property], options)
for _, snak in pairs(Qualifiers) do
if snakData.snaktype == "value" then
if snakData.datatype == "time" then
if lib.IsSnakValue(snak) then
table.insert(Values, Formatters.getFormattedValue(snak, format_options))
options["value-module"] = "Wikidata/datum"
options["value-function"] = "formatDate"
options.precision = 9
end
table.insert(Values, formatDatavalue(snakData.datavalue, options))
end
end
end
end
elseif property == "TIME" then
elseif property == "TIME" then
local Data = {}
options["value-module"] = "Wikidata/datum"
for key, array in pairs(lib.props) do
options["value-function"] = "formatDate"
options.precision = 9
local Datavalues = {}
for key, array in pairs(props) do
for _, prop in pairs(array) do
for _, prop in pairs(array) do
if statement.qualifiers[prop] then
if statement.qualifiers[prop] then
for _, snakData in pairs(statement.qualifiers[prop]) do
for _, snak in pairs(statement.qualifiers[prop]) do
if snakData.snaktype == "value" then
if lib.IsSnakValue(snak) then
Datavalues[key] = snakData.datavalue
Data[key] = Formatters.getRawValue(snak)
break
break
end
end
Řádek 709: Řádek 119:
end
end
end
end
local Date = require 'Modul:Wikidata/datum'
if Datavalues.point then
if Data.point then
table.insert(Values, formatDatavalue(Datavalues.point, options))
table.insert(Values, Date.formatDateFromTimevalue(Data.point, options))
elseif Datavalues.begin or Datavalues.ending then
elseif Data.begin or Data.ending then
local Date = require 'Modul:Wikidata/datum'
table.insert(Values, Date.formatDateRange(options, Datavalues.begin, Datavalues.ending))
table.insert(Values, Date.formatDateRange(Data, options))
end
end
end
end
Řádek 724: Řádek 134:
end
end
end
end
if not qualifiers and options.showtargetdata and options.showtargetdata ~= '' then
if not qualifiers and options.showtargetdata then
local Snaks = {}
local entity
local entity
if statement.mainsnak.snaktype == "value" then
if lib.IsSnakValue(statement.mainsnak) then
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
entity = getEntityFromId(p.getEntityIdFromValue(statement.mainsnak.datavalue.value))
entity = getEntityFromId(Formatters.getRawValue(statement.mainsnak))
else
else
return formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property')
return error(lib.formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
end
end
end
end
if entity and entity.claims then
if entity then
local PropList = {}
local PropList = lib.textToTable(options.showtargetdata)
if type(options.showtargetdata) == "table" then
local options = {
autoformat = true,
PropList = options.showtargetdata
date = options.targetdate,
else
entity = entity,
PropList = mw.text.split(tostring(options.showtargetdata):upper(), "%s*,%s*")
precision = 9,
end
rank = (options.targetdate and 'valid') or 'best',
sort = 'date'
}
local Snaks = {}
for _, property in pairs(PropList) do
for _, property in pairs(PropList) do
local Values = {}
local result
if mw.ustring.lower(property) == 'time' then
local options = {
autoformat = true,
local Data = {}
for key, array in pairs(lib.props) do
date = options.targetdate,
entity = entity,
property = property,
rank = (options.targetdate and 'valid') or 'best',
sort = 'date'
}
if entity.claims[property] then
local Statements = filterStatements(entity, options)
for _, statement in pairs(Statements) do
if statement.mainsnak.datatype == "time" then
options["value-module"] = "Wikidata/datum"
options["value-function"] = "formatDate"
end
table.insert(Values, formatDatavalue(statement.mainsnak.datavalue, options))
end
elseif property == "TIME" then
options["value-module"] = "Wikidata/datum"
options["value-function"] = "formatDate"
local Datavalues = {}
for key, array in pairs(props) do
for _, prop in pairs(array) do
for _, prop in pairs(array) do
options.property = prop
options.property = prop
local Statements = filterStatements(entity, options)
local Statements = Filterers.filterStatementsFromEntity(entity, options)
for _, statement in pairs(Statements) do
for _, statement in pairs(Statements) do
Datavalues[key] = statement.mainsnak.datavalue
Data[key] = Formatters.getRawValue(statement.mainsnak)
break
break
end
end
end
end
end
end
local Date = require 'Modul:Wikidata/datum'
if Datavalues.point then
if Data.point then
table.insert(Values, formatDatavalue(Datavalues.point, options))
result = Date.formatDateFromTimevalue(Data.point, options)
elseif Datavalues.begin or Datavalues.ending then
elseif Data.begin or Data.ending then
local Date = require 'Modul:Wikidata/datum'
table.insert(Values, Date.formatDateRange(options, Datavalues.begin, Datavalues.ending))
result = Date.formatDateRange(Data, options)
end
end
else
options.property = property
result = p.formatStatementsFromLua(options)
end
end
if #Values > 0 then
if result then
table.insert(Snaks, mw.text.listToText(Values))
table.insert(Snaks, result)
end
end
end
end
Řádek 790: Řádek 187:
end
end
end
end
if statement.references and options.showsource and tostring(options.showsource) == 'true' then
if statement.references and lib.IsOptionTrue(options, 'showsource') then
local Module = require 'Module:Wikidata/cite' --TODO
local Module = require 'Module:Wikidata/cite'
references = Module.formatSource(statement.references, options)
references = Module.formatSource(statement.references, options)
end
end


if qualifiers or targetdata then
if qualifiers or targetdata then
if options.qualifiersOnly and qualifiers then
if lib.IsOptionTrue(options, 'qualifiersOnly') then
mainsnak = (qualifiers or targetdata)
mainsnak = qualifiers or targetdata
else
else
if options.delimiter and options.delimiter ~= '' then
if options.delimiter then
mainsnak = mainsnak .. options.delimiter .. (qualifiers or targetdata)
mainsnak = mainsnak .. options.delimiter .. (qualifiers or targetdata)
else
else
Řádek 805: Řádek 202:
end
end
end
end
end
if options.qualifiersOnly and not qualifiers then
return ""
end
end
if references then
if references then
Řádek 819: Řádek 212:
local value = options.value
local value = options.value
if value then
if value then
if value == '' and tostring(options.over) == 'true' then
if value == '' and lib.IsOptionTrue(options, 'over') then
value = nil
value = nil
end
end
if value and not (tostring(options.compare) == 'true') then
if value and not lib.IsOptionTrue(options, 'compare') then
return value
return value
end
end
Řádek 832: Řádek 225:
options.limit = tonumber(options.limit) --TODO default
options.limit = tonumber(options.limit) --TODO default
local add_more = false
local add_more = false
if not (tostring(options.compare) == 'true') then
if not lib.IsOptionTrue(options, 'compare') then
if options.limit and options.showmore and tostring(options.showmore) == 'true' then
if options.limit and lib.IsOptionTrue(options, 'showmore') then
options.limit = options.limit + 1
options.limit = options.limit + 1
add_more = true
add_more = true
Řádek 839: Řádek 232:
end
end


local Filterers = require 'Modul:Wikidata/Filterers'
local Statements = filterStatements(entity, options)
local Statements = Filterers.filterStatementsFromEntity(entity, options)


options.property = mw.ustring.upper(options.property)
if value then
if value then
local Check = require 'Modul:Wikidata/compare'
local Check = require 'Modul:Wikidata/compare'
Řádek 865: Řádek 260:
end
end
if add_more then
if add_more then
table.insert(formattedStatements, mw.ustring.format(i18n.more, entity.id, options.property))
table.insert(formattedStatements, mw.ustring.format(i18n["more-on-Wikidata"], entity.id, options.property))
end
end
value = mw.text.listToText(formattedStatements, options.separator, options.conjunction)
value = mw.text.listToText(formattedStatements, options.separator, options.conjunction)
if tostring(options.addcat) == 'true' then
if lib.IsOptionTrue(options, 'addcat') then
value = value .. lib.category('used-property', options.catbase or options.property)
local Cat = require 'Modul:Kategorie'
value = value .. Cat.makeCategory('Údržba:Použití vlastnosti ' .. options.catbase or options.property)
end
end
if tostring(options.infobox) == 'true' then
if lib.IsOptionTrue(options, 'addlink') then
value = value .. ' <sup class="wd-link">[[d:' .. entity.id .. '#' .. options.property .. '|e]]</sup>'
value = value .. ' <sup class="wd-link">([[d:' .. entity.id .. '#' .. options.property .. '|e]])</sup>'
end
value = '<span class="wd">' .. value .. '</span>'
if lib.IsOptionTrue(options, 'addclass') then
value = lib.addWdClass(value)
end
end
return value
return value
Řádek 889: Řádek 285:
local site = args.site or nil
local site = args.site or nil
if not site or site == '' then
if not site or site == '' then
return formatError( 'param-not-provided', 'site' )
return error(lib.formatError('param-not-provided', 'site'))
end
end
local entity = findEntity( args )
local entity = findEntity( args )
Řádek 898: Řádek 294:
end
end
end
end
return table.concat( Badges, ', ' ) or ''
return table.concat( Badges, ', ' )
end
end


Řádek 904: Řádek 300:
local args = frame and frame.args or {}
local args = frame and frame.args or {}
local lang = args.lang or nil
local lang = args.lang or nil
if not lang or lang == '' or lang == i18n.lang.code then
if not lang or lang == '' or lang == mw.language.getContentLanguage():getCode() then
return mw.wikibase.label(args.id or nil)
return mw.wikibase.label(args.id or nil)
end
end
Řádek 911: Řádek 307:
return entity.labels[lang].value
return entity.labels[lang].value
end
end
return ''
return nil
end
end


Řádek 917: Řádek 313:
local args = frame and frame.args or {}
local args = frame and frame.args or {}
local lang = args.lang or nil
local lang = args.lang or nil
if not lang or lang == '' or lang == i18n.lang.code then
if not lang or lang == '' or lang == mw.language.getContentLanguage():getCode() then
return mw.wikibase.description(args.id or nil)
return mw.wikibase.description(args.id or nil)
end
end
Řádek 924: Řádek 320:
return entity.descriptions[lang].value
return entity.descriptions[lang].value
end
end
return ''
return nil
end
end


Řádek 932: Řádek 328:
local entity = findEntity( args )
local entity = findEntity( args )
if not lang or lang == '' then
if not lang or lang == '' then
lang = i18n.lang.code
lang = mw.language.getContentLanguage():getCode()
end
end
if not entity or not entity.aliases or not entity.aliases[lang] then
if not entity or not entity.aliases or not entity.aliases[lang] then
return ''
return nil
end
end


Řádek 952: Řádek 348:
local args = frame and frame.args or {}
local args = frame and frame.args or {}
if not args.property or args.property == '' then
if not args.property or args.property == '' then
return formatError( 'param-not-provided', 'property' )
return error(lib.formatError('param-not-provided', 'property'))
end
end


Řádek 976: Řádek 372:
end
end


-- @deprecated
-- move to submodule
function p.filterStatementsFromLua(entity, options)
function p.filterStatementsFromLua(...)
local Filterers = require 'Modul:Wikidata/Filterers'
return filterStatements(entity, options)
return Filterers.filterStatementsFromEntity(...)
end
end



Verze z 6. 12. 2015, 13:39

Hlavní modul pro práci s daty na Wikidatech. Jeho základ byl převzat z test2wiki:Module:Wikidata, postupně je rozšiřován o nové funkce.

Modul je rozdělen do submodulů:

Viz též seznam šablon, které tento modul využívají.

Použití

Podrobnější nápovědu naleznete na stránce Wikipedie:Wikidata/Přebírání do infoboxů.

Do šablony vložte {{#invoke:Wikidata|funkce|parametry = jako v šablonách}}.

Parametry a funkce označené hvězdičkou (*) nejsou plně podporované a není zatím doporučeno je využívat. Naopak parametry či funkce označené křížkem (†) jsou zastaralé a mohou být v brzké době odstraněny.

Přehled všech funkcí a parametrů
Funkce Popis funkce Parametr Povinný Popis parametru
formatStatements získá data, vybere tvrzení, přefiltruje, seřadí a zformátuje jejich hodnoty a vrátí jejich seznam id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
property ano identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), jejíž hodnoty se mají zformátovat a zobrazit
addlink ne pokud je „true“, na konci dat z repozitáře se objeví (e) odkazující přímo na vlastnost
addclass ne pokud je „false“, potlačí obalení údajů CSS třídou (používat jen ve výjimečných případech)
value-formatter ne submodul modulu Wikidata/Formatters (jeho podstránka), která se použije pro formátování hodnot, pokud výchozí submodul není vyhovující (seznam, návod)
limit ne maximální počet hodnot, které se v seznamu zobrazí
rank ne nutné postavení hodnoty v rámci tvrzení;
může být all – použijí se všechna tvrzení; best – použijí se buď pouze tvrzení, která mají preferované postavení, nebo pouze ta s normálním postavením, pokud žádné preferované není; valid (implicitní) – použijí se jak preferovaná, tak normálně postavená tvrzení; preferred, normal, deprecated – použijí se pouze tvrzení s odpovídajícím postavením
withtarget ne hodnota, jíž mají nabývat hledaná tvrzení (užitečné zejména pro funkce getCount a getQualifier)
withqualifier ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), která musí být přiřazena dané hodnotě v tvrzení jako vymezení
withqualifiervalue ne hodnota, jíž má nabývat vlastnost vymezení daná parametrem „withqualifier“
withoutqualifier ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), která nesmí být přiřazena dané hodnotě v tvrzení jako vymezení
withoutqualifiervalue ne hodnota, jíž nemá nabývat vlastnost vymezení daná parametrem „withoutqualifier“
withunit ne identifikátor položky na Wikidatech
withlabel*
withsitelink*
withlang ne kód jazyka, ve kterém mají být hodnoty jednojazyčného textu
date ne datum ve formátu YYYY-MM-DD nebo „#now“ (dnešní datum), ke kterému mají být tvrzení platná
sort ne způsob, jakým změnit implicitní pořadí jednotlivých hodnot; hodnota parametru odpovídá čárkou odděleným podstránkám modulu Wikidata/Sorters
invert ne pokud je „true“ a je zadán způsob řazení („sort“), řazení bude sestupné, nikoliv výchozí vzestupné
pattern ne pokud je typ hodnoty řetězec, je toto vzor pro zformátování, přičemž „$1“ nahrazuje daný řetězec
autoformat ne pokud je „true“ a typ hodnoty řetězec, modul se na stránce dotyčné vlastnosti pokusí najít náhradu za pattern (URL pro zformátování (P1630)) a aplikuje ji
precision ne přizpůsobení formátu časových údajů (pokud je skutečná přesnost nižší, formát se přizpůsobí jí); 11 – 10. června 2024, 10 – červen 2024, 9 – 2024 atd.
somevalue ne pokud je vyplněný, modul bude zobrazovat i speciální hodnotu „neznámá hodnota“ s tímto textem
novalue ne pokud je vyplněný, modul bude zobrazovat i speciální hodnotu „bez hodnoty“ s tímto textem
showqualifier ne čárkou oddělené identifikátory vlastností na Wikidatech (písmeno „p“ následované číslicemi nebo „time“), které se zobrazí v závorce za hodnotou, pokud jsou dané hodnotě jako vymezení přiřazeny
showsource ne pokud je „true“, k datům z repozitáře se přidají reference
max_ref ne maximální počet referencí, které se mají zobrazit
showmore ne pokud je hodnota „true“, tak se v případě, že existuje více hodnot, než kolik povoluje limit, zobrazí na konci jejich seznamu text „… více na Wikidatech“ s odkazem přímo na vlastnost
list ne pokud je hodnota „ul“ nebo „ol“, hodnoty budou vráceny jako HTML seznam („ol“ – číslovaný, „ul“ – odrážkový)
separator ne znaky, jimiž se v seznamu oddělí jednotlivé hodnoty, kromě předposlední a poslední (implicitně čárka, neplatí pro HTML seznam)
conjunction ne znaky, jimiž se v seznamu oddělí předposlední a poslední hodnota (implicitně spojka „a“, neplatí pro HTML seznam)
qualifiers ... ne takto uvozený argument (např. „qualifiers precision“) bude použit pro výběr a formátování vymezení
showtargetdata* ne podobné jako „showqualifier“, ovšem data se místo z vymezení získávají z cílové položky
targetdate* ne podobné jako „date“, vztahuje se k údajům cílové položky
formatStatementsFromLua funkce, kterou používají pouze jiné moduly a která je jinak shodná s formatStatements entity ne tabulka s entitou, s níž má modul pracovat
getSitelink vrátí odkaz na článek daného projektu site / první nepojmenovaný ne zkratka projektu (implicitně „cswiki“)
pattern ne vzor pro zformátování odkazu, kde „$1“ je název odkazovaného článku (implicitně „$1“)
id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
addclass ne pokud je „true“, odkaz bude obalen CSS třídou
getLabel vrátí štítek položky v daném jazyce lang ne zkratka jazyka (implicitně „cs“)
id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
addclass ne pokud je „true“, štítek bude obalen CSS třídou
getDescription vrátí popisek položky v daném jazyce lang ne zkratka jazyka (implicitně „cs“)
id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
addclass ne pokud je „true“, popisek bude obalen CSS třídou
getAliases vrátí aliasy položky v daném jazyce lang ne zkratka jazyka (implicitně „cs“)
limit ne maximální počet aliasů, který se má zobrazit
id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
showmore ne jako u formatStatements
list ne
separator ne
conjunction ne
getBadges vrátí štítek odznaku přiřazeného danému odkazu na článek site ano zkratka projektu
id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž data se mají získat pro další práci s nimi (implicitně je to položka propojená s danou stránkou)
of ne identifikátor vlastnosti na Wikidatech (písmeno „p“ následované číslicemi), ze kterého se získá entita, kterou modul skutečně využije, tak, že se použije první nejlepší hodnota vlastnosti
page ne název stránky, jejíž položka se má použít pro získání údajů
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
getCount vrátí počet tvrzení podle daných kritérií všechny parametry pro filtrování
getCurrentId vrátí id položky, se kterou je stránka propojena
getId Vrátí id položky propojené se zadanou stránkou. Není-li propojená a jedná se o přesměrování, následuje jej (i rekurzivně). Nepodaří-li se, zkusí další stránky, pokud jich bylo zadáno víc. Nedostane-li parametry přímo, zpracuje parametry předané volající šabloně. první, druhý, ... nepojmenovaný ne název stránky na dané wiki (implicitně aktuální stránka)
wiki ne zkratka projektu (např. enwiki), z něhož uvedená stránka pochází
getRawValue použije stejná kritéria jako formatStatements, ovšem vrátí strojově čitelný (nezformátovaný) údaj všechny parametry pro filtrování
field ne pokud je typ hodnoty souřadnice, toto je její část, která se zobrazí; jedno z „latitude“, „longitude“, „precision“ a „globe“
getRawValueFromLua jako getRawValue, pro použití v jiném modulu entity ne tabulka s entitou, s níž má modul pracovat
getQualifier vrací hodnoty vymezení nalezeného tvrzení qualifier ano vlastnost vymezení, jejíž hodnoty mají být vráceny
qualifiers ... ne takto uvozený argument (např. „qualifiers withlang“) bude použit pro výběr (při filtrování) vymezení
stejné jako u funkce formatStatements
getRawQualifier aplikuje chování funkce getRawValue na getQualifier stejné jako u funkce getQualifier
formatEntity lokalizuje položku zadanou pomocí jejího identifikátoru (pokusí se vytvořit lokální odkaz a zobrazit štítek) id ne id položky, která se má zformátovat (jinak id položky, se kterou je stránka propojena)
entityExists zjistí, zda entita (položka, vlastnost atd.) s daným identifikátorem existuje (přesměrování se považuje za existující) id / první nepojmenovaný ano id položky, jejíž existenci zjišťujeme
ifexpr ne pokud je „true“, negativní hodnota bude vrácena jako „0“, jinak (výchozí chování) jako prázdný řetězec (užitečné, pokud ve wikitextu používáme funkci #ifexpr:, a ne #if:)
isValidEntityId zjistí, zda zadaný řetězec je platný identifikátor entity (položky, vlastnosti atd.) id / první nepojmenovaný ano řetězec, jehož validitu testujeme
ifexpr ne jako u entityExists
dumpWikidataEntity zobrazí entitu v čitelné podobě, užitečná pro ladění a zavádění nových funkcí, nepoužívá se v šablonách nebo článcích id ne identifikátor položky (písmeno „q“ následované číslicemi) nebo vlastnosti (písmeno „p“ následované číslicemi) na Wikidatech, jejíž entita se zobrazí (implicitně je to položka propojená s danou stránkou)

require "Modul:No globals"

local p = {}

local lib = require "Modul:Wikidata/lib"
local i18n = mw.loadData("Modul:Wikidata/i18n")

local function getEntityFromId(id)
	return mw.wikibase.getEntityObject(id)
end

local function findEntity(options)
	local entity
	if options.entity and type(options.entity) == "table" then
		entity = options.entity
	end
	if not entity then
		if options.id and options.id ~= '' then
			local id = options.id:upper()
			entity = getEntityFromId(id)
			if entity and entity.id ~= id then
				mw.log(id .. ' je přesměrování na ' .. entity.id)
			end
		else
			entity = getEntityFromId()
		end
	end
	if options.of and options.of ~= '' then
		if entity then
			local Statements = entity:getBestStatements(options.of)
			for _, statement in pairs(Statements) do
				if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
					local id = lib.getEntityIdFromValue(statement.mainsnak.datavalue.value)
					entity = getEntityFromId(id)
					if entity and entity.id ~= id then
						mw.log(id .. ' je přesměrování na ' .. entity.id)
					end
					return entity
				else
					return error(lib.formatError('invalid-datatype', options.of:upper(), statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
				end
			end
		end
		return nil
	end
	return entity
end

local function getSitelink(options)
	local options = lib.common.cleanArgs(options)

	local entity = findEntity(options)
	if not entity or not entity.sitelinks then
		return nil
	end

	local site = options.site or options[1]

	local sitelink = entity:getSitelink(site)
	if not sitelink then
		return nil
	end

	if options.pattern then
		sitelink = lib.formatFromPattern(sitelink, options.pattern)
	end
	return sitelink
end

-- @deprecated
local function formatEntityId(entityId, options)
	local formatter = require 'Modul:Wikidata/item'
	return formatter.formatEntityId(entityId, options)
end

local function formatStatement(statement, options)
	if not statement.type or statement.type ~= 'statement' then
		return error(lib.formatError('unknown-claim-type', statement.type))
	end

	local options = lib.common.cleanArgs(options)
	local Filterers = require 'Modul:Wikidata/Filterers'
	local Formatters = require 'Modul:Wikidata/Formatters'

	local mainsnak, qualifiers, targetdata, references
	if not lib.IsOptionTrue(options, 'qualifiersOnly') then
		mainsnak = Formatters.getFormattedValue(statement.mainsnak, options)
	end
	if statement.qualifiers and options.showqualifier then
		local PropList = lib.textToTable(options.showqualifier)
		local Snaks = {}
		for _, property in pairs(PropList) do
			local Values = {}
			local property = mw.ustring.upper(property)
			local format_options = {
				autoformat = true,
				precision = 9,
				property = property,
			}
			if statement.qualifiers[property] then
				local Qualifiers = Filterers.filterQualifiers(statement.qualifiers[property], options)
				for _, snak in pairs(Qualifiers) do
					if lib.IsSnakValue(snak) then
						table.insert(Values, Formatters.getFormattedValue(snak, format_options))
					end
				end
			elseif property == "TIME" then
				local Data = {}
				for key, array in pairs(lib.props) do
					for _, prop in pairs(array) do
						if statement.qualifiers[prop] then
							for _, snak in pairs(statement.qualifiers[prop]) do
								if lib.IsSnakValue(snak) then
									Data[key] = Formatters.getRawValue(snak)
									break
								end
							end
						end
					end
				end
				local Date = require 'Modul:Wikidata/datum'
				if Data.point then
					table.insert(Values, Date.formatDateFromTimevalue(Data.point, options))
				elseif Data.begin or Data.ending then
					table.insert(Values, Date.formatDateRange(Data, options))
				end
			end
			if #Values > 0 then
				table.insert(Snaks, mw.text.listToText(Values))
			end
		end
		if #Snaks > 0 then
			qualifiers = table.concat(Snaks, '; ')
		end
	end
	if not qualifiers and options.showtargetdata then
		local entity
		if lib.IsSnakValue(statement.mainsnak) then
			if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
				entity = getEntityFromId(Formatters.getRawValue(statement.mainsnak))
			else
				return error(lib.formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
			end
		end
		if entity then
			local PropList = lib.textToTable(options.showtargetdata)
			local options = {
				autoformat = true,
				date = options.targetdate,
				entity = entity,
				precision = 9,
				rank = (options.targetdate and 'valid') or 'best',
				sort = 'date'
			}
			local Snaks = {}
			for _, property in pairs(PropList) do
				local result
				if mw.ustring.lower(property) == 'time' then
					local Data = {}
					for key, array in pairs(lib.props) do
						for _, prop in pairs(array) do
							options.property = prop
							local Statements = Filterers.filterStatementsFromEntity(entity, options)
							for _, statement in pairs(Statements) do
								Data[key] = Formatters.getRawValue(statement.mainsnak)
								break
							end
						end
					end
					local Date = require 'Modul:Wikidata/datum'
					if Data.point then
						result = Date.formatDateFromTimevalue(Data.point, options)
					elseif Data.begin or Data.ending then
						result = Date.formatDateRange(Data, options)
					end
				else
					options.property = property
					result = p.formatStatementsFromLua(options)
				end
				if result then
					table.insert(Snaks, result)
				end
			end
			if #Snaks > 0 then
				targetdata = table.concat(Snaks, '; ')
			end
		end
	end
	if statement.references and lib.IsOptionTrue(options, 'showsource') then
		local Module = require 'Module:Wikidata/cite'
		references = Module.formatSource(statement.references, options)
	end

	if qualifiers or targetdata then
		if lib.IsOptionTrue(options, 'qualifiersOnly') then
			mainsnak = qualifiers or targetdata
		else
			if options.delimiter then
				mainsnak = mainsnak .. options.delimiter .. (qualifiers or targetdata)
			else
				mainsnak = mainsnak .. ' (' .. (qualifiers or targetdata) .. ')'
			end
		end
	end
	if references then
		mainsnak = mainsnak .. references
	end
	return mainsnak
end

local function formatStatements(options)
	local value = options.value
	if value then
		if value == '' and lib.IsOptionTrue(options, 'over') then
			value = nil
		end
		if value and not lib.IsOptionTrue(options, 'compare') then
			return value
		end
	end

	--Get entity
	local entity = findEntity(options)

	options.limit = tonumber(options.limit) --TODO default
	local add_more = false
	if not lib.IsOptionTrue(options, 'compare') then
		if options.limit and lib.IsOptionTrue(options, 'showmore') then
			options.limit = options.limit + 1
			add_more = true
		end
	end

	local Filterers = require 'Modul:Wikidata/Filterers'
	local Statements = Filterers.filterStatementsFromEntity(entity, options)

	options.property = mw.ustring.upper(options.property)
	if value then
		local Check = require 'Modul:Wikidata/compare'
		return Check.compareValues(value, Statements, {
			catbase = options.catbase,
			property = options.of or options.property
		})
	end

	if #Statements == 0 then return nil end

	-- Format statements and concat them cleanly
	local formattedStatements = {}
	if add_more then
		if #Statements == options.limit then
			table.remove(Statements)
		else
			add_more = false
		end
	end
	options.entity = entity
	for _, statement in pairs(Statements) do
		table.insert(formattedStatements, formatStatement(statement, options))
	end
	if add_more then
		table.insert(formattedStatements, mw.ustring.format(i18n["more-on-Wikidata"], entity.id, options.property))
	end
	value = mw.text.listToText(formattedStatements, options.separator, options.conjunction)
	if lib.IsOptionTrue(options, 'addcat') then
		value = value .. lib.category('used-property', options.catbase or options.property)
	end
	if lib.IsOptionTrue(options, 'addlink') then
		value = value .. ' <sup class="wd-link">([[d:' .. entity.id .. '#' .. options.property .. '|e]])</sup>'
	end
	if lib.IsOptionTrue(options, 'addclass') then
		value = lib.addWdClass(value)
	end
	return value
end

function p.dumpWikidataEntity( frame )
	local args = frame and frame.args or {}

	return mw.dumpObject( getEntityFromId( args.id or nil ) )
end

function p.getBadges( frame )
	local args = frame and frame.args or {}
	local site = args.site or nil
	if not site or site == '' then
		return error(lib.formatError('param-not-provided', 'site'))
	end
	local entity = findEntity( args )
	local Badges = {}
	if entity and entity.sitelinks and entity.sitelinks[site] then
		for _, badge in pairs( entity.sitelinks[site].badges ) do
			table.insert( Badges, formatEntityId( badge ) )
		end
	end
	return table.concat( Badges, ', ' )
end

function p.getLabel( frame )
	local args = frame and frame.args or {}
	local lang = args.lang or nil
	if not lang or lang == '' or lang == mw.language.getContentLanguage():getCode() then
		return mw.wikibase.label(args.id or nil)
	end
	local entity = findEntity( args )
	if entity and entity.labels and entity.labels[lang] then
		return entity.labels[lang].value
	end
	return nil
end

function p.getDescription( frame )
	local args = frame and frame.args or {}
	local lang = args.lang or nil
	if not lang or lang == '' or lang == mw.language.getContentLanguage():getCode() then
		return mw.wikibase.description(args.id or nil)
	end
	local entity = findEntity( args )
	if entity and entity.descriptions and entity.descriptions[lang] then
		return entity.descriptions[lang].value
	end
	return nil
end

function p.getAliases( frame )
	local args = frame and frame.args or {}
	local lang = args.lang or nil
	local entity = findEntity( args )
	if not lang or lang == '' then
		lang = mw.language.getContentLanguage():getCode()
	end
	if not entity or not entity.aliases or not entity.aliases[lang] then
		return nil
	end

	local limit = tonumber(args.limit)

	local Aliases = {}
	for i, alias in pairs( entity.aliases[lang] ) do
		if not limit or (limit and i <= limit) then
			table.insert( Aliases, alias.value )
		else break end
	end
	return mw.text.listToText( Aliases, args.separator, args.conjunction )
end

function p.getCount( frame )
	local args = frame and frame.args or {}
	if not args.property or args.property == '' then
		return error(lib.formatError('param-not-provided', 'property'))
	end

	local entity = findEntity( args )

	args.limit = nil
	local Statements = filterStatements(entity, args)

	return #Statements or 0
end

function p.getCurrentId()
	local entity = getEntityFromId()
	return entity and entity.id
end

function p.getSitelink( frame )
	return getSitelink( frame.args )
end

function p.getSitelinkFromLua( options )
	return getSitelink( options )
end

-- @deprecated
function p.filterStatementsFromLua(...)
	local Filterers = require 'Modul:Wikidata/Filterers'
	return Filterers.filterStatementsFromEntity(...)
end

function p.formatStatements(frame)
	local args = frame and frame.args or {}
	return formatStatements(frame.args)
end

function p.formatStatementsFromLua(options)
	return formatStatements(options)
end

return p