Modul:Artwork
Aus WikiWaldhof
Die Dokumentation für dieses Modul kann unter Modul:Artwork/Doku erstellt werden
--[[
__ __ _ _ _ _ _
| \/ | ___ __| |_ _| | ___ _ / \ _ __| |___ _____ _ __| | __
| |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ /
| | | | (_) | (_| | |_| | | __/_ / ___ \| | | |_ \ V V / (_) | | | <
|_| |_|\___/ \__,_|\__,_|_|\___(_)_/ \_\_| \__| \_/\_/ \___/|_| |_|\_\
This module is intended to be the engine behind "Version:Artwork".
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 authorityControl = require("Module:Authority control")._authorityControl -- used for formatting of Authority control row
local City = require("Module:City") -- used to add wikidata bases links to names of places
local labels = require("Module:I18n/artwork") -- internationalization of labels
local creator = require("Module:Creator")._creator -- render creator templates
local institution = require("Module:Institution")._institution -- render institution templates
local ISOdate = require('Module:ISOdate')
local Size = require('Module:Size')._size -- Lua code behing {{Size}} template
local Art = require('Module:Wikidata art') --
local yesno = require('Module:Yesno')
-- ==================================================
-- === Internal functions ===========================
-- ==================================================
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 isodate2timestamp(dateStr)
-- convert isodate to timestamp used by quick statements
local tStamp = nil
if string.match(dateStr,"^%d%d%d%d$") then -- if YYYY format
tStamp = '+' .. dateStr .. '-00-00T00:00:00Z/9'
elseif string.match(dateStr,"^%d%d%d%d%-%d%d$") then -- if YYYY-MM format
tStamp = '+' .. dateStr .. '-00T00:00:00Z/10'
elseif string.match(dateStr,"^%d%d%d%d%-%d%d%-%d%d$") then -- if YYYY-MM-DD format
tStamp = '+' .. dateStr .. 'T00:00:00Z/11'
end
return tStamp
end
local function empty2nil(str)
if str=='' then
return nil
else
return str;
end
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
-- ====================================================================
-- This function is responsible for producing HTML of a single row of the template
-- At this stage all the fields are already filed. There is either one or two fields
-- INPUTS:
-- * param1 and param2 - structures for 2 fields containing fields:
-- - tag - I18n tag used for localization of the field name. Usually name of page in MediaWiki namespace which was imported from translatewiki.org.
-- Alternative is to pass already translated field name.
-- - field - field content
-- - id - ID tag added to HTML's <td> cell. if IDs of 2 fields ar the same than we ignore the second one
-- - wrapper - some fields need a <span class=...> wrapper around the field content
-- ====================================================================
-- special case for "Institution + location" field pair
local function Build_html_row2(param, args)
local field1 = args[param[1].field]
local field2 = args[param[2].field]
if field1=='' then field1=nul; end
if field2=='' then field2=nul; end
if not (field1 or field2 or args.demo) then
return nil
end
local tag = mw.message.new( param[1].tag ):inLanguage(args.lang):plain() -- label message in args.lang language
local cell1 = string.format('<td id="%s" rowspan="2" class="fileinfo-paramfield" lang="%s">%s</td>\n', param[1].id, args.lang, tag)
local cell2 = string.format('<td>\n'.. param[1].wrapper ..'</td>', field1 or '')
local cell3 = string.format('<td id="%s">\n'.. param[2].wrapper ..'</td>', param[2].id, field2 or '')
return string.format('<tr valign="top">\n%s%s\n</tr>\n\n<tr valign="top">\n%s\n</tr>\n\n', cell1, cell2, cell3)
end
--All other fields
local function Build_html_row(param, args)
if not param.field then
return Build_html_row2(param, args)
end
local field = args[param.field]
if field=='' then field=nul; end
if not (field or args.demo) then
return nil
end
if not param.id then -- "other fields" parameter
return field
end
local tag = param.tag or 'bad'
if string.sub(tag,1,10) == 'wm-license' then
tag = mw.message.new( tag ):inLanguage(args.lang):plain() -- label message in args.lang language
elseif labels[tag] then
tag = langSwitch(labels[tag], args.lang)
end
cell1 = string.format('<td id="%s" class="fileinfo-paramfield" lang="%s">%s</td>\n', param.id, args.lang, tag)
local cell2 = string.format('<td>\n'.. param.wrapper ..'</td>', field or '')
return string.format('<tr valign="top">\n%s%s\n</tr>\n\n', cell1, cell2)
end
-- ====================================================================
-- === This function is just responsible for producing HTML of the ===
-- === template. At this stage all the fields are already filed ===
-- ====================================================================
local function Build_html(args, cats)
-- get text direction
local dir
if mw.language.new( args.lang ):isRTL() then
dir = 'rtl'
else
dir = 'ltr'
end
-- files with no source will be flagged
if (not args.source and not args.source_) and args.strict and (args.namespace==6) then
args.nosource = mw.getCurrentFrame():expandTemplate{ title = 'Source missing' }
end
local nCol = 2
if not args.image and args.demo then
args.image = 'Noun project - Mona Lisa - in frame.svg'
end
if args.image then
nCol = 3
end
-- Top line
local top, results = {}, {}
table.insert(top, string.format('<span class="fn" id="artwork"><bdi>%s\n</bdi></span>', args.name or 'missing name') )
if args.linkback then -- Wikidata Link
table.insert(top, string.format('[[File:Blue pencil.svg|15px|%s|link=%s]]', args.linkback, args.linkback) )
end
if args.wikidata then -- Wikidata Link
table.insert(top, string.format('[[File:Wikidata-logo.svg|20px|wikidata:%s|link=wikidata:%s]]', args.wikidata, args.wikidata) )
end
if args.QS then -- quick_statement link to upload missing info to wikidata
table.insert(top, string.format('%s', args.QS) )
end
if args.name or args.wikidata or args.QS or args.demo then
local line = string.format('<th colspan="%i" style="background-color:#ccf; font-weight:bold; border:1px solid #aaa" text-align="left">%s</th>', nCol, table.concat(top, ' '))
--local line = string.format('<th colspan="2" class="fileinfo-paramfield" text-align="left">%s</th>', table.concat(top, ' '))
table.insert(results, string.format('<tr valign="top">\n%s\n</tr>\n', line))
end
-- Permissions tag
-- {{int:wm-license-information-permission}}<br /><small>([[{{int:wm-license-information-permission-reusing-link}}|{{int:wm-license-information-permission-reusing-text}}]])</small>
local tag1 = mw.message.new( "wm-license-information-permission" ):inLanguage(args.lang):plain()
local tag2 = mw.message.new( "wm-license-information-permission-reusing-link" ):inLanguage(args.lang):plain()
local tag3 = mw.message.new( "wm-license-information-permission-reusing-text" ):inLanguage(args.lang):plain()
local permission_tag = string.format("%s<br /><small>([[%s|%s]])</small>", tag1, tag2, tag3)
local photographer_tag = getLabel('Q33231', args.lang, "-", 'ucfirst')
-- add other fields
local param = {
{field='artist' , id='fileinfotpl_aut' , tag='wm-license-artwork-artist', wrapper='<div class="fn value">\n%s</div>'},
{field='author' , id='fileinfotpl_aut' , tag='wm-license-information-author', wrapper='<div class="fn value">\n%s</div>'},
{field='photographer' , id='fileinfotpl_aut' , tag=photographer_tag, wrapper='<div class="fn value">\n%s</div>'},
{field='other_fields_1'},
{field='title' , id='fileinfotpl_art_title' , tag='wm-license-artwork-title', wrapper='<div class="fn">\n%s</div>'},
{field='object_type' , id='fileinfotpl_art_object_type' , tag='object_type', wrapper='%s'},
{field='description' , id='fileinfotpl_desc' , tag='wm-license-information-description', wrapper='<div class="description">\n%s</div>'},
{field='depicted_people' , id='fileinfotpl_art_depicted_people' , tag='depicted_people', wrapper='%s'},
{field='depicted_place' , id='fileinfotpl_art_depicted_place' , tag='depicted_place', wrapper='%s'},
{field='other_fields_2'},
{field='date' , id='fileinfotpl_date' , tag='wm-license-information-date', wrapper='%s'},
{field='medium' , id='fileinfotpl_art_medium' , tag='wm-license-artwork-medium', wrapper='%s'},
{field='dimensions' , id='fileinfotpl_art_dimensions' , tag='wm-license-artwork-dimensions', wrapper='%s'},
{{field='institution' , id='fileinfotpl_art_gallery' , tag='wm-license-artwork-current-location', wrapper='%s'},
{field='department' , id='fileinfotpl_art_location' , wrapper='<div class="locality">\n%s</div>'}},
{field='id' , id='fileinfotpl_art_id' , tag='wm-license-artwork-id', wrapper='<div class="identifier">\n%s</div>'},
{field='place_of_creation' , id='fileinfotpl_art_creation_place' , tag='place_of_creation', wrapper='%s'},
{field='place_of_discovery', id='fileinfotpl_art_discovery_place' , tag='place_of_discovery', wrapper='%s'},
{field='object_history' , id='fileinfotpl_art_object_history' , tag='wm-license-artwork-object-history', wrapper='%s'},
{field='exhibition_history', id='fileinfotpl_art_exhibition_history' , tag='exhibition_history', wrapper='%s'},
{field='credit_line' , id='fileinfotpl_art_credit_line' , tag='wm-license-artwork-credit-line', wrapper='%s'},
{field='inscriptions' , id='fileinfotpl_art_inscriptions' , tag='wm-license-artwork-inscriptions', wrapper='%s'},
{field='notes' , id='fileinfotpl_art_notes' , tag='wm-license-artwork-notes', wrapper='%s'},
{field='other_fields_3'},
{field='references' , id='fileinfotpl_art_references' , tag='wm-license-artwork-references', wrapper='%s'},
{field='authority' , id='fileinfotpl_art_authority' , tag=args.authority_tag, wrapper='%s'},
{field='source' , id='fileinfotpl_src' , tag='wm-license-artwork-source', wrapper='%s'}, -- source/photographer
{field='source_' , id='fileinfotpl_src' , tag='wm-license-information-source', wrapper='%s'}, -- source
{field='nosource' , id='fileinfotpl_nosrc' , tag='wm-license-information-source', wrapper='%s'},
{field='permission' , id='fileinfotpl_perm' , tag=permission_tag, wrapper='%s'},
{field='other_versions' , id='fileinfotpl_ver' , tag='wm-license-information-other-versions', wrapper='%s'},
{field='other_fields'}
}
for i=1,#param do
table.insert(results, Build_html_row(param[i], args))
end
-- Image on the Right
if args.image then --Wikiquote link
field = string.format('[[File:%s|250x250px|alt=%s|class=photo]]', args.image, args.name or '')
local nRow = #results -- number of rows below
line = string.format('<td rowspan="%i" style="width:200px; text-align: right;" id="fileinfotpl_creator_image"><span class="wpImageAnnotatorControl wpImageAnnotatorOff">%s</span></td></tr>\n\n', nRow, field)
results[2] = mw.ustring.gsub(results[2], "</tr>%s*$", line);
end
-- add table and outer layers
local style = string.format('class="fileinfotpl-type-artwork toccolours vevent mw-content-%s" dir="%s" style="width: 100%%" cellpadding="4"', dir, dir)
results = string.format('<table %s>\n%s\n</table>\n', style, table.concat(results))
results = string.format('<div class="hproduct commons-file-information-table">\n%s\n</div>\n', results)
return results
end
-- ===========================================================================
-- === This function is responsible for adding maintenance categories ===
-- === which are not related to wikidata ===
-- === INPUTS: ===
-- === * args - merged data from the local arguments and Wikidata ===
-- ===========================================================================
local function add_maintenance_categories(args0, args)
local cats = '' -- categories
mw.getCurrentFrame():expandTemplate{ title = 'Infobox template tag' } -- add the template tag
-- ====================================================
-- === automatic tagging of pages in all namespaces ===
-- ====================================================
if args.date or args.year then
-- add an empty template which can be used as a tag in PetScan
local d = os.date('!*t') -- current date table
local current_year = tonumber(d.year) -- current year
local creation_year = tonumber(ISOdate._ISOyear(args.year or args.date))
if creation_year and current_year and (current_year-creation_year)>200 then
mw.getCurrentFrame():expandTemplate{ title ='Works created more than 200 years ago' }
end
end
-- add [[Category:Creator templates with unknown parameter]] category, if some parameter not on the following list is used
local fields = { 'artist', 'author', 'title', 'object_type', 'description', 'date', 'medium', 'permission', 'photographer',
'dimensions', 'institution', 'department', 'references', 'object_history', 'artist_id', 'author_id', 'institution_id',
'exhibition_history', 'credit_line', 'other_versions', 'source', 'strict', 'inscriptions', 'notes', 'linkback',
'other_fields', 'other_fields_1', 'other_fields_2', 'other_fields_3', 'demo', 'id', 'wikidata', 'year', 'homecat',
'place_of_creation', 'place_of_discovery', 'source_', 'wikidata_cat', 'namespace', 'lang', 'image', 'url', 'pagename',
'depicted_people', 'depicted_place'}
local set = {}
for _, field in ipairs(fields) do set[field] = true end
for field, _ in pairs( args0 ) do
if not set[field] then
cats = cats .. '[[Category:Pages using Artwork template with incorrect parameter]]'
cats = cats .. string.format('\n;<span style="color:red">Error in [[Version:Artwork|{{Artwork}} template]]: unknown parameter "%s".</span>', field)
end
end
if args0.namespace==0 and mw.ustring.sub(args0.pagename,1,8) == "Artwork:" then
cats = cats .. '\n[[Category:Artwork templates]]'
if args.homecat then
cats = cats .. '\n[[Category:' .. args.homecat .. ']]'
end
end
return cats
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 creator template page ===
-- === * args1 - merge of local and wikidata metadata ===
-- === * data - data pulled from Wikidata ===
-- ===========================================================================
local function add_wikidata_maintenance_categories(args0, args1, data)
local cats = '' -- categories
local comp = {} -- outcome of argument vs. wikidata comparison
if (args0.namespace~=6 and args0.namespace~=14) or args0.wikidata_cat then -- continue only if the namespace is a Category or file
return cats, args1
end
-- skip the rest if no item ID
if not args0.wikidata then
cats = string.format('%s\n[[Category:Artworks without Wikidata item]]', cats)
if string.find(args1.object_type or '', 'painting') then
cats = string.format('%s\n[[Category:Paintings without Wikidata item]]', cats)
end
return cats, args1
end
--=======================================================================================================
--=== Categories and files with {{Artwork}} template linked to Wikidata item below
--=======================================================================================================
-- setup QuickStatements
local qsTable = {} -- table to store QuickStatements
-- convert QS table to a string
local today = '+' .. os.date('!%F') .. 'T00:00:00Z/11' -- today's date in QS format
-- default QuickStatements command
local qsCommand1 = '%s|%s|%s|S143|Q565|S813|' .. today
local qsCommand2 = '%s|%s|S143|Q565|S813|' .. today
cats = string.format('%s\n[[Category:Artworks with Wikidata item|%s]]', cats, args0.wikidata)
-- 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' }
-- groups {Q15727816='painting series', sculpture series (Q19479037), artwork series (Q15709879), group of sculptures (Q27031439), group of paintings (Q18573970) }
-- good {Q199414='bog body', Q7881='skeleton'}
local groupItem = false
if data.object_type_id then
local bad = false
local bwLUT = {Q5=1, Q11266439=1, Q4167410=1, Q4167836=1, Q532=1, Q482994=1, Q16521=1, Q15727816=2, Q19479037=2, Q15709879=2, Q27031439=2, Q18573970=2, Q199414=3, Q7881=3}
for _, typeId in ipairs( data.object_type_id ) do
local v = bwLUT[typeId]
if v==1 then
bad = true
elseif v==2 then
groupItem = true
cats = string.format('%s\n[[Category:Artworks with group Wikidata item|%s]]', cats, args0.wikidata)
break
elseif v==3 then
bad = false
break
end
end
if bad then
cats = string.format('%s\n[[Category:Artworks with wrong Wikidata item|%s]]', cats, args0.wikidata)
end
end
-- local fields which are missing on Wikidata
local fields = {'date', 'medium', 'dimensions', 'image', 'institution', 'author', 'artist'}
for _, field in ipairs( fields ) do
if not data[field] and args0[field] then
comp[field] = 'missing'
end
end
-- mark local fields redundant to Wikidata
local fields = {['date']='date', medium='medium', dimensions='dimensions', institution_id='institution', author_id='author', artist_id='artist'}
for field1, field2 in ipairs( fields ) do
if data[field1] and args0[field1] and data[field1]==args0[field1] then
comp[field2] = 'redundant'
end
end
-- Redundant author and artist
if (not data.artist and args0.artist_id) then
--table.insert( qsTable, string.format(qsCommand1, args0.wikidata, "P170", args0.artist_id) )
end
if (data.author_id==args0.artist_id and data.author_id) then
comp.artist = 'redundant'
end
if (data.artist_id==args0.author_id and data.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.artist or '', "%[%[:Creator:") and data.artist) then
args1.artist = data.artist
comp.artist = 'redundant'
end
if (string.match(args0.author or '', "%[%[:Creator:") and data.author) then
args1.author = data.author
comp.author = 'redundant'
end
-- process "image" field
if (data.image and args0.image) then
comp.image = 'redundant'
end
if (not data.image and args0.image) then -- QS code to help transfer image to Wikidata
table.insert( qsTable, string.format(qsCommand1, args0.wikidata, "P18", '"' .. args0.image.. '"') )
end
if (not data.image and args0.namespace==6) then -- QS code to help transfer image to Wikidata
table.insert( qsTable, string.format(qsCommand1, args0.wikidata, "P18", '"' .. args0.pagename.. '"') )
comp.image = 'missing'
end
-- process "date" field
if (not data.date and args0.date) then
args0.date = string.gsub(args0.date, "date QS:P,", "date QS:P571,") -- this line is related to next section
local val = isodate2timestamp(args0.date)
if val then
table.insert( qsTable, string.format(qsCommand1, args0.wikidata, "P571", val) )
end
end
-- look for hidden text in various templates so they can be passed to Wikidata
local fields = {'date', 'medium', 'dimensions', 'institution', 'creator'}
for _, field in ipairs( fields ) do
if args0[field] and not data[field] then
local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>'
local qs = string.match(args0[field], pat)
_, nMatch = string.gsub(args0[field], pat, "")
if qs and nMatch==1 then -- allow only single matches
qs = string.gsub(qs, ',', '|')
for _, v in ipairs( mw.text.split( qs, ';', true ) ) do
table.insert( qsTable, string.format(qsCommand2, args0.wikidata, v) )
end
end
end
end
-- add categories related to accession number
if args0.id then
local sortkey = 'zzz'
if #args0.id<15 then
sortkey = args0.id
end
cats = string.format('%s\n[[Category:Artworks with known accession number| %s]]', cats, sortkey)
elseif data.id 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_id or 'zzz')
end
-- ==================================================
-- === Create categories based on comp structure ====
-- ==================================================
for field, outcome in pairs( comp ) do
cats = string.format('%s\n[[Category:Artworks with Wikidata item %s %s|%s]]', cats, outcome, field, args0.wikidata)
end
-- ==================================================
-- === Create QuickStatement codes ==================
-- ==================================================
local QS = '' -- quick_statements final string
if #qsTable>0 and not groupItem then -- do not use QS on group items
local qsHeader = 'https://tools.wmflabs.org/quickstatements/index_old.html#v1=%s%%0A'
local qsWrapper = ' [[File:Commons_to_Wikidata_QuickStatements.svg|15px|link=%s]]'
QS = table.concat( qsTable, '%0A') -- combine multiple statements into a single command separated by \n (line feed)
QS = mw.ustring.gsub(QS, '|', "%%09") -- replace some characters with ASCII hex values
QS = mw.ustring.gsub(QS, '"', "%%22") -- "%%" instead of "%" is because mw.ustring.gsub is a regexp function
QS = mw.ustring.gsub(QS, ' ', "%%20")
QS = string.format(qsHeader , QS); -- create full URL link
QS = string.format(qsWrapper, QS) -- use URL as a link accessed by clicking Wikidata icon
cats = cats .. '\n[[Category:Artworks with Wikidata item: quick statements]]'
end
args1.QS = QS;
return cats, args1
end
-- ===========================================================================
-- === Harvest wikidata properties matching creator template fields ===
-- === INPUTS: ===
-- === * itemID - item id or a q-code ===
-- === * lang - language id of the desired language ===
-- === * namespace - namespace number of the page calling the module ===
-- ===========================================================================
local function harvest_wikidata(itemID, lang, namespace)
local data = {} -- structure similar to "args" but filled with wikidata data
local cats = ''
local frame = mw.getCurrentFrame()
local entity = nil
if mw.wikibase and itemID then
entity = mw.wikibase.getEntity(itemID)
if not entity then
cats = '[[Category:Artworks with bad Wikidata link]]'
elseif entity.id~=itemID then
cats = '[[Category:Artworks with redirected Wikidata link]]'
end
end
data.authority_tag = "[[w:en:Help:Authority control|Authority control]]"
if not entity then
return data, cats
end
-- inception date: translated date and year number
local d = getDate(entity, 'P571' , lang) -- inception date
if not d.str then
d = getDate(entity, 'P577' , lang) -- publication date
end
data.date, data.date_, data.year = d.str, d.iso, d.year
-- harvest string properties
local Debug ={}
local property = {P10='video', P18='image', P996='scan', P373='homecat', P2093='authorStr'}
for prop, field in pairs( property ) do
data[field] = getProperty(entity, prop, 'one')
end
data.image = data.image or data.scan or data.video
-- harvest Q-code properties which are than converted to labels
local property = { P189='place_of_discovery', P2348='era', P2079='technique'}
for prop, field in pairs( property ) do
local id = getProperty(entity, prop, 'one')
if id then
data[field] = getLabel(id, lang, "wikipedia")
end
end
if data.era and data.date then
data.date = data.date .. "<br/>" .. data.era
elseif data.era and not data.date then
data.date = data.era
end
-- get object_type
data.object_type_id = getProperty(entity, 'P31', 'all')
if data.object_type_id then
local T = {}
for _, id in ipairs( data.object_type_id ) do
table.insert(T, getLabel(id, lang))
end
data.object_type = table.concat(T, " / ")
end
-- get author and/or author creator template
local d = Art.get_creator(entity, 'P170', lang) -- P170='creator'
if not d.str then
d = Art.get_creator(entity, 'P84', lang) -- P84='architect'
end
data.artist, data.artist_id = d.str, d.id
d = Art.get_creator(entity, 'P50', lang) -- P50='author'
data.author, data.author_id = d.str, d.id
local creator_name = data.artist_id or data.author_id
if creator_name then
creator_name = getLabel(creator_name, lang)
end
data.author = data.author or data.authorStr -- P2093='author name string'
-- get title (from 3 properties and label)
local property = { P1476 = 'title', P1448='official_name', P1705='native_label', }
for prop, field in pairs( property ) do
local title = {}
for _, statement in pairs( entity:getBestStatements(field)) do
if (statement.mainsnak.snaktype == "value") then
local val = statement.mainsnak.datavalue.value
title[val.language] = val.text -- look for multiple values each with a language code
end
end
if #title>0 then
data[field] = langSwitch(title, lang)
end
end
data.title = data.title or data.official_name or data.native_label
-- Create "name" to be used in the top row of wikidata based template
local label = data.title or getLabel(entity, lang) or "(unknown title)" -- create name based on wikidata label
if creator_name then
local colon = mw.message.new( "Colon-separator" ):inLanguage(lang):plain()
data.name = creator_name .. colon .. label
else
data.name = label
end
-- get authority control (rarely used for artworks)
data.authority, AC_cats = authorityControl(entity, {wikidata = qCode}, lang, 5)
local _,nIdentifiers = string.gsub(data.authority, "*", "")
if nIdentifiers<=1 then
data.authority, AC_cats = nil, ''
end
if not (namespace == 2 or namespace == 828 or math.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
if data.authority and lang~='en' then -- translate phrase Authority control
data.authority_tag = getLabel("Q36524", lang, "wikipedia", "ucfirst")
end
-- 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) or data.technique;
data.references = Art.get_references(entity, lang)
data.depicted_people = Art.get_depicted_people(entity, lang)
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);
return data, cats
end
-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}
-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p._artwork(args0)
local lang = args0.lang -- user's language
local cats = '' -- categories
local str, data
-- ===========================================================================
-- === Step 1: clean up of template arguments "args0"
-- ===========================================================================
if args0.date then
args0.year = empty2nil(ISOdate._ISOyear(args0.date))
args0.date = ISOdate._ISOdate(args0.date, lang)
end
if args0.object_type then
args0.object_type = mw.getCurrentFrame():expandTemplate{ title = 'I18n/objects', args = { ["1"]=args0.object_type, lang=lang } }
end
if args0.author then -- collapse {{Creator}} templates and extract item ID from them
args0.author = mw.ustring.gsub (args0.author, 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"')
args0.author_id = mw.ustring.match(args0.author, "link=wikidata:(Q%d+)%]")
end
if args0.artist then -- collapse {{Creator}} templates and extract item ID from them
args0.artist = mw.ustring.gsub (args0.artist, 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"')
args0.artist_id = mw.ustring.match(args0.artist, "link=wikidata:(Q%d+)%]")
end
if args0.institution then -- collapse {{Institution}} templates and extract item ID from them
args0.institution = mw.ustring.gsub (args0.institution, 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"')
args0.institution_id = mw.ustring.match(args0.institution, '%<div style="display: none;"%>institution QS:([^%<]+)%</div%>')
end
if args0.depicted_people and not string.find(args0.depicted_people, ' ') then
args.depicted_people = City._city(args0.depicted_people, lang) -- single word depicted_people will get a link
end
-- ===========================================================================
-- === Step 2: one by one merge wikidata and creator data
-- ===========================================================================
data, cats = harvest_wikidata(args0.wikidata, lang, args0.namespace)
-- mass merge (prioritize local values)
local args = {}
local fields = { 'artist', 'author', 'title', 'object_type', 'description', 'date', 'medium', 'name', 'depicted_people', 'depicted_place',
'dimensions', 'institution', 'department', 'references', 'object_history', 'artist_id', 'author_id', 'photographer',
'exhibition_history', 'credit_line', 'other_versions', 'source', 'strict', 'inscriptions', 'notes', 'permission',
'other_fields', 'other_fields_1', 'other_fields_2', 'other_fields_3', 'demo', 'id', 'wikidata', 'place_of_creation',
'place_of_discovery', 'source_', 'wikidata_cat', 'namespace', 'lang', 'homecat', 'authority', 'authority_tag', 'image'}
for _, field in ipairs( fields ) do
args[field] = args0[field] or data[field]
end
if args.artist_id and #args.artist_id>1 and args.artist_id==args.author_id then
args.author, args.author_id = nil, nil; -- if artist and author are the same than drop one
end
-- convert all empty strings to nils
for _, field in ipairs( fields ) do
if args[field] == '' then
args[field] = nil;
end
end
-- ===========================================================================
-- === Step 3: create maintenance categories and render html of the table
-- ===========================================================================
cats = cats .. add_maintenance_categories(args0, args)
-- If institution namespace than add maintenance categories
args.QS = nil;
str, args = add_wikidata_maintenance_categories(args0, args, data)
cats = cats .. str
local results = Build_html(args, cats)
return results, cats
end
-- ===========================================================================
-- === Version of the function to be called from template namespace
-- ===========================================================================
function p.artwork(frame)
-- switch to lowercase parameters to make them case independent
local args = {}
for name, value in pairs( frame:getParent().args ) do
if value ~= '' then -- nuke empty strings
local name1 = string.gsub( string.lower(name), ' ', '_')
args[name1] = value
end
end
for name, value in pairs( frame.args ) do
if value ~= '' then -- nuke empty strings
local name1 = string.gsub( string.lower(name), ' ', '_')
args[name1] = value
end
end
if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then
args.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
end
local title = mw.title.getCurrentTitle()
args.namespace = title.namespace -- get page namespace
args.url = title:canonicalUrl()
args.pagename = title.text
-- resolve aliases
args.medium = args.medium or args.technique
args.date = args.date or args.year
args.dimensions = args.dimensions or args.size
args.institution = args.institution or args.gallery or args.museum
args.department = args.department or args.location
args.id = args.accession_number or args.id
args.object_type = args.object_type or args.type
args.place_of_creation = args.place_of_creation or args.place_of_origin or args.country
args.permission = args.permission or args.artwork_license
args.object_history = args.object_history or args.history
args.technique, args.year, args.size, args.gallery = nil, nil, nil, nil
args.location, args.type, args.museum, args.accession_number = nil, nil, nil, nil
args.place_of_origin, args.country, args.artwork_license, args.history = nil, nil, nil, nil
args.wikidata_cat = yesno(args.wikidata_cat, true)
-- call the inner "core" function
local results, cats = p._artwork(args)
return results .. cats
end
return p