Module:Infobox: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Ganaram inukshuk (talk | contribs)
m todo
Ganaram inukshuk (talk | contribs)
add support for header and footer
Line 11: Line 11:


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
------------------------------- HELPER FUNCTIONS -------------------------------
-------------------------------- MAIN FUNCTIONS --------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


-- Infobox header with adjacent links
-- Function to be called by other modules; also called by wrapper function
-- Adjacent links are placed on the sides of the title, with options for 0, 2,
function p._infobox(args)
-- or 8 links.
local title          = args["Title"] or "Infobox Title"
function p.infobox_header(title, adjacent_links)
local adjacent_links = args["Adjacent Links"]
local header = ''
local header_row = args["Header"]
if adjacent_links == nil then
local rows      = args["Rows"  ]
header = title
local footer_row = args["Footer"]
elseif #adjacent_links == 2 then
lines = {}
-- Nested helper function
--table.insert(lines, "\n")
-- Produces the title and, if present, prev/next links
table.insert(lines, '{| style="width: 100%;"')
function infobox_title()
table.insert(lines, '|-')
if adjacent_links == nil then
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
return title
table.insert(lines, '| style="width: 50%;" | ' .. title)
elseif #adjacent_links == 2 then
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[2])
lines = {}
table.insert(lines, '|}')
--table.insert(lines, "\n")
table.insert(lines, '{| style="width: 100%;"')
header = table.concat(lines, "\n")
table.insert(lines, '|-')
elseif #adjacent_links == 8 then
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
lines = {}
table.insert(lines, '| style="width: 50%;" | ' .. title)
--table.insert(lines, "\n")
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[2])
table.insert(lines, '{| style="width: 100%;"')
table.insert(lines, '|}')
table.insert(lines, '|-')
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
return table.concat(lines, "\n")
table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[2])
elseif #adjacent_links == 8 then
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[3])
lines = {}
table.insert(lines, '|-')
--table.insert(lines, "\n")
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[4])
table.insert(lines, '{| style="width: 100%;"')
table.insert(lines, '| style="width: 50%;"  | ' .. title)
table.insert(lines, '|-')
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[5])
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
table.insert(lines, '|-')
table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[2])
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[6])
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[3])
table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[7])
table.insert(lines, '|-')
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[8])
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[4])
table.insert(lines, '|}')
table.insert(lines, '| style="width: 50%;"  | ' .. title)
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[5])
table.insert(lines, '|-')
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[6])
table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[7])
table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[8])
table.insert(lines, '|}')
return table.concat(lines, "\n")
else
return title
end
end
-- Nested helper function
-- Produces a row in the infobox
function infobox_row(row_content)
if #row_content > 1 then
local lines = {}
table.insert(lines, '|-')
table.insert(lines, '| style="text-align: right; padding-right: 0.25em;" | ' .. row_content[1])
table.insert(lines, '| style="background-color: white; padding-left: 0.25em; font-weight: bold;" | ' .. row_content[2])
return table.concat(lines, "\n")
elseif #row_content == 1 then
local lines = {}
table.insert(lines, '|-')
table.insert(lines, '| colspan="2" style="text-align: center;" | ' .. row_content[1])
header = table.concat(lines, "\n")
return table.concat(lines, "\n")
else
end
header = title
end
end
return header
-- Nested helper function
end
-- Produces a header or footer row
 
function header_footer_row(row_content)
-- Row of an infobox
-- Infobox is set up as a Mediawiki table with two cols.
function p.infobox_row(row_content)
local row = ""
if #row_content > 1 then
local lines = {}
table.insert(lines, '|-')
table.insert(lines, '| style="text-align: right; padding-right: 0.25em;" | ' .. row_content[1])
table.insert(lines, '| style="background-color: white; padding-left: 0.25em; font-weight: bold;" | ' .. row_content[2])
row = table.concat(lines, "\n")
elseif #row_content == 1 then
local lines = {}
local lines = {}
table.insert(lines, '|-')
table.insert(lines, '|-')
table.insert(lines, '| colspan="2" style="text-align: center;" | ' .. row_content[1])
table.insert(lines, '| colspan="2" style="text-align: center; font_size: 0.8em;" | ' .. row_content)
row = table.concat(lines, "\n")
return table.concat(lines, "\n")
end
end
return row
end
--------------------------------------------------------------------------------
-------------------------------- MAIN FUNCTIONS --------------------------------
--------------------------------------------------------------------------------
-- Function to be called by other modules; also called by wrapper function
function p._infobox(args)
local title = args["Title"] or "Infobox Title"
local adjacent_links = args["Adjacent Links"]
local rows = args["Rows"]
-- Start of infobox; outer div and start of table
-- Start of infobox; outer div and start of table
local lines = {}
local lines = {}
-- Infobox boilerplate
table.insert(lines, [[<div style="
table.insert(lines, [[<div style="
border: 1px solid #999;  
border: 1px solid #999;  
Line 104: Line 107:
overflow: auto;">]]
overflow: auto;">]]
)
)
table.insert(lines, '{| style="border-collapse: collapse; width: 100%;"')
table.insert(lines, '{| style="border-collapse: collapse; width: 100%;"')
table.insert(lines, '|+ style="font-size: 105%; font-weight: bold; text-align: center;" | ')
table.insert(lines, '|+ style="font-size: 105%; font-weight: bold; text-align: center;" | ')
table.insert(lines, p.infobox_header(title, adjacent_links))
-- Title
table.insert(lines, infobox_title())
-- Header
if header_row then
table.insert(lines, header_footer_row(header_row))
end
-- For loop for populating entries
-- Rows
for i = 1, #rows do
for i = 1, #rows do
table.insert(lines, p.infobox_row(rows[i]))
table.insert(lines, infobox_row(rows[i]))
end
-- Footer
if footer_row then
table.insert(lines, header_footer_row(footer_row))
end
end

Revision as of 07:53, 11 October 2025

Module documentation[view] [edit] [history] [purge]
This module implements a metatemplate, and may be invoked by templates using its corresponding template Template:Infobox, or used directly from other modules.

Module:Infobox is a module that implements the {{Infobox}} template. Infobox templates can be made by using the template or by calling the _sidebar function from another module.

On templates, you can create an infobox by using {{Infobox}}, which calls this module's wrapper function.

On modules, you can include local infobox= require("Module:Infobox")._infobox to create an infobox.
Introspection summary for Module:Infobox 
Functions provided (4)
Line Function Params
17 _infobox (main) (args)
139 infobox (invokable) (frame)
231 build (title, entries, prev_link, next_link)
242 build_multilink (title, entries, adjacent_links)
Lua modules required (2)
Variable Module Functions used
getArgs Module:Arguments getArgs
yesno Module:Yesno yesno

No function descriptions were provided. The Lua code may have further information.


local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")
local p = {}

-- TODO (low priority):
-- - Add a header/footer option.
-- - Allow for headerless data rows and dataless header rows. Requires changing
--   row content from a regular array to an associative array.

-- TODO (medium priority): nest helper functions

--------------------------------------------------------------------------------
-------------------------------- MAIN FUNCTIONS --------------------------------
--------------------------------------------------------------------------------

-- Function to be called by other modules; also called by wrapper function
function p._infobox(args)
	local title          = args["Title"] or "Infobox Title"
	local adjacent_links = args["Adjacent Links"]
	local header_row = args["Header"]
	local rows       = args["Rows"  ]
	local footer_row = args["Footer"]
	
	-- Nested helper function
	-- Produces the title and, if present, prev/next links
	function infobox_title()
		if adjacent_links == nil then
			return title
		elseif #adjacent_links == 2 then
			lines = {}
			--table.insert(lines, "\n")
			table.insert(lines, '{| style="width: 100%;"')
			table.insert(lines, '|-')
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
			table.insert(lines, '| style="width: 50%;" | ' .. title)
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[2])
			table.insert(lines, '|}')
			
			return table.concat(lines, "\n")
		elseif #adjacent_links == 8 then
			lines = {}
			--table.insert(lines, "\n")
			table.insert(lines, '{| style="width: 100%;"')
			table.insert(lines, '|-')
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[1])
			table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[2])
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[3])
			table.insert(lines, '|-')
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[4])
			table.insert(lines, '| style="width: 50%;"  | ' .. title)
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[5])
			table.insert(lines, '|-')
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[6])
			table.insert(lines, '| style="font-size: 0.75em; width: 50%;" | ' .. adjacent_links[7])
			table.insert(lines, '| style="font-size: 0.75em;" | ' .. adjacent_links[8])
			table.insert(lines, '|}')
				
			return table.concat(lines, "\n")
		else
			return title
		end
	end
	
	-- Nested helper function
	-- Produces a row in the infobox
	function infobox_row(row_content)
		if #row_content > 1 then
			local lines = {}
			table.insert(lines, '|-')
			table.insert(lines, '| style="text-align: right; padding-right: 0.25em;" | ' .. row_content[1])
			table.insert(lines, '| style="background-color: white; padding-left: 0.25em; font-weight: bold;" | ' .. row_content[2])
			
			return table.concat(lines, "\n")
		elseif #row_content == 1 then
			local lines = {}
			table.insert(lines, '|-')
			table.insert(lines, '| colspan="2" style="text-align: center;" | ' .. row_content[1])
			
			return table.concat(lines, "\n")
		end
	end
	
	-- Nested helper function
	-- Produces a header or footer row
	function header_footer_row(row_content)
		local lines = {}
		table.insert(lines, '|-')
		table.insert(lines, '| colspan="2" style="text-align: center; font_size: 0.8em;" | ' .. row_content)
		
		return table.concat(lines, "\n")
	end
	
	-- Start of infobox; outer div and start of table
	local lines = {}
	
	-- Infobox boilerplate
	table.insert(lines, [[<div style="
		border: 1px solid #999; 
		margin: 0; 
		margin-left: 1em; 
		margin-bottom: 0.5em; 
		padding: 0.5em; 
		background-color: #f0f0f0; 
		min-width: 15em; 
		float: right; 
		max-width: 100%; 
		overflow: auto;">]]
	)
	table.insert(lines, '{| style="border-collapse: collapse; width: 100%;"')
	table.insert(lines, '|+ style="font-size: 105%; font-weight: bold; text-align: center;" | ')
	
	-- Title
	table.insert(lines, infobox_title())
	
	-- Header
	if header_row then
		table.insert(lines, header_footer_row(header_row))
	end
		
	-- Rows
	for i = 1, #rows do
		table.insert(lines, infobox_row(rows[i]))
	end
	
	-- Footer
	if footer_row then
		table.insert(lines, header_footer_row(footer_row))
	end
	
	-- End of infobox
	table.insert(lines, "|}</div>")

	return table.concat(lines, "\n")
end

-- Function to be #invoke'd
-- Wrapper function for template-based infoboxes
-- Modeled off of navbox
function p.infobox(frame)
	local args = getArgs(frame)
	
	-- Preprocess adjacent links
	-- If there are two adjacent links (such as with edos), then links will be
	-- placed on the left and right of the title:
	--		[Link 1] Title [Link 2]
	-- - Link 1 is previous, link 2 is next
	-- If there are eight adjacent links (such as with mosses), then links
	-- surround the title in a 3x3 grid:
	--		[Link 1] [Link 2] [Link 3]
	--		[Link 4]  Title   [Link 5]
	--		[Link 6] [Link 7] [Link 8]
	-- Individual links can be omitted. If at least one upper or lower link is
	-- present, then rows for those two sets of links are added. Having no links
	-- defaults to having only the title.
	local is_upper_lower_links_present = args["Upper Left Link"] ~= nil or args["Upper Link"] ~= nil or args["Upper Right Link"] ~= nil
		or args["Lower Left Link"] ~= nil or args["Lower Link"] ~= nil or args["Lower Right Link"] ~= nil
	local is_side_links_present  = args["Left Link"] ~= nil or args["Right Link"] ~= nil
	
	local adjacent_links = {}
	if is_upper_lower_links_present then
		table.insert(adjacent_links, args["Upper Left Link" ] or "")
		table.insert(adjacent_links, args["Upper Link"      ] or "")
		table.insert(adjacent_links, args["Upper Right Link"] or "")
	end
	if is_side_links_present then
		table.insert(adjacent_links, args["Left Link" ] or "")
		table.insert(adjacent_links, args["Right Link"] or "")
	end
	if is_upper_lower_links_present then
		table.insert(adjacent_links, args["Lower Left Link" ] or "")
		table.insert(adjacent_links, args["Lower Link"      ] or "")
		table.insert(adjacent_links, args["Lower Right Link"] or "")
	end
	args["Adjacent Links"] = adjacent_links
	
	-- Cleanup individual links, as they've been combined into one table
	args["Upper Left Link" ] = nil
	args["Upper Link"      ] = nil
	args["Upper Right Link"] = nil
	args["Left Link"       ] = nil
	args["Right Link"      ] = nil
	args["Lower Left Link" ] = nil
	args["Lower Link"      ] = nil
	args["Lower Right Link"] = nil
	
	-- Preprocess rows
	-- Set row count to 30, under the reasoning that an infobox may need more
	-- rows and/or headers. This may be increased to 40 if needed.
	local rows = {}
	for i = 1, 30 do
		local header = args["Header " .. i]
		local data   = args["Data "   .. i]
		
		local row = nil
		if (header == nil and data ~= nil) then
			row = {}
			table.insert(row, data)
		elseif (header ~= nil and data ~= nil) then
			row = {}
			table.insert(row, header)
			table.insert(row, data)
		end
		if row ~= nil then
			table.insert(rows, row)
		end
		
		-- Remove original entries as cleanup
		args["Header " .. i] = nil
		args["Data "   .. i] = nil
	end
	args["Rows"] = rows
	
	
	local result = p._infobox(args)
	local debugg = yesno(args["debug"])
	if debugg == true then
		result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>"
	end
	
	return result
end

--------------------------------------------------------------------------------
------------------------------- LEGACY FUNCTIONS -------------------------------
--------------------------------------------------------------------------------

-- These functions are kept in the meantime to support older infoboxes and WILL
-- be entirely deleted later! Please switch to the new functions!

-- Original function signature, kept for legacy support (for now).
function p.build(title, entries, prev_link, next_link)
	local args = {
		["Adjacent Links"] = { (prev_link or ""), (next_link or "") },
		["Title"] = title,
		["Rows"] = entries,
	}

	return p._infobox(args)
end

-- Original 8-link function signature, pulled from infobox mos.
function p.build_multilink(title, entries, adjacent_links)
	local args = {
		["Adjacent Links"] = adjacent_links,
		["Title"] = title,
		["Rows"] = entries,
	}

	return p._infobox(args)
end

return p