Jump to content

Module:Infobox functions

From WhiskerWiki

Documentation for this module may be created at Module:Infobox functions/doc

local cargo = mw.ext.cargo -- for cargo queries if needed
local utils = require("Module:Utilities")



local ibf = {}


-- Helper function to escape_html
local function escape_html(text)
    if not text or text == "" then return "" end -- Prevent error if text is nil

    text = text:gsub("&(?![%w#]+;)", "&")   -- Escape ampersands unless already part of an entity (e.g. &, ')
    text = text:gsub("'", "'")              -- Escape single quotes
    text = text:gsub('"', """)             -- Escape double quotes
    text = text:gsub(">", ">")               -- Escape greater-than sign
    text = text:gsub("<", "&lt;")               -- Escape less-than sign
    text = text:gsub("&lt;br ?/?&gt;", "<br/>")  -- Allow <br> or <br/>

    -- Allow known safe formatting tags back in (optional)
    text = text:gsub("&lt;i&gt;", "<i>")        -- Unescape <i> tag
    text = text:gsub("&lt;/i&gt;", "</i>")      -- Unescape </i> tag
    text = text:gsub("&lt;b&gt;", "<b>")        -- Unescape <b> tag
    text = text:gsub("&lt;/b&gt;", "</b>")      -- Unescape </b> tag

    return text                                 -- Return the processed, safe HTML text
end



-- Deprecated
function ibf.create_infobox_old(root, title, subtitle, html_theme_class)
    
    -- Escape HTML characters in title and subtitle
    title = escape_html(title)
    subtitle = escape_html(subtitle)    
    
    -- Begin creating the html table infobox template
    root = mw.html.create('table')
        :addClass('infobox')
        :addClass('infobox' .. html_theme_class)

    -- Title row (standalone)
    root:tag('tr')
        :tag('th')
            :addClass('infobox-title')
            :addClass('infobox-title' .. html_theme_class)
            :attr('colspan', 2)
            :wikitext(title)

    -- Subtitle row (separate row for clean styling)
    if subtitle and subtitle ~= '' then
        root:tag('tr')
            :tag('th')
                :addClass('infobox-subtitle')
                :addClass('infobox-subtitle' .. html_theme_class)
                :attr('colspan', 2)
                :wikitext(subtitle)
    end

    -- Add spacer row after the title and subtitle
    root:tag('tr')
        :tag('td')
            :addClass('spacer-row')
            :attr('colspan', 2)
        :done()

    return root
end






function ibf.create_infobox(root, title, subtitle, html_theme_class)
    
    -- Escape HTML characters in title
    title = escape_html(title)
    subtitle = escape_html(subtitle)    
    
    
    -- Begin creating the html table infobox template
    root = mw.html.create('table')
        :addClass('infobox')
        :addClass('infobox' .. html_theme_class)

    -- Prepare title and subtitle content
    local content = mw.html.create('')
    content:wikitext(title)
    if subtitle and subtitle ~= '' then
        -- Add the subtitle directly after the title, within the same <th> element
        content
            :newline()
            :tag('div') -- Use a div for subtitle for more control
                :addClass('infobox-subtitle')
                :wikitext(subtitle)
                :allDone()
    end

    -- Add title (and subtitle) to the infobox
    root:tag('tr')
        :tag('th')
            :addClass('infobox-title')
            -- add additional styles based on taxon
            :addClass('infobox-title' .. html_theme_class)
            :attr('colspan', 2)
            :node(content) -- Use the prepared content that includes both title and subtitle
            :done()

    -- Add spacer row after the title/subtitle
    root:tag('tr')
        :tag('td')
            :addClass('spacer-row')
            :attr('colspan', 2)
        :done()

    return root
end





function ibf.add_subtitle(root, text, html_theme_class, colspan)
    if text then
	    root:tag('tr')
	        :tag('th')
	            :addClass('infobox-subtitle')
	            :addClass('infobox-subtitle' .. html_theme_class)
	            :wikitext(text)
	            :attr('colspan', colspan or 2)
	            :css('text-align', 'center')
	        :done()
	        
	    -- Add spacer row after
        root:tag('tr')
            :tag('td')
                :addClass('spacer-row')
                :attr('colspan', colspan or 2)
            :done()
            return root
    	else return root
	end	
end





function ibf.add_header(root, text, html_theme_class, colspan)
    if text then
        -- Add spacer row before header
        root:tag('tr')
            :tag('td')
                :addClass('spacer-row') -- Use a different class if styling differs from the after-header spacer
                :attr('colspan', colspan or 2)
            :done()

        -- Add header row
        root:tag('tr')
            :tag('th')
                :addClass('infobox-header')
                :addClass('infobox-header' .. html_theme_class)
                :wikitext(text)
                :attr('colspan', colspan or 2)
                :css('text-align', 'center')
            :done()

        -- Add spacer row after header (as before)
        root:tag('tr')
            :tag('td')
                :addClass('spacer-row')
                :attr('colspan', colspan or 2)
            :done()

        return root
    else 
        return root
    end
end





-- Add an image row to an infobox
-- Arguments:
-- root (table): The root tag object
-- image (string): The image filename or external URL
-- html_theme_class (string): CSS class to add
-- options (table, optional):
--     link (string): Link target when clicking the image
--     caption (string): Caption to show under the image (optional)
function ibf.add_image(root, image, html_theme_class, options)
    options = options or {}

    if image ~= nil and image ~= "" then
        -- Add "File:" prefix if needed
        image = utils.add_file_prefix_gentle(image)

        -- Check if it's a URL
        local is_url = image:match("^https?://") ~= nil

        -- Create the image row
        local td = root:tag('tr'):tag('td')
        td:addClass('infobox-image')
          :addClass('infobox-image' .. html_theme_class)
          :attr('colspan', 2)

        -- Helper function to build image wikitext
        local function build_image_markup()
            local link_part = options.link and ("|link=" .. options.link) or ""
            local caption_part = options.caption and ("|" .. options.caption) or ""
            return string.format('[[%s|300px|frameless|center%s%s]]', image, link_part, caption_part)
        end

        if is_url then
            td:wikitext(image)
        else
            td:wikitext(build_image_markup())
        end

        td:done()

        -- Add spacer row after
        root:tag('tr')
            :tag('td')
                :addClass('spacer-row')
                :attr('colspan', 2)
            :done()

        return root
    else
        return root
    end
end




function ibf.add_row(root, name, value, html_theme_class)
    -- Return root immediately if either name or value are nil or empty
    if not (name and name ~= "" and value and value ~= "") then
        return root
    end

    local row_type_class = 'infobox-row' .. html_theme_class

    root:tag('tr')
        :tag('td')
            :addClass(row_type_class)
            :addClass('infobox-label') -- Add label-specific class for padding
            :wikitext('<b>' .. name .. '</b>')
        :done()
        :tag('td')
            :addClass(row_type_class)
            :wikitext(value)
        :done()

    return root
end






function ibf.add_spanning_row(root, text, html_theme_class)
    if text and text ~= '' then
        
        root:tag('tr')
            :tag('td')
                :attr('colspan', '2')
                :addClass('infobox-row')
                :addClass('infobox-row' .. html_theme_class)
                :css('text-align', 'center') -- This line centers the text
                :wikitext(text)
                :done()
        return root
    else 
        return root
    end
end




--[[
This function is used for now only on WhiskerWiki.
--]]
function ibf.create_infobox_small(root, title, html_theme_class)
    -- Begin creating the html table infobox template
    root = mw.html.create('table')
        :addClass('infobox_small')
        :addClass('infobox_small' .. html_theme_class)

    -- add title
    root:tag('tr')
        :tag('th')
        :addClass('infobox_small-title')
        -- add additional styles based on taxon
        :addClass('infobox_small-title' .. html_theme_class)
        :attr('colspan', 2)
        :wikitext(title)
        :done()
        
        -- Add spacer row after
        root:tag('tr')
            :tag('td')
                :addClass('spacer-row')
                :attr('colspan', colspan or 2)
            :done()
        
    return root
end 








return ibf
Cookies help us deliver our services. By using our services, you agree to our use of cookies.