Module:Artwork

--[[   __  __           _       _           _         _                      _     |  \/  | ___   __| |_   _| | ___ _   / \   _ __| |___      _____  _ __| | __ | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ / | |  | | (_) | (_| | |_| | |  __/_ / ___ \| |  | |_ \ 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: ]] require('Module:No globals') -- used for debugging purposes as it detects cases of unintended global variables local getLabel        = require("Module:Wikidata label")._getLabel            -- used for creation of name based on wikidata local getSitelinks    = require("Module:Wikidata label")._sitelinks           -- 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 based links to names of places local labels          = require("Module:I18n/artwork")                        -- internationalization of labels local ISOdate         = require('Module:ISOdate') local Size            = require('Module:Size')._size                          -- Lua code behing  template local TitleFromWD     = require('Module:Title').wikidata_title                -- Lua code behing  template local Art             = require('Module:Wikidata art')                        -- local alterName       = require("Module:Name")._name local core            = require("Module:Core") local bit32           = require("bit32")
 * User:Jarekt - original version

-- ================================================== -- === Internal functions =========================== -- ==================================================

--- local function isodate2timestamp(dateStr) -- convert isodate to timestamp used by quick statements local tStamp = nil if string.match(dateStr,"^[0-1]%d%d%d$") then              -- if YYYY  format tStamp = '+' .. dateStr .. '-00-00T00:00:00Z/9' elseif string.match(dateStr,"^[0-1]%d%d%d%-[0-1]%d$") then     -- if YYYY-MM format tStamp = '+' .. dateStr .. '-00T00:00:00Z/10' elseif string.match(dateStr,"^[0-1]%d%d%d%-[0-1]%d%-[0-3]%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 nowiki(str) -- remove all the links if not str then return str end str = mw.ustring.gsub(str, '% [^%<]+%', '') str = mw.ustring.gsub(str, '%', '') 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, "%[[^ ]+ ", "")  -- remove URL links, like ""	str = mw.ustring.gsub(str, "%[%[", "" )      -- remove piped links, like "[["	str = mw.ustring.gsub(str, "%", "" )        -- remove piped links, like "]" or "]]"	return str end

local function nowiki_title(str) -- remove all the links and url encode some characters if not str then return str end str = mw.ustring.gsub(str, "%)", "%%29" )   -- encode parenthesis	str = mw.ustring.gsub(str, "%(", "%%28" )    -- encode parenthesis str = mw.ustring.gsub(str, " ", " " )       -- multi-space to a single one str = mw.ustring.gsub(str, " ", "%%20" )    -- encode parenthesis return nowiki(str) 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 elseif val.amount then val = tonumber(val.amount) 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 cell. if IDs of 2 fields ar the same than we ignore the second one --   - wrapper  - some fields need a wrapper around the field content -- ====================================================================

--All other fields local function Build_html_row(param, args) local LUT = {artwork=0, photograph=1, book=2} local demo = args.demo and bit32.extract( param.demo or 0, LUT[args.infobox])==1 local field = args[param.field] if field=='' then field=nil; end if not (field or 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 string.match(tag, "^[QP]%d+$") then tag = getLabel(tag, args.lang, "-", "ucfirst") elseif labels[tag] then tag = core.langSwitch(labels[tag], args.lang) end local cell1 = string.format('%s \n', param.id, args.lang, tag) local cell2 = string.format(' \n'.. param.wrapper ..' ', field or '') return string.format(' \n%s%s\n \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

-- original_description row has a different look than other rows if args.original_description and (args.original_description_info or args.biased) then local tag1, tag2 = "", "" if args.original_description_info then tag1 = string.format(' %s ', dir, args.original_description_info) end if args.biased then tag2 = core.langSwitch(labels.inaccurate_description, args.lang) tag2 = string.format(' %s: %s ', tag2, args.biased) end args.original_description = tag1 .. tag2 .. args.original_description end -- files with no source will be flagged if (not args.source) and (not args.source_) and (args.strict==true) 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 = args.demo_image end if args.image then nCol = 3 end -- Top line local top, results = {}, {} if args.name then table.insert(top, string.format(' %s\n ', args.name ) ) end if args.linkback then -- Wikidata Link table.insert(top, string.format('', args.linkback, args.linkback) ) end if args.wikidata then -- Wikidata Link table.insert(top, string.format('', args.wikidata, args.wikidata) ) table.insert(top, string.format('', args.wikidata, args.wikidata) ) end if args.wikisource then --Wikisource link table.insert(top, string.format('', args.wikisource, args.wikisource) ) end if args.wikiquote then --Wikiquote link table.insert(top, string.format('', args.wikiquote, args.wikiquote) ) end if args.QS then -- quick_statement link to upload missing info to wikidata table.insert(top, string.format('%s', args.QS) ) end if #top>0 then local line = string.format('%s ', nCol, table.concat(top, ' ')) table.insert(results, string.format(' \n%s\n \n', line)) end -- Permissions tag 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 (%s) ", tag1, tag2, tag3) -- define constants for readability -- demo=art+photo+book will show that row in demo mode in {{artwork}, and  templates local none = 0 local art  = 1 local photo = 2 local book = 4 -- add other fields 'author_of_foreword', 'author_of_afterword' local param = { -- field name                  machine readable tag                         field name i18n approach                     show in demo mode? field value wrapper {field='artist'             , id='fileinfotpl_aut'                       , tag='wm-license-artwork-artist',             demo=art,            wrapper=' \n%s '}, {field='author'             , id='fileinfotpl_aut'                       , tag='wm-license-information-author',         demo=          book, wrapper=' \n%s '}, {field='editor'             , id='fileinfotpl_book_editor'               , tag='wm-license-book-editor',                demo=          book, wrapper=' \n%s '}, {field='translator'         , id='fileinfotpl_book_translator'           , tag='wm-license-book-translator',            demo=          book, wrapper=' \n%s '}, {field='illustrator'        , id='fileinfotpl_book_illustrator'          , tag='wm-license-book-illustrator',           demo=          book, wrapper=' \n%s '}, {field='author_of_foreword' , id='fileinfotpl_aut'                       , tag='P2679',                                 demo=          book, wrapper=' \n%s '}, {field='author_of_afterword', id='fileinfotpl_aut'                       , tag='P2680',                                 demo=          book, wrapper=' \n%s '}, {field='architect'          , id='fileinfotpl_aut'                       , tag='Q42973',                                demo=none,           wrapper=' \n%s '}, {field='designer'           , id='fileinfotpl_aut'                       , tag='Q5322166',                              demo=none,           wrapper=' \n%s '}, {field='photographer'       , id='fileinfotpl_aut'                       , tag='Q33231',                                demo=    photo,      wrapper=' \n%s '}, {field='other_fields_1'}, -- title & desctiption block {field='title'              , id='fileinfotpl_art_title'                 , tag='wm-license-artwork-title',              demo=art+photo+book, wrapper=' \n%s '}, {field='subtitle'           , id='fileinfotpl_book_subtitle'             , tag='wm-license-book-subtitle',              demo=          book, wrapper='%s'}, {field='series_title'       , id='fileinfotpl_book_series-title'         , tag='wm-license-book-series-title',          demo=          book, wrapper='%s'}, {field='volume'             , id='fileinfotpl_book_volume'               , tag='wm-license-book-volume',                demo=          book, wrapper='%s'}, {field='edition'            , id='fileinfotpl_edition'                   , tag='wm-license-book-edition',               demo=          book, wrapper='%s'}, {field='publisher'          , id='fileinfotpl_book_publisher'            , tag='wm-license-book-publisher',             demo=          book, wrapper=' \n%s '}, {field='printer'            , id='fileinfotpl_book_printer'              , tag='wm-license-book-printer',               demo=          book, wrapper=' \n%s '}, {field='object_type'        , id='fileinfotpl_art_object_type'           , tag='object_type',                           demo=art,            wrapper='%s'}, {field='genre'              , id='fileinfotpl_art_genre'                 , tag='Q483394',                               demo=          book, wrapper='%s'}, {field='original_description', id='fileinfotpl_desc'                     , tag='original_description',                  demo=    photo,      wrapper=' \n%s '}, {field='description'        , id='fileinfotpl_desc'                      , tag='wm-license-information-description',    demo=art+photo+book, wrapper=' \n%s '}, {field='pageoverview'       , id='fileinfotpl_book-page-overview'        , tag='wm-license-book-page-overview',         demo=none,           wrapper='%s'}, {field='depicted_people'    , id='fileinfotpl_art_depicted_people'       , tag='depicted_people',                       demo=art+photo,      wrapper='%s'}, {field='depicted_place'     , id='fileinfotpl_art_depicted_place'        , tag='depicted_place',                        demo=art+photo,      wrapper='%s'}, {field='depicted_part'      , id='fileinfotpl_art_depicted_part'         , tag='P5961',                                 demo=art+photo+book, wrapper='%s'}, {field='language'           , id='fileinfotpl_book_language'             , tag='wm-license-book-language',              demo=          book, wrapper='%s'}, {field='other_fields_2'}, -- date, object outside description, history, etc.		{field='date'               , id='fileinfotpl_date'                      , tag='wm-license-information-date',           demo=art+photo,      wrapper='%s'}, {field='publication_date'   , id='fileinfotpl_publication_date'          , tag='P577',                                  demo=          book, wrapper='%s'}, {field='medium'             , id='fileinfotpl_art_medium'                , tag='wm-license-artwork-medium',             demo=art+photo,      wrapper='%s'}, {field='dimensions'         , id='fileinfotpl_art_dimensions'            , tag='wm-license-artwork-dimensions',         demo=art+photo,      wrapper='%s'}, {field='institution'        , id='fileinfotpl_art_gallery'               , tag='Q2668072',                              demo=art+photo,      wrapper='%s'}, {field='department'         , id='fileinfotpl_art_location'              , tag='wm-license-artwork-current-location',   demo=art+photo     , wrapper=' \n%s '}, {field='id'                 , id='fileinfotpl_art_id'                    , tag='wm-license-artwork-id',                 demo=art+photo,      wrapper=' \n%s '}, {field='coordinates'        , id='fileinfo-paramfield'                   , tag='ObjectLocation',                        demo=art+photo,      wrapper='%s'}, {field='place_of_publication', id='fileinfotpl_book_place-of-publication' , tag='wm-license-book-place-of-publication', demo=          book, wrapper='%s'}, {field='place_of_creation'  , id='fileinfotpl_art_creation_place'        , tag='place_of_creation',                     demo=art,            wrapper='%s'}, {field='place_of_discovery' , id='fileinfotpl_art_discovery_place'       , tag='place_of_discovery',                    demo=art,            wrapper='%s'}, {field='object_history'     , id='fileinfotpl_art_object_history'        , tag='wm-license-artwork-object-history',     demo=art,            wrapper='%s'}, {field='exhibition_history' , id='fileinfotpl_art_exhibition_history'    , tag='exhibition_history',                    demo=art+photo,      wrapper='%s'}, {field='credit_line'        , id='fileinfotpl_art_credit_line'           , tag='wm-license-artwork-credit-line',        demo=art,            wrapper='%s'}, {field='inscriptions'       , id='fileinfotpl_art_inscriptions'          , tag='wm-license-artwork-inscriptions',       demo=art,            wrapper='%s'}, {field='notes'              , id='fileinfotpl_art_notes'                 , tag='wm-license-artwork-notes',              demo=art+photo,      wrapper='%s'}, {field='other_fields_3'}, -- references, and sources {field='references'         , id='fileinfotpl_art_references'            , tag='wm-license-artwork-references',         demo=art+photo+book, wrapper='%s'}, {field='authority'          , id='fileinfotpl_art_authority'             , tag='Q36524',                                demo=none,           wrapper='%s'}, {field='source'             , id='fileinfotpl_src'                       , tag='wm-license-artwork-source',             demo=art,            wrapper='%s'}, -- source/photographer {field='source_'            , id='fileinfotpl_src'                       , tag='wm-license-information-source',         demo=    photo+book, wrapper='%s'}, -- source {field='nosource'           , id='fileinfotpl_nosrc'                     , tag='wm-license-information-source',         demo=none,           wrapper='%s'}, {field='permission'         , id='fileinfotpl_perm'                      , tag=permission_tag,                          demo=art+photo+book, wrapper='%s'}, {field='other_versions'     , id='fileinfotpl_ver'                       , tag='wm-license-information-other-versions', demo=art+photo+book, wrapper='%s'}, {field='other_fields'}, {field='camera_coord'}, }	for i=1,#param do		table.insert(results, Build_html_row(param[i], args)) end -- add material on the right: image, wikisource icon, etc.	if args.image then if args.image_page and args.image then -- page parameter for DjVu and PDF files args.image = string.format('%s|page=%i', args.image, args.image_page) end if args.infobox=='book' then -- page parameter for DjVu and PDF files tag1 = mw.message.new( 'wm-license-book-start-this-book' ):inLanguage(args.lang):plain tag2 = string.format('|thumb|%s', args.image, tag1) else tag2 = '' end local field = string.format(, args.image, args.name or , tag2) local nRow = #results -- number of rows below local line = string.format(' %s  \n\n', nRow, field) results[2] = mw.ustring.gsub(results[2], " %s*$", line); -- attach image section to the right side of the table, by attaching to row #2 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(' \n', style, table.concat(results)) -- combine "results", an array of strings into a single string results = string.format(' \n%s\n \n', results) return results end

local function verify_input_parameters(args0) local cats = '' -- categories -- add category, if some parameter not on the following list is used local fields = { 'title', 'object_type', 'description', 'date', 'medium', 'permission', 'artist', 'author', 'architect', 'designer', 'illustrator', 'publisher', 'editor', 'translator', 'printer', 'photographer', 'dimensions', 'institution', 'department',  'references', 'object_history', 'genre', 'exhibition_history', 'credit_line', 'other_versions', 'source', 'strict', 'inscriptions', 'notes', 'linkback', 'camera_coord', 'other_fields', 'other_fields_1', 'other_fields_2', 'other_fields_3', 'demo', 'id', 'wikidata', 'year', 'homecat', 'authority', 'place_of_creation', 'place_of_discovery', 'source_', 'wikidata_cat', 'namespace', 'lang', 'image', 'noimage', 'depicted_people', 'depicted_place', 'original_description_info', 'original_description', 'biased', 'photo_date', 'infobox', 'place_of_publication', 'publication_date', 'language', 'subtitle', 'series_title', 'volume', 'edition', 'edition_of', 'pageoverview', 'wikisource', 'wikiquote', 'demo_image', 'image_page', 'depicted_part', 'mimeType', 'num_pages', 'author_of_foreword', 'author_of_afterword', 'infobox'} local set = {} for _, field in ipairs(fields) do set[field] = true end for field, _ in pairs( args0 ) do 		if not set[field] then local LUT = {artwork='Artwork', photograph='Photograph', book='Book'} local infobox = LUT[args0.infobox] cats = cats .. ''			cats = cats .. string.format('\n; Error in template: unknown parameter "%s". ', infobox, infobox, field) end end return cats 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       === -- =========================================================================== 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 if args0.namespace==0 and mw.ustring.sub(args0.pagename,1,8) == "Artwork:" then cats = cats .. '\n' if args.homecat then cats = cats .. '\n' end end -- add categories related to accession number for artworks if args0.id and args0.infobox=='artwork' then local sortkey = nowiki(args0.id) -- strip any links that might be there if #sortkey>30 then sortkey = 'zzz' end cats = string.format('%s\n', cats, sortkey) end

-- add categories related to template:book transcluded into template for specific book if args0.infobox=='book' and args0.namespace==10 then cats = cats .. '\n' -- add homecat category if args0.homecat~='~' then local page = {} if args0.homecat then cats = string.format('%s\n',cats, args0.homecat) page = mw.title.new( args0.homecat, 'category' ) end if not page or not page.exists or not args0.homecat then cats = cats .. '\n' end end end -- add invisible template tags based on book's date of publication if args0.infobox=='book' then local pubYear = args.publication_year if pubYear then local curYear = tonumber(os.date('!*t').year) -- current year if pubYear<year-95 then mw.getCurrentFrame:expandTemplate{ title ='Books published more than 95 years ago' } end if pubYear<year-200 then mw.getCurrentFrame:expandTemplate{ title ='Works created more than 200 years ago' } end 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 local OK = ((args0.infobox=='artwork' or args0.infobox=='photograph') and (args0.namespace==6 or args0.namespace==14)) -- artworks and photographs can be in file or category namespace or (args0.infobox=='book' and (args0.namespace==10 or args0.namespace==14) ) -- books can be in template or category namespace or (args0.infobox=='book' and args0.namespace==6 and (args0.mimeType=='application/pdf' or args0.mimeType=='image/vnd.djvu')) -- books can also be in file namespace if it is PDF or DjVu

if ( not OK or (args0.wikidata_cat==false)) then -- continue only if the namespace is a Category or file return cats, args1 end local LUT = {artwork='Artworks', photograph='Photographs', book='Books'}

-- skip the rest if no item ID	if not args0.wikidata then local TypeLUT = {['grave']='Graves', ['tomb']='Graves', ['funeral chapel']='Graves', ['funeral niche']='Graves', ['painting']='Paintings' } local oType = TypeLUT[string.lower(args0.object_type or '')] or LUT[args0.infobox] cats = string.format('%s\n', cats, oType) return cats, args1 end --=======================================================================================================	--=== Categories and files with template linked to Wikidata item below --=======================================================================================================	-- setup QuickStatements local qsTable = {} -- table to store QuickStatements -- default QuickStatements command local today = '+' .. os.date('!%F') .. 'T00:00:00Z/11' -- today's date in QS format local fname = '"https://commons.wikimedia.org/wiki/File:' .. string.gsub(args0.pagename,' ','_') .. '"' local source = '|S143|Q565|S813|' .. today .. '|S4656|' .. fname local qsCommand1 = '%s|%s|%s' .. source local qsCommand2 = '%s|%s' .. source

cats = string.format('%s\n', cats, LUT[args0.infobox], 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),  polyptych (Q1278452),  diptych (Q475476),  triptych (Q79218)  } -- good {Q199414='bog body', Q7881='skeleton'} -- one of those overwrites "bad" flag so 'human' & 'bog body' is OK	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, Q1278452=2, Q475476=2, Q79218 = 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', cats, LUT[args0.infobox], args0.wikidata) break elseif v==3 then bad = false break end end if bad then cats = string.format('%s\n', cats, LUT[args0.infobox], args0.wikidata) end end -- local fields which are missing on Wikidata local fields = {'date', 'publication_date', 'medium', 'dimensions', 'image', 'institution', 'author', 'artist'} for _, field in ipairs( fields ) do		if not data[field] and args0[field] and not string.match(args0[field], '% Unknown '..field..'<%/div%>') then comp[field] = 'missing' end end if not data.id and args0.id then comp['accession number'] = 'missing' local id = nowiki(args0.id) -- strip any links that might be there if args0.institution_id and #id<20 then table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P217', '"' .. id.. '"|P195|'..args0.institution_id) ) end end if comp.artist=='missing' and string.match(args0.artist, '% Unknown a%w+%<%/div%>') then comp.artist = nil -- ignore artist 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 (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 local ext = string.lower(string.sub(args0.image,-4)) if (ext=='.pdf' or ext =='djvu') and args0.image_page then table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P996', '"' .. args0.image.. '"|P4714|'.. tostring(args0.image_page)) ) elseif (ext=='.pdf' or ext =='djvu') then table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P996', '"' .. args0.image.. '"') ) else table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P18', '"' .. args0.image.. '"') ) end comp.image = 'missing' elseif (not data.image and args0.namespace==6 and args0.num_pages>1 and (args0.mimeType=='application/pdf' or args0.mimeType=='image/vnd.djvu')) then -- QS code to help transfer image to Wikidata if args0.image_page then table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P996', '"' .. args0.pagename.. '"|P4714|'.. tostring(args0.image_page)) ) else table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P996', '"' .. args0.pagename.. '"') ) end comp.image = 'missing' elseif (not data.image and args0.namespace==6 and args0.num_pages==1 and args0.infobox=='artwork') then -- QS code to help transfer image to Wikidata table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P18', '"' .. args0.pagename.. '"') ) comp.image = 'missing' 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 if args0['date'] and string.find(args0['date'], '% era QS:([^%<]+)%') 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 currectly in some templates like institution in book template and are not alowed to create QS	local fields = {object_type='artwork', era='artwork', medium='artwork', dimensions='artwork', institution='artwork', artist='artwork', reference_wga='artwork', date='all' , language='book', author='book', translator='book', publisher='book', printer='book', illustrator='book', editor='book', publication_date='book'} for field, infobox in pairs( fields ) do		if args0[field] and not data[field] and (args0.infobox==infobox or infobox=='all') then local pat = '% '..field..' QS:([^%<]+)%' local qs = string.match(args0[field], pat) -- find hidden tag with QS code local _, nMatch = string.gsub(args0[field], pat, "") -- count matches 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 "Commons Category" (P373) if template at category page if not data.homecat and args0.namespace==14 then table.insert( qsTable, string.format(qsCommand1, args0.wikidata, 'P373', '"' .. args0.pagename.. '"' )) end -- Special case of QS codes for multilingual labels extracted from and  templates, etc.	if args0.title then local max_title_len = 100 -- strip titles from title field with template: local pat = '% title QS:P1476,((%w+):[^%<]+)%' for label, lang in mw.ustring.gmatch(args0.title, pat) do			label = nowiki_title(label) if not data.title_[lang] and #label' for lang, label in mw.ustring.gmatch(args0.title, pat) do			label = nowiki_title(label) if not(data.labels and data.labels[lang]) and #labelFrançais : Les bateaux rouges, Argenteuil --pat = '%% *([^%<]+)%' pat = '% *([^%<]+)%' for lang, label in mw.ustring.gmatch(args0.title, pat) do			label = nowiki_title(label) if not(data.labels and data.labels[lang]) and #label<max_title_len then table.insert( qsTable, string.format('%s|%s|"%s"', args0.wikidata, 'L'..lang, label) ) end end end -- add categories related to accession number for artworks if not args0.id and data.id and args0.infobox=='artwork' then cats = string.format('%s\n', cats, args0.wikidata) cats = string.format('%s\n', 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', cats, LUT[args0.infobox], 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 qsWrapper = ' ' QS = table.concat( qsTable, '||')   -- combine multiple statements into a single command separated by \n (line feed) QS = mw.ustring.gsub (mw.uri.encode(QS),'%%2520','%%20') QS = 'https://quickstatements.toolforge.org/#/v1=' .. QS   -- create full URL link QS = mw.ustring.format(qsWrapper, QS)    -- use URL as a link accessed by clicking Wikidata icon cats = string.format('%s\n', cats, LUT[args0.infobox]) end args1.QS = QS; return cats, 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      === -- =========================================================================== local function harvest_SDC(args0, lang)

local bookFlag = (args0.infobox=='book' and (args0.mimeType=='application/pdf' or args0.mimeType=='image/vnd.djvu')) local sdc = {} -- structure similar to "args" but filled with SDC data local cats = '' local entity = mw.wikibase.getEntity if not entity then if args0.wikidata and bookFlag then cats = cats .. '\n' elseif args0.wikidata and args0.infobox~='book' then cats = cats .. '\n' end return sdc, cats end local property = {P6243='wikidata', P4714='image_page' } for prop, field in pairs( property ) do		sdc[field] = getProperty(entity, prop, 'one') end -- get wikidata item ID from P6243 if sdc.wikidata then local wEntity = mw.wikibase.getEntity(sdc.wikidata) if wEntity.id~=sdc.wikidata then cats = cats .. ''		end end if not sdc.wikidata and args0.wikidata then if bookFlag then cats = cats .. '\n' elseif args0.infobox~='book' then cats = cats .. '\n' end elseif sdc.wikidata and args0.wikidata and sdc.wikidata~=args0.wikidata then cats = cats .. '\n' end -- get source from P7482 if entity.statements and entity.statements.P7482 then local statement = entity.statements.P7482[1] if statement.mainsnak.datavalue.value.id=='Q74228490' and statement.qualifiers and statement.qualifiers.P973 then local url = statement.qualifiers.P973[1].datavalue.value if statement.qualifiers.P137 then local id = statement.qualifiers.P137[1].datavalue.value.id				local label = 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 return sdc, 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      === -- =========================================================================== local function harvest_wikidata(itemID1, itemID2, lang, namespace, infobox) local data = {} -- structure similar to "args" but filled with wikidata data local cats = '' local frame = mw.getCurrentFrame local entity = nil local itemID = itemID1 or itemID2 if mw.wikibase and itemID then local LUT = {artwork='Artworks', photograph='Photographs', book='Books'} entity = mw.wikibase.getEntity(itemID) if not entity then cats = string.format('', LUT[infobox]) elseif entity.id~=itemID and itemID1 then cats = string.format('', LUT[infobox]) end end if not entity then return data, cats end

-- inception date: translated date and year number local d = getDate(entity, 'P571', lang) -- inception date if d.str then 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 local d = getDate(entity, 'P577', lang) -- publication date if d.str then 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 local Debug ={} local property = {P10='video', P18='image', P996='scan', P4896='model3D', P373='homecat', P2093='authorStr', P393='edition', P4714='image_page', P1957='wikisource_index', P7420='framed_image' } for prop, field in pairs( property ) do		data[field] = getProperty(entity, prop, 'one') end data.image = data.image or data.scan or data.video or data.model3D or data.framed_image data.image_page = tonumber(data.image_page) if data.edition then 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) local property = { P189='place_of_discovery', P2079='technique', P123='publisher', P872='printer', P136='genre', P921='subject', P179='series_title', P291='place_of_publication', P407='language', P629='edition_of'} for prop, field in pairs( property ) do		local id = getProperty(entity, prop, 'one') if id then data[field] = getLabel(id, lang, "wikipedia") .. core.editAtWikidata(entity.id, prop, lang) end end -- harvest Q-code properties which are than converted from Q-number to labels (pick all) local property = { P31='object_type', P407='language'} for prop, field in pairs( property ) do		local ids = getProperty(entity, prop, 'all') if ids then local T = {} for _, id in ipairs( 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 = getProperty(entity, 'P2348', 'all') if data.era_id then local periodSpan = require('Module:Period')._periodSpan local T = {} for _, id in ipairs( data.era_id ) do			local eraText = getLabel(id, lang) local spanText = periodSpan(id, lang) if spanText then eraText = eraText .. ' ' .. spanText end table.insert(T, eraText) end data.era = table.concat(T, " / ") .. core.editAtWikidata(entity.id, 'P2348', lang) end if data.era and data.date then data.date = data.date .. " " .. data.era elseif data.era and not data.date then data.date = data.era end -- get author and/or author creator template local property = { P170='creator', P50='author', P84='architect', P287='designer', P98='editor', P655='translator', P110='illustrator', P2679='author_of_foreword', P2680='author_of_afterword' } for prop, field in pairs( property ) do		local d = Art.get_creator(entity, prop, lang) data[field] = d.str data[field.."_id"] = d.id	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', P1680='subtitle'} local property = { P1476 = 'title', P1680='subtitle'} 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] = core.langSwitch(title, lang) end if field=='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 = {} if entity.labels then for lang, val in pairs(entity.labels) do -- loop over all labels data.labels[lang] = val.value; data.label = data.label or data.labels[lang] -- no label in prefered language so grab any label end end -- get authority control (rarely used for artworks) local AC_cats data.authority, AC_cats = authorityControl(entity, {wikidata = itemID}, 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 -- get object location if getProperty(entity, 'P625', 'one') then local coorFun = require('Module:Coordinates')._LocationTemplateCore local coori18n = require('Module:i18n/coordinates') labels.ObjectLocation = coori18n.ObjectLocation data.coordinates = coorFun({wikidata=entity, lang=lang, globe='earth', mode='object', bare=true}) end -- prepare fallback list of languages local langList = mw.language.getFallbacksFor(lang) table.insert(langList, 1, lang) -- get wikisource or wikiquote local projects = {s='wikisource', q='wikiquote'} for code, project in pairs(projects) do		local sitelinks = getSitelinks(entity, project) if sitelinks then local lng, _ = 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 _, language in ipairs(langList) do 				local sitelink = sitelinks[language] if sitelink then 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.wikisource or data.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) or data.technique; data.references        = Art.get_references(entity, lang) data.reference_wga     = data.references and mw.ustring.isutf8(data.references) and mw.ustring.find( data.references, 'www%.wga%.hu' ) -- is there a link to wga.hu? data.depicted_people   = Art.get_depicted_people(entity, lang) local 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

-- =========================================================================== -- === Adjust parameters related to books  === -- === and resolve potential aliases                                      === -- === INPUTS:                                                            === -- === * frame - contains imput parameters passed from the template       === -- === OUTPUTS:                                                           === -- === * args - cleaned up inputs                                         === -- =========================================================================== local function header_customization(args0, data, args1)

-- get author wikidata ID based on wikidata local creator_label, creator_id, title_label = nil, nil, nil if args0.wikidata then creator_id = data.creator_id or data.author_id or data.architect_id or data.designer_id or data.editor_id or data.translator_id or data.illustrator_id title_label = data.label -- create name based on wikidata label end

-- get author wikidata ID based on commons if not creator_id then if args0.infobox=='artwork' then creator_id = args0.artist_id or args0.author_id elseif args0.infobox=='photograph' then creator_id = args0.photographer_id or args0.author_id elseif args0.infobox=='book' then creator_id = args0.author_id end end -- convert wikidata ID to a label if creator_id and creator_id:match("^Q%d+$") then creator_label = getLabel(creator_id, args0.lang) elseif creator_id then -- if author was "" than creator_id will be "Q4233718,P1776,Q446631" local res = {creator_id:match("^Q4233718,(P%d+),(Q%d+)$")} if res and res[1] and res[2]then creator_label = getLabel(res[2], args0.lang) local LUT = {P1773='attributed to', P1774='workshop of', P1775='follower of', P1776='circle of', P1777='manner of', P1779='possibly', P1780='school of', P1877='after'} creator_label = alterName(LUT[res[1]], creator_label, args0.lang) -- call module:Name with the task if creator_label == "name not supported" then creator_label = nil end else creator_label = creator_id end end -- scrape labels from template if not title_label and args0.title then local labels = {} local pat = '% label QS:L(%w+),"([^%<]+)"%' for lang, label in mw.ustring.gmatch(args0.title, pat) do			labels[lang]=label end title_label = core.langSwitch(labels,args0.lang) end -- get title based on commons if not title_label and args0.title then title_label = nowiki(args0.title) end -- if title too long than truncate it	if title_label and #title_label>250 then title_label = nil end if creator_label and #creator_label>150 then creator_label = nil end -- combing author and title labels if creator_label and title_label then local colon = 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 template in file namespace and file of in PDF or DjVu than use it as image if args0.infobox=='book' and args0.namespace==6 and args1.image==nil and (args0.noimage==false or args1.image_page) and (args0.mimeType=='application/pdf' or args0.mimeType=='image/vnd.djvu') then args1.image = args0.pagename end

return args1 end

-- =========================================================================== -- === Read input "frame", normalize input parameters (lower case, etc.)  === -- === and resolve potential aliases                                      === -- === INPUTS:                                                            === -- === * frame - contains imput parameters passed from the template       === -- === OUTPUTS:                                                           === -- === * args - cleaned up inputs                                         === -- =========================================================================== local function read_input_parameters(frame) -- switch to lowercase parameters to make them case independent local args = core.getArgs(frame) -- resolve aliases args.permission = args.permission or args.license 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.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.history, args.license = nil, nil, nil, nil -- ensure the right format args.wikidata_cat = core.yesno(args.wikidata_cat, true) args.strict      = core.yesno(args.strict, true) args.noimage     = core.yesno(args.noimage, false) args.image_page  = tonumber(args.image_page) if args.language and #args.language==2 then args.language = frame:callParserFunction( "#language", { args.language, args.lang } ) -- get language of the written work end return args end

-- ================================================== -- === External functions =========================== -- ================================================== local p = {}

-- =========================================================================== -- === Version of the function to be called from other LUA codes -- =========================================================================== function p.create_infobox(args0) local lang = args0.lang -- user's language local cats, cats2 = ,         -- categories local str, data, sdc -- ===========================================================================	-- === Step 1: clean up of template arguments "args0" -- ===========================================================================	local page = mw.title.getCurrentTitle args0.namespace  = page.namespace   -- get page namespace args0.url        = page:canonicalUrl args0.pagename   = page.text if args0.namespace==6 then -- file namespace args0.mimeType = page.file.mimeType args0.num_pages = 1 if page.file.pages then args0.num_pages = #page.file.pages -- in case of DjVu or PDF files count pages end end if args0.date then args0.year = empty2nil(ISOdate._ISOyear(args0.date)) -- get year end -- for places run them through template local fields = { 'depicted_people', 'depicted_place', 'place_of_discovery'	} for _, field in ipairs( fields ) do 		if args0[field] and not string.find(args0[field], ' ') then args0[field] = City._city(args0[field], lang) -- single word depicted_people will get a link end end -- for dates run them through template and add invisible QS tag if possible local fields = { 'date', 'publication_date'} for _, field in ipairs( fields ) do 		if args0[field] then local val = isodate2timestamp(args0[field])        -- if date is in YYYY, YYYY-MM or YYYY-MM-DD formats than it will be saved args0[field] = ISOdate._ISOdate(args0[field], lang) -- apply ISODate to function to date string to convert date in ISO format to translated date string if val then                                        -- if date is in ISO format than add an invisible tag which will be used to potentially add this date to QS used to move it to Wikidata args0[field] = string.format('%s date QS:P,%s ', args0[field], val) end end end -- collapse local and  templates and extract item ID from them local fields = {author='creator', artist='creator', photographer='creator', architect='creator', printer='creator', designer='creator', editor='creator', translator='creator', illustrator='creator', institution='institution'} for field, keyword in pairs( fields ) do 		if args0[field] then args0[field] = mw.ustring.gsub (args0[field], 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"') local pat = '% '.. keyword ..' QS:P%d+,([^%<]+)%</div%>' --local pat = '% '.. keyword ..' QS:P%d+,(Q%d+)%</div%>' local _, nMatch = string.gsub(args0[field], pat, "") if nMatch==1 then -- if multiple templates than skip args0[field..'_id'] = mw.ustring.match(args0[field], pat) args0[field]       = string.gsub(args0[field], '% '.. keyword ..' QS:P', ' '.. field ..' QS:P') end end end -- in case of invisible QS tags add correct property based on which field and infobox it come from local repList = { {'author', 'book',  'creator QS:P170,', 'author QS:P50,'}, {'illustrator',     'book',       'creator QS:P170,', 'illustrator QS:P110,'}, {'editor',          'book',       'creator QS:P170,', 'editor QS:P98,'}, {'translator',      'book',       'creator QS:P170,', 'translator QS:P655,'}, {'printer',         'book',       'creator QS:P170,', 'printer QS:P872,'}, {'publication_date', 'book',      'date QS:P,',       'publication_date QS:P577,'}, {'date',            'photograph', 'date QS:P,',       'date QS:P571,'}, {'date',            'artwork',    'date QS:P,',       'date QS:P571,'}} for _, repItem in ipairs( repList ) do		local field, infobox, oldStr, newStr = unpack(repItem) if args0[field] and args0.infobox==infobox then args0[field] = string.gsub(args0[field], oldStr, newStr) end end if args0.source and mw.ustring.find( args0.source, 'www%.wga%.hu' ) then -- code to help copy links to www.wga.hu to wikidata args0.reference_wga = string.gsub(args0.source, 'http://www%.wga%.hu', 'https://www.wga.hu') end -- ===========================================================================	-- === Step 2: one by one merge wikidata and creator data -- ===========================================================================	local wikidata_temp = args0.wikidata -- wikidata from template sdc = {} if args0.namespace==6 then -- if file namespace sdc, cats2 = harvest_SDC(args0, lang) -- harvest Structured Data on Commons if (args0.infobox=='photograph' and args0.demo_image=='Breezeicons-actions-22-view-preview.svg' and args0.wikidata_cat==false) then -- get wikidata from SDC only if this is NOT the photograph infobox of template sdc.wikidata = nil end args0.source_   = args0.source_    or sdc.source_    -- if source not provided than get it from SDC args0.wikidata  = args0.wikidata   or sdc.wikidata   -- if wikidata not provided than get it from P6243 ("digital representation of") args0.image_page = args0.image_page or sdc.image_page -- title image page for multipage book files end data, cats = harvest_wikidata(wikidata_temp, sdc.wikidata, lang, args0.namespace, args0.infobox) cats = (cats or '') .. (cats2 or '') -- based on the template type determine the meaning of "creator" if args0.infobox=='photograph' then data.photographer, data.photographer_id = data.creator, data.creator_id elseif args0.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) local args = {} local fields = { 'artist', 'artist_id', 'author', 'author_id', 'architect', 'designer', 'illustrator', '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' }	for _, field in ipairs( fields ) do 		args[field] = args0[field] or data[field] end -- copy fields only defined locally local fields = { 'wikidata', 'description', 'original_description_info', 'original_description', 'biased', 'camera_coord', 'other_versions', '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', 'depicted_part' }	for _, field in ipairs( fields ) do 		args[field] = args0[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 cats = cats .. '\n' end if args0.infobox=='artwork' and args0.photo_date and args0.photographer then cats = cats .. '\n' end if args0.infobox=='book' and args0.publication_date and data.date then -- 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 -- internationalize local object_type string if args0.object_type and args.object_type==args0.object_type then local objectType = require('Module:I18n/objects')._object args.object_type = objectType(args.object_type, nil, lang) 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 -- ===========================================================================	args = header_customization(args0, data, args) cats = cats .. add_maintenance_categories(args0, args) -- If institution namespace than add maintenance categories args.QS = nil; cats2, args = add_wikidata_maintenance_categories(args0, args, data) cats = cats .. cats2 if not sdc.wikidata and args0.wikidata and (args.namespace==6) then local oType = string.lower(args.object_type or '') if string.find(oType, '[Pp]ainting') then cats = cats .. '\n' end end

local results = build_html(args, cats) return results, cats end

-- =========================================================================== -- === Versions of the function to be called from template namespace -- === Each template with it's own entry point -- =========================================================================== function p.artwork(frame) local args = read_input_parameters(frame) args.infobox = 'artwork' local cats0 = verify_input_parameters(args) args.demo_image = 'Noun project - Mona Lisa - in frame.svg' local results, cats1 = p.create_infobox(args) -- call the inner "core" function return results .. cats0 .. cats1 end

function p.photograph(frame) local args = read_input_parameters(frame) args.infobox = 'photograph' local cats0 = verify_input_parameters(args) args.source_ = args.source or args.source_ args.source = nil args.demo_image = 'Breezeicons-actions-22-view-preview.svg' local results, cats = p.create_infobox(args) -- call the inner "core" function -- most photographs do not have wikidata id so do not botter cats = mw.ustring.gsub(cats,'%\n%[%[Category:Photographs without Wikidata item%]%]','') return results .. cats end

function p.art_photo(frame) local args = read_input_parameters(frame)	-- clean up input parameters args.permission = args.permission or args.photo_license or args.photo_licence  -- additional aliases args.artwork_license = args.artwork_license or args.artwork_licence args.source = args.source or args.source_ args.photo_license, args.photo_licence, args.artwork_licence, args.source_ = nil, nil, nil, nil local results = {} -- split input arguments local args2 = {} local fields = {['date']='photo_date', title='photo_title', description='photo_description', medium='photo_medium', dimensions='photo_dimensions', institution='photo_institution', department='photo_department', id='photo_accession_number', photographer='photographer', inscriptions='photo_inscriptions', source='source', other_versions='other_versions', other_fields ='other_fields', permission='photo_license', permission='permission' }	for field1, field2 in pairs( fields ) do 		if args[field2] then args2[field1] = args[field2] args [field2] = nil end end for _, field in ipairs( {'lang', 'namespace', 'url', 'pagename'} ) do 		args2[field] = args[field] end args.permission = args.artwork_license args.artwork_license = nil

-- create object infobox args.infobox = 'artwork' local cats0 = verify_input_parameters(args) local header = frame:expandTemplate{ title = 'Section header', args = { ["1"]=args.artwork_header or 'Object', lang=args.lang } } table.insert(results, "===" .. header .. "===") args.demo_image = 'Noun project - Mona Lisa - in frame.svg' args.strict = false local infobox, cats1 = p.create_infobox(args) -- call the inner "core" function table.insert(results, infobox) --create photograph infobox args2.infobox = 'photograph' local cats2 = verify_input_parameters(args2) header = frame:expandTemplate{ title = 'Section header', args = { ["1"]='Photograph', lang=args.lang } } table.insert(results, "===" .. header .. "===") args2.demo_image = 'Breezeicons-actions-22-view-preview.svg' args2.wikidata_cat = false local infobox, cats3 = p.create_infobox(args2) -- call the inner "core" function table.insert(results, infobox) local fields = { title=1, medium=1, dimensions=1, institution=1, department=1, id=1, inscriptions=1 } local cats4 = '' for field, _ in pairs( args2 ) do 		if fields[field] then cats4 = '' end end table.insert(results, cats0 .. cats1 .. cats2 .. cats3 .. cats4) return table.concat(results, '\n') end

function p.book(frame) local args = read_input_parameters(frame) args.infobox              = 'book' args.demo_image           = 'Placeholder book.svg' args.strict               = false args.place_of_publication = args.place_of_publication or args.city -- book specific aliases args.publication_date     = args.publication_date or args.date args.source_              = args.source or args.source_ if args.isbn or args.lccn or args.oclc or args.bnf then args.authority = frame:expandTemplate{ title = 'Book authority control', args = { ISBN=args.isbn, LCCN=args.lccn, OCLC=args.oclc, BNF=args.bnf, bare=1 } } args.isbn, args.lccn, args.oclc, args.bnf = nil, nil, nil, nil end args.source, args.city, args.date = nil, nil, nil local results, cats = p.create_infobox(args) -- call the inner "core" function return results .. cats end

return p