KKeine Bearbeitungszusammenfassung |
K ("qualifiers-order" und "snaks-order") |
||
Zeile 26: | Zeile 26: | ||
end |
end |
||
+ | -- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field |
||
+ | -- use these as the second parameter and this function instead of the built-in "pairs" function |
||
+ | -- to iterate over all qualifiers and snaks in the intended order. |
||
local function orderedpairs(array, order) |
local function orderedpairs(array, order) |
||
+ | if not order then return pairs(array) end |
||
+ | |||
-- return iterator function |
-- return iterator function |
||
local i = 0 |
local i = 0 |
||
Zeile 201: | Zeile 206: | ||
local rankb = claims[b].rank or "normal" |
local rankb = claims[b].rank or "normal" |
||
return ranka > rankb |
return ranka > rankb |
||
+ | |||
− | --return ranka and rankb and rankmap[ranka] > rankmap[rankb] -- normal sort order is "<", but high priority needs to be sorted first (descending sort) |
||
− | |||
--return mw.wikibase.label("Q" .. .mainsnak.datavalue.value["numeric-id"]) < mw.wikibase.label("Q" .. claims[b].mainsnak.datavalue.value["numeric-id"]) |
--return mw.wikibase.label("Q" .. .mainsnak.datavalue.value["numeric-id"]) < mw.wikibase.label("Q" .. claims[b].mainsnak.datavalue.value["numeric-id"]) |
||
end |
end |
Version vom 9. April 2014, 14:57 Uhr
Die Dokumentation für dieses Modul kann unter Modul:Wikidata/Doku erstellt werden
-- module local variables
local wiki =
{
langcode = mw.language.getContentLanguage().code
}
-- internationalisation
local i18n = {
["errors"] = {
["property-not-found"] = "Eigenschaft nicht gefunden.",
["entity-not-found"] = "Entity nicht gefunden.",
["unknown-claim-type"] = "Unbekannter Aussagentyp.",
["unknown-snak-type"] = "Unbekannter Snak-Typ.",
["unknown-datavalue-type"] = "Unbekannter Datentyp.",
["unknown-entity-type"] = "Unbekannter Entity-Typ.",
["qualifier-not-found"] = "Qualifikator nicht gefunden."
},
["somevalue"] = "''unbekannter Wert''",
["novalue"] = "''kein Wert''"
}
local p = { }
local function printError(code)
return '<span class="error">' .. i18n.errors[code] .. '</span>'
end
-- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field
-- use these as the second parameter and this function instead of the built-in "pairs" function
-- to iterate over all qualifiers and snaks in the intended order.
local function orderedpairs(array, order)
if not order then return pairs(array) end
-- return iterator function
local i = 0
return function()
i = i + 1
if order[i] then
return order[i], array[order[i]]
end
end
end
function p.descriptionIn(frame)
local langcode = frame.args[1]
-- return description of a Wikidata entity in the given language or the default language of this Wikipedia site
return mw.wikibase.getEntityObject().descriptions[langcode or wiki.langcode].value
end
function p.labelIn(frame)
local langcode = frame.args[1]
-- return label of a Wikidata entity in the given language or the default language of this Wikipedia site
return mw.wikibase.getEntityObject().labels[langcode or wiki.langcode].value
end
local function printDatavalueCoordinate(data, parameter)
-- data fields: latitude [double], longitude [double], altitude [double], precision [double], globe [wikidata URI, usually http://www.wikidata.org/entity/Q2 [earth]]
if parameter then
if parameter == "globe" then data.globe = mw.ustring.match(data.globe, "Q%d+") end -- extract entity id from the globe URI
return data[parameter]
else
return data.latitude .. "/" .. data.longitude -- combine latitude and longitude, which can be decomposed using the #titleparts wiki function
end
end
local function printDatavalueQuantity(data, parameter)
-- data fields: amount [number], unit [string], upperBound [number], lowerBound [number]
if parameter then
return data[paramater]
else
return tonumber(data.amount)
end
end
local function printDatavalueTime(data, parameter)
-- data fields: time [ISO 8601 time], timezone [int in minutes], before [int], after [int], precision [int], calendarmodel [wikidata URI]
-- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millenia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second
-- calendarmodel: e.g. http://www.wikidata.org/entity/Q1985727 for the proleptic Gregorian calendar or http://www.wikidata.org/wiki/Q11184 for the Julian calendar]
data.time = mw.text.trim(data.time, " +0")
if parameter then
if parameter == "calendarmodel" then data.calendarmodel = mw.ustring.match(data.calendarmodel, "Q%d+") end -- extract entity id from the calendar model URI
return data[parameter]
else
return data.time
end
end
local function printDatavalueEntity(data, parameter)
-- data fields: entity-type [string], numeric-id [int, Wikidata id]
if parameter then
return data[parameter]
else
if data["entity-type"] == "item" then return mw.wikibase.label("Q" .. data["numeric-id"]) else printError("unknown-entity-type") end
end
end
function findClaims(entity, property)
if not property or not entity or not entity.claims then return end
if mw.ustring.match(property, "^P%d+$") then
-- if the property is given by an id (P..) access the claim list by this id
return entity.claims[property]
else
-- otherwise, iterate over all properties, fetch their labels and compare this to the given property name
for k, v in pairs(entity.claims) do
if mw.wikibase.label(k) == property then return v end
end
return
end
end
function getSnakValue(snak, parameter)
-- snaks have three types: "novalue" for null/nil, "somevalue" for not null/not nil, or "value" for actual data
if snak.snaktype == "novalue" then return i18n["novalue"]
elseif snak.snaktype == "somevalue" then return i18n["somevalue"]
elseif snak.snaktype ~= "value" then return nil, printError("unknown-snak-type")
end
-- call the respective snak parser
if snak.datavalue.type == "string" then return snak.datavalue.value
elseif snak.datavalue.type == "globecoordinate" then return printDatavalueCoordinate(snak.datavalue.value, parameter)
elseif snak.datavalue.type == "quantity" then return printDatavalueQuantity(snak.datavalue.value, parameter)
elseif snak.datavalue.type == "time" then return printDatavalueTime(snak.datavalue.value, parameter)
elseif snak.datavalue.type == "wikibase-entityid" then return printDatavalueEntity(snak.datavalue.value, parameter)
else return nil, printError("unknown-datavalue-type")
end
end
function getQualifierSnak(claim, qualifierId)
-- a "snak" is Wikidata terminology for a typed key/value pair
-- a claim consists of a main snak holding the main information of this claim,
-- as well as a list of attribute snaks and a list of references snaks
if qualifierId then
-- search the attribute snak with the given qualifier as key
if claim.qualifiers then
local qualifier = claim.qualifiers[qualifierId]
if qualifier then return qualifier[1] end
end
return nil, printError("qualifier-not-found")
else
-- otherwise return the main snak
return claim.mainsnak
end
end
function getValueOfClaim(claim, qualifierId, parameter)
local error
local snak
snak, error = getQualifierSnak(claim, qualifierId)
if snak then
return getSnakValue(snak, parameter)
else
return nil, error
end
end
function getReferences(claim)
local result = ""
-- traverse through all references
for ref in pairs(claim.references or {}) do
local refparts
-- traverse through all parts of the current reference
for snakkey, snakval in orderedpairs(claim.references[ref].snaks or {}, claim.references[ref]["snaks-order"]) do
if refparts then refparts = refparts .. ", " else refparts = "" end
-- output the label of the property of the reference part, e.g. "imported from" for P143
refparts = refparts .. tostring(mw.wikibase.label(snakkey)) .. ": "
-- output all values of this reference part, e.g. "German Wikipedia" and "English Wikipedia" if the referenced claim was imported from both sites
for snakidx = 1, #snakval do
if snakidx > 1 then refparts = refparts .. ", " end
refparts = refparts .. getSnakValue(snakval[snakidx])
end
end
if refparts then result = result .. "<ref>" .. refparts .. "</ref>" end
end
return result
end
function p.claim(frame)
local property = frame.args[1] or ""
local qualifierId = frame.args["qualifier"]
local parameter = frame.args["parameter"]
local list = frame.args["list"]
local references = frame.args["references"]
local showerrors = frame.args["showerrors"]
-- get wikidata entity
local entity = mw.wikibase.getEntityObject()
if not entity then
if showerrors then return printError("entity-not-found") else return end
end
-- fetch the first claim of satisfying the given property
local claims = findClaims(entity, property)
if not claims or not claims[1] then
if showerrors then return printError("property-not-found") else return end
end
-- get initial sort indices
local sortindices = {}
for idx in pairs(claims) do
sortindices[#sortindices + 1] = idx
end
-- sort by claim rank
local comparator = function(a, b)
--local rankmap = { deprecated = -1, normal = 0, preferred = 1 } -- not needed as the ranks are coincidentally in alphanumeric order
local ranka = claims[a].rank or "normal"
local rankb = claims[b].rank or "normal"
return ranka > rankb
--return mw.wikibase.label("Q" .. .mainsnak.datavalue.value["numeric-id"]) < mw.wikibase.label("Q" .. claims[b].mainsnak.datavalue.value["numeric-id"])
end
table.sort(sortindices, comparator)
local result
local error
if list then
local value
-- iterate over all elements and return their value (if existing)
for idx in pairs(claims) do
local claim = claims[sortindices[idx]]
value, error = getValueOfClaim(claim, qualifierId, parameter)
if not value and showerrors then value = error end
if result then
if value then result = result .. list .. value end
else
result = value
end
if value and references then result = result .. getReferences(claim) end
end
else
-- return first element
local claim = claims[sortindices[1]]
result, error = getValueOfClaim(claim, qualifierId, parameter)
if result and references then result = result .. getReferences(claim) end
end
if not result and showerrors then return error else return result end
end
function p.labelOf(frame)
local id = frame.args[1]
-- returns the label of the given entity/property id
-- if no id is given, the one from the entity associated with the calling Wikipedia article is used
if not id then
local entity = mw.wikibase.getEntityObject()
if not entity then return printError("entity-not-found") end
id = entity.id
end
return mw.wikibase.label(id)
end
function p.sitelinkOf(frame)
local id = frame.args[1]
-- returns the Wikipedia article name of the given entity
-- if no id is given, the one from the entity associated with the calling Wikipedia article is used
if not id then
local entity = mw.wikibase.getEntityObject()
if not entity then return printError("entity-not-found") end
id = entity.id
end
return mw.wikibase.sitelink(id)
end
-- call this in cases of script errors within a function instead of {{#invoke:Wikidata|<method>|...}} call {{#invoke:Wikidata|debug|<method>|...}}
function p.debug(frame)
local func = frame.args[1]
if func then
table.remove(frame.args, 1)
local status, result = pcall(p[func], frame)
if status then return result else return '<span class="error">' .. result .. '</span>' end
end
end
function printTable(data, level)
level = tonumber(level) or 0
local result
if level == 0 then result = "<pre>\n" else result = "" end
local prefix = ""
for idx = 1, level do prefix = prefix .. " " end
if type(data) == "table" then
for key, val in pairs(data) do
result = result .. prefix .. key .. ": "
if type(val) == "table" then result = result .. "\n" .. printTable(val, level + 1) else result = result .. tostring(val) .. "\n" end
end
else
result = prefix .. tostring(data)
end
if level == 0 then result = result .. "</pre>" end
return result
end
function p.printEntity(frame)
local entity = mw.wikibase.getEntityObject()
return printTable(entity)
end
return p