|
|
| Line 1: |
Line 1: |
| -- Module:OOOInfoBox
| |
| local DATA = require('Module:OOO/Data')
| |
| local p = {} | | local p = {} |
|
| |
|
| -- --- helpers --------------------------------------------------------------- | | -- Try JSON first (Template:Docs.json), then Lua table (Module:DocsJSON) |
| | 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 function trim(s) return s and mw.text.trim(tostring(s)) or s end | | local t = mw.title.new('Template:Docs.json') |
| local function pick(args, data, key)
| | if t then |
| local v = args[key]; if v and trim(v) ~= '' then return trim(v) end
| | local content = t:getContent() |
| v = data and data[key]; if v ~= nil and tostring(v) ~= '' then return v end
| | if content and content ~= '' then |
| end
| | local ok2, tbl = pcall(mw.text.jsonDecode, content) |
| local function warn(msg) | | if ok2 and type(tbl) == 'table' then |
| return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>'
| | return tbl, 'Template:Docs.json (jsonDecode)' |
| end
| | end |
| local function render_image(name)
| | end |
| if not name or name == '' then return nil end
| | end |
| return string.format('[[File:%s|center|300px]]', mw.text.trim(name))
| |
| end | | end |
|
| |
|
| -- units
| | local DOCS, SOURCE = load_docs() |
| local U = { | |
| m = ' m',
| |
| m2 = ' m<sup>2</sup>',
| |
| m3 = ' m<sup>3</sup>',
| |
| mw = ' MW',
| |
| kw = ' kW',
| |
| pmin = ' / min',
| |
| }
| |
|
| |
|
| local function with_unit(v, unit) | | local function trim(s) return s and mw.text.trim(tostring(s)) or s end |
| if v == nil or v == '' then return nil end
| | local function pick(args, data, key) |
| return tostring(v) .. (unit or '')
| | local v = args[key]; if v and trim(v) ~= '' then return trim(v) end |
| | v = data[key]; if v ~= nil and tostring(v) ~= '' then return v end |
| end | | end |
|
| |
|
| -- label + tooltip
| | local function warn(msg) |
| local function label_with_tip(label, tip) | | return '<div class="mw-message-box mw-message-box-warning"><b>OOOInfoBox</b>: '..msg..'</div>' |
| if not tip or tip == '' then return label end
| |
| return string.format('<span title="%s">%s</span>', tip, label)
| |
| end | | end |
|
| |
|
| -- row builders | | -- more forgiving key lookup + debug |
| local function add_row(tbl, label, value, tip) | | local function find_record(art) |
| if value ~= nil and tostring(value) ~= '' then
| | -- direct lookups |
| local tr = tbl:tag('tr') | | local rec = DOCS[art] or DOCS[tostring(tonumber(art) or art)] |
| tr:tag('th'):wikitext(label_with_tip(label, tip))
| | if rec then return rec end |
| tr:tag('td'):wikitext(value) | |
| end
| |
| end | |
|
| |
|
| local function add_group_header(tbl, text)
| | -- trim/loose match on keys (handles stray spaces/non-visible chars) |
| local tr = tbl:tag('tr'):addClass('ooo-infobox__group')
| | local art_trim = trim(art) |
| tr:tag('th'):attr('colspan', '2'):wikitext(text)
| | for k, v in pairs(DOCS) do |
| | 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 parent = frame:getParent() or frame
| | local args = frame:getParent().args or {} |
| local args = parent.args or {}
| | local art = trim(args.art or args.artNumber or args.id) |
| | if not art or art == '' then |
| | return warn('Use |art=ART_NUMBER (e.g. 400113).') |
| | end |
| | if type(DOCS) ~= 'table' or next(DOCS) == nil then |
| | return warn('Could not load data. Tried: '..(SOURCE or '(unknown)')..'.') |
| | end |
|
| |
|
| local out = mw.html.create('div')
| | local data = find_record(art) |
| out:wikitext(frame:extensionTag('templatestyles', '', { src = 'Template:OOOInfoBox/styles.css' }))
| | if not data then |
| | -- show a few keys to diagnose quickly |
| | local samples, count = {}, 0 |
| | for k, _ in pairs(DOCS) do |
| | count = count + 1 |
| | if #samples < 5 then table.insert(samples, '"'..tostring(k)..'"') end |
| | end |
| | local sample_txt = (#samples > 0) and table.concat(samples, ', ') or '(no keys)' |
| | return warn(('Key "%s" not found in %s. Sample keys: %s (count: %d)') |
| | :format(art, SOURCE or '(unknown)', sample_txt, count)) |
| | end |
|
| |
|
| local domain = trim(args.type or args.domain or 'Buildings')
| | local box = mw.html.create('table'):addClass('infobox') |
| local art = trim(args.art or args.artNumber or args.id)
| | local title = pick(args, data, 'displayName') or ('Item '..art) |
| if not art or art == '' then
| | box:tag('tr'):tag('th'):attr('colspan','2'):wikitext(title) |
| out:wikitext(warn('Use |art=ART_NUMBER (e.g. 400113).'))
| |
| return tostring(out)
| |
| end
| |
|
| |
|
| local data = DATA.get(domain, art)
| | local function row(label, key, fixed) |
| if not data then
| | local v = fixed or pick(args, data, key) |
| out:wikitext(warn(('No record for %s:%s.'):format(domain, art)))
| | if v ~= nil and tostring(v) ~= '' then |
| return tostring(out) | | local tr = box:tag('tr') |
| end
| | tr:tag('th'):wikitext(label) |
| | tr:tag('td'):wikitext(v) |
| | end |
| | end |
|
| |
|
| -- fields
| | row('Art Number', nil, art) |
| local title = pick(args, data, 'displayName') or ('Item '..art)
| | row('Type', 'type') |
| local image = pick(args, data, 'image') or 'Icon SM AsphaltPlantV3.png'
| | row('Throughput (m³/h)', 'throughput_m3h') |
| local caption = pick(args, data, 'description') or pick(args, data, 'caption')
| | row('Power (kW)', 'power_kw') |
| | | row('Capacity', 'capacity') |
| 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)
| | box:wikitext('<!-- OOOInfoBox source: '..(SOURCE or 'unknown')..' -->') |
| return tostring(out)
| | return tostring(box) |
| end | | end |
|
| |
|
| return p | | return p |