Module:Instrument: Difference between revisions
From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Jump to navigationJump to search
Create Lua instrument infobox module |
Fix: merge frame+parent args for Template:Guitar delegation; strip wikilinks from owner before {{m}} |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local function trim(s) | |||
return s:match('^%s*(.-)%s*$') | |||
end | |||
local function row(label, value) | local function row(label, value) | ||
if not value or value == '' then return | if not value or trim(value) == '' then return nil end | ||
return | return '|-\n! style="text-align: right; padding: 3px;" | ' .. label .. '\n| style="padding: 3px;" | ' .. trim(value) | ||
end | end | ||
local function sectionHeader(label) | local function sectionHeader(label) | ||
return | return '|-\n! colspan="2" style="background: #ddd; padding: 3px;" | ' .. label | ||
end | end | ||
local function any(...) | local function any(...) | ||
for _, v in ipairs({...}) do | for _, v in ipairs({...}) do | ||
if v and v ~= '' then return true end | if v and trim(v) ~= '' then return true end | ||
end | end | ||
return false | return false | ||
end | |||
local function add(out, val) | |||
if val then table.insert(out, val) end | |||
end | |||
local function getArg(frameArgs, parentArgs, key) | |||
local v = frameArgs[key] | |||
if v and trim(v) ~= '' then return v end | |||
v = parentArgs[key] | |||
if v and trim(v) ~= '' then return v end | |||
return '' | |||
end | |||
-- Strip [[ ]] wikilink markup to get plain page name | |||
local function stripWikilinks(s) | |||
-- [[Page|Display]] -> Display; [[Page]] -> Page | |||
s = s:gsub('%[%[([^%]|]+)|([^%]]+)%]%]', '%2') | |||
s = s:gsub('%[%[([^%]]+)%]%]', '%1') | |||
return trim(s) | |||
end | end | ||
function p.infobox(frame) | function p.infobox(frame) | ||
local args = frame:getParent().args | -- Merge direct #invoke args with parent template args (direct wins) | ||
local type_ = | local fArgs = frame.args | ||
local nickname = | local pArgs = frame:getParent().args | ||
local make = | local type_ = getArg(fArgs, pArgs, 'type') | ||
local model = | if type_ == '' then type_ = 'Instrument' end | ||
local serial = | local nickname = getArg(fArgs, pArgs, 'nickname') | ||
local year = | local make = getArg(fArgs, pArgs, 'make') | ||
local image = | local model = getArg(fArgs, pArgs, 'model') | ||
local current_owner = | local serial = getArg(fArgs, pArgs, 'serial') | ||
local previous_owners = | local year = getArg(fArgs, pArgs, 'year') | ||
local body_shape = | local image = getArg(fArgs, pArgs, 'image') | ||
local top_wood = | local current_owner = getArg(fArgs, pArgs, 'current_owner') | ||
local back_sides_wood = | local previous_owners = getArg(fArgs, pArgs, 'previous_owners') | ||
local neck_wood = | local body_shape = getArg(fArgs, pArgs, 'body_shape') | ||
local fingerboard_wood = | local top_wood = getArg(fArgs, pArgs, 'top_wood') | ||
local bridge_wood = | local back_sides_wood = getArg(fArgs, pArgs, 'back_sides_wood') | ||
local scale_length = | local neck_wood = getArg(fArgs, pArgs, 'neck_wood') | ||
local nut_width = | local fingerboard_wood = getArg(fArgs, pArgs, 'fingerboard_wood') | ||
local strings = | local bridge_wood = getArg(fArgs, pArgs, 'bridge_wood') | ||
local electronics = | local scale_length = getArg(fArgs, pArgs, 'scale_length') | ||
local nut_width = getArg(fArgs, pArgs, 'nut_width') | |||
local strings = getArg(fArgs, pArgs, 'strings') | |||
local electronics = getArg(fArgs, pArgs, 'electronics') | |||
-- SMW properties | -- SMW properties via #set parser function | ||
local | local setArgs = {} | ||
local propMap = { | |||
['Instrument type'] = type_, | |||
['Nickname'] = nickname, | |||
['Make'] = make, | |||
['Model'] = model, | |||
['Serial'] = serial, | |||
['Year built'] = year, | |||
['Current owner'] = current_owner, | |||
['Body shape'] = body_shape, | |||
['Top wood'] = top_wood, | |||
['Back and sides wood'] = back_sides_wood, | |||
['Neck wood'] = neck_wood, | |||
['Fingerboard wood'] = fingerboard_wood, | |||
['Bridge wood'] = bridge_wood, | |||
['Scale length'] = scale_length, | |||
['Nut width'] = nut_width, | |||
['Number of strings'] = strings, | |||
['Electronics'] = electronics, | |||
} | |||
for k, v in pairs(propMap) do | |||
if v ~= '' then | |||
table.insert(setArgs, k .. '=' .. v) | |||
end | end | ||
end | |||
if #setArgs > 0 then | |||
frame:callParserFunction('#set', setArgs) | |||
end | end | ||
| Line 97: | Line 119: | ||
table.insert(out, '! colspan="2" style="background: #ccc; font-size: 1.1em; padding: 5px;" | ' .. header) | table.insert(out, '! colspan="2" style="background: #ccc; font-size: 1.1em; padding: 5px;" | ' .. header) | ||
if image ~= '' then | if trim(image) ~= '' then | ||
table.insert(out, '|-') | table.insert(out, '|-') | ||
table.insert(out, '| colspan="2" style="text-align: center; padding: 10px;" | [[File:' .. image .. '|280px]]') | table.insert(out, '| colspan="2" style="text-align: center; padding: 10px;" | [[File:' .. trim(image) .. '|280px]]') | ||
end | end | ||
add(out, row('Type', type_)) | |||
add(out, row('Serial', serial)) | |||
add(out, row('Year', year)) | |||
if current_owner ~= '' then | if trim(current_owner) ~= '' then | ||
local ownerDisplay = frame:expandTemplate{ title = 'm', args = { | local ownerName = stripWikilinks(current_owner) | ||
local ownerDisplay = trim(frame:expandTemplate{ title = 'm', args = { ownerName } }) | |||
add(out, row('Owner', ownerDisplay)) | |||
end | end | ||
add(out, row('Previous', previous_owners)) | |||
if any(body_shape, top_wood, back_sides_wood, neck_wood, fingerboard_wood, bridge_wood) then | if any(body_shape, top_wood, back_sides_wood, neck_wood, fingerboard_wood, bridge_wood) then | ||
table.insert(out, sectionHeader('Construction')) | table.insert(out, sectionHeader('Construction')) | ||
add(out, row('Body', body_shape)) | |||
add(out, row('Top', top_wood)) | |||
add(out, row('Back/Sides', back_sides_wood)) | |||
add(out, row('Neck', neck_wood)) | |||
add(out, row('Fingerboard', fingerboard_wood)) | |||
add(out, row('Bridge', bridge_wood)) | |||
end | end | ||
if any(scale_length, nut_width, strings) then | if any(scale_length, nut_width, strings) then | ||
table.insert(out, sectionHeader('Specifications')) | table.insert(out, sectionHeader('Specifications')) | ||
add(out, row('Scale', scale_length)) | |||
add(out, row('Nut Width', nut_width)) | |||
add(out, row('Strings', strings)) | |||
end | end | ||
if electronics ~= '' then | if trim(electronics) ~= '' then | ||
table.insert(out, sectionHeader('Electronics')) | table.insert(out, sectionHeader('Electronics')) | ||
table.insert(out, '|-') | table.insert(out, '|-') | ||
table.insert(out, '| colspan="2" style="padding: 3px;" | ' .. electronics) | table.insert(out, '| colspan="2" style="padding: 3px;" | ' .. trim(electronics)) | ||
end | end | ||
Latest revision as of 04:45, 31 March 2026
Documentation for this module may be created at Module:Instrument/doc
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function row(label, value)
if not value or trim(value) == '' then return nil end
return '|-\n! style="text-align: right; padding: 3px;" | ' .. label .. '\n| style="padding: 3px;" | ' .. trim(value)
end
local function sectionHeader(label)
return '|-\n! colspan="2" style="background: #ddd; padding: 3px;" | ' .. label
end
local function any(...)
for _, v in ipairs({...}) do
if v and trim(v) ~= '' then return true end
end
return false
end
local function add(out, val)
if val then table.insert(out, val) end
end
local function getArg(frameArgs, parentArgs, key)
local v = frameArgs[key]
if v and trim(v) ~= '' then return v end
v = parentArgs[key]
if v and trim(v) ~= '' then return v end
return ''
end
-- Strip [[ ]] wikilink markup to get plain page name
local function stripWikilinks(s)
-- [[Page|Display]] -> Display; [[Page]] -> Page
s = s:gsub('%[%[([^%]|]+)|([^%]]+)%]%]', '%2')
s = s:gsub('%[%[([^%]]+)%]%]', '%1')
return trim(s)
end
function p.infobox(frame)
-- Merge direct #invoke args with parent template args (direct wins)
local fArgs = frame.args
local pArgs = frame:getParent().args
local type_ = getArg(fArgs, pArgs, 'type')
if type_ == '' then type_ = 'Instrument' end
local nickname = getArg(fArgs, pArgs, 'nickname')
local make = getArg(fArgs, pArgs, 'make')
local model = getArg(fArgs, pArgs, 'model')
local serial = getArg(fArgs, pArgs, 'serial')
local year = getArg(fArgs, pArgs, 'year')
local image = getArg(fArgs, pArgs, 'image')
local current_owner = getArg(fArgs, pArgs, 'current_owner')
local previous_owners = getArg(fArgs, pArgs, 'previous_owners')
local body_shape = getArg(fArgs, pArgs, 'body_shape')
local top_wood = getArg(fArgs, pArgs, 'top_wood')
local back_sides_wood = getArg(fArgs, pArgs, 'back_sides_wood')
local neck_wood = getArg(fArgs, pArgs, 'neck_wood')
local fingerboard_wood = getArg(fArgs, pArgs, 'fingerboard_wood')
local bridge_wood = getArg(fArgs, pArgs, 'bridge_wood')
local scale_length = getArg(fArgs, pArgs, 'scale_length')
local nut_width = getArg(fArgs, pArgs, 'nut_width')
local strings = getArg(fArgs, pArgs, 'strings')
local electronics = getArg(fArgs, pArgs, 'electronics')
-- SMW properties via #set parser function
local setArgs = {}
local propMap = {
['Instrument type'] = type_,
['Nickname'] = nickname,
['Make'] = make,
['Model'] = model,
['Serial'] = serial,
['Year built'] = year,
['Current owner'] = current_owner,
['Body shape'] = body_shape,
['Top wood'] = top_wood,
['Back and sides wood'] = back_sides_wood,
['Neck wood'] = neck_wood,
['Fingerboard wood'] = fingerboard_wood,
['Bridge wood'] = bridge_wood,
['Scale length'] = scale_length,
['Nut width'] = nut_width,
['Number of strings'] = strings,
['Electronics'] = electronics,
}
for k, v in pairs(propMap) do
if v ~= '' then
table.insert(setArgs, k .. '=' .. v)
end
end
if #setArgs > 0 then
frame:callParserFunction('#set', setArgs)
end
-- Header
local header
if make ~= '' then
header = make .. ' ' .. model
if serial ~= '' then
if tonumber(serial) then
header = header .. ' #' .. serial
else
header = header .. ' ' .. serial
end
end
elseif nickname ~= '' then
header = "''" .. nickname .. "''"
else
header = type_
end
-- Build table
local out = {}
table.insert(out, '{| class="infobox" style="width: 300px; border: 1px solid #aaa; background: #f9f9f9; padding: 10px; margin: 0 0 1em 1em; float: right;"')
table.insert(out, '|-')
table.insert(out, '! colspan="2" style="background: #ccc; font-size: 1.1em; padding: 5px;" | ' .. header)
if trim(image) ~= '' then
table.insert(out, '|-')
table.insert(out, '| colspan="2" style="text-align: center; padding: 10px;" | [[File:' .. trim(image) .. '|280px]]')
end
add(out, row('Type', type_))
add(out, row('Serial', serial))
add(out, row('Year', year))
if trim(current_owner) ~= '' then
local ownerName = stripWikilinks(current_owner)
local ownerDisplay = trim(frame:expandTemplate{ title = 'm', args = { ownerName } })
add(out, row('Owner', ownerDisplay))
end
add(out, row('Previous', previous_owners))
if any(body_shape, top_wood, back_sides_wood, neck_wood, fingerboard_wood, bridge_wood) then
table.insert(out, sectionHeader('Construction'))
add(out, row('Body', body_shape))
add(out, row('Top', top_wood))
add(out, row('Back/Sides', back_sides_wood))
add(out, row('Neck', neck_wood))
add(out, row('Fingerboard', fingerboard_wood))
add(out, row('Bridge', bridge_wood))
end
if any(scale_length, nut_width, strings) then
table.insert(out, sectionHeader('Specifications'))
add(out, row('Scale', scale_length))
add(out, row('Nut Width', nut_width))
add(out, row('Strings', strings))
end
if trim(electronics) ~= '' then
table.insert(out, sectionHeader('Electronics'))
table.insert(out, '|-')
table.insert(out, '| colspan="2" style="padding: 3px;" | ' .. trim(electronics))
end
local detailsForm = ({
Guitar = 'GuitarDetails',
Banjo = 'BanjoDetails',
Mandolin = 'MandolinDetails',
})[type_] or 'InstrumentDetails'
local pageName = mw.title.getCurrentTitle().fullText
table.insert(out, '|-')
table.insert(out, '| colspan="2" style="text-align: center; padding: 8px 3px 3px;" | [[Special:FormEdit/' .. detailsForm .. '/' .. pageName .. '|Add details & photos]]')
table.insert(out, '|}')
table.insert(out, '[[Category:Instruments]][[Category:' .. type_ .. 's]]')
return table.concat(out, '\n')
end
return p