VOOZH about

URL: https://commons.wikimedia.org/wiki/Module:Artwork

⇱ Module:Artwork - Wikimedia Commons


Jump to content
From Wikimedia Commons, the free media repository
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandbox All modules

👁 Image
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing.
👁 Protected
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
👁 ⚠
Note: This module is used on a great lot of pages. In order not to put too much load on the servers, edits should be kept to a bare minimum. Please discuss proposed changes on the talk page first.

Afterwards, changes can initially be done at and tested with Module:Artwork/sandbox.

  • Editing a module causes all pages that use the module to be re-rendered. If the module is used often, this can put a lot of load on the servers since it fills up the job queue.
  • Keep in mind that displays produced by modules used on file description pages also show up on other wikis.
Code behind {{Artwork}}, {{Photograph}}, {{Photograph of object}}, {{Art Photo}} and {{Book}}. See documentation at their pages.

Relies on

Code

--[[ 
 __ __ _ _ _ _ _ 
 | \/ | ___ __| |_ _| | ___ _ / \ _ __| |___ _____ _ __| | __
 | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ /
 | | | | (_) | (_| | |_| | | __/_ / ___ \| | | |_ \ V V / (_) | | | < 
 |_| |_|\___/ \__,_|\__,_|_|\___(_)_/ \_\_| \__| \_/\_/ \___/|_| |_|\_\
This module is intended to be the engine behind "Template:Artwork", "Template:Art photo",
"Template:Photograph" and "Template:Book".
Please do not modify this code without applying the changes first at 
"Module:Artwork/sandbox" and testing at "Template:Artwork/testcases".
Authors and maintainers:
* User:Jarekt - original version 
]]
require('strict')-- used for debugging purposes as it detects cases of unintended global variables
localgetLabel=require("Module:Wikidata label")._getLabel-- used for creation of name based on Wikidata
localgetSitelinks=require("Module:Wikidata label")._sitelinks-- 
localgetDate=require("Module:Wikidata date")._date-- used for processing of date properties
localauthorityControl=require("Module:Authority control")._authorityControl-- used for formatting of Authority control row
localISOdate=require('Module:ISOdate')-- used for simple date formating
localSize=require('Module:Size')._size-- Lua code behind {{Size}} template
localTitleFromWD=require('Module:Title').wikidata_title-- Lua code behind {{Title}} template
localArt=require('Module:Wikidata art')--
localalterName=require("Module:Name")._name
localTagQS=require('Module:TagQS')
localcore=require("Module:Core")
localartcore=require("Module:Artwork/core")
-- Lazy loading functions: load them only if they are needed
localfunctionInformation(args)
returnrequire("Module:Information")._information(args)
end
localfunctionObjectTypeID(object_type)
localLUT=mw.loadData('Module:I18n/objects/data')-- lazy loading (only if needed
returnLUT[string.lower(object_type)]
end
localfunctionperiodSpan(id,lang)
localPeriodSpan=require('Module:Period')._periodSpan
returnPeriodSpan(id,lang)
end
-- ==================================================
-- === Internal functions ===========================
-- ==================================================
-------------------------------------------------------------------------------
localfunctionempty2nil(str)
ifstr==''then
returnnil
else
returnstr
end
end
-------------------------------------------------------------------------------
localfunctionnowiki(str)-- remove all the links
ifnotstrthen
returnstr
end
str=TagQS.removeTag(str,nil)
str=mw.ustring.gsub(str,'%<abbr %</abbr%>','')
str=mw.ustring.gsub(str,"<[^>]*>","")-- remove all html tags from str
str=mw.ustring.gsub(str,"'''","")-- remove bold 
str=mw.ustring.gsub(str,"''","")-- remove italics
str=mw.ustring.gsub(str,"%[%[[Ff]ile:[^%]]+%]%]","")-- remove file icons
str=mw.ustring.gsub(str,"%[%[[^|]*|","")-- remove piped links, like "[[:en:test|"
str=mw.ustring.gsub(str,"%[[hH][tT][tT][pP][sS]?://[^ ]+ ([^%]]*)%]","%1")-- remove URL links, like "[https://www.wikidata.org/wiki/Q2706250 xxxx] -> xxxx"
str=mw.ustring.gsub(str,"%[%[","")-- remove piped links, like "[["
str=mw.ustring.gsub(str,"%]%]","")-- remove piped links, like "]]"
returnstr
end
-------------------------------------------------------------------------------
localfunctiongetProperty(entity,prop)
return(core.parseStatements(entity:getBestStatements(prop),nil)or{nil})[1]
end
-------------------------------------------------------------------------------
localfunctiongetBestProperties(entity,prop)
returncore.parseStatements(entity:getBestStatements(prop),nil)
end
-------------------------------------------------------------------------------
localfunctionquote(str)
return'"'..str..'"'
end
-------------------------------------------------------------------------------
localfunctionif_else(Boolean,TrueStatement,FalseStatement)
ifBooleanthen
returnTrueStatement
else
returnFalseStatement
end
end
-------------------------------------------------------------------------------
localfunctionadd_QS(qsTable,prop,value,qualifiers)
localqsStr=prop..'|'..value
ifqualifiersthen
forqual,valinpairs(qualifiers)do
qsStr=qsStr..'|'..qual..'|'..val
end
end
table.insert(qsTable,qsStr)
end
-------------------------------------------------------------------------------
localfunctionrender_QS_URL(qsTable,item,withIcon)
localtoday='+'..os.date('!%F')..'T00:00:00Z/11'-- today's date in QS format
localurl=mw.title.getCurrentTitle():canonicalUrl()-- URL to current page
localref='|S143|Q565|S813|'..today..'|S4656|"'..mw.uri.decode(url)..'"'
localicon='File:Commons_to_Wikidata_QuickStatements.svg'
fork,qsinipairs(qsTable)do
ifqs:sub(1,1)=='P'then
qsTable[k]=item..'|'..qs..ref
else
qsTable[k]=item..'|'..qs-- for labels, etc.
end
end
localqsURL=table.concat(qsTable,'||')
localhoverMsg='Add properties to Wikidata item based on this file'
ifstring.upper(item)=='CREATE'then
qsURL='CREATE||'..string.gsub(qsURL,item..'|','LAST|')
icon='File:Plus Wikidata.svg'
hoverMsg='Create new Wikidata item based on this file'
end
qsURL=mw.uri.encode(qsURL,"PATH")
qsURL='https://quickstatements.toolforge.org/#/v1='..qsURL-- create full URL link
withIcon=withIconortrue-- define default
ifwithIconthen-- use URL as a link accessed by clicking an icon
qsURL='&nbsp;[['..icon..'|15px|link='..qsURL..'|'..hoverMsg..']]'
end
returnqsURL
end
-- ===========================================================================
-- === This function is responsible for adding maintenance categories ===
-- === which are not related to Wikidata ===
-- === INPUTS: ===
-- === * args0 - data from the local arguments ===
-- === * args - merged data from the local arguments and Wikidata ===
-- ===========================================================================
localfunctionadd_maintenance_categories(args0,args)
localcats=''-- categories 
mw.getCurrentFrame():expandTemplate{title='Infobox template tag'}-- add the template tag
-- ====================================================
-- === automatic tagging of pages in all namespaces === 
-- ====================================================
ifargs.dateorargs.yearthen
-- add an empty template which can be used as a tag in PetScan
locald=os.date('!*t')-- current date table
localcurrent_year=tonumber(d.year)-- current year
localcreation_year=tonumber(ISOdate._ISOyear(args.yearorargs.date))
ifcreation_yearandcurrent_yearand(current_year-creation_year)>200then
mw.getCurrentFrame():expandTemplate{title='Works created more than 200 years ago'}
end
end
ifargs0.namespace==0andmw.ustring.sub(args0.pagename,1,8)=="Artwork:"then
cats=cats..'\n[[Category:Artwork templates]]'
ifargs.homecatthen
cats=cats..'\n[[Category:'..args.homecat..']]'
end
end
-- add categories related to accession number for artworks
ifargs0.idandargs0.infobox=='artwork'then
localsortkey=nowiki(args0.id)-- strip any links that might be there
if#sortkey>30then
sortkey='zzz'
end
cats=string.format('%s\n[[Category:Artworks with known accession number| %s]]',cats,sortkey)
end
-- add categories related to template:book transcluded into template for specific book
ifargs0.infobox=='book'andargs0.namespace==10then
cats=cats..'\n[[Category:Book templates]]'
-- add homecat category
ifargs0.homecat~='~'then
localpage={}
ifargs0.homecatthen
cats=string.format('%s\n[[Category:%s| ]]',cats,args0.homecat)
page=mw.title.new(args0.homecat,'category')
end
ifnotpageornotpage.existsornotargs0.homecatthen
cats=cats..'\n[[Category:Book templates without home category]]'
end
end
end
returncats
end
-- ===========================================================================
-- === This function is responsible for creating QuickStatements ===
-- === INPUTS: ===
-- === * args0 - local inputs from the Artwork template ===
-- === * data - data pulled from Wikidata ===
-- ===========================================================================
localfunctioncreate_QuickStatements(args0,data)
-- setup QuickStatements 
localqsTable={}-- table to store QuickStatements 
localitem=args0.wikidata
ifargs0.no_qsthen
returnnil-- "no_qs" flag means we do not want QuickStatements based on this file
end
-- 
if(notdata.idandargs0.id)then
localid=nowiki(args0.id)-- strip any links that might be there
ifargs0.institution_idand#id<20then
add_QS(qsTable,'P217',quote(id),{P195=args0.institution_id})
end
end
-- add QS based on "image" field
locallut={jpg='P18',jpeg='P18',png='P18',pdf='P996',djvu='P996',stl='P4896'}
--			 webm='P10', ogv='P10', mp3='P51', wav='P51' -- ignore other extensions as they are mostly wrong
if(notdata.imageandargs0.image)then-- QS code to help transfer content of "image" field to Wikidata
localext=mw.ustring.lower(mw.ustring.match(args0.image,"^.+%.(.+)$")or'')-- file extension
localimage=quote(mw.ustring.gsub(args0.image,'_',' '))
localprop=lut[ext]
ifpropandnotdata[prop]then
add_QS(qsTable,prop,image)
data[prop]=image-- mark it so we don't add it twice
end
end
-- add QS based on current filename
localimage=quote(mw.ustring.gsub(args0.pagename,'_',' '))-- get current filename
localmultiPageFile=(args0.namespace==6andargs0.num_pages>1and(args0.mimeType=='application/pdf'orargs0.mimeType=='image/vnd.djvu'))
if(notdata.imageandmultiPageFile)then-- QS code to help transfer image to Wikidata
localqual=if_else(args0.image_page,{P4714=tostring(args0.image_page)},nil)
add_QS(qsTable,'P996',image,qual)
end
if(args0.namespace==6andargs0.num_pages==1andargs0.infobox=='artwork')then-- QS code to help transfer image to Wikidata
localext=mw.ustring.lower(mw.ustring.match(args0.pagename,"^.+%.(.+)$"))-- file extension
localprop=lut[ext]
--prop = if_else(prop, prop, 'P18')
ifpropandnotdata[prop]andnotdata.imagethen
add_QS(qsTable,prop,image)
end
end
-- add "Commons Category" (P373) if template at category page
ifnotdata.homecatandargs0.namespace==14then
add_QS(qsTable,'P373',image)
end
-- look for hidden text in various templates so they can be passed to Wikidata if needed using QS
-- copy args0['data'] to args0['era'] if it contains an "era QS"
-- because they share one parameter/field at template level input,
-- but need separate handling here
-- TODO: splitting/sorting (at an earlier stage) would be better than simply copying,
-- in cases where there is one value for each they won't be processed without splitting
ifargs0['date']andTagQS.hasTag('era')then
args0['era']=args0['date']
end
-- different fields from different tables are allowed to create QS codes to allow data transfer to Wikidata
-- some fields are often not used correctly in some templates like institution in book template and are not allowed to create QS
localfields={object_type='artwork',era='artwork',medium='artwork',dimensions='artwork',institution='artwork',artist='artwork',wga='artwork',date='all',
language='book',author='book',translator='book',publisher='book',printer='book',illustrator='book',editor='book'}
forfield,infoboxinpairs(fields)do
ifargs0[field]andnotdata[field]and(args0.infobox==infoboxorinfobox=='all')then
localqs=TagQS.readTag(args0[field],field)
ifqsthen
for_,vinipairs(mw.text.split(qs,';',true))do
table.insert(qsTable,v)
end
end
end
end
-- Single field "dimensions" has "width", "height", etc. properties
ifargs0.dimensionsandnotdata.dimensionsand(args0.infobox=='artwork')then
for_,vinipairs(TagQS.readTags(args0.dimensions,'dimensions'))do
table.insert(qsTable,v)
end
end
-- Book's template publication_date should not go to periodicals and only to items with P31="version, edition, or translation"
ifargs0.publication_dateandnotdata.publication_dateand(args0.infobox=='book')and(data.object_type_id=='Q3331189')then
localqs=TagQS.readTag(args0[field],field)
if(qs)then
table.insert(qsTable,qs)
end
end
-- Special case of QS codes for multilingual labels extracted from {{title}} and {{description}} templates, etc.
ifargs0.titlethen
localmax_title_len=100
-- strip titles from title field with {{title}} template: {{title|lang=...|1=...}}
localtitle=TagQS.readTag(args0.title,'title')or''
locallabel,lang=mw.ustring.match(title,'P1476%|((%w+):.+)')
iflangandlabelthen
label=nowiki(label)
ifnot(data.title_anddata.title_[lang])and#label<max_title_lenthen
add_QS(qsTable,'P1476',label)
end
end
lang,label=mw.ustring.match(title,'P1476%|(%w+):(.+)')
iflangandlabelthen
label=nowiki(label)
ifnot(data.labelsanddata.labels[lang])and#label<max_title_lenthen
add_QS(qsTable,'L'..lang,label)
end
end
-- strip titles from title field with {{title}} templates, with fields like |en=, |es=, etc.
for_,titleinipairs(TagQS.readTags(args0.title,'label'))do
lang,label=mw.ustring.match(title,'L(%w+)[%|,](.+)')
iflangandlabelthen
label=nowiki(label)
ifnot(data.labelsanddata.labels[lang])and#label<max_title_lenthen
add_QS(qsTable,'L'..lang,label)
end
end
end
-- strip titles from title field with {{description}} templates, like {{en}}, {{es}}, etc.
-- <span class="language pl" title="Polish"><b>Polski&#58; </b></span> abc</div>
localpat='%<span class="language (%w+)" .-%</span%> *([^%<]+)%</div%>'
forlang,labelinmw.ustring.gmatch(args0.title,pat)do
label=nowiki(label)
ifnot(data.labelsanddata.labels[lang])and#label<max_title_lenthen
add_QS(qsTable,'L'..lang,quote(label))
end
end
end
-- add "instance of" statement
localtype_id=data.object_type_id
ifnotdata.object_type_idthen
ifargs0.infobox=='book'then
add_QS(qsTable,'P31','Q3331189')-- version, edition, or translation
elseifargs0.object_typethen
type_id=ObjectTypeID(args0.object_type)
iftype_idthen
add_QS(qsTable,'P31',type_id)-- painting etc.
data.object_type_id={type_id}-- object_type_id is an array
end
end
end
-- add descriptions
localartist_id=data.artist_idorargs0.artist_id
localtypeList={
Q3305213={de="Gemälde von %s",en="painting by %s",es="cuadro de %s",fr="tableau de %s",it="dipinto di %s",nl="schilderij van %s",sl="slika avtorja %s"}
}
iftype_idandartist_idandtypeList[type_id]then
forlang,phraseinpairs(typeList[type_id])do
ifnotdata.descriptionsornotdata.descriptions[lang]then
localartist=mw.wikibase.getLabelByLang(artist_id,lang)
ifartistthen
add_QS(qsTable,'D'..lang,quote(string.format(phrase,artist)))
end
end
end
end
-- ==================================================
-- === Create QuickStatement codes ================== 
-- ==================================================
if#qsTable==0then
returnnil
end
localQS=render_QS_URL(qsTable,args0.wikidata)
returnQS
end
-- ===========================================================================
-- === Function for creating search icons ===
-- === INPUTS: ===
-- === * args0 - local inputs from the Artwork template ===
-- ===========================================================================
localfunctionadd_search_link(args0)
localsTable,tTable={},{}
localcreator_id,s,t,text,QS,title
-- get English title
ifargs0.titlethen
localtitle=TagQS.readTag(args0.title,'label')or''
-- strip titles from title field with {{title}} templates, with fields like {{en}}, {{es}}, etc.
s='Len%|(.+)'
forlabelinmw.ustring.gmatch(args0.title,s)do
title=nowiki(label)
end
end
ifargs0.titleandnottitlethen
-- strip titles from title field with {{description}} templates, like {{en}}, {{es}}, etc.
s='%<span class="language en" [^%<]+%</span%> *([^%<]+)%</div%>'
forlabelinmw.ustring.gmatch(args0.title,s)do
title=nowiki(label)
end
end
text=titleornowiki(args0.title)or''
-- get author info 
ifargs0.infobox=='artwork'then
creator_id=args0.artist_idorargs0.author_id
elseifargs0.infobox=='photograph'then
creator_id=args0.photographer_idorargs0.author_id
elseifargs0.infobox=='book'then
creator_id=args0.author_id
end
ifcreator_idthen
localprop=if_else(args0.infobox=='book','P50','P170')
sTable[prop]=creator_id
else
text=text..' '..nowiki(args0.artistorargs0.authoror'')
end
-- set other properties
ifargs0.object_type=='painting'andargs0.infobox=='artwork'then
sTable.P31='Q3305213'-- painting
elseifargs0.infobox=='book'then
sTable.P31='Q3331189'-- version, edition, or translation
end
ifargs0.institution_idthen
sTable.P195=args0.institution_id
end
ifargs0.idthen
text=text..' '..nowiki(args0.id)-- add accession_id as text not as P217 statement
end
-- If no usable info than abort 
localcount=0
for_inpairs(sTable)docount=count+1end
ifcount==0then
returnnil
end
-- create URL and clickable icon with either Cirrus search
-- see https://www.mediawiki.org/wiki/Help:Extension:WikibaseCirrusSearch
table.insert(tTable,text)
forprop,fieldinpairs(sTable)do
table.insert(tTable,'haswbstatement:'..prop..'='..field)
end
s=mw.uri.encode(table.concat(tTable,' '),"QUERY")
s={'search='..s,'title=Special:Search','profile=advanced','fulltext=1','ns0=1'}
s='https://www.wikidata.org/w/index.php?'..table.concat(s,'&')-- create full URL link
s='[[File:Wikidata CheckUser.svg|15px|link='..s..'|Wikidata search (Cirrus search)]]'
-- create URL and clickable icon with SPARQL search
tTable={}
table.insert(tTable,'SELECT ?item ?itemLabel ?image')
table.insert(tTable,'WHERE {')
forprop,fieldinpairs(sTable)do
table.insert(tTable,' ?item wdt:'..prop..' wd:'..field..'.')
end
table.insert(tTable,' OPTIONAL { ?item wdt:P18 ?image } .')
table.insert(tTable,' SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }')
table.insert(tTable,'}')
t=mw.uri.encode(table.concat(tTable,'\n'),"PATH")
t='https://query.wikidata.org/#'..t
t='[[File:Wikidata Query Service Favicon.svg|15px|link='..t..'|Wikidata query (SPARQL)]]'
-- go to [[Data:Completely indexed painting collections.tab]] and look up if 
-- args0.institution_id is one of the items in column 1 
localcollCmpl,cat=false,''
ifargs0.object_type=='painting'andargs0.infobox=='artwork'andargs0.institution_idthen
localtab=mw.ext.data.get('Completely indexed painting collections.tab','en')
foriRow,rowinpairs(tab.data)do
ifrow[1]==args0.institution_idthen
collCmpl=true-- no need for adding painting items to this collection
end
end
end
ifcollCmplthen
cat='\n[[Category:Paintings from completely indexed collections]]'
end
-- go to [[Data:Completely indexed painters.tab]] and look up if 
-- args0.artist_id is one of the items in column 1 
localauthorCmpl=false
ifargs0.object_type=='painting'andargs0.infobox=='artwork'and(args0.artist_idorargs0.author_id)then
localtab=mw.ext.data.get('Completely indexed painters.tab','en')
foriRow,rowinpairs(tab.data)do
ifrow[1]==args0.artist_idorrow[1]==args0.author_idthen
authorCmpl=true-- no need for adding painting items by this painter
end
end
end
ifauthorCmplthen
cat='\n[[Category:Paintings by completely indexed painters]]'
end
ifnotcollCmplandnotauthorCmplthen
args0.wikidata='CREATE'
QS=create_QuickStatements(args0,{})
end
localsearchStr='&nbsp;('..table.concat({s,t,QS},' ')..')'
returnsearchStr,cat
end
-- ===========================================================================
localfunctionchect_instance_of(instance_of)
-- check object_type_id against a list of incorrect values for P31 property of associated item
-- Black and white list id is of wrong type if bwLUT returns "1", bwLUT = "2" means good type
-- bad {Q5='human', Q11266439='template ', Q4167410='disambiguation', Q4167836='category', Q532='village', Q482994='album', 
-- Q16521='taxon', Q1406161='artistic theme', Q12827256=myth, Q51632=parable of Jesus, Q208555=parable, Q856663=bible story
-- Q18534=metaphor, Q4167410=disambiguation page}
-- groups {Q15727816='painting series', sculpture series (Q19479037), artwork series (Q15709879), group of sculptures (Q27031439), 
-- group of paintings (Q18573970) , polyptych (Q1278452), diptych (Q475476), triptych (Q79218) }
-- good {Q199414='bog body', Q7881='skeleton'} -- one of those overwrites "bad" flag so 'human' & 'bog body' is OK (those are museum objects)
localgroupItem=false
ifinstance_ofthen
localbad=false
localbwLUT={Q5=1,Q11266439=1,Q4167410=1,Q4167836=1,Q532=1,Q482994=1,Q16521=1,Q1406161=1,Q12827256=1,Q51632=1,Q208555=1,
Q856663=1,Q18534=1,Q4167410=1,Q15727816=2,Q19479037=2,Q15709879=2,Q27031439=2,Q18573970=2,Q1278452=2,Q475476=2,
Q79218=2,Q199414=3,Q7881=3}
for_,typeIdinipairs(instance_of)do
localv=bwLUT[typeId]
ifv==1then
bad=true
elseifv==2then
groupItem=true
return'group'
elseifv==3then
bad=false
return'good'
end
end
returnif_else(bad,'bad','good')
end
return'unknown'
end
-- ===========================================================================
-- === This function is responsible for adding maintenance categories ===
-- === to pages in creator namespace which are related to Wikidata ===
-- === INPUTS: ===
-- === * args0 - local inputs from the Artwork template ===
-- === * args1 - merge of local and Wikidata metadata ===
-- === * data - data pulled from Wikidata ===
-- ===========================================================================
localfunctionadd_wikidata_maintenance_categories(args0,args1,data)
localcats=''-- categories 
localcomp={}-- outcome of argument vs. Wikidata comparison
localOK=((args0.infobox=='artwork'orargs0.infobox=='photograph')and(args0.namespace==6orargs0.namespace==14))-- artworks and photographs can be in file or category namespace
or(args0.infobox=='book'and(args0.namespace==10orargs0.namespace==14))-- books can be in template or category namespace
or(args0.infobox=='book'andargs0.namespace==6and(args0.mimeType=='application/pdf'orargs0.mimeType=='image/vnd.djvu'))-- books can also be in file namespace if it is PDF or DjVu
if(notOKor(args0.wikidata_cat==false))then-- continue only if the namespace is a Category or file
returncats,args1
end
localLUT={artwork='Artworks',photograph='Photographs',book='Books'}
-- skip the rest if no item ID
ifnotargs0.wikidatathen
localcat2,TypeLUT,oType
TypeLUT={['grave']='Graves',['tomb']='Graves',['funeral chapel']='Graves',
['funeral niche']='Graves',['painting']='Paintings',['aircraft']='SKIP'}
oType=TypeLUT[string.lower(args0.object_typeor'')]orLUT[args0.infobox]
ifoType~='SKIP'then
cats=string.format('%s\n[[Category:%s without Wikidata item]]',cats,oType)
end
args1.QS,cat2=add_search_link(args0)
returncats..(cat2or''),args1
end
--=======================================================================================================
--=== Categories and files with {{Artwork}} template linked to Wikidata item below
--=======================================================================================================
cats=string.format('%s\n[[Category:%s with Wikidata item|%s]]',cats,LUT[args0.infobox],args0.wikidata)
-- check object_type_id against a list of incorrect values for P31 property of associated item
localgroupItem=false
ifdata.object_type_idthen
localstatus=chect_instance_of(data.object_type_id)
groupItem=(status=='group')
ifstatus=='bad'orstatus=='group'then
cats=string.format('%s\n[[Category:%s with %s Wikidata item|%s]]',cats,LUT[args0.infobox],status,args0.wikidata)
end
end
-- local fields which are missing on Wikidata
localfields={'date','publication_date','medium','dimensions','image','institution','author','artist'}
for_,fieldinipairs(fields)do
ifnotdata[field]andargs0[field]andnotstring.match(args0[field],'%<span style="display: none;"%>Unknown '..field..'<%/span%>')then
comp[field]='missing'
end
end
ifnotdata.idandargs0.idthen
comp['accession number']='missing'
end
ifcomp.artist=='missing'andstring.match(args0.artist,'%<span style="display: none;"%>Unknown a%w+%<%/span%>')then
comp.artist=nil-- ignore {{Unknown|artist}}
end
-- mark local fields redundant to Wikidata
localfields={['date']='date',medium='medium',dimensions='dimensions',institution_id='institution',author_id='author',artist_id='artist'}
forfield1,field2inipairs(fields)do
ifdata[field1]andargs0[field1]anddata[field1]==args0[field1]then
comp[field2]='redundant'
end
end
-- Redundant author and artist
if(data.author_id==args0.artist_idanddata.author_id)then
comp.artist='redundant'
end
if(data.artist_id==args0.author_idanddata.artist_id)then
comp.author='redundant'
end
-- handle case when creator template is a red-link but Wikidata has creator item ID
if(string.match(args0.artistor'',"%[%[:Creator:")anddata.artist)then
args1.artist=data.artist
comp.artist='redundant'
end
if(string.match(args0.authoror'',"%[%[:Creator:")anddata.author)then
args1.author=data.author
comp.author='redundant'
end
-- process "image" field
if(data.imageandargs0.image)then
comp.image='redundant'
end
localexclude_ext={mp3=1,mid=1,oga=1,ogg=1,flac=1,wav=1,webm=1}
localext=mw.ustring.lower(mw.ustring.match(args0.pagename,"^.+%.(.+)$")or'')-- file extension
localsimpleFile=(args0.namespace==6andargs0.num_pages==1andargs0.infobox=='artwork'andnot(exclude_ext[ext]==1))
ifnotdata.imageand(args0.imageorsimpleFile)then
comp.image='missing'
end
-- add categories related to accession number for artworks
ifnotargs0.idanddata.idandargs0.infobox=='artwork'then
cats=string.format('%s\n[[Category:Artworks with accession number from Wikidata| %s]]',cats,args0.wikidata)
cats=string.format('%s\n[[Category:Artworks with known accession number| %s]]',cats,data.id_idor'zzz')
end
ifnotdata.genre_idandargs0.infobox=='artwork'andargs0.namespace==6then
cats=string.format('%s\n[[Category:Artworks with Wikidata item missing genre| %s]]',cats,args0.wikidata)
end
-- ==================================================
-- === Create categories based on comp structure ==== 
-- ==================================================
forfield,outcomeinpairs(comp)do
cats=string.format('%s\n[[Category:%s with Wikidata item %s %s|%s]]',cats,LUT[args0.infobox],outcome,field,args0.wikidata)
end
-- Add QuickStatements
ifnotgroupItemandargs0.wikidatathen
args1.QS=create_QuickStatements(args0,data)
end
ifargs1.QSthen
localname=LUT[args0.infobox]
if(name=='Artworks'anddata.object_type_id=='Q3305213')then
name='Paintings'
end
cats=string.format('%s\n[[Category:%s with Wikidata item: quick statements]]',cats,name)
end
returncats,args1
end
-- ===========================================================================
-- === Harvest Structured data on Commons properties ===
-- === INPUTS: ===
-- === * mid - SDC ID ===
-- === * lang - language id of the desired language ===
-- === * namespace - namespace number of the page calling the module ===
-- ===========================================================================
localfunctionharvest_SDC(args0,lang)
localbookFlag=(args0.infobox=='book'and(args0.mimeType=='application/pdf'orargs0.mimeType=='image/vnd.djvu'))
localsdc={}-- structure similar to "args" but filled with SDC data
localcats=''
-- Harvest the different artwork types
localtab=mw.ext.data.get('Artwork types.tab','en')
sdc.artwork_types={}
foriRow,rowinpairs(tab.data)do
sdc.artwork_types[row[1]]=row[3]
end
localentity=mw.wikibase.getEntity()
ifnotentitythen
ifargs0.wikidataandbookFlagthen
cats=cats..'[[Category:Books with SDC link missing]]\n'
elseifargs0.wikidataandargs0.infobox~='book'then
cats=cats..'[[Category:Artworks with SDC link missing]]\n'
end
returnsdc,cats
end
localproperty={P6243='digital_representation_of',P4714='image_page',P921='main_subject',P180='depicts',P760='dpla_id'}
forprop,fieldinpairs(property)do
sdc[field]=getProperty(entity,prop)
end
-- get Wikidata item ID from digital representation of (P6243) 
ifsdc.digital_representation_ofthen
localwEntity=mw.wikibase.getEntity(sdc.digital_representation_of)
ifnotwEntitythen
cats=cats..'[[Category:Artworks with structured data with deleted digital representation of property‎]]'
elseifwEntity.id~=sdc.digital_representation_ofthen
cats=cats..'[[Category:Artworks with structured data with redirected digital representation of property‎]]'
end
sdc.wikidata=sdc.digital_representation_of
-- If digital representation of is set, main subject should be set too to the same 
ifsdc.main_subjectthen
ifsdc.digital_representation_of~=sdc.main_subjectthen
cats=cats..'[[Category:Artworks with digital representation of different main subject]]'
end
else
cats=cats..'[[Category:Artworks with digital representation of missing same main subject]]'
end
-- If digital representation of is set, depicts should be set too to the same 
ifsdc.depictsthen
ifsdc.digital_representation_of~=sdc.depictsthen
cats=cats..'[[Category:Artworks with digital representation of different depicts]]'
end
else
cats=cats..'[[Category:Artworks with digital representation of missing same depicts]]'
end
end
-- get Wikidata item ID from main subject (P921). If multiple, this will get the first preferred one
-- temporarly exclude files with "dpla_id" property while I debug why are they often connect to 
-- wrong wikidata items
ifnotsdc.wikidataandsdc.main_subjectandnotsdc.dpla_idthen
localmsEntity=mw.wikibase.getEntity(sdc.main_subject)
ifnotmsEntitythen
cats=cats..'[[Category:Artworks with structured data with deleted main subject property]]'
elseifmsEntity.id~=sdc.main_subjectthen
cats=cats..'[[Category:Artworks with structured data with redirected main subject property]]'
end
-- Make sure it's an actual thing (instance) instead of something general (subclass)
localmsProperty={P31='instance_of',P279='subclass_of'}
localmsProperties={}
forprop,fieldinpairs(msProperty)do
msProperties[field]=getProperty(msEntity,prop)
end
ifmsProperties.instance_ofandnotmsProperties.subclass_ofthen
localartwork_type=sdc.artwork_types[msProperties.instance_of]
localLUT={['2D']=1,['3D']=1,both=1}
ifLUT[artwork_type]then-- limit main subject (P921) use to artworks only
sdc.wikidata=sdc.main_subject
sdc.main_subject_accepted=sdc.main_subject
-- If main subject is set, depicts should be set too to the same 
ifsdc.main_subject_acceptedandsdc.depictsthen
ifsdc.main_subject~=sdc.depictsthen
-- Here we'll probably see some false positives
cats=cats..'[[Category:Artworks with main subject different depicts]]'
end
else
cats=cats..'[[Category:Artworks with main subject missing same depicts]]'
end
end
end
end
ifnotsdc.wikidataandargs0.wikidataandnotsdc.main_subjectthen
ifbookFlagthen
cats=cats..'[[Category:Books with SDC link missing]]\n'
elseifargs0.infobox~='book'then
cats=cats..'[[Category:Artworks with SDC link missing]]\n'
end
elseifsdc.wikidataandargs0.wikidataandsdc.wikidata~=args0.wikidatathen
cats=cats..'[[Category:Artworks with mismatching digital representation of]]\n'
end
-- get source from P7482
ifentity.statementsandentity.statements.P7482then
localstatement=entity.statements.P7482[1]
ifstatement.mainsnak.datavalue.value.id=='Q74228490'andstatement.qualifiersandstatement.qualifiers.P973then
localurl=statement.qualifiers.P973[1].datavalue.value
ifstatement.qualifiers.P137then
localid=statement.qualifiers.P137[1].datavalue.value.id
locallabel=getLabel(id,lang,'-')
sdc.source_='['..url..' '..label..']'..core.editAtSDC(args0.pagename,'P7482',lang)
else
sdc.source_=url..core.editAtSDC(args0.pagename,'P7482',lang)
end
end
end
returnsdc,cats
end
-- ===========================================================================
-- === Harvest Wikidata properties matching creator template fields ===
-- === INPUTS: ===
-- === * itemID1 - item id or a q-code from the template ===
-- === * itemID2 - item id or a q-code from SDC ===
-- === * lang - language id of the desired language ===
-- === * namespace - namespace number of the page calling the module ===
-- ===========================================================================
localfunctionharvest_wikidata(itemID1,itemID2,lang,namespace,infobox,pagename)
localdata={}-- structure similar to "args" but filled with Wikidata data
localcats=''
localframe=mw.getCurrentFrame()
localentity=nil
localitemID=itemID1oritemID2
ifmw.wikibaseanditemIDthen
localLUT={artwork='Artworks',photograph='Photographs',book='Books'}
entity=mw.wikibase.getEntity(itemID)
ifnotentitythen
cats=string.format('[[Category:%s with bad Wikidata link]]',LUT[infobox])
elseifentity.id~=itemIDanditemID1then
cats=string.format('[[Category:%s with redirected Wikidata link]]',LUT[infobox])
end
end
ifnotentitythen
returndata,cats
end
-- inception date: translated date and year number
locald=getDate(entity,'P571',lang)-- inception date
ifd.strthen
data.date_,data.year=d.iso,d.year
data.date=d.str..core.editAtWikidata(entity.id,'P571',lang)
end
-- publication date: translated date and year number
locald=getDate(entity,'P577',lang)-- publication date
ifd.strthen
data.publication_date_,data.publication_year=d.iso,d.year
data.publication_date=d.str..core.editAtWikidata(entity.id,'P577',lang)
end
-- harvest string properties
localDebug={}
localproperty={P10='video',P18='image',P996='scan',P4896='model3D',P373='homecat',P51='audio',P158='seal',P11807='wga',
P2093='authorStr',P393='edition',P4714='image_page',P1957='wikisource_index',P7420='framed_image',P3030='sheet_music'}
forprop,fieldinpairs(property)do
data[field]=getProperty(entity,prop)
data[prop]=data[field]-- keep tract which properties were present at Wikidata
end
data.image=data.imageordata.scanordata.videoordata.model3Dordata.framed_imageordata.sealordata.sheet_music
data.image_page=tonumber(data.image_page)
ifdata.editionthen
data.edition=data.edition..core.editAtWikidata(entity.id,'P393',lang)
end
-- harvest Q-code properties which are than converted from Q-number to labels (pick one)
localproperty={P189='place_of_discovery',P2079='technique',P872='printer',
P136='genre',P921='subject',P179='series_title',P361='part_of',
P629='edition_of',P1071='place_of_creation',P495='country_of_origin'}
forprop,fieldinpairs(property)do
localid=getProperty(entity,prop)
ifidthen
data[field]=getLabel(id,lang,"wikipedia")..core.editAtWikidata(entity.id,prop,lang)
end
end
data.place_of_creation=data.place_of_creationordata.country_of_origin
data.genre_id=getProperty(entity,'P136')
-- harvest Q-code properties which are than converted from Q-number to labels (pick all)
localproperty={P31='object_type',P407='language',P123='publisher',P291='place_of_publication'}
forprop,fieldinpairs(property)do
localids=getBestProperties(entity,prop)
ifidsthen
localT={}
for_,idinipairs(ids)do
table.insert(T,getLabel(id,lang))
end
data[field]=table.concat(T," / ")..core.editAtWikidata(entity.id,prop,lang)
data[field..'_id']=ids
end
end
-- get era
data.era_id=getBestProperties(entity,'P2348')
ifdata.era_idthen
localT={}
for_,idinipairs(data.era_id)do
localeraText=getLabel(id,lang)
localspanText=periodSpan(id,lang)
ifspanTextthen
eraText=eraText..' '..spanText
end
table.insert(T,eraText)
end
data.era=table.concat(T," / ")..core.editAtWikidata(entity.id,'P2348',lang)
end
ifdata.eraanddata.datethen
data.date=data.date.."<br/>"..data.era
elseifdata.eraandnotdata.datethen
data.date=data.era
end
-- get author and/or author creator template
localproperty={P170='creator',P50='author',P84='architect',P287='designer',P98='editor',P86='composer',
P655='translator',P110='illustrator',P2679='author_of_foreword',P2680='author_of_afterword'}
forprop,fieldinpairs(property)do
locald=Art.get_creator(entity,prop,lang)
data[field]=d.str
data[field.."_id"]=d.id
end
data.author=data.authorordata.authorStr-- P2093='author name string'
-- get title (from 3 properties and label)
--local property = { P1476 = 'title', P1448='official_name', P1705='native_label', P1680='subtitle'}
localproperty={P1476='title',P1680='subtitle'}
forprop,fieldinpairs(property)do
localtitle={}
for_,statementinpairs(entity:getBestStatements(field))do
if(statement.mainsnak.snaktype=="value")then
localval=statement.mainsnak.datavalue.value
title[val.language]=val.text-- look for multiple values each with a language code
end
end
if#title>0then
data[field]=core.langSwitch(title,lang)
end
iffield=='title'then
data.title_=title
end
end
--data.title = data.title or data.official_name or data.native_label
data.title=TitleFromWD(entity,lang)
data.label=getLabel(entity,lang)
-- get labels in all the languages
data.labels={}
ifentity.labelsthen
forlang,valinpairs(entity.labels)do-- loop over all labels
data.labels[lang]=val.value;
data.label=data.labelordata.labels[lang]-- no label in preferred language so grab any label
end
end
-- get labels in all the languages
data.descriptions={}
ifentity.descriptionsthen
forlang,valinpairs(entity.descriptions)do-- loop over all descriptions
data.descriptions[lang]=1;-- just record if it is present or not
end
end
-- get authority control (rarely used for artworks)
localAC_cats
data.authority,AC_cats=authorityControl(entity,{wikidata=itemID},lang,5)
local_,nIdentifiers=string.gsub(data.authority,"*","")
ifnIdentifiers<=1then
data.authority,AC_cats=nil,''
end
ifnot(namespace==2ornamespace==828ormath.fmod(namespace,2)==1)then
cats=cats..AC_cats-- lets not add authorityControl categories to user pages, modules or talk pages and concentrate on templates and categories instead
end
-- get object location
ifgetProperty(entity,'P625')orgetProperty(entity,'P9149')then
localcoorFun=require('Module:Coordinates')._LocationTemplateCore
localcoori18n=require('Module:i18n/coordinates')
data.coordinates=coorFun({wikidata=entity,lang=lang,globe='earth',mode='object',bare=true})
end
-- prepare fallback list of languages
locallangList=mw.language.getFallbacksFor(lang)
table.insert(langList,1,lang)
-- get wikisource or wikiquote
localprojects={s='wikisource',q='wikiquote'}
forcode,projectinpairs(projects)do
localsitelinks=getSitelinks(entity,project)
ifsitelinksthen
locallng,_=next(sitelinks)-- get language of the first sitelink
table.insert(langList,lng)-- and add it to the list	so there is at least one lang with sitelink on the list
for_,languageinipairs(langList)do
localsitelink=sitelinks[language]
ifsitelinkthen
data[project]=string.format('%s:%s:%s',code,language,sitelink)
break
end
end
end
end
-- if no wikisource sitelink than use P1957 'wikisource_index' property
-- wikisource_index is in full url format (like https://es.wikisource.org/wiki/%C3%8Dndice:Sonetos_-_Leopoldo_Diaz.pdf) 
-- instead of interlink format (like s:es:%C3%8Dndice:Sonetos_-_Leopoldo_Diaz.pdf) 
data.wikisource=data.wikisourceordata.wikisource_index
-- properties with functions
data.object_history=Art.get_object_history(entity,lang)-- object history
data.exhibition_history=Art.get_exhibition_history(entity,lang)-- exhibition.history
data.inscriptions=Art.get_inscription(entity,lang)
data.medium=Art.get_medium(entity,lang)
data.medium=empty2nil(data.medium)ordata.technique;
data.references=Art.get_references(entity,lang)
localexclude_list={pagename,data.image}-- list of files to exclude
data.other_versions=Art.get_other_versions(entity,exclude_list,lang)
localX=Art.get_depicted(entity,lang)
data.depicted_people=X[1]
data.description=X[2]-- depicted artistic or religious themes
X=Art.get_accession_number(entity,lang)
data.id=X.str-- wikitext version of the accession number 
data.id_id=X.id-- one of accession numbers, which will be used as a sortkey
X=Art.get_institution(entity,lang)
data.institution=X.institution
data.institution_id=X.id
data.department=X.location
data.dimensions=Size({entity=entity},nil,nil,lang)
data.dimensions=empty2nil(data.dimensions);
returndata,cats
end
-- ===========================================================================
-- === Adjust parameters related to books ===
-- === and resolve potential aliases ===
-- === INPUTS: ===
-- === * frame - contains imput parameters passed from the template ===
-- === OUTPUTS: ===
-- === * args - cleaned up inputs ===
-- ===========================================================================
localfunctionheader_customization(args0,data,args1)
-- get author Wikidata ID based on Wikidata
localcreator_label,creator_id,creator_str,title_label,creator_tag
ifargs0.wikidatathen
creator_id=data.creator_idordata.author_idordata.architect_idordata.designer_idordata.editor_idordata.translator_idordata.illustrator_idordata.composer_id
ifcreator_idthen
creator_label=getLabel(creator_id,args0.lang)
end
title_label=data.label-- create name based on Wikidata label
end
-- get author Wikidata ID based on commons
ifnotcreator_labelthen
ifargs0.infobox=='artwork'then
creator_id=args0.artist_idorargs0.author_id
creator_str=args0.artistorargs0.author
elseifargs0.infobox=='photograph'then
creator_id=args0.photographer_idorargs0.author_id
creator_str=args0.photographerorargs0.author
elseifargs0.infobox=='book'then
creator_id=args0.author_id
creator_str=args0.author
end
creator_tag=TagQS.readTag(creator_stror'','creator')
ifcreator_tagthen
-- if author was "{{Creator:Meister Theoderich von Prag|circle of}}" than creator_id will be "P170|Q4233718|P1776|Q446631 "
localres={creator_tag:match("^P170%|Q4233718%|(P%d+)%|(Q%d+)$")}-- Q4233718 = annonymous
ifresandres[1]andres[2]then
creator_label=getLabel(res[2],args0.lang)
localLUT={P1774='workshop of',P1775='follower of',P1776='circle of',
P1777='manner of',P1779='possibly',P1780='school of',P1877='after'}
ifres[1]=='P5102'then-- using "nature of statement (P5102)" qualifier
creator_label=getLabel('Q4233718',args0.lang)-- display "anonymous (Q4233718)""
end
ifLUT[res[1]]then
creator_label=alterName(LUT[res[1]],creator_label,args0.lang)-- call [[module:Name]] with the task
end
ifcreator_label=="name not supported"then
creator_label=nil
end
end
elseifcreator_idandcreator_id:match("^Q%d+$")then
creator_label=getLabel(creator_id,args0.lang)
end
end
-- scrape labels from {{title}} template
ifnottitle_labelandargs0.titlethen
locallabels={}
for_,titleinipairs(TagQS.readTags(args0.title,'label'))do
locallang,label=mw.ustring.match(title,'L(%w+)%|"([^"]+)"')
iflangandlabelthen
labels[lang]=label
end
end
title_label=core.langSwitch(labels,args0.lang)
end
-- get title based on commons
ifnottitle_labelandargs0.titlethen
title_label=nowiki(args0.title)
end
-- if title too long than truncate it
iftitle_labeland#title_label>250then
title_label=nil
end
ifcreator_labeland#creator_label>150then
creator_label=nil
end
-- combing author and title labels
ifcreator_labelandtitle_labelthen
localcolon=mw.message.new("Colon-separator"):inLanguage(args0.lang):plain()
args1.name=creator_label..colon..title_label
else
args1.name=title_label
end
-- if we have a {{book}} template in file namespace and file of in PDF or DjVu than use it as image
ifargs0.infobox=='book'andargs0.namespace==6andargs1.image==nil
and(args0.noimage==falseorargs1.image_page)
and(args0.mimeType=='application/pdf'orargs0.mimeType=='image/vnd.djvu')then
args1.image=args0.pagename
end
returnargs1
end
-- ==================================================
-- === External functions ===========================
-- ==================================================
localp={}
-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
functionp.create_infobox(args0)
locallang=args0.lang-- user's language
localcats,cats1,cats2='','',''-- categories 
localstr,data,sdc
-- ===========================================================================
-- === Step 1: clean up of template arguments "args0"
-- ===========================================================================
args0=artcore.clean_input_parameters(args0)
ifnotargs0.wikidataandargs0.namespace==14then
localentity=mw.wikibase.getEntity()
ifentitythen-- category page connected to Wikidata through a sitelink
args0.wikidata=entity.id
localqid=getProperty(entity,'P301')-- follow wikidata's item redirect-like properties
ifqidthen-- item had "category's main topic (P301)" -> use it
args0.wikidata=qid
end
end
end
-- ===========================================================================
-- === Step 2: one by one merge Wikidata and creator data
-- ===========================================================================
localwikidata_temp=args0.wikidata-- Wikidata from template
sdc={}
ifnotargs0.no_sdcandargs0.namespace==6then-- if file namespace
sdc,cats2=harvest_SDC(args0,lang)-- harvest Structured Data on Commons
if(args0.sdc_source==false)or(args0.source)then
-- get source from SDC only if this is NOT the artwork infobox of {{Art Photo}} template
-- also skip sdc.source if we have args0.source, otherwise we might and up with 2 source fields
sdc.source_=nil
args0.sdc_source=nil-- not needed anymore
end
args0.source_=args0.source_orsdc.source_-- if source not provided than get it from SDC
args0.wikidata=args0.wikidataorsdc.wikidata-- if Wikidata not provided than get it from P6243 ("digital representation of") 
args0.image_page=args0.image_pageorsdc.image_page-- title image page for multipage book files 
end
data,cats=harvest_wikidata(wikidata_temp,sdc.wikidata,lang,args0.namespace,args0.infobox,args0.pagename)
cats=(catsor'')..(cats1or'')..(cats2or'')
-- based on the template type determine the meaning of "creator" 
ifargs0.infobox=='photograph'then
data.photographer,data.photographer_id=data.creator,data.creator_id
elseifargs0.infobox=='book'then
--data.author, data.author_id = data.creator, data.creator_id
else-- args0.infobox=='artwork'
data.artist,data.artist_id=data.creator,data.creator_id
end
-- mass merge (prioritize local values) 
localargs={}
localfields={'artist','artist_id','author','author_id','architect','designer','illustrator','composer',
'publisher','editor','translator','printer','photographer','photographer_id','wikisource','wikiquote',
'title','object_type','authority','image','id','homecat','coordinates','genre','subject','image_page',
'date','medium','name','depicted_people','depicted_place','place_of_creation','place_of_discovery',
'dimensions','institution','department','references','object_history','exhibition_history','inscriptions',
'place_of_publication','publication_date','language','subtitle','series_title','volume','edition','edition_of',
'author_of_foreword','author_of_afterword','description','other_versions','part_of'
}
for_,fieldinipairs(fields)do
args[field]=args0[field]ordata[field]
end
-- copy fields only defined locally
localfields={'wikidata','original_description_info','original_description','biased','camera_coord','depicted_part',
'source','source_','strict','permission','demo','lang','notes','credit_line','linkback','pageoverview',
'other_fields','other_fields_1','other_fields_2','other_fields_3','wikidata_cat','namespace','infobox','demo_image',
'no_qs'
}
for_,fieldinipairs(fields)do
args[field]=args0[field]
end
ifargs.artist_idand#args.artist_id>1andargs.artist_id==args.author_idanddata.artist_id~=data.author_idthen
-- args.artist_id is string so #args.artist_id is string length. data.artist_id!=data.author_id is to make sure
-- both _ids are not coming from Wikidata. Might need to also skip if args0.author has content other than creator template
args.author,args.author_id=nil,nil;-- if artist and author are the same than drop one
cats=cats..'[[Category:Artworks with the same artist and author]]\n'
end
ifargs0.infobox=='artwork'andargs0.photo_dateandargs0.photographerthen
cats=cats..'[[Category:Artworks with photograph information]]\n'
end
ifargs0.infobox=='book'andargs0.publication_dateanddata.datethen
-- some magazines have local publication date for specific issue and inception date on Wikidata for the 
-- magazine (publication of the first issue) -> ignore the inception date
args.date=nil
end
-- look for cases where a field like "photographer" has a single creator template with a role
-- "photographer" stated in front of it -> strip the role.
localLUT={Q483501='artist',Q482980='author',Q42973='architect',Q5322166='designer',Q36834='composer',
Q1607826='editor',Q333634='translator',Q644687='illustrator',Q33231='photographer'}
foritem,fieldinpairs(LUT)do
ifargs[field]andargs[field..'_id']then
localtag=TagQS.createTag('creator_role',nil,item)
localstart,finish=mw.ustring.find(args[field],tag,1,true)
ifstartthen-- remove "<b>...</b>: " + tag
-- split the string in 2 using the tag as a divider
localstr1=mw.ustring.sub(args[field],1,start-1)
localstr2=mw.ustring.sub(args[field],finish+1)
-- remove bold text at the end of str1
localstr1=mw.ustring.gsub(str1,"'''.*''': $",'')
args[field]=str1..str2-- splice 2 halfs
end
end
end
-- internationalize local object_type string
ifargs0.object_typeandargs.object_type==args0.object_typethen
localobjectType=require('Module:I18n/objects')._object
args.object_type=objectType(args.object_type,nil,lang)
end
-- convert all empty strings to nils
for_,fieldinipairs(fields)do
ifargs[field]==''then
args[field]=nil;
end
end
-- ===========================================================================
-- === Step 3: create maintenance categories and render html of the table
-- ===========================================================================
args=header_customization(args0,data,args)
cats=cats..add_maintenance_categories(args0,args)
args.QS=nil;
ifnotargs0.no_sdcthen
cats2,args=add_wikidata_maintenance_categories(args0,args,data)
cats=cats..cats2
end
ifargs0.wikidataand(args0.wikidata~='CREATE')and(args.namespace==6)andnot(sdc.digital_representation_oforsdc.main_subject)then
ifdata.object_type_idthen
for_,typeIdinipairs(data.object_type_id)do
localartwork_type=sdc.artwork_types[typeId]
ifartwork_type=='2D'then
cats=string.format('%s\n[[Category:Artworks missing digital representation of for 2D work |%s]]',cats,args0.wikidata)
elseifartwork_type=='3D'then
cats=string.format('%s\n[[Category:Artworks missing main subject for 3D work|%s]]',cats,args0.wikidata)
-- Can add the other types here later
end
end
end
elseifsdc.digital_representation_oforsdc.main_subject_acceptedthen
ifdata.object_type_idthen
for_,typeIdinipairs(data.object_type_id)do
localartwork_type=sdc.artwork_types[typeId]
ifartwork_typeandsdc.digital_representation_ofthen
ifartwork_type=='2D'then
cats=string.format('%s\n[[Category:Artworks digital representation of 2D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='3D'then
cats=string.format('%s\n[[Category:Artworks digital representation of 3D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='both'then
cats=string.format('%s\n[[Category:Artworks digital representation of both 2D and 3D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='unclassified'then
cats=string.format('%s\n[[Category:Artworks digital representation of unclassified work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='no'then
cats=string.format('%s\n[[Category:Artworks digital representation of not a work of art|%s]]',cats,sdc.wikidata)
else
cats=string.format('%s\n[[Category:Artworks digital representation of unknown type of work|%s]]',cats,sdc.wikidata)
end
elseifnotartwork_typeandsdc.digital_representation_ofthen
cats=string.format('%s\n[[Category:Artworks digital representation of unknown type of work|%s]]',cats,sdc.wikidata)
elseifartwork_typeandsdc.main_subject_acceptedthen
ifartwork_type=='2D'then
cats=string.format('%s\n[[Category:Artworks main subject 2D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='3D'then
cats=string.format('%s\n[[Category:Artworks main subject 3D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='both'then
cats=string.format('%s\n[[Category:Artworks main subject both 2D and 3D work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='unclassified'then
cats=string.format('%s\n[[Category:Artworks main subject unclassified work|%s]]',cats,sdc.wikidata)
elseifartwork_type=='no'then
cats=string.format('%s\n[[Category:Artworks main subject not a work of art|%s]]',cats,sdc.wikidata)
else
cats=string.format('%s\n[[Category:Artworks main subject type of work|%s]]',cats,sdc.wikidata)
end
elseifnotartwork_typeandsdc.main_subject_acceptedthen
cats=string.format('%s\n[[Category:Artworks main subject type unknown type of work|%s]]',cats,sdc.wikidata)
end
end
end
end
localresults=artcore.build_html(args)
returnresults,cats
end
-- ===========================================================================
-- === Versions of the function to be called from template namespace
-- === Each template with it's own entry point
-- ===========================================================================
functionp.artwork(frame)
localargs=artcore.read_input_parameters(frame)
args.infobox='artwork'
localcats0=artcore.verify_input_parameters(args)
args.demo_image='Noun project - Mona Lisa - in frame.svg'
localresults,cats1=p.create_infobox(args)-- call the inner "core" function	 
returnresults..cats0..cats1
end
-- ===========================================================================
functionp.photograph(frame)
localargs=artcore.read_input_parameters(frame)
args.infobox='photograph'
localcats0=artcore.verify_input_parameters(args)
args.source_=args.sourceorargs.source_
args.source=nil
args.demo_image='Breezeicons-actions-22-view-preview.svg'
localresults,cats=p.create_infobox(args)-- call the inner "core" function
-- most photographs do not have Wikidata id so remove cat "Photographs without Wikidata item"
cats=mw.ustring.gsub(cats,'%\n%[%[Category:Photographs without Wikidata item%]%]','')
returnresults..cats
end
-- ===========================================================================
-- This is for when we have photograph template in addition to artwork and we don't want any Wikidata
functionp.photograph_of_object(frame)
localargs=artcore.read_input_parameters(frame)
args.infobox='photograph'
localcats0=artcore.verify_input_parameters(args)
args.source_=args.sourceorargs.source_
args.source=nil
args.no_sdc=true
localresults,cats=p.create_infobox(args)-- call the inner "core" function
returnresults..cats
end
-- ===========================================================================
functionp.art_photo(frame)
localargs=artcore.read_input_parameters(frame)-- clean up input parameters
args.permission=args.permissionorargs.photo_licenseorargs.photo_licence-- additional aliases
args.artwork_license=args.artwork_licenseorargs.artwork_licence
args.source=args.sourceorargs.source_
args.photo_license,args.photo_licence,args.artwork_licence,args.source_=nil,nil,nil,nil
localresults={}
-- split input arguments
localargs2={}
localfields={['date']='photo_date',description='photo_description',author='photographer',
source='source',other_versions='other_versions',other_fields='other_fields',
permission='photo_license',permission='permission'
}
forfield1,field2inpairs(fields)do
ifargs[field2]then
args2[field1]=args[field2]
args[field2]=nil
end
end
for_,fieldinipairs({'lang','demo'})do
args2[field]=args[field]
end
args.permission=args.artwork_license
args.artwork_license=nil
-- create object infobox
args.infobox='artwork'
localcats0=artcore.verify_input_parameters(args)
localheader=frame:expandTemplate{title='Section header',args={["1"]=args.artwork_headeror'Object',lang=args.lang}}
table.insert(results,"==="..header.."===")
args.demo_image='Noun project - Mona Lisa - in frame.svg'
args.strict=false
args.sdc_source=false-- no picking sources from SDC for this infobox
localinfobox,cats1=p.create_infobox(args)-- call the inner "core" function	
table.insert(results,infobox)
--create {{information}} infobox
header=frame:expandTemplate{title='Section header',args={["1"]='Photograph',lang=args.lang}}
table.insert(results,"==="..header.."===")
args2.strict=false
table.insert(results,Information(args2))
table.insert(results,cats0..cats1)
returntable.concat(results,'\n')
end
-- ===========================================================================
functionp.book(frame)
localargs=artcore.read_input_parameters(frame)
args.infobox='book'
args.demo_image='Placeholder book.svg'
args.strict=false
args.place_of_publication=args.place_of_publicationorargs.city-- book specific aliases
args.publication_date=args.publication_dateorargs.date
args.source_=args.sourceorargs.source_
ifargs.isbnorargs.lccnorargs.oclcorargs.bnfthen
localauth_args={ISBN=args.isbn,LCCN=args.lccn,OCLC=args.oclc,BNF=args.bnf,bare=1}
args.authority=frame:expandTemplate{title='Book authority control',args=auth_args}
args.isbn,args.lccn,args.oclc,args.bnf=nil,nil,nil,nil
end
args.source,args.city,args.date=nil,nil,nil
localresults,cats=p.create_infobox(args)-- call the inner "core" function	 
returnresults..cats
end
returnp