Extension:LinkedWiki/lua

From MediaWiki.org
Jump to navigation Jump to search
This infobox is able to read, save and check data with an external knowledge base such as Wikidata. That is one of many possible use cases with the LinkedWiki Lua class.

LinkedWiki provides a Lua Scribunto interface that implements functions to access data from RDF databases with SPARQL endpoints. If Scribunto is installed in your wiki, Lua modules and wiki templates can invoke these functions and the Linkedwiki Class.

Quick start[edit]

Usually, the part Lua of LinkedWiki used in infoboxes. Here, you can see an example.

The objective of this module is to create an infobox that is able to save directly in a RDF database and where data are marked with a red flag when data are different of another RDF database such as Wikidata.

{{#invoke:Pape|infobox
| Wikidata ID = Q132845
| Bnf ID =
| Titre = Adrien IV
| Image = http://commons.wikimedia.org/wiki/Special:FilePath/Pope%20Hadrian%20IV.jpg
| Nom de naissance = Nicolas Breakspear
| Date de naissance = 1100-1-1
| Naissance précision (années) = 10
| Lieu de naissance = Abbots Langley
| Date de décès = 1159-09-1
| Lieu de décès = Anagni
| Election au pontificat = 1154-12-4
| Intronisation = 1154-12-5
| Fin du pontificat = 1159-9-1
}}

The module uses the Extension:Capiunto.

The first part saves the infobox's parameters. The second part searches the data of Wikidata. The last part builds an infobox and compare data of Wikidata with the parameters.

local p = {}

function p.infobox(f)
    local capiunto = require 'capiunto'
    local linkedwiki = require 'linkedwiki'

    -- init the prefix
    local rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    local rdfs = 'http://www.w3.org/2000/01/rdf-schema#'
    local ri = 'http://gregorius.fr/wiki/'
    local rp = 'http://gregorius.fr/wiki/Property:'
    local xsd = 'http://www.w3.org/2001/XMLSchema#'
    local wdt = 'http://www.wikidata.org/prop/direct/'
    local wd = 'http://www.wikidata.org/entity/'
    local p = 'http://www.wikidata.org/prop/'
    local pq = 'http://www.wikidata.org/prop/qualifier/'
    local ps = 'http://www.wikidata.org/prop/statement/'

    local dateFormat = "d M Y"

    local subject = f.args.iri or linkedwiki.getCurrentIRI();  --find the iri of the current page

    local object = linkedwiki.new(subject)
    --object:setDebug(true)
    object:removeSubject() -- delete all triples of this subject

    -- Save the data in the infobox in a knowledge base
    mw.log(object:addPropertyWithIri(rdf .. 'type', ri .. 'Pape'))
    mw.log(object:addPropertyString(rdfs .. 'label', f.args["Titre"]))
    mw.log(object:addPropertyWithIri(rp .. 'picture', f.args["Image"]))
    mw.log(object:addProperty(rp .. 'nomDeNaissance', f.args['Nom de naissance']))
    mw.log(object:addProperty(rp .. 'naissance', f.args['Date de naissance'], xsd .. 'date', ''))
    mw.log(object:addProperty(rp .. 'naissancePrecision', f.args['Naissance précision (années)'], xsd .. 'integer', ''))
    mw.log(object:addPropertyString(rp .. 'lieuDeNaissance', f.args['Lieu de naissance']))
    mw.log(object:addProperty(rp .. 'deces', f.args['Date de décès'], xsd .. 'date', ''))
    mw.log(object:addPropertyString(rp .. 'lieuDeDeces', f.args['Lieu de décès']))
    mw.log(object:addProperty(rp .. 'electionAuPontificat', f.args['Election au pontificat'], xsd .. 'date', ''))
    mw.log(object:addProperty(rp .. 'intronisation', f.args['Intronisation'], xsd .. 'date', ''))
    mw.log(object:addProperty(rp .. 'finDuPontificat', f.args['Fin du pontificat'], xsd .. 'date', ''))

    --compare data with Wikidata
    local iriWikidata = ""
    local objWikidata = nil
    local objWikidataLieuNaissance = nil
    local objWikidataLieuDeces = nil
    local objPapeFonction = nil
    local linkWikidata = ""

    if not linkedwiki.isEmpty(f.args['Wikidata ID']) then
        local idConfigWikidata = 'http://www.wikidata.org'
        local taglang = 'fr'

        iriWikidata = wd .. f.args['Wikidata ID']
        objWikidata = linkedwiki.new(iriWikidata, idConfigWikidata, taglang)
        mw.log(object:addPropertyWithIri(rp .. 'WikidataID', iriWikidata))
        objWikidataLieuNaissance = linkedwiki.new(objWikidata:getValue(wdt .. 'P19'), idConfigWikidata, taglang)
        objWikidataLieuDeces = linkedwiki.new(objWikidata:getValue(wdt .. 'P20'), idConfigWikidata, taglang)

        listIri = linkedwiki.explode(";", objWikidata:getValue(p .. 'P39'))
        objPapeFonction = nil
        for i, iri in ipairs(listIri) do
            objPapeFonction = linkedwiki.new(iri, idConfigWikidata, taglang)
            if objPapeFonction:getValue(ps .. 'P39') == wd .. "Q19546" then
                break
            end
        end

        linkWikidata = '[' .. iriWikidata .. ' ' .. f.args['Wikidata ID'] .. ']'
    end

    --Make infobox with capiunto
    local infobox = capiunto.create({
        bodyStyle = 'width : 50px',
        bodyClass = 'gregoriusPape',
        title = 'Pape',
        top = objWikidata:checkString(rdfs .. 'label', f.args.Title),
        topStyle = 'background:#FFD200;height:50px;font-size: 25px;vertical-align:middle'
    })

    infobox:addImage(objWikidata:checkImage(wdt .. 'P18', f.args["Image"], 200), "", "Image")
    infobox:addRow('Nom de naissance', objWikidata:checkString(wdt .. "P1477", f.args['Nom de naissance']))
    infobox:addRow('Lieu de naissance', objWikidataLieuNaissance:checkString(rdfs .. "label", f.args['Lieu de naissance']))
    infobox:addRow('Naissance', objWikidata:checkDate(wdt .. "P569", f.args['Date de naissance'], dateFormat))
    infobox:addRow('Lieu de décès', objWikidataLieuDeces:checkString(rdfs .. "label", f.args['Lieu de décès']))
    infobox:addRow('Date de décès', objWikidata:checkDate(wdt .. "P570", f.args['Date de décès'], dateFormat))
    infobox:addRow('Élection au pontificat', f.args['Election au pontificat'])
    infobox:addRow('Intronisation', objPapeFonction:checkDate(pq .. "P580", f.args['Intronisation'], dateFormat))
    infobox:addRow('Fin du pontificat', objPapeFonction:checkDate(pq .. "P582", f.args['Fin du pontificat'], dateFormat))
    infobox:addRow('Source Wikidata', linkWikidata)

    return infobox
end

return p

You can test your module in the lua console with this code :

frame = mw.getCurrentFrame() -- Get a frame object
newFrame = frame:newChild{ -- Get one with args
	title = 'Adrien IV' ,
 args = {
 iri = 'http://gregorius.fr/wiki/Adrien_IV' ,
["Wikidata ID"] = 'Q132845' ,
["Bnf ID"] = '' ,
["Titre"] = 'Adrien IV' ,
["Image"] = 'http://commons.wikimedia.org/wiki/Special:FilePath/Pope%20Hadrian%20IV.jpg' ,
['Nom de naissance'] = 'Nicolas Breakspear' ,
['Lieu de naissance'] = 'Abbots Langley' ,
['Date de naissance'] = '1159-09-1' ,
['Naissance précision (années)'] = '10' ,
['Lieu de décès'] = 'Anagni' ,
['Date de décès'] = '1159-09-01' ,
['Election au pontificat'] = '1154-12-4' ,
['Intronisation'] = '1154-12-5' ,
['Fin du pontificat'] = '1159-9-1'
    }
}
mw.log(p.infobox( newFrame ) )

Best usage with the Linkedwiki Class[edit]

Constructor : build a new object[edit]

linkedwiki.new(subject,config=nil,tagLang=nil,debug=nil)
linkedwiki.new(subject) uses the configuration by default
linkedwiki.new(subject,config) uses the configuration of config
linkedwiki.new(subject,config,tagLang) uses the configuration of config but with the language of tagLang

Returns a LinkedWiki object .

subject : string
select the subject of triples

config : string : id of endpoint in the file extension.json
select the configuration in order to read/write or delete the triples of this object in the database.If nil, it uses the configuration by default.

tagLang : string : tag lang for example : fr or en
select the default language for the function getString and addPropertyString. If nil, it uses the language in the configuration.

debug : boolean
Enable the debug mode.

Examples :

local linkedwiki = require 'linkedwiki'
local subject = linkedwiki.getCurrentIRI(); -- read the iri of the current page
local object =  linkedwiki.new(subject)
mw.log(object:getConfig()) -- show the configuration id uses by this object


Configuration[edit]

Config[edit]

obj:getConfig()

Returns configuration id (string) used by this instance.(see details about configurations)


obj:setConfig(iriConfiguration)

Returns nil. It changes the configuration of this instance.

iriConfiguration : configuration id (see details about configurations)

Example :

local linkedwiki = require 'linkedwiki'
local subject = "http://www.example.org/mysubject"; 
local object =  linkedwiki.new(subject)
mw.log(object:getConfig()) -- show the configuration id uses by this object

object:setConfig("http://www.example.org") -- change the configuration of this object
mw.log(object:getConfig()) -- show the configuration id uses by this object

Lang[edit]

obj:getLang()

Returns lang tag (string) used by this instance.


obj:setLang(tagLang)

Returns nil. It changes the lang tag of this instance.

tagLang : lang tag

Example :

local linkedwiki = require 'linkedwiki'
local subject = "http://www.example.org/mysubject"; 
local object =  linkedwiki.new(subject)
mw.log(object:getLang()) -- show the current lang tag

object:setLang("fr") -- change the configuration of this object with the french lang tag
mw.log(object:getLang())

Subject[edit]

obj:getSubject()

Returns subject (iri/string) used by this instance.


obj:setSubject(iriSubject)

Returns nil. It changes the subject of this instance.

Example :

local linkedwiki = require 'linkedwiki'
local subject = "http://www.example.org/mysubject"; 
local object =  linkedwiki.new(subject)
mw.log(object:getSubject()) -- show the current subject

object:setSubject("http://www.example.org/mysubject2") -- change the subject 
mw.log(object:getSubject())

initConfig[edit]

obj:initConfig()

Returns nil

Useful only before using a static function in order to initialize the configuration, the language and the debug mode.

Read data[edit]

Iri or litteral without language tag[edit]

obj:getValue(iriProperty)

Returns the value IRI or litteral without language tag of current subject with this property.

iriProperty : IRI of the property

Example :

local linkedwiki = require 'linkedwiki'
local wd = 'http://www.wikidata.org/entity/'
local wdt = 'http://www.wikidata.org/prop/direct/'
local subject = wd.."Q1"; 
local propertyImage = wdt.."P18"; 

local univers =  linkedwiki.new(subject,"http://www.wikidata.org")
mw.log(object:getValue(propertyImage))

litteral with language tag[edit]

obj:getString(iriProperty, tagLang=nil)

Returns the litteral with this language tag in function of current subject with this property.

iriProperty : IRI of the property

tagLang : lang tag. If nil, it uses the lang tag by default.

Example :

local linkedwiki = require 'linkedwiki'
local wd = 'http://www.wikidata.org/entity/'
local rdfs = 'http://www.w3.org/2000/01/rdf-schema#'
local subject = wd.."Q1"; 
local propertyLabel = rdfs.."label"; 

local univers =  linkedwiki.new(subject,"http://www.wikidata.org","fr") --uses Wikidata's config and the french tag 
mw.log(object:getString(propertyLabel))

Write data[edit]

Iri[edit]

obj:addPropertyWithIri(iriProperty, iriValue)

Returns the response of the database. It saves one IRI in function of the storage method defined in the configuration.

iriProperty : IRI of the property

iriValue : IRI of the value

Example :

local ex = 'http://example.com/ont#'
local rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
local subject = "http://www.example.org/mysubject"; 

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)
object:addPropertyWithIri(rdf..'type',ex..'MyType') -- record one information
mw.log(linkedwiki.object:getValue(rdf..'type')) -- read this information

Litteral[edit]

Value without language tag[edit]

obj:addProperty(iriProperty, value, type=nil)

Returns the response of the database. It saves one value without a lang tag in function of the storage method defined in the configuration.

iriProperty : IRI of the property

value : string or number or date or etc.

type : IRI of type (see type available in XSD in SPARQL). If nil, the database will use the SPARQL standard in order to choose the type. For example, if the value is 7, the database will use xsd:integer but with the value 7.1, it will use xsd:float or xsd:double.

Example without explicit type :

local ex = 'http://example.com/ont#'
local subject = "http://www.example.org/mysubject"; 

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)
object:addProperty(ex..'age',35) -- record one integer
mw.log(linkedwiki.object:getValue(ex..'age')) -- read this information

Example with a date :

local ex = 'http://example.com/ont#'
local xsd = 'http://www.w3.org/2001/XMLSchema#'
local subject = "http://www.example.org/mysubject"; 

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)
object:addProperty(ex..'birth',"1955-01-15",xsd..'date') -- record one date
mw.log(linkedwiki.object:getValue(ex..'birth')) -- read this date

Example with a double :

local ex = 'http://example.com/ont#'
local xsd = 'http://www.w3.org/2001/XMLSchema#'
local subject = "http://www.example.org/mysubject"; 

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)
object:addProperty(ex..'price',"5",xsd..'double') -- record a price
mw.log(linkedwiki.object:getValue(ex..'price')) -- read this price


String[edit]

obj:addPropertyString(iriProperty, value, tagLang=nil)

Returns the response of the database. It saves one string with a lang tag in function of the storage method defined in the configuration.

iriProperty : IRI of the property

value : string

tagLang : language tag to use with this text. If nil, the default lang tag in the configuration will be used.

Example :

local ex = 'http://example.com/ont#'
local subject = "http://www.example.org/mysubject"; 
local rdfs = 'http://www.w3.org/2000/01/rdf-schema#'

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)

object:addPropertyString(rdfs..'label',"Title") -- write "Title"@en if English is the language by default 
object:addPropertyString(rdfs..'label',"Title",nil) -- write "Title"@en if English is the language by default 
object:addPropertyString(rdfs..'label',"Title", "fr") -- write "Title"@fr 
object:addPropertyString(rdfs..'label',"Title", "") -- write "Title" without tag
mw.log(linkedwiki.object:getString(rdfs..'label')) -- read this information
Other cases[edit]

obj:addPropertyWithLitteral(iriProperty, value, type, tagLang)

Returns the response of the database. It saves one litteral with a specific type and tag language tag in function of the storage method defined in the configuration.

Load data[edit]

..TODO Example :

local linkedwiki = require 'linkedwiki'
    local subject = linkedwiki.getCurrentIRI()
    local object =  linkedwiki.new(subject)
--local config = 'http://database-test'
--object:setConfig(config)
object:loadData(f.args.Titles)
mw.log(object:getLastQuery())

Delete data[edit]

obj:removeSubject()

Returns the response of the database. It deletes all triples with the current subject of the instance in function of the storage method defined in the configuration.

Example :

local subject = "http://www.example.org/mysubject"; 

local linkedwiki = require 'linkedwiki'
local object =  linkedwiki.new(subject)

object:removeSubject() -- delete all triples with the current subject

Functions for infoboxes[edit]

Litteral without language tag[edit]

obj:checkValue(property, valueInWiki)

Returns wiki text. This function compares the value of this property with the parameter valueInWiki.

Litteral with language tag[edit]

obj:checkString(property, valueInWiki, tagLang=nil)

Returns wiki text. This function compares the value of this property with the parameter valueInWiki.

tagLang Lang tag of value with this property. If nil, it uses the lang tag of the current configuration.

Label with language tag[edit]

obj:checkTitle(property, labelInWiki, tagLang)

Returns wiki text. This function compares the rdfs:label of object linked via property with the parameter labelInWiki.

tagLang Lang tag of label. If nil, it uses the lang tag of the current configuration.

Intern Link[edit]

obj:checkLabelOfInternLink(link, propertyOfLabel, labelInWiki, tagLang=nil)

Returns wiki text. This function inserts an intern link.

link Url of link

propertyOfLabel Property in order to read the label

labelInWiki label of link

tagLang Lang tag of label. If nil, it uses the lang tag of the current configuration.

Extern Link[edit]

obj:checkIriOfExternLink(labelOfExternLink, propertyOfExternLink, externLinkInWiki)

Returns wiki text. This function inserts an external link.

labelOfExternLink label of link

propertyOfLabel Property in order to read the url of link in the database

externLinkInWiki Url of link

tagLang Lang tag of label. If nil, it uses the lang tag of the current configuration.

User[edit]

obj:checkUser(property, valueInWiki, tagLang)

Returns wiki text. This function compares the list of users in the database with the parameter valueInWiki. This function creates links to the user's pages and add a link to emails when its exist in the database with the property vcard:email.

Date[edit]

obj:checkDate(property, valueInWiki, format)

Returns wiki text. This function compares the date of this property with the parameter valueInWiki.

format Format in output the date with the parser #Time

Image[edit]

obj:checkImage(property, valueInWiki, width=nil, height=nil)

Returns wiki text. This function compares the value of this property with the parameter valueInWiki.

width image width

height image height

Wikidata item[edit]

obj:checkItem(property, valueInWiki, tagLang)

Returns wiki text. This function compares the list of Wikidata ID in the database with the parameter valueInWiki.

Tools[edit]

getCurrentTitle[edit]

linkedwiki.getCurrentTitle()

Returns Title of the page

getCurrentIRI[edit]

linkedwiki.getCurrentIRI()

Returns IRI of the page

isEmpty[edit]

linkedwiki.isEmpty(s)

Returns Boolean. Check if s is empty (nil or "").

explode[edit]

linkedwiki.explode(div, str)

Returns a list.

Example :

        listIri = linkedwiki.explode(";", objWikidata:getValue(p .. 'P39'))
        for i, iri in ipairs(listIri) do
            mw.log(iri)
        end

concatWithComma[edit]

linkedwiki.concatWithComma(list)

Returns a string.

Example :

        listIri = linkedwiki.explode(";", objWikidata:getValue(p .. 'P39'))
        mw.log(linkedwiki.concatWithComma(listIri))

trim[edit]

For information in Scribunto, remove the spaces before and after the text.

mw.text.trim(str)

fullUrl[edit]

For information in Scribunto, read the fullUrl of an article.

mw.title.new(title):fullUrl()

Restore database RDF[edit]

If you want to restore your database RDF, you can use the feature "refresh all page with Lua" in the special page RDFSave (with user right data).

Debug[edit]

obj:setDebug(boolDebug)
obj:isDebug()

You can use setDebug in order to see the errors in the SPARQL queries.

obj:getLastQuery()

With this function, you can see the last SPARQL query used by the precedent function.