Module:Artwork/core

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules


Part of Module:Artwork which is responsible for rendering the template and input parameter processing.

Test

Code Render
Test simple case:

{{#invoke:Artwork/core|test
|infobox        = artwork
|description    = description
|date           = 2024-05-03
|source         = {{own}}
|author         = author
|permission     = permission     
|other versions = <gallery>File:Image-x-generic - black.svg</gallery>
}}
Author
author
Description
description
Date 3 May 2024
Source/Photographer own
Permission
(Reusing this file)
permission
Other versions
Test case with missing source, author and description:

{{#invoke:Artwork/core|test
|infobox = artwork
|demo = 1
}}
Artist
Title
Part of
Object type
Description
Depicted people
Depicted place
Depicted part
Date
Medium
Dimensions
Current location
Accession number
Object location
Place of creation
Place of discovery
Object history
Exhibition history
Credit line
Inscriptions
Notes
References
Source/Photographer
Permission
(Reusing this file)
Other versions


Code

--[[  
  __  __           _       _           _         _                      _        __                 
 |  \/  | ___   __| |_   _| | ___ _   / \   _ __| |___      _____  _ __| | __   / /__ ___  _ __ ___ 
 | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ /  / / __/ _ \| '__/ _ \
 | |  | | (_) | (_| | |_| | |  __/_ / ___ \| |  | |_ \ V  V / (_) | |  |   <  / / (_| (_) | | |  __/
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_/   \_\_|   \__| \_/\_/ \___/|_|  |_|\_\/_/ \___\___/|_|  \___|
                                                                                                                                                                               
This submodule is intended for converting inputs into html.

Please do not modify this code without applying the changes first at 
"Module:Artwork/sandbox" and testing at "Template:
/testcases".

Authors and maintainers:
* User:Jarekt - original version 
]]
require('strict') -- 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 core     = require("Module:Core")
local labels   = require("Module:I18n/artwork")                        -- internationalization of labels
local bit32    = require("bit32")
local TagQS    = require('Module:TagQS')
local City     = require("Module:City")                                -- used to add Wikidata based links to names of places
local ISOdate  = require('Module:ISOdate')                             -- used for simple date formating
local p = {}

-- Lazy loading function: load them only if they are needed
local function ObjectLocation_label()
	return mw.loadData('Module:i18n/coordinates').ObjectLocation
end

local function Creator(args)
	return require("Module:Creator")._creator(args)
end

local function Institution(args)
	return require("Module:Institution")._institution(args)
end

-- ==================================================
-- === 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 if_else(Boolean, TrueStatement, FalseStatement)
	if Boolean then
		return TrueStatement
	else
		return FalseStatement
	end
end

-------------------------------------------------------------------------------
local function empty2nil(str)
	if str=='' then
		return nil
	else 
		return str
	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 are the same than we ignore the second one
--    - wrapper  - some fields need a <span class=...> wrapper around the field content 
-- ====================================================================
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('<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>\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 filled    ===
-- ====================================================================
function p.build_html(args)
	-- get text direction
	local dir = if_else(mw.language.new( args.lang ):isRTL(),'rtl','ltr')
	
	-- 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('<div style="background:#dde; font-size:86%%; direction:%s;">%s</div>', dir, args.original_description_info)
		end
		if args.biased then
			tag2 = core.langSwitch(labels.inaccurate_description, args.lang)
			tag2 = string.format('<div style="padding:0.5ex; margin:0 0 0.5ex 0; border: 1px solid red;">%s: %s</div>', 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
	if args.demo or args.coordinates then
		labels.ObjectLocation = ObjectLocation_label()
	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('<span class="fn" id="artwork"><bdi>%s\n</bdi></span>', args.name ) )
	end
	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) )
		table.insert(top, string.format('[[File:Wikidata-Reasonator_small_logo.svg|5px|reasonator:%s|link=https://reasonator.toolforge.org/test/?q=%s]]', args.wikidata, args.wikidata) )
	end
	if args.wikisource then --Wikisource link
		table.insert(top, string.format('[[File:Wikisource-logo.svg|15px|%s|link=%s]]', args.wikisource, args.wikisource) )
	end
	if args.wikiquote then --Wikiquote link
		table.insert(top, string.format('[[File:Wikiquote-logo.svg|15px|%s|link=%s]]', args.wikiquote, args.wikiquote) )
	end
	if #top>0 and args.QS then -- quick_statement link to upload missing info to Wikidata (add if the row is not empty)
		table.insert(top, string.format('%s', args.QS) )
	end
	if #top>0 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, '&nbsp;')) 
		table.insert(results, string.format('<tr valign="top">\n%s\n</tr>\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<br /><small>([[%s|%s]])</small>", tag1, tag2, tag3)
	
	-- define constants for readability
	-- demo=art+photo+book will show that row in demo mode in {{artwork}, {{Photograph}} and {{Book}} templates
	local none, art, photo, book  = 0, 1, 2, 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='<div class="fn value">\n%s</div>'},
		{field='author'               , id='fileinfotpl_aut'                       , tag='wm-license-information-author',         demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='editor'               , id='fileinfotpl_book_editor'               , tag='wm-license-book-editor',                demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='translator'           , id='fileinfotpl_book_translator'           , tag='wm-license-book-translator',            demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='illustrator'          , id='fileinfotpl_book_illustrator'          , tag='wm-license-book-illustrator',           demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='author_of_foreword'   , id='fileinfotpl_aut'                       , tag='P2679',                                 demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='author_of_afterword'  , id='fileinfotpl_aut'                       , tag='P2680',                                 demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='architect'            , id='fileinfotpl_aut'                       , tag='Q42973',                                demo=none,           wrapper='<div class="fn value">\n%s</div>'},
		{field='designer'             , id='fileinfotpl_aut'                       , tag='Q5322166',                              demo=none,           wrapper='<div class="fn value">\n%s</div>'},
		{field='photographer'         , id='fileinfotpl_aut'                       , tag='Q33231',                                demo=    photo,      wrapper='<div class="fn value">\n%s</div>'},
		{field='other_fields_1'},
		-- title & desctiption block
		{field='title'                , id='fileinfotpl_art_title'                 , tag='wm-license-artwork-title',              demo=art+photo+book, wrapper='<div class="fn">\n%s</div>'},
		{field='subtitle'             , id='fileinfotpl_book_subtitle'             , tag='wm-license-book-subtitle',              demo=          book, wrapper='%s'},
		{field='part_of'              , id='fileinfotpl_art_part_of'               , tag='P361',                                  demo=art+photo+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='<div class="fn value">\n%s</div>'},
		{field='printer'              , id='fileinfotpl_book_printer'              , tag='wm-license-book-printer',               demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{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='<div class="description">\n%s</div>'},
		{field='description'          , id='fileinfotpl_desc'                      , tag='wm-license-information-description',    demo=art+photo+book, wrapper='<div class="description">\n%s</div>'},
		{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='P195',                                  demo=art+photo,      wrapper='%s'},
		{field='department'           , id='fileinfotpl_art_location'              , tag='wm-license-artwork-current-location',   demo=art+photo     , wrapper='<div class="locality">\n%s</div>'},
		{field='id'                   , id='fileinfotpl_art_id'                    , tag='wm-license-artwork-id',                 demo=art+photo,      wrapper='<div class="identifier">\n%s</div>'},
		{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|[[:File:%s|%s]]', args.image, tag1)
		else
			tag2 = ''
		end
		local field = string.format('[[File:%s|250x250px|alt=image of artwork listed in title parameter on this page|class=photo%s]]', args.image, args.name or '', tag2) 
		local nRow = #results -- number of rows below 
		local line = string.format('<td rowspan="%i" style="width:200px; text-align: right;" id="fileinfotpl_creator_image"><div class="wpImageAnnotatorControl wpImageAnnotatorOff">%s</div></td></tr>\n\n', nRow, field) 
		results[2] = mw.ustring.gsub(results[2], "</tr>%s*$", line); -- attach image section to the right side of the table, by attaching to row #2
	end
	
	local templatestyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:Information/styles.css' }
	}

	-- add table and outer layers
	local style = string.format('class="fileinfotpl-type-artwork vevent mw-content-%s" dir="%s"', dir, dir)
	results = string.format('<table %s>\n%s\n</table>\n', style, table.concat(results)) -- combine "results", an array of strings into a single string
	results = string.format('<div class="hproduct commons-file-information-table">\n%s\n%s\n</div>', templatestyles, results)
	return results
end

-- ===========================================================================
-- === Read input "frame", normalize input parameters (lower case, etc.)   ===
-- === and resolve potential aliases                                       ===
-- === INPUTS:                                                             ===
-- ===  * frame - contains input parameters passed from the template       ===
-- === OUTPUTS:                                                            ===
-- ===  * args - cleaned up inputs                                         ===
-- ===========================================================================
function p.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.department        = args.department       or args.location
	args.id                = args.accession_number or args.id
	args.object_type       = args.object_type      or args.type
	args.dimensions        = args.dimensions       or args.size
	args.object_history    = args.object_history   or args.history
	args.coordinates       = args.coordinates      or args.object_location
	args.institution       = args.institution or args.gallery or args.museum
	args.place_of_creation = args.place_of_creation or args.place_of_origin or args.country
	args.original_description = args.original_description or args.original_caption
	
	-- remove unneeded parameters
	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
	args.object_location, args.original_caption = 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.no_qs        = core.yesno(args.no_qs, false)
	args.no_sdc       = core.yesno(args.no_sdc, 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

-- ===========================================================================
function p.verify_input_parameters(args)
	local cats = '' -- categories 
	
	-- add [[Category:Creator templates with unknown parameter]] 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', 'no_qs', 'no_sdc', 'part_of'
	}
	local set = {}
	for _, field in ipairs(fields) do set[field] = true end
	for field, _ in pairs( args ) do 
		if not set[field] then
			local LUT = {artwork='Artwork', photograph='Photograph', book='Book'}
			local infobox = LUT[args.infobox]
			cats = cats .. '[[Category:Pages using ' .. infobox .. ' template with incorrect parameter]]'
			cats = cats .. string.format('\n;<span style="color:red">Error in [[Template:%s|{{%s}} template]]: unknown parameter "%s".</span>', infobox, infobox, field)
		end
	end 
	return cats
end

-- ===========================================================================
function p.clean_input_parameters(args)
	local lang = args.lang  -- user's language
	
	-- === Step 1: clean up of template arguments "args"
	local page = mw.title.getCurrentTitle()
	args.namespace   = page.namespace   -- get page namespace
	args.url         = page:canonicalUrl()
	args.pagename    = page.text
	if args.namespace==6 then -- file namespace
		args.mimeType  = page.file.mimeType
		args.num_pages = 1
		if page.file.pages then
			args.num_pages = #page.file.pages -- in case of DjVu or PDF files count pages
		end
	end
	if args.date then 
		args.year = empty2nil(ISOdate._ISOyear(args.date)) -- get year
	end
	
	-- for places run them through {{City}} template
	local fields = { 'depicted_people', 'depicted_place', 'place_of_discovery', 'part_of'	}
	for _, field in ipairs( fields ) do 
		if args[field] and not string.find(args[field], ' ') then
			args[field] = City._city(args[field], lang) -- single word depicted_people will get a link
		end	
	end
		
	-- for dates run them through {{ISOdate}} template and add invisible QS tag if possible
	local fields = { 'date', 'publication_date'}
	for _, field in ipairs( fields ) do 
		if args[field] then 
			local val  = isodate2timestamp(args[field])        -- if date is in YYYY, YYYY-MM or YYYY-MM-DD formats than it will be saved
			args[field] = ISOdate._ISOdate(args[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
				args[field] = args[field] .. TagQS.createTag('date', nil, val)
			end		
		end
	end
	
	-- collapse local {{Creator}} and {{Institution}} 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 args[field] then 
			if string.match(args[field], "^Q%d+$") and keyword=='creator' then -- this is wikidata item
				args[field..'_id'] = args[field]
				if keyword=='creator' then
					args[field] = Creator({wikidata=args[field], lang=lang, collapse=1})-- create creator based on item id 
				elseif keyword=='institution' then
					args[field] = Institution({wikidata=args[field], lang=lang, collapse=1})-- create institution based on item id 
				end
			else
				-- collapse local {{Creator}} and {{Institution}} templates
				args[field] = mw.ustring.gsub (args[field], 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"')
				-- extract item ID: retrieve the tag and grab the second component
				local v = mw.text.split(  TagQS.readTag(args[field], keyword) or '', '|', true )
				if v and #v>=2 then 
					args[field..'_id'] = v[2]
				end
			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', 'P170', 'P50' }, 
		{'artist',           'artwork',    'creator', 'P170', 'P170' },
		{'illustrator',      'book',       'creator', 'P170', 'P110'}, 
		{'editor',           'book',       'creator', 'P170', 'P98' }, 
		{'translator',       'book',       'creator', 'P170', 'P655'}, 
		{'printer',          'book',       'creator', 'P170', 'P872'}, 
		{'publication_date', 'book',       'date',     nil,   'P577'}, 
		{'date',             'photograph', 'date',     nil,   'P571'}, 
		{'date',             'artwork',    'date',     nil,   'P571'}}   
	for _, repItem in ipairs( repList ) do
		local field, infobox, tag, oldP, newP = unpack(repItem)
		if args[field] and args.infobox==infobox then 	
			args[field] = TagQS.changeProperty(args[field], tag, oldP, newP) 
			args[field] = TagQS.changeField(args[field], tag, field) 
		end
	end
	if args.source and mw.ustring.find( args.source, 'www%.wga%.hu' ) then
		-- code to help copy links to www.wga.hu to Wikidata
		args.reference_wga = string.gsub(args.source, 'http://www%.wga%.hu', 'https://www.wga.hu')
	end
	return args
end

-- ===========================================================================
function p.test(frame)
	local args  = p.read_input_parameters(frame)
	args.infobox = 'artwork'
	local cats0 = p.verify_input_parameters(args)
	args  = p.clean_input_parameters(args)
	return p.build_html(args)
end

return p