Redigerer
Modul:Sandkasse/Cocu/Wikidata
Hopp til navigering
Hopp til søk
Advarsel:
Du er ikke innlogget. IP-adressen din vil bli vist offentlig om du redigerer. Hvis du
logger inn
eller
oppretter en konto
vil redigeringene dine tilskrives brukernavnet ditt, og du vil få flere andre fordeler.
Antispamsjekk.
Ikke
fyll inn dette feltet!
local p = {} -- module local variables local wiki = { langcode = mw.language.getContentLanguage().code } -- internationalisation local i18n = { ["errors"] = { ["property-not-found"] = "Egenskap ikke funnet.", ["entity-not-found"] = "Wikidata-entitet ikke funnet.", ["unknown-claim-type"] = "Ukjent utsagnstype.", ["unknown-entity-type"] = "Ukjent entitettype.", ["qualifier-not-found"] = "Kvalifikator ikke funnet.", ["site-not-found"] = "Wikimedia-prosjekt ikke funnet.", }, ["datetime"] = { -- $1 is a placeholder for the actual number [0] = "$1 milliarder år", -- precision: billion years [1] = "$100 millioner år", -- precision: hundred million years [2] = "$10 millioner år", -- precision: ten million years [3] = "$1 million år", -- precision: million years [4] = "$100 000 år", -- precision: hundred thousand years [5] = "$10 000 år", -- precision: ten thousand years [6] = "$1 millenium", -- precision: millennium [7] = "$1 århundre", -- precision: century [8] = "$1", -- precision: decade -- the following use the format of #time parser function [9] = "Y", -- precision: year, [10] = "F Y", -- precision: month [11] = "F j, Y", -- precision: day [12] = "F j, Y ga", -- precision: hour [13] = "F j, Y g:ia", -- precision: minute [14] = "F j, Y g:i:sa", -- precision: second ["beforenow"] = "$1 fvt.", -- how to format negative numbers for precisions 0 to 5 ["afternow"] = "$1 evt.", -- how to format positive numbers for precisions 0 to 5 ["bc"] = '$1 "fvt."', -- how print negative years ["ad"] = "$1" -- how print positive years }, ["monolingualtext"] = '<span lang="%language">%text</span>' } local function printError(code) return '<span class="error">' .. (i18n.errors[code] or code) .. '</span>' end function p.descriptionIn(frame) local langcode = frame.args[1] local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration -- return description of a Wikidata entity in the given language or the default language of this Wikipedia site return mw.wikibase.getEntityObject(id).descriptions[langcode or wiki.langcode].value end function p.labelIn(frame) local langcode = frame.args[1] local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration -- return label of a Wikidata entity in the given language or the default language of this Wikipedia site return mw.wikibase.getEntityObject(id).labels[langcode or wiki.langcode].value end -- This is used to get a value, or a comma separated list of them if multiple values exist p.getValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local input_parm = mw.text.trim(frame.args[2] or "") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() local claims if entity and entity.claims then claims = entity.claims[propertyID] end if claims then -- if wiki-linked value output as link if possible if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then local out = {} for k, v in pairs(claims) do local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"]) local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"]) if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end if sitelink then out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]" else out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='Artikkelen er foreløpig ikke opprettet på denne wikien'><sup>[!]</sup></abbr>[[Kategori:Artikler med informasjon i infoboks som mangler artikkel på nowiki]]" end end return table.concat(out, ", ") else -- just return best vakues return entity:formatPropertyValues(propertyID).value end else return "" end else return input_parm end end -- This is used to get a value, or a comma separated list of them if multiple values exist -- from an arbitrary entry by using its QID. -- Use : {{#invoke:Wikidata|getValueFromID|<ID>|<Property>|hent_wikidata}} -- E.g.: {{#invoke:Wikidata|getValueFromID|Q151973|P26|hent_wikidata}} - to fetch value of 'spouse' (P26) from 'Richard Burton' (Q151973) -- Please use sparingly - this is an *expensive call*. p.getValueFromID = function(frame) local itemID = mw.text.trim(frame.args[1] or "") local propertyID = mw.text.trim(frame.args[2] or "") local input_parm = mw.text.trim(frame.args[3] or "") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntity(itemID) local claims = entity.claims[propertyID] if claims then -- if wiki-linked value output as link if possible if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then local out = {} for k, v in pairs(claims) do local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"]) local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"]) if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end if sitelink then out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]" else out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='Artikkelen er foreløpig ikke opprettet på denne wikien'><sup>[!]</sup></abbr>[[Kategori:Artikler med informasjon i infoboks som mangler artikkel på nowiki]]" end end return table.concat(out, ", ") else return entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value end else return "" end else return input_parm end end p.getQualifierValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local qualifierID = mw.text.trim(frame.args[2] or "") local input_parm = mw.text.trim(frame.args[3] or "") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() if entity.claims[propertyID] ~= nil then local out = {} for k, v in pairs(entity.claims[propertyID]) do for k2, v2 in pairs(v.qualifiers[qualifierID]) do if v2.snaktype == 'value' then if (mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"])) then out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"]) .. "]]" else out[#out + 1] = "[[:d:Q" .. v2.datavalue.value["numeric-id"] .. "|" .. mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) .. "]]<abbr title='Artikkelen er foreløpig ikke opprettet på denne wikien'><sup>[!]</sup></abbr>[[Kategori:Artikler med informasjon i infoboks som mangler artikkel på nowiki og etikett på Wikidata]]]" end end end end return table.concat(out, ", ") else return "" end else return input_parm end end -- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators p.getRawValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local input_parm = mw.text.trim(frame.args[2] or "") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() local claims if entity then claims = entity.claims[propertyID] end if claims then local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value -- if number type: remove thousand separators if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2") end return result else return "" end else return input_parm end end p.getRawQualifierValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local qualifierID = mw.text.trim(frame.args[2] or "") local input_parm = mw.text.trim(frame.args[3] or "") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() if entity.claims[propertyID] ~= nil then local out = {} for k, v in pairs(entity.claims[propertyID]) do for k2, v2 in pairs(v.qualifiers[qualifierID]) do if v2.snaktype == 'value' then if v2.datavalue.value["numeric-id"] then out[#out + 1] = mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) else out[#out + 1] = v2.datavalue.value end end end end local ret = table.concat(out, ", ") return string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2) else return "" end else return input_parm end end -- This is used to get a date value for date_of_birth (P569), etc. which won't -- be linked -- consolidate by testing if entity.claims[propertyID].mainsnak.datavalue.type -- is "time". Dates and times are stored in ISO 8601 format. p.getDateValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local input_parm = mw.text.trim(frame.args[2] or "") local date_format = mw.text.trim(frame.args[3] or "dmy") local date_suffix = mw.text.trim(frame.args[4] or "BC") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() if entity.claims[propertyID] ~= nil then local out = {} local dt = {} for k, v in pairs(entity.claims[propertyID]) do if v.mainsnak.snaktype == 'value' then -- check for negative date local suffix = "" local timestamp = v.mainsnak.datavalue.value.time if string.sub(timestamp, 1, 1) == '-' then timestamp = '+' .. string.sub(timestamp, 2) suffix = " " .. date_suffix end local function d(f) return mw.language.new(wiki.langcode):formatDate(f, timestamp) .. suffix end if date_format == "mdy" then out[#out + 1] = d("F j, Y") elseif date_format == "my" then out[#out + 1] = d("F Y") elseif date_format == "y" then -- suppress leading zeros in year local stryear = d("Y") while string.sub(stryear, 1, 1) == '0' do stryear = string.sub(stryear, 2) end out[#out + 1] = stryear else out[#out + 1] = d("j F Y") end end end return table.concat(out, ", ") else return "" end else return input_parm end end p.getQualifierDateValue = function(frame) local propertyID = mw.text.trim(frame.args[1] or "") local qualifierID = mw.text.trim(frame.args[2] or "") local input_parm = mw.text.trim(frame.args[3] or "") local date_format = mw.text.trim(frame.args[4] or "dmy") if input_parm == "hent_wikidata" then local entity = mw.wikibase.getEntityObject() if entity.claims[propertyID] ~= nil then local out = {} for k, v in pairs(entity.claims[propertyID]) do for k2, v2 in pairs(v.qualifiers[qualifierID]) do if v2.snaktype == 'value' then local function d(f) return mw.language.new(wiki.langcode):formatDate(f, v2.datavalue.value.time) end if date_format == "mdy" then out[#out + 1] = d("F j, Y") elseif date_format == "my" then out[#out + 1] = d("F Y") elseif date_format == "y" then out[#out + 1] = d("Y") else out[#out + 1] = d("j F Y") end end end end return table.concat(out, ", ") else return "" end else return input_parm end end -- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323) -- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm -- uses the newer mw.wikibase calls instead of directly using the snaks -- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string p.getTAValue = function(frame) local ent = mw.wikibase.getEntityObject() local props = ent:formatPropertyValues('P1323') local out = {} local t = {} for k, v in pairs(props) do if k == 'value' then t = mw.text.split( v, ", ") for k2, v2 in pairs(t) do out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]" end end end local ret = table.concat(out, "<br> ") if #ret == 0 then ret = "Invalid TA" end return ret end -- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata function p.pageId(frame) local entity = mw.wikibase.getEntityObject() if not entity then return nil else return entity.id 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) 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 -- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millennia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second local function normalizeDate(date) date = mw.text.trim(date, "+") -- extract year local yearstr = mw.ustring.match(date, "^\-?%d+") local year = tonumber(yearstr) -- remove leading zeros of year return year .. mw.ustring.sub(date, #yearstr + 1), year end local function formatDate(date, precision, timezone) precision = precision or 11 local date, year = normalizeDate(date) if year == 0 and precision <= 9 then return "" end -- precision is 10000 years or more if precision <= 5 then local factor = 10 ^ ((5 - precision) + 4) local y2 = math.ceil(math.abs(year) / factor) local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2)) if year < 0 then relative = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) else relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) end return relative end -- precision is decades, centuries and millennia local era if precision == 6 then era = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(math.floor((math.abs(year) - 1) / 1000) + 1)) end if precision == 7 then era = mw.ustring.gsub(i18n.datetime[7], "$1", tostring(math.floor((math.abs(year) - 1) / 100) + 1)) end if precision == 8 then era = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(math.floor(math.abs(year) / 10) * 10)) end if era then if year < 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc, '"', ""), "$1", era) elseif year > 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad, '"', ""), "$1", era) end return era end -- precision is year if precision == 9 then return year end -- precision is less than years if precision > 9 then --[[ the following code replaces the UTC suffix with the given negated timezone to convert the global time to the given local time timezone = tonumber(timezone) if timezone and timezone ~= 0 then timezone = -timezone timezone = string.format("%.2d%.2d", timezone / 60, timezone % 60) if timezone[1] ~= '-' then timezone = "+" .. timezone end date = mw.text.trim(date, "Z") .. " " .. timezone end ]]-- local formatstr = i18n.datetime[precision] if year == 0 then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], "") elseif year < 0 then -- Mediawiki formatDate doesn't support negative years date = mw.ustring.sub(date, 2) formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.bc, "$1", i18n.datetime[9])) elseif year > 0 and i18n.datetime.ad ~= "$1" then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.ad, "$1", i18n.datetime[9])) end return mw.language.new(wiki.langcode):formatDate(formatstr, date) end end local function printDatavalueEntity(data, parameter) -- data fields: entity-type [string], numeric-id [int, Wikidata id] local id if data["entity-type"] == "item" then id = "Q" .. data["numeric-id"] elseif data["entity-type"] == "property" then id = "P" .. data["numeric-id"] else return printError("unknown-entity-type") end if parameter then if parameter == "link" then local linkTarget = mw.wikibase.sitelink(id) local linkName = mw.wikibase.label(id) if linkTarget then -- if there is a local Wikipedia article link to it using the label or the article title return "[[" .. linkTarget .. "|" .. (linkName or linkTarget) .. "]]" else -- if there is no local Wikipedia article output the label or link to the Wikidata object to let the user input a proper label if linkName then return linkName else return "[[:d:" .. id .. "|" .. id .. "]]" end end else return data[parameter] end else return mw.wikibase.label(id) or id 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 - millennia, 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] if parameter then if parameter == "calendarmodel" then data.calendarmodel = mw.ustring.match(data.calendarmodel, "Q%d+") -- extract entity id from the calendar model URI elseif parameter == "time" then data.time = normalizeDate(data.time) end return data[parameter] else return formatDate(data.time, data.precision, data.timezone) end end local function printDatavalueMonolingualText(data, parameter) -- data fields: language [string], text [string] if parameter then return data[parameter] else local result = mw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext, "%%language", data["language"]), "%%text", data["text"]) return result end end local 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 property = mw.wikibase.resolvePropertyId(property) if not property then return end return entity.claims[property] end end local function getSnakValue(snak, parameter) if snak.snaktype == "value" then -- 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) elseif snak.datavalue.type == "monolingualtext" then return printDatavalueMonolingualText(snak.datavalue.value, parameter) end end return mw.wikibase.renderSnak(snak) end local 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 local 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 local function getReferences(frame, 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 .. frame:extensionTag("ref", refparts) end end return result end function p.claim(frame) local property = frame.args[1] or "" local id = frame.args["id"] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration 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"] local default = frame.args["default"] if default then showerrors = nil end -- get wikidata entity local entity = mw.wikibase.getEntityObject(id) if not entity then if showerrors then return printError("entity-not-found") else return default 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 default 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 = 2, normal = 1, preferred = 0 } local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a) local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b) return ranka < rankb end table.sort(sortindices, comparator) local result local error if list then local value -- iterate over all elements and return their value (if existing) result = {} 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 value and references then value = value .. getReferences(frame, claim) end result[#result + 1] = value end result = table.concat(result, list) else -- return first element local claim = claims[sortindices[1]] result, error = getValueOfClaim(claim, qualifierId, parameter) if result and references then result = result .. getReferences(frame, claim) end end if result then return result else if showerrors then return error else return default end end end -- look into entity object function p.ViewSomething(frame) local data = mw.wikibase.getEntityObject() if not data then return nil end local f = frame.args[1] and frame or frame:getParent() local i = 1 while true do local index = f.args[i] if not index then if type(data) == "table" then return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY) else return tostring(data) end end data = data[index] or data[tonumber(index)] if not data then return end i = i + 1 end end function p.Dump(frame) local data = mw.wikibase.getEntityObject() if not data then return i18n.warnDump end local f = frame.args[1] and frame or frame:getParent() local i = 1 while true do local index = f.args[i] if not index then return "<pre>"..mw.dumpObject(data).."</pre>".. i18n.warnDump end data = data[index] or data[tonumber(index)] if not data then return i18n.warnDump end i = i + 1 end end return p
Redigeringsforklaring:
Merk at alle bidrag til Wikisida.no anses som frigitt under Creative Commons Navngivelse-DelPåSammeVilkår (se
Wikisida.no:Opphavsrett
for detaljer). Om du ikke vil at ditt materiale skal kunne redigeres og distribueres fritt må du ikke lagre det her.
Du lover oss også at du har skrevet teksten selv, eller kopiert den fra en kilde i offentlig eie eller en annen fri ressurs.
Ikke lagre opphavsrettsbeskyttet materiale uten tillatelse!
Avbryt
Redigeringshjelp
(åpnes i et nytt vindu)
Forhåndsvis en side som bruker denne malen
Mal som brukes på denne siden:
Modul:Sandkasse/Cocu/Wikidata/dok
(
rediger
)
Navigasjonsmeny
Personlige verktøy
Ikke logget inn
Brukerdiskusjon
Bidrag
Opprett konto
Logg inn
Navnerom
Modul
Diskusjon
English
Visninger
Les
Rediger kilde
Vis historikk
Mer
Navigasjon
Forside
Siste endringer
Tilfeldig side
Hjelp til MediaWiki
Verktøy
Lenker hit
Relaterte endringer
Spesialsider
Sideinformasjon