Module:Infobox ship
Appearance
| This module's documentation is missing, inadequate, or does not accurately describe its functionality or the parameters in its code. Please help add, expand, or improve it. |
| This module depends on the following other modules: |
| This module uses TemplateStyles: |
Implements:
require('strict');
local utilities = require ('Module:WPSHIPS_utilities');
local infobox = require ('Module:Infobox').infobox;
local infobox_ship_flag = utilities._infobox_ship_flag;
local ship_name_format = utilities._ship_name_format;
local synonym_check = utilities._synonym_check;
local unbulleted_list = utilities._unbulleted_list;
local get_args = require ('Module:Arguments').getArgs;
local data = mw.loadData ('Module:Infobox_ship/data');
--[[--------------------------< L I N E _ I T E M S >-----------------------------------------------------------------------------
spin through <params_t> sequence. Get parameter name and matching infobox label. Look in <args_t> for parameter name. When parameter
name has a value, add infobox label and parameter value to the infobox table <infobox_ship_t>. <i> identifies where label and data
enumerators begin.
]]
local function line_items (args_t, params_t, infobox_ship_t, i, frame)
for _, v in ipairs (params_t) do -- v is a sequence table with parameter name and associated infobox label
if args_t[v[1]] then -- if parameter has a value
infobox_ship_t['label' .. i] = v[2]; -- add the label
infobox_ship_t['data' .. i] = unbulleted_list (args_t[v[1]]); -- and add the parameter value as data
i = i + 1; -- bump the enumerator
end
end
end
--[[--------------------------< A D D _ W A R N I N G >--------------------------------------------------------
for unknown parameters, add a message in the edit-preview message box
<template> is the name of the enclosing infobox ship or one of the subtemplates
<k> is the parameter name
<v> is the parameter value
]]
local function add_warning (template, k, v)
if v:find (data.stripmarker) then -- if we find a templatestyles stripmarker
v = ''; -- suppress <v> as being too ugly
end
mw.addWarning (string.format (data.warning_fmt_str, data.warn_span_style, data.warn_code_style, template, template, data.warn_code_style, k, v));
-- has_unknown_params = (0 == data.namespace) or (118 == data.namespace) or (2 == data.namespace); -- add unknown params category when infobox is rendered; mainspace and draftspace only
end
--[[--------------------------< U N K N O W N _ P A R A M S _C H E C K >---------------------------------------
check parameters supplied in <template> against known parameters for that template. Emit preview warning when
a parameter is unknown.
Empty unknown parameters are not identified because Module:Arguments removes blank parameters by default.
]]
local function unknown_params_check (args_t, known_params_t, template)
local has_unknown_params = false;
for k, v in pairs (args_t) do
if 'string' == type (k) then
local param = k:gsub ('%d+$', '#'); -- for enumerated parameters, replace enumerator with '#'
if not known_params_t[param] then
add_warning (template, k, v); -- add warning message when <param> is not known for <template>
has_unknown_params = (0 == data.namespace) or (118 == data.namespace) or (2 == data.namespace); -- add unknown params category when infobox is rendered; mainspace and draftspace only
end
else -- here when <k> not a string (likely a positional parameter)
add_warning (template, k, v); -- add warning message when <param> is not known for <template>
has_unknown_params = (0 == data.namespace) or (118 == data.namespace) or (2 == data.namespace); -- add unknown params category when infobox is rendered; mainspace and draftspace only
end
end
return has_unknown_params;
end
--[[--------------------------< F I N A L _ R E N D E R I N G >------------------------------------------------
final rendering for the various subtemplates
]]
local function final_rendering (infobox_ship_t, frame)
if 'yes' ~= infobox_ship_t.child then -- when not 'yes', we are in stand-alone mode
infobox_ship_t.bodyclass = 'mainbox'; -- use basic infobox css for stand-alone mode
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Infobox ship/styles.css'}), -- apply templatestyles
infobox (infobox_ship_t), -- render the infobox
(has_unknown_params and '[[Category:Pages using infobox ship with unknown parameters]]' or '') -- add category for any unknown parameters
});
else
return frame:expandTemplate ({title='Infobox', args = infobox_ship_t}); -- return a rendering of this infobox
end
end
--[[--------------------------< I N F O B O X _ S H I P _ B E G I N >------------------------------------------
fill infobox table parameters 'bodystyle' and 'title' (infobox caption); auto-article title formatting ({{DISPLAYTITLE}})
]]
local function infobox_ship_begin (args_t, infobox_ship_t, frame)
local name = mw.title.getCurrentTitle().text;
infobox_ship_t['bodyclass'] = 'mainbox';
if args_t.infobox_caption then
if 'yes' == args_t.infobox_caption then -- format article title as infobox caption
infobox_ship_t.title = ship_name_format ({name=name, adj='off', showerrs=args_t.showerrs, sclass=args_t.sclass});
elseif 'nodab' == args_t.infobox_caption then -- format article title without disambiguation as infobox caption
infobox_ship_t.title = ship_name_format ({name=name, dab='none', showerrs=args_t.showerrs});
else -- use value supplied in |infobox_caption= as infobox caption
infobox_ship_t.title = args_t.infobox_caption;
end
else
infobox_ship_t.title = ''; -- to allow for possible displaytitle concatenation
end
if args_t.display_title then
if 'ital' == args_t.display_title then -- use {{italic title}} template
infobox_ship_t.title = infobox_ship_t.title .. require ('Module:italic title')._main ({}); -- {{italic title}} without template overhead
elseif ('none' ~= args_t.display_title) then -- any value but 'none' use value in |display_title= for {{DISPLAYTITLE}} magic word
infobox_ship_t.title = infobox_ship_t.title .. frame:preprocess ('{{DISPLAYTITLE:' .. args_t.display_title .. '}}');
end
else -- |display_title= empty or omitted, use article title
infobox_ship_t.title = infobox_ship_t.title .. frame:preprocess ('{{DISPLAYTITLE:' .. ship_name_format ({name=name, sclass=args_t.sclass}) .. '}}');
end
end
--[[--------------------------< I N F O B O X _ S H I P _ I M A G E >------------------------------------------
Returns a child infobox for Infobox ship/image unless |child=no for a stand-alone rendering
images in {{infobox ship}} default to 300px; upright is ignored
]]
local function infobox_ship_image (frame)
local args_t = get_args (frame);
if not args_t.image then
return ((0 == namespace) or (118 == namespace)) and data.categories_t.no_image; -- if no image specified, abandon with category
end
local infobox_ship_t = {
child = args_t.child or 'yes'; -- default to child
image1 = require ('Module:InfoboxImage').InfoboxImage ({args = {'InfoboxImage', 'InfoboxImage', image=args_t.image, size=args_t.image_size, alt=args_t.image_alt, sizedefault = '300px'}}); -- upright='1' ignored
caption1 = args_t.image_caption;
}
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_image_params_t, 'Infobox ship/image');
return table.concat ({
final_rendering (infobox_ship_t, frame), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P _ C A R E E R >----------------------------------------
Returns a child infobox for Infobox ship/career unless |child=no for a stand-alone rendering
]]
local function infobox_ship_career (frame)
local template_name = 'Infobox ship/career';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes'; -- default to child
headerclass = 'country';
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
if not ('title' == args_t.hide_header) then -- |hide_header=title then no title bar
local spoof_t = {
child = 'yes', -- default to child
decat = 'yes', -- spoof infobox does not have data; don't categorize in Category:Articles using infobox templates with no data rows
header1 = 'History',
headerclass = "history",
}
infobox_ship_t.data1 = frame:expandTemplate ({title='Infobox', args = spoof_t}); -- return a rendering of this spoof infobox
i = i + 1;
end
if args_t.ship_country and args_t.ship_flag then
infobox_ship_t['header' .. i] = infobox_ship_flag (args_t.ship_flag) .. '<span style="padding-left:1em">' .. args_t.ship_country .. '</span>';
elseif args_t.ship_country then
infobox_ship_t['header' .. i] = args_t.ship_country;
elseif args_t.ship_flag then
infobox_ship_t['header' .. i] = infobox_ship_flag (args_t.ship_flag);
end
end
if infobox_ship_t['header' .. i] then
i = i + 1;
end
local error_flag;
error_flag = synonym_check (args_t, 'ship_stricken', 'ship_struck', error_flag); -- error if both synonymous parameters set
synonym_check (args_t, 'ship_honours', 'ship_honors', error_flag);
line_items (args_t, data.infobox_career_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_career_params_t, 'Infobox ship/career');
return table.concat ({
final_rendering (infobox_ship_t, frame), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P _ C H A R A C T E R I S T I C S >----------------------
Returns a child infobox for Infobox ship/characteristics unless |child=no for a stand-alone rendering
]]
local function infobox_ship_characteristics (frame)
local template_name = 'Infobox ship/characteristics';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
local header = 'General characteristics'; -- the default header
if args_t.header_caption then
header = header .. ' ' .. args_t.header_caption; -- concatenate |header_caption= onto default header
end
infobox_ship_t['header' .. i] = header; -- add the header
i = i + 1; -- bump the enumerator
end
local error_flag;
error_flag = synonym_check (args_t, 'ship_armour', 'ship_armor', error_flag); -- error if both synonymous parameters set
synonym_check (args_t, 'ship_draught', 'ship_draft', error_flag); -- when both set modify with error message and category
line_items (args_t, data.infobox_characteristics_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_characteristics_params_t, template_name);
return table.concat ({
final_rendering (infobox_ship_t, frame), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P _ C L A S S _ O V E R V I E W >------------------------
Returns a child infobox for Infobox ship/class overview unless |child=no for a stand-alone rendering
]]
local function infobox_ship_class_overview (frame)
local template_name = 'Infobox ship/class overview';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
infobox_ship_t['header' .. i] = 'Class overview'; -- add the header
i = i + 1; -- bump the enumerator
end
synonym_check (args_t, 'total_ships_cancelled', 'total_ships_canceled', nil); -- error if both synonymous parameters set
line_items (args_t, data.infobox_class_overview_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_class_overview_params_t, template_name);
return table.concat ({
final_rendering (infobox_ship_t, frame), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P _ S E R V I C E _ R E C O R D >------------------------
Returns a child infobox for Infobox ship/service record unless |child=no for a stand-alone rendering. This
function implements the ship-only portion of {{Infobox service record}}; does not know about |is_ship= and
|is_multi= parameters. Adds support for |hide_header= parameter
]]
local function infobox_ship_service_record (frame)
local template_name = 'Infobox ship/service record';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
infobox_ship_t['header' .. i] = args_t.header_caption or args_t.label or 'Service record'; -- add the header; |label= is deprecated
i = i + 1; -- bump the enumerator
end
line_items (args_t, data.infobox_ship_service_record_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_service_record_params_t, template_name);
return table.concat ({
final_rendering (infobox_ship_t, frame), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P >------------------------------------------------------
{{#invoke:Infobox ship|infobox_ship}}
To discover when two child infoboxen are concatenated without a proper |sectionn= parameter between them, this
function looks for and counts template styles strip markers. Each child prepends a <templatestyles>...</templatestyles>
tags to its rendering. MediaWiki returns stripmarkers for those tags which will be replaced at the final rendering
of the page. This function counts the stripmarkers in each parameter. If there are:
0 stripmarkers – ok; parameter does not include a child infobox rendering
1 – ok; parameter holds a child infobox
2 – ok if one of them has has class="infobox-header history"; {{infobox ship/history}} creates a child of its own for the history header; TODO: is there a better way to do that?
2 – not ok when neither has class="infobox-header history"
3+ – not ok
]]
local function infobox_ship (frame)
local args_t = get_args (frame);
local infobox_ship_t = {} -- table that holds infobox parameters
infobox_ship_begin (args_t, infobox_ship_t, frame); -- fetch parameters that once belonged to obsolete {{infobox ship begin}}
for k, v in pairs (args_t) do -- copy infobox parameters from the frame into our local table
if 'string' == type (k) then -- must be string; positional parameters no supported
local enum = k:match ('section(%d+)'); -- <enum> gets a value when this parameter is |section<n>=
if enum then
infobox_ship_t['data'..enum] = v; -- translate |section<n> = to |data<n>=
else
infobox_ship_t[k] = v; -- assume that parameter name is one known to Module:Infobox
end
end
end
mw.logObject (infobox_ship_t)
for k, v in pairs (infobox_ship_t) do -- look for malformed input (concatenated child infoboxen)
local _, count = v:gsub (data.stripmarker, ''); -- count templatestyles stripmarkers; there should only be one
if ((2 == count) and not v:find ('class="infobox-header history"', 1, true)) or -- plain-text find the <spoof_t> ibox that is the history header which will emit a second stripmarker
2 < count then
infobox_ship_t[k] = table.concat ({
string.format (data.error_messages_t.missing_section, k:match ('%d')), -- emit an error message
((0 == namespace) or (118 == namespace)) and data.categories_t.no_image or '',
});
end
end
local has_unknown_params = unknown_params_check (args_t, data.known_infobox_ship_params_t, 'Infobox ship');
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Infobox ship/styles.css'}), -- apply template styles
infobox (infobox_ship_t), -- render the infobox
(has_unknown_params and data.categories_t.unknown) or '' -- add category for any unknown parameters
});
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
infobox_ship = infobox_ship,
infobox_ship_image = infobox_ship_image,
infobox_ship_career = infobox_ship_career,
infobox_ship_characteristics = infobox_ship_characteristics,
infobox_ship_class_overview = infobox_ship_class_overview,
infobox_ship_service_record = infobox_ship_service_record,
}