Jump to content

Module:OOOInfoBox: Difference between revisions

From Out of Ore Wiki
No edit summary
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
-- Module:OOOInfoBox
local DATA = require('Module:OOO/Data')
local DATA = require('Module:OOO/Data')
local p = {}
local p = {}
-- --- helpers ---------------------------------------------------------------


local function trim(s) return s and mw.text.trim(tostring(s)) or s end
local function trim(s) return s and mw.text.trim(tostring(s)) or s end
Line 7: Line 10:
   v = data and data[key]; if v ~= nil and tostring(v) ~= '' then return v end
   v = data and data[key]; if v ~= nil and tostring(v) ~= '' then return v end
end
end
local function warn(msg)
local function warn(msg)
   return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
   return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
end
local function render_image(name)
  if not name or name == '' then return nil end
  return string.format('[[File:%s|center|300px]]', mw.text.trim(name))
end
-- units
local U = {
  m  = '&nbsp;m',
  m2 = '&nbsp;m<sup>2</sup>',
  m3 = '&nbsp;m<sup>3</sup>',
  mw = '&nbsp;MW',
  kw = '&nbsp;kW',
  pmin = '&nbsp;/&nbsp;min',
}
local function with_unit(v, unit)
  if v == nil or v == '' then return nil end
  return tostring(v) .. (unit or '')
end
-- label + tooltip
local function label_with_tip(label, tip)
  if not tip or tip == '' then return label end
  return string.format('<span title="%s">%s</span>', tip, label)
end
-- row builders
local function add_row(tbl, label, value, tip)
  if value ~= nil and tostring(value) ~= '' then
    local tr = tbl:tag('tr')
    tr:tag('th'):wikitext(label_with_tip(label, tip))
    tr:tag('td'):wikitext(value)
  end
end
local function add_group_header(tbl, text)
  local tr = tbl:tag('tr'):addClass('ooo-infobox__group')
  tr:tag('th'):attr('colspan', '2'):wikitext(text)
end
local function add_group(tbl, header, rows)
  -- rows: { {label, value, tip}, ... }
  local has = false
  for _, r in ipairs(rows) do
    if r then
      local v = r[2]
      if v ~= nil and tostring(v) ~= '' then
        has = true
        break
      end
    end
  end
  if not has then return end
  add_group_header(tbl, header)
  for _, r in ipairs(rows) do
    if r then
      local label, value, tip = r[1], r[2], r[3]
      if value ~= nil and tostring(value) ~= '' then
        add_row(tbl, label, value, tip)
      end
    end
  end
end
end
-- Compact "W × L × H" builder (returns nil when nothing to show)
local function join_dims(a, b, c, unit)
  local parts = {}
  if a then parts[#parts+1] = tostring(a) end
  if b then parts[#parts+1] = tostring(b) end
  if c then parts[#parts+1] = tostring(c) end
  if #parts == 0 then return nil end
  return table.concat(parts, ' × ') .. (unit or '')
end
-- --- main ------------------------------------------------------------------


function p.building(frame)
function p.building(frame)
Line 16: Line 93:
   local args = parent.args or {}
   local args = parent.args or {}


   -- Required inputs
   local out = mw.html.create('div')
   local domain = trim(args.type or args.domain or 'Buildings') -- default to Buildings for convenience
  out:wikitext(frame:extensionTag('templatestyles', '', { src = 'Template:OOOInfoBox/styles.css' }))
 
   local domain = trim(args.type or args.domain or 'Buildings')
   local art    = trim(args.art or args.artNumber or args.id)
   local art    = trim(args.art or args.artNumber or args.id)
   if not art or art == '' then
   if not art or art == '' then
     return warn('Use |art=ART_NUMBER (e.g. 400113).')
     out:wikitext(warn('Use |art=ART_NUMBER (e.g. 400113).'))
    return tostring(out)
   end
   end


  -- Lookup record
   local data = DATA.get(domain, art)
   local data = DATA.get(domain, art)
   if not data then
   if not data then
     return warn(('No record for %s:%s.'):format(domain, art))
     out:wikitext(warn(('No record for %s:%s.'):format(domain, art)))
    return tostring(out)
  end
 
  -- fields
  local title  = pick(args, data, 'displayName') or ('Item '..art)
  local image  = pick(args, data, 'image') or 'Icon SM AsphaltPlantV3.png'
  local caption = pick(args, data, 'description') or pick(args, data, 'caption')
 
  local box = mw.html.create('table'):addClass('ooo-infobox')
  -- optional width (keeps CSS default if omitted)
  local w = tonumber((frame:getParent() or frame).args.width)
  if w and w >= 240 and w <= 600 then
    box:css('width', w .. 'px')
   end
   end


   -- Build table
 
   local box = mw.html.create('table'):addClass('infobox')
   -- default is right via CSS; only add class when overriding
   local title = pick(args, data, 'displayName') or ('Item '..art)
   local align = trim(args.align)
  box:tag('tr'):tag('th'):attr('colspan','2'):wikitext(title)
  if align == 'left' then
    box:addClass('ooo-infobox--left')
   elseif align == 'none' then
    box:addClass('ooo-infobox--none')
  elseif align == 'center' then
    box:addClass('ooo-infobox--center')
  end


   local function row(label, key, fixed)
   -- keep optional extra classes
    local v = fixed or pick(args, data, key)
  local extra_class = trim(args.class)
    if v ~= nil and tostring(v) ~= '' then
  if extra_class and extra_class ~= '' then
      local tr = box:tag('tr')
    for c in mw.text.gsplit(extra_class, '%s+') do box:addClass(c) end
      tr:tag('th'):wikitext(label)
  end
      tr:tag('td'):wikitext(v)
 
     end
  -- Title
  box:tag('tr')
    :tag('th')
        :addClass('ooo-infobox__title')
        :attr('colspan', '2')
        :wikitext(title)
 
  -- Image
  local img = render_image(image)
  if img then
    box:tag('tr')
      :tag('td')
        :addClass('ooo-infobox__image')
        :attr('colspan','2')
        :wikitext(img)
  end
  if caption and caption ~= '' then
     box:tag('tr')
      :tag('td')
        :addClass('ooo-infobox__caption')
        :attr('colspan','2')
        :wikitext(caption)
   end
   end


   row('Domain', nil, domain)
   -- Basics
   row('Art Number', nil, art)
add_group(box, 'General', {
   row('Type', 'type')
   {'Art Number', art},
   row('Throughput (m³/h)', 'throughput_m3h')
  {'Category',  pick(args, data, 'category')},
   row('Power (kW)', 'power_kw')
   {'Subcategory',pick(args, data, 'subcategory')},
   row('Capacity', 'capacity')
  {'Price',      pick(args, data, 'price')},
   {'Domain',    domain},
})
 
-- Performance (auto-hides if empty)
add_group(box, 'Performance', {
  {'Throughput (m³/h)', pick(args, data, 'throughput_m3h')},
   {'Capacity',          pick(args, data, 'capacity')},
})
 
-- Power (keep separate from Performance; easy to add more later)
add_group(box, 'Power', {
  {'Power (kW)', with_unit(pick(args, data, 'power_kw'), U.kw)},
   -- Example for later: {'Generated (MW)', with_unit(pick(args, data, 'power_generated_mw'), U.mw)},
})
 
-- I/O (mergers/splitters etc.)
add_group(box, 'I/O', {
  {'Conveyor inputs',  pick(args, data, 'beltInputs')},
  {'Conveyor outputs', pick(args, data, 'beltOutputs')},
  {'Pipeline inputs',  pick(args, data, 'pipeInputs')},
  {'Pipeline outputs', pick(args, data, 'pipeOutputs')},
})
 
-- Dimensions: supports size={x,y,z} OR flat keys; always compact
local sx, sy, sz
if data.size and type(data.size) == 'table' then
  sx, sy, sz = data.size.x, data.size.y, data.size.z
end
local size_w    = pick(args, data, 'size_width')  or sx
local size_l    = pick(args, data, 'size_length') or sy
local size_h    = pick(args, data, 'size_height') or sz
local size_note = pick(args, data, 'size_note')
 
add_group(box, 'Dimensions', {
  {'Overall', join_dims(size_w, size_l, size_h, U.m), 'Width × Length × Height'},
  {'Note',    size_note},
})
 


   return tostring(box)
  out:node(box)
   return tostring(out)
end
end


return p
return p

Latest revision as of 20:08, 12 October 2025

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

-- Module:OOOInfoBox
local DATA = require('Module:OOO/Data')
local p = {}

-- --- helpers ---------------------------------------------------------------

local function trim(s) return s and mw.text.trim(tostring(s)) or s end
local function pick(args, data, key)
  local v = args[key]; if v and trim(v) ~= '' then return trim(v) end
  v = data and data[key]; if v ~= nil and tostring(v) ~= '' then return v end
end
local function warn(msg)
  return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
end
local function render_image(name)
  if not name or name == '' then return nil end
  return string.format('[[File:%s|center|300px]]', mw.text.trim(name))
end

-- units
local U = {
  m  = '&nbsp;m',
  m2 = '&nbsp;m<sup>2</sup>',
  m3 = '&nbsp;m<sup>3</sup>',
  mw = '&nbsp;MW',
  kw = '&nbsp;kW',
  pmin = '&nbsp;/&nbsp;min',
}

local function with_unit(v, unit)
  if v == nil or v == '' then return nil end
  return tostring(v) .. (unit or '')
end

-- label + tooltip
local function label_with_tip(label, tip)
  if not tip or tip == '' then return label end
  return string.format('<span title="%s">%s</span>', tip, label)
end

-- row builders
local function add_row(tbl, label, value, tip)
  if value ~= nil and tostring(value) ~= '' then
    local tr = tbl:tag('tr')
    tr:tag('th'):wikitext(label_with_tip(label, tip))
    tr:tag('td'):wikitext(value)
  end
end

local function add_group_header(tbl, text)
  local tr = tbl:tag('tr'):addClass('ooo-infobox__group')
  tr:tag('th'):attr('colspan', '2'):wikitext(text)
end

local function add_group(tbl, header, rows)
  -- rows: { {label, value, tip}, ... }
  local has = false
  for _, r in ipairs(rows) do
    if r then
      local v = r[2]
      if v ~= nil and tostring(v) ~= '' then
        has = true
        break
      end
    end
  end
  if not has then return end
  add_group_header(tbl, header)
  for _, r in ipairs(rows) do
    if r then
      local label, value, tip = r[1], r[2], r[3]
      if value ~= nil and tostring(value) ~= '' then
        add_row(tbl, label, value, tip)
      end
    end
  end
end

-- Compact "W × L × H" builder (returns nil when nothing to show)
local function join_dims(a, b, c, unit)
  local parts = {}
  if a then parts[#parts+1] = tostring(a) end
  if b then parts[#parts+1] = tostring(b) end
  if c then parts[#parts+1] = tostring(c) end
  if #parts == 0 then return nil end
  return table.concat(parts, ' × ') .. (unit or '')
end

-- --- main ------------------------------------------------------------------

function p.building(frame)
  local parent = frame:getParent() or frame
  local args = parent.args or {}

  local out = mw.html.create('div')
  out:wikitext(frame:extensionTag('templatestyles', '', { src = 'Template:OOOInfoBox/styles.css' }))

  local domain = trim(args.type or args.domain or 'Buildings')
  local art    = trim(args.art or args.artNumber or args.id)
  if not art or art == '' then
    out:wikitext(warn('Use |art=ART_NUMBER (e.g. 400113).'))
    return tostring(out)
  end

  local data = DATA.get(domain, art)
  if not data then
    out:wikitext(warn(('No record for %s:%s.'):format(domain, art)))
    return tostring(out)
  end

  -- fields
  local title   = pick(args, data, 'displayName') or ('Item '..art)
  local image   = pick(args, data, 'image') or 'Icon SM AsphaltPlantV3.png'
  local caption = pick(args, data, 'description') or pick(args, data, 'caption')

  local box = mw.html.create('table'):addClass('ooo-infobox')
  -- optional width (keeps CSS default if omitted)
  local w = tonumber((frame:getParent() or frame).args.width)
  if w and w >= 240 and w <= 600 then
    box:css('width', w .. 'px')
  end

  
  -- default is right via CSS; only add class when overriding
  local align = trim(args.align)
  if align == 'left' then
    box:addClass('ooo-infobox--left')
  elseif align == 'none' then
    box:addClass('ooo-infobox--none')
  elseif align == 'center' then
    box:addClass('ooo-infobox--center')
  end

  -- keep optional extra classes
  local extra_class = trim(args.class)
  if extra_class and extra_class ~= '' then
    for c in mw.text.gsplit(extra_class, '%s+') do box:addClass(c) end
  end

  -- Title
  box:tag('tr')
     :tag('th')
        :addClass('ooo-infobox__title')
        :attr('colspan', '2')
        :wikitext(title)

  -- Image
  local img = render_image(image)
  if img then
    box:tag('tr')
       :tag('td')
         :addClass('ooo-infobox__image')
         :attr('colspan','2')
         :wikitext(img)
  end
  if caption and caption ~= '' then
    box:tag('tr')
       :tag('td')
         :addClass('ooo-infobox__caption')
         :attr('colspan','2')
         :wikitext(caption)
  end

  -- Basics
add_group(box, 'General', {
  {'Art Number', art},
  {'Category',   pick(args, data, 'category')},
  {'Subcategory',pick(args, data, 'subcategory')},
  {'Price',      pick(args, data, 'price')},
  {'Domain',     domain},
})

-- Performance (auto-hides if empty)
add_group(box, 'Performance', {
  {'Throughput (m³/h)', pick(args, data, 'throughput_m3h')},
  {'Capacity',          pick(args, data, 'capacity')},
})

-- Power (keep separate from Performance; easy to add more later)
add_group(box, 'Power', {
  {'Power (kW)', with_unit(pick(args, data, 'power_kw'), U.kw)},
  -- Example for later: {'Generated (MW)', with_unit(pick(args, data, 'power_generated_mw'), U.mw)},
})

-- I/O (mergers/splitters etc.)
add_group(box, 'I/O', {
  {'Conveyor inputs',  pick(args, data, 'beltInputs')},
  {'Conveyor outputs', pick(args, data, 'beltOutputs')},
  {'Pipeline inputs',  pick(args, data, 'pipeInputs')},
  {'Pipeline outputs', pick(args, data, 'pipeOutputs')},
})

-- Dimensions: supports size={x,y,z} OR flat keys; always compact
local sx, sy, sz
if data.size and type(data.size) == 'table' then
  sx, sy, sz = data.size.x, data.size.y, data.size.z
end
local size_w    = pick(args, data, 'size_width')  or sx
local size_l    = pick(args, data, 'size_length') or sy
local size_h    = pick(args, data, 'size_height') or sz
local size_note = pick(args, data, 'size_note')

add_group(box, 'Dimensions', {
  {'Overall', join_dims(size_w, size_l, size_h, U.m), 'Width × Length × Height'},
  {'Note',    size_note},
})


  out:node(box)
  return tostring(out)
end

return p