Module:CRTModel: Difference between revisions
Created page with "-- Module:CRTModel -- Builds the CRT infobox as strict HTML to avoid MediaWiki's whitespace -> <p><br></p> behavior. local p = {} local function trim(s) if s == nil then return nil end s = tostring(s) s = s:gsub('^%s+', ''):gsub('%s+$', '') if s == '' then return nil end return s end local function css(node, cssText) if cssText and cssText ~= '' then node:cssText(cssText) end return node end local function addSectionRow(tbl, title) local tr = tbl:tag('tr')..." |
No edit summary |
||
| Line 1: | Line 1: | ||
-- Module:CRTModel | -- Module:CRTModel | ||
-- Builds the CRT infobox as strict HTML to avoid | -- Builds the CRT infobox as strict HTML to avoid whitespace -> <p><br></p> | ||
-- Uses frame:preprocess() so parser functions like #ask and #formredlink evaluate. | |||
local p = {} | local p = {} | ||
| Line 26: | Line 27: | ||
end | end | ||
local function addRow(tbl, label, | local function addRow(tbl, label, valueHtmlOrWikitext, isRawHtml) | ||
local tr = tbl:tag('tr') | local tr = tbl:tag('tr') | ||
css(tr:tag('th'), 'text-align:left; padding:0.2em 0.4em;') | css(tr:tag('th'), 'text-align:left; padding:0.2em 0.4em;') | ||
:wikitext(label) | :wikitext(label) | ||
:wikitext( | local td = tr:tag('td') | ||
css(td, 'padding:0.2em 0.4em;') | |||
-- After preprocess, what we have is HTML. Use :node() to insert it as HTML. | |||
if isRawHtml then | |||
td:node(mw.html.create('span'):wikitext(valueHtmlOrWikitext)) | |||
else | |||
td:wikitext(valueHtmlOrWikitext) | |||
end | |||
end | end | ||
local function addFullRow(tbl, | local function addFullRow(tbl, valueHtmlOrWikitext, cssText, isRawHtml) | ||
local tr = tbl:tag('tr') | local tr = tbl:tag('tr') | ||
local td = tr:tag('td'):attr('colspan', '2') | local td = tr:tag('td'):attr('colspan', '2') | ||
css(td, cssText or '') | css(td, cssText or '') | ||
td:wikitext( | |||
if isRawHtml then | |||
td:node(mw.html.create('span'):wikitext(valueHtmlOrWikitext)) | |||
else | |||
td:wikitext(valueHtmlOrWikitext) | |||
end | |||
end | end | ||
| Line 50: | Line 64: | ||
local pageId = title.id or 0 | local pageId = title.id or 0 | ||
local brand = trim(args.brand) | local brand = trim(args.brand) | ||
local model_code = trim(args.model_code) | local model_code = trim(args.model_code) | ||
| Line 64: | Line 77: | ||
local standards_semantic = trim(args.standards_semantic) | local standards_semantic = trim(args.standards_semantic) | ||
local tbl = mw.html.create('table') | local tbl = mw.html.create('table') | ||
tbl:addClass('infobox') | tbl:addClass('infobox') | ||
css(tbl, 'float:right; clear:right; margin:0 0 1em 1em; width:22em; border:1px solid #a2a9b1; border-spacing:3px; background:#f8f9fa; font-size:88%; line-height:1.5em;') | css(tbl, 'float:right; clear:right; margin:0 0 1em 1em; width:22em; border:1px solid #a2a9b1; border-spacing:3px; background:#f8f9fa; font-size:88%; line-height:1.5em;') | ||
local caption = tbl:tag('caption') | local caption = tbl:tag('caption') | ||
css(caption, 'font-size:125%; font-weight:bold; padding:0.5em;') | css(caption, 'font-size:125%; font-weight:bold; padding:0.5em;') | ||
caption:wikitext((brand or '') .. ' ' .. (model_code or '')) | caption:wikitext((brand or '') .. ' ' .. (model_code or '')) | ||
if image_main then | if image_main then | ||
local file = image_main:gsub('^File:', '') | local file = image_main:gsub('^File:', '') | ||
| Line 80: | Line 90: | ||
tbl, | tbl, | ||
string.format('[[File:%s|frameless|300px]]', file), | string.format('[[File:%s|frameless|300px]]', file), | ||
'text-align:center; padding:0;' | 'text-align:center; padding:0;', | ||
false | |||
) | ) | ||
end | end | ||
addSectionRow(tbl, 'Overview') | addSectionRow(tbl, 'Overview') | ||
-- Brand row ( | -- Brand row using #formredlink (must preprocess) | ||
if brand then | if brand then | ||
local | local brandWikitext = string.format( | ||
'{{#formredlink: target=%s |form=Manufacturer |existing page link text=%s }}', | '{{#formredlink: target=%s |form=Manufacturer |existing page link text=%s }}', | ||
brand, brand | brand, brand | ||
) | ) | ||
addRow(tbl, 'Brand', | local brandHtml = frame:preprocess(brandWikitext) | ||
addRow(tbl, 'Brand', brandHtml, true) | |||
end | end | ||
-- ECID row | -- ECID row: build as a normal external link wikitext; preprocess not required, but fine. | ||
local ecidWikitext = string.format('[{{fullurl:%s|curid=%d}} EC%d]', pageName, pageId, pageId) | |||
local | addRow(tbl, 'ECID', frame:preprocess(ecidWikitext), true) | ||
addRow(tbl, 'ECID', | |||
if model_code then | if model_code then | ||
addRow(tbl, 'Model code', model_code) | addRow(tbl, 'Model code', model_code, false) | ||
else | else | ||
addRow(tbl, 'Model code', '', false) | |||
addRow(tbl, 'Model code', '') | |||
end | end | ||
if crt_type then | if crt_type then | ||
addRow(tbl, 'Type', crt_type) | addRow(tbl, 'Type', crt_type, false) | ||
end | end | ||
if screen_size_in then | if screen_size_in then | ||
addRow(tbl, 'Screen size', screen_size_in .. '″') | addRow(tbl, 'Screen size', screen_size_in .. '″', false) | ||
end | end | ||
if tvl then | if tvl then | ||
addRow(tbl, 'TVL', tvl) | addRow(tbl, 'TVL', tvl, false) | ||
end | end | ||
if chassis then | if chassis then | ||
local | local chassisWikitext = string.format( | ||
'{{#formredlink: target=%s |form=Chassis |existing page link text=%s }}', | '{{#formredlink: target=%s |form=Chassis |existing page link text=%s }}', | ||
chassis, chassis | chassis, chassis | ||
) | ) | ||
addRow(tbl, 'Chassis', | local chassisHtml = frame:preprocess(chassisWikitext) | ||
addRow(tbl, 'Chassis', chassisHtml, true) | |||
end | end | ||
if height or width or depth then | if height or width or depth then | ||
addSectionRow(tbl, 'Dimensions') | addSectionRow(tbl, 'Dimensions') | ||
| Line 133: | Line 141: | ||
local w = width or '–' | local w = width or '–' | ||
local d = depth or '–' | local d = depth or '–' | ||
addRow(tbl, 'H × W × D', string.format('%s × %s × %s', h, w, d)) | addRow(tbl, 'H × W × D', string.format('%s × %s × %s', h, w, d), false) | ||
end | end | ||
-- Weight row | -- Weight row: uses #show, so preprocess it | ||
if weight then | if weight then | ||
local weightWikitext = '{{#show: ' .. fullPageName .. ' |?Weight # lb }} / {{#show: ' .. fullPageName .. ' |?Weight # kg }}' | |||
addRow(tbl, 'Weight', frame:preprocess(weightWikitext), true) | |||
end | end | ||
-- Inputs section | -- Inputs section: preprocess #ask so it renders | ||
addSectionRow(tbl, 'Inputs') | addSectionRow(tbl, 'Inputs') | ||
local askWikitext = | |||
'{{#ask:\n' .. | '{{#ask:\n' .. | ||
' [[Has CRT model::' .. fullPageName .. ']]\n' .. | ' [[Has CRT model::' .. fullPageName .. ']]\n' .. | ||
| Line 154: | Line 163: | ||
' |named args=yes\n' .. | ' |named args=yes\n' .. | ||
' |searchlabel=\n' .. | ' |searchlabel=\n' .. | ||
'}}', | '}}' | ||
local askHtml = frame:preprocess(askWikitext) | |||
addFullRow(tbl, askHtml, 'padding:0.2em 0.4em;', true) | |||
addSectionRow(tbl, 'Standards') | addSectionRow(tbl, 'Standards') | ||
addFullRow(tbl, standards_semantic or '', 'padding:0.2em 0.4em;') | addFullRow(tbl, standards_semantic or '', 'padding:0.2em 0.4em;', false) | ||
return tostring(tbl) | return tostring(tbl) | ||
Revision as of 23:16, 22 December 2025
Documentation for this module may be created at Module:CRTModel/doc
-- Module:CRTModel
-- Builds the CRT infobox as strict HTML to avoid whitespace -> <p><br></p>
-- Uses frame:preprocess() so parser functions like #ask and #formredlink evaluate.
local p = {}
local function trim(s)
if s == nil then return nil end
s = tostring(s)
s = s:gsub('^%s+', ''):gsub('%s+$', '')
if s == '' then return nil end
return s
end
local function css(node, cssText)
if cssText and cssText ~= '' then
node:cssText(cssText)
end
return node
end
local function addSectionRow(tbl, title)
local tr = tbl:tag('tr')
css(tr:tag('td'), 'text-align:center; padding:0.5em; background:#e0e0e0; font-weight:bold;')
:attr('colspan', '2')
:wikitext(title)
end
local function addRow(tbl, label, valueHtmlOrWikitext, isRawHtml)
local tr = tbl:tag('tr')
css(tr:tag('th'), 'text-align:left; padding:0.2em 0.4em;')
:wikitext(label)
local td = tr:tag('td')
css(td, 'padding:0.2em 0.4em;')
-- After preprocess, what we have is HTML. Use :node() to insert it as HTML.
if isRawHtml then
td:node(mw.html.create('span'):wikitext(valueHtmlOrWikitext))
else
td:wikitext(valueHtmlOrWikitext)
end
end
local function addFullRow(tbl, valueHtmlOrWikitext, cssText, isRawHtml)
local tr = tbl:tag('tr')
local td = tr:tag('td'):attr('colspan', '2')
css(td, cssText or '')
if isRawHtml then
td:node(mw.html.create('span'):wikitext(valueHtmlOrWikitext))
else
td:wikitext(valueHtmlOrWikitext)
end
end
function p.infobox(frame)
local parent = frame:getParent()
local args = parent and parent.args or frame.args
local title = mw.title.getCurrentTitle()
local pageName = title.text
local fullPageName = title.fullText
local pageId = title.id or 0
local brand = trim(args.brand)
local model_code = trim(args.model_code)
local image_main = trim(args.image_main)
local crt_type = trim(args.crt_type)
local screen_size_in = trim(args.screen_size_in)
local tvl = trim(args.tvl)
local chassis = trim(args.chassis)
local height = trim(args.height)
local width = trim(args.width)
local depth = trim(args.depth)
local weight = trim(args.weight)
local standards_semantic = trim(args.standards_semantic)
local tbl = mw.html.create('table')
tbl:addClass('infobox')
css(tbl, 'float:right; clear:right; margin:0 0 1em 1em; width:22em; border:1px solid #a2a9b1; border-spacing:3px; background:#f8f9fa; font-size:88%; line-height:1.5em;')
local caption = tbl:tag('caption')
css(caption, 'font-size:125%; font-weight:bold; padding:0.5em;')
caption:wikitext((brand or '') .. ' ' .. (model_code or ''))
if image_main then
local file = image_main:gsub('^File:', '')
addFullRow(
tbl,
string.format('[[File:%s|frameless|300px]]', file),
'text-align:center; padding:0;',
false
)
end
addSectionRow(tbl, 'Overview')
-- Brand row using #formredlink (must preprocess)
if brand then
local brandWikitext = string.format(
'{{#formredlink: target=%s |form=Manufacturer |existing page link text=%s }}',
brand, brand
)
local brandHtml = frame:preprocess(brandWikitext)
addRow(tbl, 'Brand', brandHtml, true)
end
-- ECID row: build as a normal external link wikitext; preprocess not required, but fine.
local ecidWikitext = string.format('[{{fullurl:%s|curid=%d}} EC%d]', pageName, pageId, pageId)
addRow(tbl, 'ECID', frame:preprocess(ecidWikitext), true)
if model_code then
addRow(tbl, 'Model code', model_code, false)
else
addRow(tbl, 'Model code', '', false)
end
if crt_type then
addRow(tbl, 'Type', crt_type, false)
end
if screen_size_in then
addRow(tbl, 'Screen size', screen_size_in .. '″', false)
end
if tvl then
addRow(tbl, 'TVL', tvl, false)
end
if chassis then
local chassisWikitext = string.format(
'{{#formredlink: target=%s |form=Chassis |existing page link text=%s }}',
chassis, chassis
)
local chassisHtml = frame:preprocess(chassisWikitext)
addRow(tbl, 'Chassis', chassisHtml, true)
end
if height or width or depth then
addSectionRow(tbl, 'Dimensions')
local h = height or '–'
local w = width or '–'
local d = depth or '–'
addRow(tbl, 'H × W × D', string.format('%s × %s × %s', h, w, d), false)
end
-- Weight row: uses #show, so preprocess it
if weight then
local weightWikitext = '{{#show: ' .. fullPageName .. ' |?Weight # lb }} / {{#show: ' .. fullPageName .. ' |?Weight # kg }}'
addRow(tbl, 'Weight', frame:preprocess(weightWikitext), true)
end
-- Inputs section: preprocess #ask so it renders
addSectionRow(tbl, 'Inputs')
local askWikitext =
'{{#ask:\n' ..
' [[Has CRT model::' .. fullPageName .. ']]\n' ..
' |?Has video signal format=signal\n' ..
' |?Has connector type=connector\n' ..
' |?Has input count=count\n' ..
' |?Has input location=location\n' ..
' |format=ul\n' ..
' |template=CRT input inline\n' ..
' |named args=yes\n' ..
' |searchlabel=\n' ..
'}}'
local askHtml = frame:preprocess(askWikitext)
addFullRow(tbl, askHtml, 'padding:0.2em 0.4em;', true)
addSectionRow(tbl, 'Standards')
addFullRow(tbl, standards_semantic or '', 'padding:0.2em 0.4em;', false)
return tostring(tbl)
end
return p