Jump to content

Module:OOOInfoBox: Difference between revisions

From Out of Ore Wiki
No edit summary
Tag: Reverted
No edit summary
Tag: Manual revert
Line 1: Line 1:
-- Module:OOOInfoBox
local DATA = require('Module:OOO/Data')
local p = {}
local p = {}


-- Try JSON first (Template:Docs.json), then Lua table (Module:DocsJSON)
-- --- helpers ---------------------------------------------------------------
local function load_docs()
    local ok, data = pcall(mw.loadJsonData, 'Template:Docs.json')
    if ok and type(data) == 'table' then
        return data, 'Template:Docs.json (loadJsonData)'
    end


    local t = mw.title.new('Template:Docs.json')
local function trim(s) return s and mw.text.trim(tostring(s)) or s end
    if t then
local function pick(args, data, key)
        local content = t:getContent()
  local v = args[key]; if v and trim(v) ~= '' then return trim(v) end
        if content and content ~= '' then
  v = data and data[key]; if v ~= nil and tostring(v) ~= '' then return v end
            local ok2, tbl = pcall(mw.text.jsonDecode, content)
end
            if ok2 and type(tbl) == 'table' then
local function warn(msg)
                return tbl, 'Template:Docs.json (jsonDecode)'
  return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
            end
end
        end
local function render_image(name)
    end
  if not name or name == '' then return nil end
  return string.format('[[File:%s|center|300px]]', mw.text.trim(name))
end
end


local DOCS, SOURCE = load_docs()
-- 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 trim(s) return s and mw.text.trim(tostring(s)) or s end
local function with_unit(v, unit)
local function pick(args, data, key)
  if v == nil or v == '' then return nil end
    local v = args[key]; if v and trim(v) ~= '' then return trim(v) end
  return tostring(v) .. (unit or '')
    v = data[key]; if v ~= nil and tostring(v) ~= '' then return v end
end
end


local function warn(msg)
-- label + tooltip
    return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
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
end


-- more forgiving key lookup + debug
-- row builders
local function find_record(art)
local function add_row(tbl, label, value, tip)
    -- direct lookups
  if value ~= nil and tostring(value) ~= '' then
     local rec = DOCS[art] or DOCS[tostring(tonumber(art) or art)]
     local tr = tbl:tag('tr')
     if rec then return rec end
    tr:tag('th'):wikitext(label_with_tip(label, tip))
     tr:tag('td'):wikitext(value)
  end
end


    -- trim/loose match on keys (handles stray spaces/non-visible chars)
local function add_group_header(tbl, text)
    local art_trim = trim(art)
  local tr = tbl:tag('tr'):addClass('ooo-infobox__group')
    for k, v in pairs(DOCS) do
  tr:tag('th'):attr('colspan', '2'):wikitext(text)
        if trim(tostring(k)) == art_trim then
            return v
        end
    end
    return nil
end
end
-- --- main ------------------------------------------------------------------


function p.building(frame)
function p.building(frame)
    local args = frame:getParent().args or {}
  local parent = frame:getParent() or frame
    local art = trim(args.art or args.artNumber or args.id)
  local args = parent.args or {}
    if not art or art == '' then
 
        return warn('Use |art=ART_NUMBER (e.g. 400113).')
  local out = mw.html.create('div')
     end
  out:wikitext(frame:extensionTag('templatestyles', '', { src = 'Template:OOOInfoBox/styles.css' }))
     if type(DOCS) ~= 'table' or next(DOCS) == nil then
 
         return warn('Could not load data. Tried: '..(SOURCE or '(unknown)')..'.')
  local domain = trim(args.type or args.domain or 'Buildings')
     end
  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')
 
  -- 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_row(box, 'Domain', domain)
  add_row(box, 'Art Number', art)
  add_row(box, 'Type', pick(args, data, 'type'))
 
  -- Performance / Power
  add_group_header(box, 'Performance')
  add_row(box, 'Throughput (m³/h)', pick(args, data, 'throughput_m3h'))
  add_row(box, 'Power (kW)', with_unit(pick(args, data, 'power_kw'), U.kw))
  add_row(box, 'Capacity', pick(args, data, 'capacity'))


    local data = find_record(art)
  -- I/O (mergers/splitters etc.)
    if not data then
  local belt_in  = pick(args, data, 'beltInputs')
        -- show a few keys to diagnose quickly
  local belt_out = pick(args, data, 'beltOutputs')
        local samples, count = {}, 0
  local pipe_in  = pick(args, data, 'pipeInputs')
        for k, _ in pairs(DOCS) do
  local pipe_out = pick(args, data, 'pipeOutputs')
            count = count + 1
  if belt_in or belt_out or pipe_in or pipe_out then
            if #samples < 5 then table.insert(samples, '"'..tostring(k)..'"') end
    add_group_header(box, 'I/O')
        end
    add_row(box, 'Conveyor inputs', belt_in)
        local sample_txt = (#samples > 0) and table.concat(samples, ', ') or '(no keys)'
    add_row(box, 'Conveyor outputs', belt_out)
        return warn(('Key "%s" not found in %s. Sample keys: %s (count: %d)')
    add_row(box, 'Pipeline inputs', pipe_in)
            :format(art, SOURCE or '(unknown)', sample_txt, count))
    add_row(box, 'Pipeline outputs', pipe_out)
    end
  end


    local box = mw.html.create('table'):addClass('infobox')
  -- Dimensions (with tiny tooltip like their wiki)
    local title = pick(args, data, 'displayName') or ('Item '..art)
  local size_w = pick(args, data, 'size_width')
    box:tag('tr'):tag('th'):attr('colspan','2'):wikitext(title)
  local size_l = pick(args, data, 'size_length')
  local size_h = pick(args, data, 'size_height')
  local size_note = pick(args, data, 'size_note')


     local function row(label, key, fixed)
  if size_w or size_l or size_h or size_note then
        local v = fixed or pick(args, data, key)
     add_group_header(box, 'Dimensions')
        if v ~= nil and tostring(v) ~= '' then
    add_row(box, 'Width',  with_unit(size_w, U.m), 'Measured outer width')
            local tr = box:tag('tr')
    add_row(box, 'Length', with_unit(size_l, U.m), 'Measured outer length')
            tr:tag('th'):wikitext(label)
    add_row(box, 'Height', with_unit(size_h, U.m), 'Measured to highest point')
            tr:tag('td'):wikitext(v)
    if tonumber(size_w) and tonumber(size_l) then
        end
      local area = tonumber(size_w) * tonumber(size_l)
      add_row(box, 'Area', with_unit(area, U.m2))
     end
     end
    add_row(box, 'Note', size_note)
  end


    row('Art Number', nil, art)
  out:node(box)
    row('Type', 'type')
  return tostring(out)
    row('Throughput (m³/h)', 'throughput_m3h')
    row('Power (kW)', 'power_kw')
    row('Capacity', 'capacity')
 
    box:wikitext('<!-- OOOInfoBox source: '..(SOURCE or 'unknown')..' -->')
    return tostring(box)
end
end


return p
return p

Revision as of 06:27, 7 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

-- --- 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')

  -- 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_row(box, 'Domain', domain)
  add_row(box, 'Art Number', art)
  add_row(box, 'Type', pick(args, data, 'type'))

  -- Performance / Power
  add_group_header(box, 'Performance')
  add_row(box, 'Throughput (m³/h)', pick(args, data, 'throughput_m3h'))
  add_row(box, 'Power (kW)', with_unit(pick(args, data, 'power_kw'), U.kw))
  add_row(box, 'Capacity', pick(args, data, 'capacity'))

  -- I/O (mergers/splitters etc.)
  local belt_in  = pick(args, data, 'beltInputs')
  local belt_out = pick(args, data, 'beltOutputs')
  local pipe_in  = pick(args, data, 'pipeInputs')
  local pipe_out = pick(args, data, 'pipeOutputs')
  if belt_in or belt_out or pipe_in or pipe_out then
    add_group_header(box, 'I/O')
    add_row(box, 'Conveyor inputs', belt_in)
    add_row(box, 'Conveyor outputs', belt_out)
    add_row(box, 'Pipeline inputs', pipe_in)
    add_row(box, 'Pipeline outputs', pipe_out)
  end

  -- Dimensions (with tiny tooltip like their wiki)
  local size_w = pick(args, data, 'size_width')
  local size_l = pick(args, data, 'size_length')
  local size_h = pick(args, data, 'size_height')
  local size_note = pick(args, data, 'size_note')

  if size_w or size_l or size_h or size_note then
    add_group_header(box, 'Dimensions')
    add_row(box, 'Width',  with_unit(size_w, U.m), 'Measured outer width')
    add_row(box, 'Length', with_unit(size_l, U.m), 'Measured outer length')
    add_row(box, 'Height', with_unit(size_h, U.m), 'Measured to highest point')
    if tonumber(size_w) and tonumber(size_l) then
      local area = tonumber(size_w) * tonumber(size_l)
      add_row(box, 'Area', with_unit(area, U.m2))
    end
    add_row(box, 'Note', size_note)
  end

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

return p