Modul:Artwork/core
aus Wikipedia, der freien Enzyklopädie
< Modul:Artwork
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 5. November 2022 um 17:59 Uhr durch c>Jonesey95 (replace in-line span tag, which is often used to wrap block content, with equivalent div tag to fix Linter errors.). Sie kann sich erheblich von der aktuellen Version unterscheiden.
Die Dokumentation für dieses Modul kann unter Modul:Artwork/core/Doku erstellt werden
--[[
__ __ _ _ _ _ _ __
| \/ | ___ __| |_ _| | ___ _ / \ _ __| |___ _____ _ __| | __ / /__ ___ _ __ ___
| |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ / / / __/ _ \| '__/ _ \
| | | | (_) | (_| | |_| | | __/_ / ___ \| | | |_ \ 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 valign="top">\n%s%s\n</tr>\n\n', cell1, cell2)
end
-- ====================================================================
-- === This function is just responsible for producing HTML of the ===
-- === template. At this stage all the fields are already 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, ' '))
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='Q2668072', 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=%s|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
-- add table and outer layers
local style = string.format('class="fileinfotpl-type-artwork toccolours vevent mw-content-%s" dir="%s" style="width: 100%%" cellpadding="4"', dir, dir)
results = string.format('<table %s>\n%s\n</table>\n', style, table.concat(results)) -- combine "results", an array of strings into a single string
results = string.format('<div class="hproduct commons-file-information-table">\n%s\n</div>\n', 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