Module:Wikidata
Appearance
Documentation for this module may be created at Module:Wikidata/doc
-- module local variableslocalwiki={langcode=mw.language.getContentLanguage().code}-- internationalisationlocali18n={["errors"]={["property-not-found"]="Eigenschap niet gevonden.",["entity-not-found"]="Wikidata-entiteit niet gevonden.",["unknown-claim-type"]="Onbekend statementtype.",["unknown-snak-type"]="Onbekend snaktype.",["unknown-datavalue-type"]="Onbekend gegevenstype.",["unknown-entity-type"]="Onbekend entiteitstype.",["qualifier-not-found"]="Kwalificatie niet gevonden.",["site-not-found"]="Wikimedia-project niet gevonden."},["somevalue"]="",["novalue"]="",["datetime"]={-- $1 is a placeholder for the actual number[0]="$1 bion aña",-- precision: billion years[1]="$100 mion aña",-- precision: hundred million years[2]="$10 miom aña",-- precision: ten million years[3]="$1 mion aña",-- precision: million years[4]="$100.000 aña",-- precision: hundred thousand years[5]="$10.000 aña",-- precision: ten thousand years[6]="$1e millennium",-- precision: millennium[7]="[[siglo $1]]",-- precision: century[8]="dékada $1",-- precision: decade-- the following use the format of #time parser function[9]="Y",-- precision: year[10]="F Y",-- precision: month[11]="j F Y",-- precision: day[12]='j F Y, G "ora"',-- precision: hour[13]="j F Y G:i",-- precision: minute[14]="j F Y G:i:s",-- precision: second["beforenow"]="$1 geleden",-- how to format negative numbers for precisions 0 to 5["afternow"]="over $1",-- how to format positive numbers for precisions 0 to 5["bc"]='$1 "a.K."',-- how print negative years["bce"]='$1 "a.K."',-- how print negative years["ad"]="$1"-- how print positive years},["monolingualtext"]='<span lang="%language">%text</span>'}localp={}localfunctionprintError(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.localfunctionorderedpairs(array,order)ifnotorderthenreturnpairs(array)end-- return iterator functionlocali=0returnfunction()i=i+1iforder[i]thenreturnorder[i],array[order[i]]endendend-- getting sitelink of a given wiki-- source: https://en.wikipedia.org/w/index.php?title=Module:Wikidata&oldid=757775054 line 1102functionp.getSiteLink(frame)localsiteId=frame.args[1]localwikidataId=frame.args["id"]localentity=mw.wikibase.getEntity(wikidataId)ifnotentitythenreturnendlocallink=entity:getSitelink(siteId)ifnotlinkthenreturnendreturnlinkendfunctionp.descriptionIn(frame)locallangcode=frame.args[1]localid=frame.args[2]-- return description of a Wikidata entity in the given language or the default language of this Wikipedia sitereturnmw.wikibase.getEntityObject(id).descriptions[langcodeorwiki.langcode].valueendfunctionp.labelIn(frame)locallangcode=frame.args[1]localid=frame.args[2]-- return label of a Wikidata entity in the given language or the default language of this Wikipedia sitereturnmw.wikibase.getEntityObject(id).labels[langcodeorwiki.langcode].valueendlocalfunctionprintDatavalueCoordinate(data,parameter)-- data fields: latitude [double], longitude [double], altitude [double], precision [double], globe [wikidata URI, usually http://www.wikidata.org/entity/Q2 [earth]]ifparameterthenifparameter=="globe"thendata.globe=mw.ustring.match(data.globe,"Q%d+")end-- extract entity id from the globe URIreturndata[parameter]elsereturndata.latitude.."/"..data.longitude-- combine latitude and longitude, which can be decomposed using the #titleparts wiki functionendendlocalfunctionprintDatavalueQuantity(data,parameter)-- data fields: amount [number], unit [string], upperBound [number], lowerBound [number]ifparameterthenreturndata[parameter]elsereturnstring.gsub(tonumber(data.amount),"%.",",")-- nl: replace dot decimal separator by comma decimal separatorendend-- 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 - secondlocalfunctionnormalizeDate(date)date=mw.text.trim(date,"+")-- extract yearlocalyearstr=mw.ustring.match(date,"^\-?%d+")localyear=tonumber(yearstr)-- remove leading zeros of yearreturnyear..mw.ustring.sub(date,#yearstr+1),yearendfunctionformatDate(date,precision,timezone,calendarmodel)precision=precisionor11date,year=normalizeDate(date)ifyear==0andprecision<=9thenreturn""endifprecision<=5thenlocalfactor=10^((5-precision)+4)localy2=math.ceil(math.abs(year)/factor)localrelative=mw.ustring.gsub(i18n.datetime[precision],"$1",tostring(y2))ifyear<0thenrelative=mw.ustring.gsub(i18n.datetime.beforenow,"$1",relative)elserelative=mw.ustring.gsub(i18n.datetime.afternow,"$1",relative)endreturnrelativeendlocaleraifprecision==6thenera=mw.ustring.gsub(i18n.datetime[6],"$1",tostring(math.floor((math.abs(year)-1)/1000)+1))endifprecision==7thenera=mw.ustring.gsub(i18n.datetime[7],"$1",tostring(math.floor((math.abs(year)-1)/100)+1))endifprecision==8thenera=mw.ustring.gsub(i18n.datetime[8],"$1",tostring(math.floor(math.abs(year)/10)*10))endiferathenifyear<0thenera=mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc,'"',""),"$1",era)elseifyear>0thenera=mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad,'"',""),"$1",era)endreturneraendifprecision==9thenreturnyearendifprecision>9thenlocalformatstr=i18n.datetime[precision]ifyear==0thenformatstr=mw.ustring.gsub(formatstr,i18n.datetime[9],"")elseifyear<0thendate=mw.ustring.sub(date,2)formatstr=mw.ustring.gsub(formatstr,i18n.datetime[9],mw.ustring.gsub(i18n.datetime.bc,"$1",i18n.datetime[9]))elseifyear>0andi18n.datetime.ad~="$1"thenformatstr=mw.ustring.gsub(formatstr,i18n.datetime[9],mw.ustring.gsub(i18n.datetime.ad,"$1",i18n.datetime[9]))endlocalformattedDate=mw.language.new(wiki.langcode):formatDate(formatstr,date)formattedDate=formattedDate:gsub("(%d+) (%a+)","%1 di %2")if(mw.ustring.find(calendarmodel,'Q1985786',1,true))andyear>1582thenreturnformattedDate..'<sup> [[Kalènder yüliano|jul.]]</sup>'elsereturnformattedDateendendendlocalfunctionformatDateLink(time,precision,calendarmodel)precision=precisionor11localyear,m,d=mw.ustring.match(time,"(%-?%d+)%-(%d+)%-(%d+)T")localmaanden={'yanüari','febrüari','mart','aprel','mei','yüni','yüli','ougùstùs','sèptèmber','òktober','novèmber','desèmber'}m=tonumber(m)d=tonumber(d)year=tonumber(year)-- precision is decades, centuries and millenialocaleraifprecision==6thenera=mw.ustring.gsub(i18n.datetime[6],"$1",tostring(math.floor((math.abs(year)-1)/1000)+1))endifprecision==7thenera=mw.ustring.gsub(i18n.datetime[7],"$1",tostring(math.floor((math.abs(year)-1)/100)+1))endifprecision==8thenera=mw.ustring.gsub(i18n.datetime[8],"$1",tostring(math.floor(math.abs(year)/10)*10))endiferathenifyear<0thenera=mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc,'"',""),"$1",era)elseifyear>0thenera=mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad,'"',""),"$1",era)endreturneraendifprecision==9thenreturn'[['..year..']]'endifprecision==10thenreturn'[['..d..' di '..maanden[m]..']] [['..year..']]'endifprecision>10thenlocalformattedDate='[['..d..' di '..maanden[m]..']] [['..year..']]'if(mw.ustring.find(calendarmodel,'Q1985786',1,true))andyear>1582thenreturnformattedDate..'<sup> [[Kalènder yüliano|jul.]]</sup>'elsereturnformattedDateendendendlocalfunctionprintDatavalueTime(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]ifparameterthenifparameter=="calendarmodel"thendata.calendarmodel=mw.ustring.match(data.calendarmodel,"Q%d+")-- extract entity id from the calendar model URIelseifparameter=="time"thendata.time=normalizeDate(data.time)endifparameter=="link"thenreturnformatDateLink(data.time,data.precision,data.calendarmodel)endreturndata[parameter]elsereturnformatDate(data.time,data.precision,data.timezone,data.calendarmodel)endendlocalfunctionprintDatavalueEntity(data,parameter)-- data fields: entity-type [string], numeric-id [int, Wikidata id]localid="Q"..data["numeric-id"]ifparameterthenifparameter=="link"thenreturn"[["..(mw.wikibase.sitelink(id)or(":d:"..id)).."|"..(mw.wikibase.label(id)orid).."]]"elsereturndata[parameter]endelseifdata["entity-type"]=="item"thenreturnmw.wikibase.label("Q"..data["numeric-id"])oridelseprintError("unknown-entity-type")endendendlocalfunctionprintDatavalueMonolingualText(data,parameter)-- data fields: language [string], text [string]ifparameterthenreturndata[parameter]elsereturnmw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext,"%%language",data["language"]),"%%text",data["text"])endendfunctionfindClaims(entity,property)ifnotpropertyornotentityornotentity.claimsthenreturnendifmw.ustring.match(property,"^P%d+$")then-- if the property is given by an id (P..) access the claim list by this idreturnentity.claims[property]elseproperty=mw.wikibase.resolvePropertyId(property)ifnotpropertythenreturnendreturnentity.claims[property]endendfunctiongetSnakValue(snak,parameter)-- snaks have three types: "novalue" for null/nil, "somevalue" for not null/not nil, or "value" for actual dataifsnak.snaktype=="novalue"thenreturni18n["novalue"]elseifsnak.snaktype=="somevalue"thenreturni18n["somevalue"]elseifsnak.snaktype~="value"thenreturnnil,printError("unknown-snak-type")end-- call the respective snak parserifsnak.datavalue.type=="string"thenreturnsnak.datavalue.valueelseifsnak.datavalue.type=="globecoordinate"thenreturnprintDatavalueCoordinate(snak.datavalue.value,parameter)elseifsnak.datavalue.type=="quantity"thenreturnprintDatavalueQuantity(snak.datavalue.value,parameter)elseifsnak.datavalue.type=="time"thenreturnprintDatavalueTime(snak.datavalue.value,parameter)elseifsnak.datavalue.type=="wikibase-entityid"thenreturnprintDatavalueEntity(snak.datavalue.value,parameter)elseifsnak.datavalue.type=="monolingualtext"thenreturnprintDatavalueMonolingualText(snak.datavalue.value,parameter)elsereturnnil,printError("unknown-datavalue-type")endendlocalfunctiongetQualifierSnak(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 snaksifqualifierIdthen-- search the attribute snak with the given qualifier as keyifclaim.qualifiersthenlocalqualifier=claim.qualifiers[qualifierId]ifqualifierthenreturnqualifier[1]endendreturnnil,printError("qualifier-not-found")else-- otherwise return the main snakreturnclaim.mainsnakendendlocalfunctiongetValueOfClaim(claim,qualifierId,parameter)localerrorlocalsnaksnak,error=getQualifierSnak(claim,qualifierId)ifsnakthenreturngetSnakValue(snak,parameter)elsereturnnil,errorendendlocalfunctiongetReferences(frame,claim)localresult=""-- traverse through all referencesforrefinpairs(claim.referencesor{})dolocalrefparts-- traverse through all parts of the current referenceforsnakkey,snakvalinorderedpairs(claim.references[ref].snaksor{},claim.references[ref]["snaks-order"])doifrefpartsthenrefparts=refparts..", "elserefparts=""end-- output the label of the property of the reference part, e.g. "imported from" for P143refparts=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 sitesforsnakidx=1,#snakvaldoifsnakidx>1thenrefparts=refparts..", "endrefparts=refparts..getSnakValue(snakval[snakidx])endendifrefpartsthenresult=result..frame:extensionTag("ref",refparts)endendreturnresultendfunctionp.claim(frame)localproperty=frame.args[1]or""localid=frame.args["id"]localqualifierId=frame.args["qualifier"]localparameter=frame.args["parameter"]locallist=frame.args["list"]localreferences=frame.args["references"]localshowerrors=frame.args["showerrors"]localdefault=frame.args["default"]ifdefaultthenshowerrors=nilend-- get wikidata entitylocalentity=mw.wikibase.getEntityObject(id)ifnotentitythenifshowerrorsthenreturnprintError("entity-not-found")elsereturndefaultendend-- fetch the first claim of satisfying the given propertylocalclaims=findClaims(entity,property)ifnotclaimsornotclaims[1]thenifshowerrorsthenreturnprintError("property-not-found")elsereturndefaultendend-- get initial sort indiceslocalsortindices={}foridxinpairs(claims)dosortindices[#sortindices+1]=idxend-- sort by claim ranklocalcomparator=function(a,b)localrankmap={deprecated=2,normal=1,preferred=0}localranka=rankmap[claims[a].rankor"normal"]..string.format("%08d",a)localrankb=rankmap[claims[b].rankor"normal"]..string.format("%08d",b)returnranka<rankbendtable.sort(sortindices,comparator)localresultlocalerroriflistthenlocalvalue-- iterate over all elements and return their value (if existing)result={}foridxinpairs(claims)dolocalclaim=claims[sortindices[idx]]value,error=getValueOfClaim(claim,qualifierId,parameter)ifnotvalueandshowerrorsthenvalue=errorendifvalueandreferencesthenvalue=value..getReferences(frame,claim)endresult[#result+1]=valueendresult=table.concat(result,list)elseifparameter=="count"thenresult=#claimselse-- return first elementlocalclaim=claims[sortindices[1]]result,error=getValueOfClaim(claim,qualifierId,parameter)ifresultandreferencesthenresult=result..getReferences(frame,claim)endendifresultthenreturnresultelseifshowerrorsthenreturnerrorelsereturndefaultendendendfunctionp.getValue(frame)localparam=frame.args[2]ifparam=="FETCH_WIKIDATA"thenreturnp.claim(frame)elsereturnparamendendfunctionp.pageId(frame)localentity=mw.wikibase.getEntityObject()ifnotentitythenreturnnilelsereturnentity.idendendfunctionp.labelOf(frame)localid=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 usedifnotidthenlocalentity=mw.wikibase.getEntityObject()ifnotentitythenreturnprintError("entity-not-found")endid=entity.idendreturnmw.wikibase.label(id)endfunctionp.sitelinkOf(frame)localid=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 usedifnotidthenlocalentity=mw.wikibase.getEntityObject()ifnotentitythenreturnprintError("entity-not-found")endid=entity.idendreturnmw.wikibase.sitelink(id)endfunctionp.badges(frame)localsite=frame.args[1]localid=frame.args[2]ifnotsitethenreturnprintError("site-not-found")endlocalentity=mw.wikibase.getEntityObject(id)ifnotentitythenreturnprintError("entity-not-found")endlocalbadges=entity.sitelinks[site].badgesifbadgesthenlocalresultforidx=1,#badgesdoifresultthenresult=result.."/"..badges[idx]elseresult=badges[idx]endendreturnresultendend-- call this in cases of script errors within a function instead of {{#invoke:Wikidata|<method>|...}} call {{#invoke:Wikidata|debug|<method>|...}}functionp.debug(frame)localfunc=frame.args[1]iffuncthen-- create new parameter set, where the first parameter with the function name is removedlocalnewargs={}forkey,valinpairs(frame.args)doiftype(key)=="number"thenifkey>1thennewargs[key-1]=valendelsenewargs[key]=valendendframe.args=newargslocalstatus,result=pcall(p[func],frame)ifstatusthenreturnresultelsereturn'<span class="error">'..result..'</span>'endelsereturn'<span class="error">invalid parameters</span>'endendreturnp