ਮੌਡਿਊਲ:Wikidata art
Documentation for this module may be created at ਮੌਡਿਊਲ:Wikidata art/doc
--[[
__ __ _ _ __ ___ _ _ _ _ _
| \/ | ___ __| |_ _| | ___ \ \ / (_) | _(_) __| | __ _| |_ __ _ __ _ _ __| |_
| |\/| |/ _ \ / _` | | | | |/ _ (_) \ /\ / /| | |/ / |/ _` |/ _` | __/ _` | / _` | '__| __|
| | | | (_) | (_| | |_| | | __/_ \ V V / | | <| | (_| | (_| | || (_| | | (_| | | | |_
|_| |_|\___/ \__,_|\__,_|_|\___(_) \_/\_/ |_|_|\_\_|\__,_|\__,_|\__\__,_| \__,_|_| \__|
This module is intended to provide localized text for different infobox fields.
At the moment we have:
|====================|===========================|=====================|
| Infobox Field | Property | Template |
|====================|===========================|=====================|
| object history | commissioned by (P88) | {{ProvenanceEvent}} |
| | owned by (P127) | |
| | significant event (P793) | |
| exhibition history | exhibition history (P608) | none |
| inscriptions | inscription (P1684) | {{inscription}}m |
| medium | material used (P186) | {{Technique}} |
| work location | work location (P937) | none |
| creator | creator(P170), author(P50)| |
| | architect (P84) | {{Creator}} |
| institution | inventory number (P217) | {{Institution}} |
| | collection (P195) | |
| | location (P276) | |
| accession number | inventory number (P217) | none |
|====================|===========================|=====================|
Please do not modify this code without applying the changes first at
"Module:Artwork/sandbox" and testing at "Module:Artwork/testcases".
Authors and maintainers:
* User:Jarekt - original version
]]
local getLabel = require("Module:Wikidata label")._getLabel -- used for creation of name based on wikidata
local getDate = require("Module:Wikidata date")._date -- used for processing of date properties
local qualifierDate = require("Module:Wikidata date")._qualifierDate -- used for processing of date qualifiers
local creator = require("Module:Creator")._creator -- render creator templates
local institution = require("Module:Institution")._institution -- render institution templates
local material_LUT = require('Module:Artwork/Technique LUT')
-- ==================================================
-- === Internal functions ===========================
-- ==================================================
local function length(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
local function langSwitch(list,lang)
local langList = mw.language.getFallbacksFor(lang)
table.insert(langList,1,lang)
for i,language in ipairs(langList) do
if list[language] then
return list[language]
end
end
return nil
end
local function getProperty(entity, prop, outputType)
local Output = {}
if entity.claims and entity.claims[prop] then
for _, statement in pairs( entity:getBestStatements( prop )) do
if (statement.mainsnak.snaktype == "value") then
local val = statement.mainsnak.datavalue.value
if val.id then
val = val.id
elseif val.text then
val = val.text
end
table.insert(Output, val)
end
end
end
if #Output==0 then
return nil
elseif outputType=='one' then
return Output[1]
else
return Output
end
end
local function getPropertyQual(entity, prop, qualifiers, lang, offset)
local Res = {}
if entity.claims and entity.claims[prop] then
for k, statement in ipairs( entity:getBestStatements( prop )) do
if (statement.mainsnak.snaktype == "value") then
local res = {} -- table with fields: key, value, P... (qualifiers)
local jdn = k + (offset or 0) -- "Julian day number" will be used as a key for sorting events; initialize
local val = statement.mainsnak.datavalue.value
if val.id then
res.value_id = val.id
val = getLabel(val.id, lang)
elseif val.text then
res.value_lang = val.language
val = val.text
end
res.value = val
for iQual, qual in ipairs( qualifiers ) do
if statement.qualifiers and statement.qualifiers[qual] then
local snak = statement.qualifiers[qual][1]
if (snak.snaktype == "value" and snak.datatype == 'wikibase-item') then
val = getLabel(snak.datavalue.value.id, lang)
res[qual ..'_id'] = snak.datavalue.value.id
elseif (snak.snaktype == "value" and snak.datatype == 'string') then
val = snak.datavalue.value
elseif (snak.snaktype == "value" and snak.datatype == 'monolingualtext') then
val = snak.datavalue.value.text
res[qual.."_lang"] = snak.datavalue.value.language
elseif (snak.snaktype == "value" and snak.datatype == 'time') then
val = qualifierDate(snak, lang)
if iQual==1 then -- first qualifier in the qualifiers list will be used as a sorting value
jdn = val.jdn
end
val = val.str
else
val = nil
end
res[qual] = val
end
end
res.key = jdn
table.insert(Res, res)
end
end
end
local tableComp = function (rec1, rec2) return rec1.key<rec2.key end
table.sort(Res, tableComp)
return Res
end
-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}
-- ===========================================================================
function p.get_object_history(entity, lang)
-- Provenance look up table converting items IDs to template inputs
local ProvenanceLUT = {
Q22340494 = "acquisition", --acquisition
Q707482 = "gift", --gift
Q211557 = "bequest", --bequest
Q194189 = "sale", --sales
Q184303 = "gift", --gift
Q177923 = "auction", --auction
Q5260774 = "deposit", --deposit
Q1124860 = "gift", --donation
Q1362753 = "acquisition", --acquisition
Q1756454 = "theft", --art theft
Q17781833 = "destruction", --destruction
Q217102 = "restored", --conservation
Q2727213 = "theft", --theft
Q6498684 = "in collection", --ownership
Q753297 = "discovery", --discovery
Q14903979 = "conveyance", --change of ownership
Q189539 = "loan", --loan
Q601401 = "exchange", --trade
Q6160 = "damaged", --vandalism
Q19880899 = "theft", --Isabella Stewart Gardner Museum theft
Q1156800 = "restitution", --restitution
Q1369832 = "purchase", --purchasing
Q851304 = "theft", --Looted art
Q3030513 = "missing", --disappearance
Q21745157 = "destruction", --destroyed artwork
Q53706 = "theft", --robbery
Q328376 = "theft", --Nazi plunder
Q420708 = "acquisition", --Acquisition
Q760089 = "commission", --commission
Q200303 = "inheritance", --inheritance
Q3196 = "burnt", --fire
Q192623 = "theft", --looting
}
--{{ProvenanceEvent|time=1950-03-01|type=discovery|newowner=Elias Cohen|place=The Hague}}
local frame = mw.getCurrentFrame()
local EventList = {}
-- discovery statements
local discoveror = getProperty(entity, 'P61', 'one') -- discoverer or inventor (P61)
local discoveryPlace = getProperty(entity, 'P189', 'one') -- location of discovery (P189)
local d = getDate(entity, 'P575' , lang) -- discovery date
local discoveryTime = d.str
local event = {}
if discoveror or discoveryPlace or discoveryTime then
event.str = frame:expandTemplate{ title = 'ProvenanceEvent', args = { type='discovery', time=discoveryTime, discoveror=event.value, place=discoveryPlace, lang=lang } }
event.key = 0;
--event.str = '(P61) ' .. event.str
table.insert(EventList, event)
end
-- from commissioned by (P88) / point in time (P585) (time property)
local provEvents = getPropertyQual(entity, 'P88', {'P585'}, lang) -- 0 is where the numbering of undated events will start
for _, event in ipairs( provEvents) do
if event.P585 then
event.str = frame:expandTemplate{ title = 'ProvenanceEvent', args = { type='commissioned', time=event.P585, newowner=event.value, lang=lang } }
--event.str = '(P88) ' .. event.str
table.insert(EventList, event)
end
end
-- from owned by (P127) / P580 (time property)
local provEvents = getPropertyQual(entity, 'P127', {'P580'}, lang, 100) -- 100 is where the numbering of undated events will start
for _, event in ipairs( provEvents) do
if event.P580 then
event.str = frame:expandTemplate{ title = 'ProvenanceEvent', args = { type='acquisition', time=event.P580, newowner=event.value, lang=lang } }
--event.str = '(P127) ' .. event.str
table.insert(EventList, event)
end
end
-- from significant event P793 property with point in time (P585) qualifier
local provEvents = getPropertyQual(entity, 'P793', {'P585'}, lang, 200) -- 200 is where the numbering of undated events will start
for _, event in ipairs( provEvents) do
local eventType = ProvenanceLUT[event.value_id] -- look up event type based on stored item ID
if event.P585 and eventType then
event.str = frame:expandTemplate{ title = 'ProvenanceEvent', args = { type=eventType, time=event.P585, lang=lang } }
--event.str = '(P793) ' .. event.str
table.insert(EventList, event)
elseif event.P585 then
event.str = event.P585 .. ": unknown event: "..event.value.."<br/>"
--event.str = '(P793) ' .. event.str
table.insert(EventList, event)
end
end
if #EventList>0 then -- if any events
local tableComp = function (rec1, rec2) return rec1.key<rec2.key end
table.sort(EventList, tableComp) -- sort them by the date using sort key
local X, event = {}, {}
for _, event in ipairs(EventList) do -- collect just text of the template
table.insert(X, event.str)
end
return '* ' .. table.concat(X,"\n* ")
end
return nil
end
-- ===========================================================================
function p.get_exhibition_history(entity, lang)
-- exhibition history (P608) (item property) / 'P580', 'P582' (time properties)
local prop = getPropertyQual(entity, 'P608', {'P580', 'P582'}, lang)
local X={}
for _, p in ipairs(prop) do
local str = p.value
if p.P580 then
str = mw.ustring.format("%s (%s - %s)", p.value, p.P580, p.P582 or '')
end
table.insert(X, str)
end
if length(X)>0 then
return "\n*" .. table.concat(X,"\n*")
end
return nil
end
-- ===========================================================================
function p.get_medium(entity, lang)
-- material used (P186) (item property) / applies to part (P518) (item property)
local prop = getPropertyQual(entity, 'P186', {'P518'}, lang)
if not prop then
return nil -- if no P186 statements than exit
end
local temp_args = {} -- technique template arguments
local And = {'1', 'and', 'and2', 'and3', 'and4'} -- field names to use
temp_args.lang = lang
local material = {}
local n = 0;
local ok = true;
for _, p in ipairs( prop) do
table.insert(material, p.value)
local mat = material_LUT[p.value_id] -- use lookup table to convert item IDs to terms used by the template
if not mat then
ok = false; -- unrecognized material
end
if p.P518_id=='Q861259' then -- applies to part: painting surface
temp_args.on = mat
elseif n<4 then
n = n + 1;
temp_args[And[n]] = mat
end
end
if length(material)==2 and temp_args["1"]=='oil' and temp_args.on=='canvas' then
local LUT = require("Module:i18n/oil on canvas") -- oil on canvas can be done in LUA
return langSwitch(LUT, lang)
elseif ok then -- if
local frame = mw.getCurrentFrame()
return frame:expandTemplate{ title = 'technique', args=temp_args }
else
return table.concat(material,", ")
end
local id = getProperty(entity, 'P2079', 'one')
if id then
return getLabel(id, lang)
end
return nil
end
-- ===========================================================================
function p.get_inscription(entity, lang)
--[[
Wikidata
inscription (P1684) - Monolingual text
applies to part (P518) - item property
instance of (P31) - item property
Commons template:
{{inscription |1= |full form= |type= |side= |position= |description= |comment= |ID= |language= |translation= |en= |de= |medium= }}
]]
local LUT = {
-- positions
Q15332388 = "bottom",
Q17525439 = "bottom",
Q16421635 = "bottom",
Q23595 = "center",
Q13196750 = "left",
Q17525441 = "left",
Q257418 = "obverse",
Q82383 = "on base",
Q11193 = "on base",
Q860792 = "on frame",
Q1542661 = "reverse",
Q32198402 = "reverse",
Q16938807 = "reverse",
Q14565199 = "right",
Q17525442 = "right",
Q15332375 = "top",
Q17525438 = "top",
-- sides
Q9305022 = "recto",
Q9368452 = "verso",
-- type
Q188675 = "signature",
Q205892 = "date",
Q1898184 = "dedication",
Q168346 = "monogram",
Q2221906 = "place",
Q783521 = "title",
Q206287 = "quotation",
Q644099 = "stamp",
Q162919 = "seal",
-- complex positions
bottom_left = "bottom left",
bottom_right = "bottom right",
bottom_center = "bottom center",
center_left = "center left",
center_right = "center right",
left_top = "top left",
right_top = "top right",
center_top = "top center"
}
local frame = mw.getCurrentFrame()
local X = {}
for _, statement in ipairs( entity:getBestStatements( 'P1684' )) do
if (statement.mainsnak.snaktype == "value") then
local val = statement.mainsnak.datavalue.value
local temp_args, position, iType = {}, {}, {}
temp_args['1'] = val.text -- text
temp_args.language = val.language -- language of the text
temp_args.lang = lang -- language of the reader
if statement.qualifiers then
if statement.qualifiers.P31 then
for _, snak in ipairs( statement.qualifiers.P31) do
table.insert(iType, LUT[snak.datavalue.value.id])
end
temp_args.type = table.concat(iType, '/')
end
if statement.qualifiers.P518 then
for _, snak in ipairs( statement.qualifiers.P518) do
local part = LUT[snak.datavalue.value.id]
if (part=="recto" or part=="verso") then
temp_args.side = part
else
table.insert(position, part)
end
end
end
if length(position)==1 then
temp_args.position = position[1]
elseif length(position)==2 then
table.sort(position)
temp_args.position = LUT[table.concat(position, '_')]
end
end
val = frame:expandTemplate{ title = 'inscription', args=temp_args }
table.insert(X, val)
end
end
if length(X)==1 then
return X[1]
elseif length(X)>0 then
return "\n*" .. table.concat(X,"\n*")
end
return nil
end
-- ===========================================================================
function p.get_work_location(entity, lang)
-- work_location (P937) / 'P580', 'P582' (time properties)
local prop = getPropertyQual(entity, 'P937', {'P580', 'P582', 'P585'}, lang)
local X={}
for _, p in ipairs(prop) do
local str = p.value
if p.P580 or p.P582 then
str = mw.ustring.format("%s (%s - %s)", p.value, p.P580 or '', p.P582 or '')
elseif p.P585 then
str = mw.ustring.format("%s (%s)", p.value, p.P585)
else
str = p.value
end
table.insert(X, str)
end
if length(X)>0 then
return table.concat(X,"; ")
end
return nil
end
-- ===========================================================================
function p.get_depicted_people(entity, lang)
local prop = getProperty(entity, 'P180', 'all') -- look up "instance of" property for "Institution" entity
local X={}
for i, pid in ipairs(prop or {}) do
if i<50 then
local cEntity = mw.wikibase.getEntity(pid)
local P31 = getProperty(cEntity, 'P31', 'all')
for _, p31 in ipairs(P31 or {}) do
if p31=='Q5' then -- instance of "human"
table.insert(X, getLabel(cEntity, lang))
end
end
end
end
if length(X)==1 then
return X[1]
elseif length(X)>0 then
return '* ' .. table.concat(X,"\n* ")
end
return nil
end
-- ===========================================================================
function p.get_accession_number (entity, lang)
local Res = {} -- initialize final output
-- harvest data from inventory number (P217) property with qualifiers: collection (P195) and end time (P582)
local Y = {} -- Y is a structure where we have a table of IDs for each collection
local prop = getPropertyQual(entity, 'P217', {'P195', 'P582'}, lang)
for k, p in ipairs(prop) do -- loop over all IDs found
if not p.P582 then -- skip if there is an "end date"
local key = p.P195_id or k
if not Y[key] then Y[key]={} end -- initialize if it does not exist
table.insert(Y[key], p.value) -- group IDs by collection
Res.id = p.value -- return one of the pure ID strings, to be used as category sortkey
end
end
--assemble the wikitext of the accession_number field
local strTable = {} -- table with wikitext strings for each "collection"
for key, id in pairs(Y) do -- loop over institutions
local id=mw.text.listToText(id) -- convert all the IDs into a single string (in most cases there will be only one)
if type(key)=='string' then -- if "collection" qualifier is used than add it to the ID
table.insert(strTable, mw.ustring.format( "%s <small>(%s)</small>", id , getLabel(key, lang) ) )
else
table.insert(strTable, id ) -- if no "collection" is mentioned than just return ID
end
end
-- assemble final output structure
if #strTable==1 then -- single ID case
Res.str = strTable[1] -- just return the string
elseif #strTable>1 then -- if more than one than return bulleted list
Res.str = "* " .. table.concat(strTable, "\n* ")
end
return Res
end
-- ===========================================================================
local function renderInstitution(entity, lang)
-- local function to create wikitext for a single institution template or {{Private collection}} template
-- once we have entity check if Institution template exist and call it or assemble one based on Wikidata
local frame = mw.getCurrentFrame()
-- first check for few special cases which will result in {{Private collection}} template
if entity.id == 'Q768717' then -- render {{Private collection}} template
return frame:expandTemplate{ title ='Private collection'} .. '<br/>\n'
end
local P31 = getProperty(entity, 'P31', 'all') -- look up "instance of" property for "Institution" entity
for _, p in ipairs(P31 or {}) do
if p=='Q5' then -- if "Institution" entity is a person than render {{Private collection}} template
return frame:expandTemplate{ title ='Private collection', args={ owner = getLabel(entity, lang)}} .. '<br/>\n'
elseif p=='Q768717' then -- if "Institution" is an instance of "Private collection" than render {{Private collection}} template
return frame:expandTemplate{ title ='Private collection'} .. '<br/>\n'
end
end
-- render Institution template
local P1612 = getProperty(entity, 'P1612', 'one') -- look up "Commons Institution page" property
-- make sure second argument is string, never nil (it returns nil for the empty string, but throws error for nil)
local templateName = mw.title.makeTitle( 'Institution', P1612 or '' )
if templateName and templateName.exists then
return frame:expandTemplate{ title ='Institution:' .. P1612, args={'collapse'} } -- use existing template
else
local inst,_ = institution({wikidata=entity.id, lang=lang, collapse=1}) -- create institution based on item id
return inst
end
end
-- ===========================================================================
function p.get_institution(entity, lang)
local collection, location = {}, {} -- relevant data is stored in collection (P195) and location (P276) properties
-- harvest data from inventory number (P217) property with qualifiers: collection (P195), and end time (P582)
local prop = getPropertyQual(entity, 'P217', {'P580', 'P582', 'P195'}, lang) -- P580 if present is used for sorting
for _, p in ipairs(prop) do
if not p.P582 and p.P195_id then -- skip if there is an "end date"
collection[p.P195_id] = 1 -- store collection item ID
end
end
-- harvest data from collection (P195) / start time (P580) + end time (P582)
local prop = getPropertyQual(entity, 'P195', {'P580', 'P582'}, lang) -- P580 if present is used for sorting
for _, p in ipairs(prop) do
if p.P582 then -- skip if there is an "end date"
collection[p.value_id] = nil -- and delete from Collection list
else
collection[p.value_id] = 1 -- otherwise collection item ID to the list
end
end
-- harvest data from location (P276) / start time (P580) + end time (P582)
local prop = getPropertyQual(entity, 'P276', {'P580', 'P582'}, lang)
for _, p in ipairs(prop) do
if not p.P582 and not collection[p.value_id] then -- skip if there is an "end date" or the value is in collection table
location[p.value_id] = 1 -- store location item ID
end
end
-- initialize output structure
local Res = {}
Res.institution = nil
Res.location = nil
Res.id = nil
-- first try usual cases of single collection item
if length(collection)==1 then -- only a single collection item
local cId, _ = next(collection, nil) -- collection item ID
local cEntity = mw.wikibase.getEntity(cId) -- collection entity
local cParent = getProperty(cEntity, 'P361', 'one') -- collection parent object of which collection item is part of (P361)
if cParent == 'Q19675' or cParent == 'Q1075988' then -- special case where collection is part of Louvre Museum
local frame = mw.getCurrentFrame()
Res.institution = frame:expandTemplate{ title ='Institution:Louvre', args={'collapse'} } -- render existing {{Institution:Louvre}} template
Res.id = 'Q1075988'
Res.location = getLabel(cEntity, lang) -- use collection and location tables to populate location/department field
if length(location)>0 then
local lId, _ = next(location, nil) -- Location item ID
Res.location = Res.location .. '<br/>\n' .. getLabel(lId, lang)
end
return Res
end
if cId=='Q812285' and length(location)>0 then -- if collection is Bavarian State Painting Collections (Q812285)
collection = location -- use location instead collection
else
Res.institution = renderInstitution(cEntity, lang) -- use collection entity to render Institution template
Res.id = cEntity.id
if length(location)>0 then -- single collection and at least one location
local lId, _ = next(location , nil) -- location item ID
local lEntity = mw.wikibase.getEntity(lId) -- location entity
local lParent = getProperty(lEntity, 'P361', 'one') -- location parent object of which location item is part of (P361)
if lParent == cId then -- location is part of the collection listed above
Res.location = getLabel(lEntity, lang) -- use location entity as location/department field
end -- if collection and locations are not related so ignore location(s)
end
return Res
end
end
-- If the case is not usual try generic approach
if length(collection)==0 and length(location)>0 then -- no collections but we have some locations
collection = location -- use location instead collection
end
if length(collection)>0 then -- collections or locations only or locations same as collections
local X = {} -- table with wikitext of all the institution templates
for cId, _ in pairs(collection) do -- render all collections
table.insert(X, renderInstitution(mw.wikibase.getEntity(cId), lang) )
end
Res.institution = table.concat(X, '\n')
end
return Res
end
-- ===========================================================================
function p.get_creator(entity, prop, lang)
-- harvest the data
local IDs = {}
local qualifiers = {P1773='attributed to', P1774='workshop of', P1775='follower of', P1776='circle of', P1777='manner of', P1779='possibly', P1780='school of', P1877='after'};
local LUT = {Q18122778='presumably', Q30230067='possibly', Q56644435='probably', Q50137645='attributed to'}
if entity.claims and entity.claims[prop] then
for _, statement in ipairs( entity:getBestStatements( prop )) do
local option, itemID1, itemID2, role
if (statement.mainsnak.snaktype == "somevalue") then
table.insert(IDs, {itemID=nil, option=nil, role=nil});
elseif (statement.mainsnak.snaktype == "value") then
itemID1 = statement.mainsnak.datavalue.value.id
if statement.qualifiers and statement.qualifiers.P518 then -- applies to part (P518)
role = statement.qualifiers.P518[1].datavalue.value.id -- specify role of "creator" like: bookbinding, lithography, etc.
end
if statement.qualifiers and statement.qualifiers.P1480 then -- sourcing circumstances (P1480)
option = LUT[statement.qualifiers.P1480[1].datavalue.value.id] -- add certainty qualifiers
end
for qual, opt in pairs( qualifiers ) do
if statement.qualifiers and statement.qualifiers[qual] then
itemID2 = statement.qualifiers[qual][1].datavalue.value.id -- those qualifiers provide new creator ID
table.insert(IDs, {itemID=itemID2, option=opt, role=role});
break
end
end
if not (itemID1=='Q4233718' and itemID2) then -- add new creator, except for the case when they are anonymous and we already have one
table.insert(IDs, {itemID=itemID1, option=option, role=role});
end
end
end
end
--sort the table
local tableComp = function (rec1, rec2) return (rec1.itemID or 'ZZZ')<(rec2.itemID or 'ZZZ') end
table.sort(IDs, tableComp)
-- IDs table cleanup
-- "workshop of", "circle of", "school of", "studio of", "or follower", "or workshop", "and workshop", "attributed to", "after", "formerly attributed to", "follower of", "manner of", "namepiece", "possibly", "probably".
for k = 2, #IDs do
if IDs[k-1].itemID==IDs[k].itemID then
local val = (IDs[k-1].option or '') .. (IDs[k].option or '')
if val=='workshop of' then
IDs[k ].option = "and workshop"
IDs[k-1].option = "delete"
elseif val=="follower of" then
IDs[k ].option = "or follower"
IDs[k-1].option = "delete"
end
end
end
-- render the output template(s)
local Creators = {}
local frame = mw.getCurrentFrame()
for k =1, #IDs do
local val, _
local itemID = IDs[k].itemID
local option = IDs[k].option
local role = IDs[k].role
if itemID==nil then -- render {{Unknown|author}} template
val = frame:expandTemplate{ title ='Unknown', args={'author'}}
table.insert(Creators, val)
elseif itemID=='Q4233718' then -- render anonymous label
val = getLabel(itemID, lang)
table.insert(Creators, val)
elseif option ~= "delete" then
local eEntity = mw.wikibase.getEntity(itemID)
local P1472 = getProperty(eEntity, 'P1472', 'one') -- look up "Commons Creator page" property
if P1472 then
if option then option=option..'/collapse' else option='collapse' end
val = frame:expandTemplate{ title ='Creator:' .. P1472, args = {option} } -- use existing template
else
val, _ = creator({wikidata=itemID, lang=lang, option=option, collapse=1})-- create creator based on item id
end
if role then
val = "'''" .. getLabel(role, lang) .. "''': " .. val
end
table.insert(Creators, val)
end
end -- for
-- gather the output structure
local Res = {}
Res.str = nil
Res.id = nil -- if only one creator and no "option" modifier than return ID
Res.IDs = IDs -- raw data used to render the template(s)
if #Creators>0 then
Res.str = table.concat(Creators, '\n') -- text of the template
end
if #IDs==1 and not IDs[1].option then
Res.id = IDs[1].itemID
end
return Res
end
-- ===========================================================================
function p.get_references(entity, lang)
local Res -- initialize final output
local wordsep = mw.message.new( "Word-separator" ):inLanguage(lang):plain()
local colon = mw.message.new( "Colon-separator" ):inLanguage(lang):plain() .. wordsep
local semicolon = mw.message.new( "Semicolon-separator" ):inLanguage(lang):plain() .. wordsep
-- harvest data from catalog code (P528) property with qualifiers: catalog (P972)
local strTable = {} -- table with wikitext strings for each "reference"
local prop = getPropertyQual(entity, 'P528', {'P972'}, lang)
local catalog, catalog_code, str
for k, p in ipairs(prop) do -- loop over all IDs found
if p.P972 then -- skip if there is an "end date"
if not catalog then
catalog = getLabel('Q2352616', lang); -- get translation of word "catalog"
catalog_code = getLabel('P528', lang); -- get translation of word "catalog code"
end
str = catalog .. colon .. "''" .. p.P972 .. "''" .. semicolon .. catalog_code .. colon .. p.value
table.insert(strTable, str) -- group IDs by collection
end
end
-- harvest data from "described at URL" (P973) property with qualifier: language (P407), title (P1476), publisher (P123) and author (P50)
local label
prop = getPropertyQual(entity, 'P973', {'P407', 'P1476', 'P123', 'P50'}, lang)
for k, p in ipairs(prop) do
if not label then
label = getLabel('P973', lang) -- get translation of phrase "described at URL"
end
str = string.format("%s%s [%s ''%s'']", label, colon, p.value, mw.uri.decode( p.value ) )
if p.P1476 then -- display title if available rather than raw URL
str = string.format("%s%s [%s ''%s'']", label, colon, p.value, p.P1476)
end
if p.P50 then -- add author
str = str .. ", " .. p.P50
end
if p.P123 then -- add publisher
str = str .. ", " .. p.P123
end
if p.P407 then -- add language
str = str .. " (" .. p.P407 .. ")"
end
table.insert(strTable, str) -- group IDs by collection
end
-- Support for direct ID to museum databases: table of
-- a) Wikidata properties of the museum cataogue ID and
-- b) names of the corresponding template on Wikimedia Commons
-- e.g. the Louvre database, Atlas, has an "Atlas ID" (P1212) on Wikidata
-- and Template:Louvre_online on Wikimedia Commons.
-- we can add everything from https://commons.wikimedia.org/wiki/Category:Museum_database_templates
local commons_templates_for_database = {
["P347"] = "Joconde", -- Joconde database (French Republic)
["P1212"] = "Louvre online", -- Atlas database (Louvre)
["P4659"] = "Orsay online", -- Orsay database (Musée d'Orsay)
["P4157"] = "MEG online", -- MEG database (Musée d'Ethnographie de Genève)
["P1679"] = "Art UK", -- identifier for artworks (publicly owned oil paintings in the UK)
["P2014"] = "Moma online", -- identifier for a Museum of Modern Art artwork
["P2092"] = "Bildindex", -- Bildindex der Kunst und Architektur ID
["P2108"] = "Kunstindeks", -- Kunstindeks Danmark artwork ID
["P4611"] = "LACMA online", -- Los Angeles County Museum of Art website
["P350"] = "RKDimages" -- RDK (Netherlands Institute for Art History)
}
for property, template_name in pairs(commons_templates_for_database) do
local database_id = getProperty(entity, property, 'one')
if database_id then
local frame = mw.getCurrentFrame()
str = frame:expandTemplate{ title = template_name, args = { database_id } }
table.insert(strTable, str)
end
end
-- harvest data from described by source (P1343) property with qualifiers: pages (P304), publication date (P577),
-- section, verse, or paragraph (P958), volume (P478), reference URL (P854), title (P1476), statement is subject of (P805)
prop = getPropertyQual(entity, 'P1343', {'P304', 'P958', 'P478', 'P854', 'P1476', 'P805', 'P577'}, lang)
label = nil
for k, p in ipairs(prop) do
if not label then
label = getLabel('P1343', lang) -- get translation of word ""
end
local frame = mw.getCurrentFrame()
local cite_arg = {}
cite_arg.title = p.value -- described by source (P1343)
cite_arg.url = p.P854 or '' -- reference URL (P854)
cite_arg.volume = p.P478 or '' -- volume (P478)
cite_arg.pages = p.P304 or '' -- pages (P304)
cite_arg.chapter = p.P958 or '' -- section, verse, or paragraph (P958)
cite_arg.series = p.P805 or '' -- statement is subject of (P805)
cite_arg.date = p.P577 or '' -- statement is subject of (P805)
str = frame:expandTemplate{ title ='Cite_book', args = cite_arg }
table.insert(strTable, label .. colon .. str)
end
-- assemble final output structure
if #strTable==1 then -- single ID case
Res = strTable[1] -- just return the string
elseif #strTable>1 then -- if more than one than return bulleted list
Res = "* " .. table.concat(strTable, "\n* ")
end
return Res
end
-- ===========================================================================
function p.debug(frame)
local field = frame.args.field
local lang = frame.args.lang
local entity = mw.wikibase.getEntity(frame.args.wikidata)
local str, X
if field=='object_history' then
return p.get_object_history(entity, lang) -- object history
elseif field=='exhibition_history' then
return p.get_exhibition_history(entity, lang) -- exhibition history
elseif field=='inscription' then
return p.get_inscription(entity, lang)
elseif field=='medium' then
return p.get_medium(entity, lang)
elseif field=='work_location' then
return p.get_work_location(entity, lang)
elseif field=='institution' then
X = p.get_institution(entity, lang)
return (X.institution or '') .. '\n' .. (X.location or '')
elseif field=='accession_number' then
local res = p.get_accession_number(entity, lang)
return res.str or ''
elseif field=='creator' then
local res = p.get_creator(entity, 'P170', lang)
return res.str or '';
elseif field=='references' then
return p.get_references(entity, lang) or ''
elseif field=='depicted_people' then
return p.get_depicted_people(entity, lang) or ''
end
return ''
end
return p