Module:CRTModel: Difference between revisions

Fix badge: replace broken mw.html.create('a') with plain wikilinks (MediaWiki sanitizer strips raw a tags) (via update-page on MediaWiki MCP Server)
Revert to Rev 7377 + fix badge: use plain wikilinks instead of mw.html.create('a') which gets HTML-escaped. Fixes Lua error on all CRT pages. (via update-page on MediaWiki MCP Server)
Line 413: Line 413:
if chassis_family then
if chassis_family then
-- Link directly to the chassis family page (no namespace prefix)
local familyWikitext = string.format(
local familyWikitext = string.format(
'{{#formredlink: target=%s |form=Chassis family |existing page link text=%s }}',
'{{#formredlink: target=%s |form=Chassis family |existing page link text=%s }}',
Line 420: Line 421:
if chassis then
if chassis then
-- Both: show chassis with family in parentheses on next line
chassisDisplay = chassisDisplay .. '<br><small>Family: ' .. familyHtml .. '</small>'
chassisDisplay = chassisDisplay .. '<br><small>Family: ' .. familyHtml .. '</small>'
else
else
-- Only family: show family alone
chassisDisplay = familyHtml .. ' <small>(family)</small>'
chassisDisplay = familyHtml .. ' <small>(family)</small>'
end
end
Line 440: Line 443:
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 ecidWikitext = string.format('[{{fullurl:%s|curid=%d}} EC%d]', pageName, pageId, pageId)
addRow(container, 'ECID', frame:preprocess(ecidWikitext), true)
addRow(container, 'ECID', frame:preprocess(ecidWikitext), true)


-- Tube section
-- Tube section: show if we have any tube specs
if mask_type or pitch or phosphor_type or gun_type or deflection_angle or neck_diameter or visible_w or visible_h or visible_diag then
if mask_type or pitch or phosphor_type or gun_type or deflection_angle or neck_diameter or visible_w or visible_h or visible_diag then
addSectionRow(container, 'Tube')
addSectionRow(container, 'Tube')
if mask_type then addRow(container, 'Mask', mask_type, false) end
if pitch then addRow(container, 'Pitch', pitch .. ' mm', false) end
if mask_type then
if phosphor_type then addRow(container, 'Phosphors', phosphor_type, false) end
addRow(container, 'Mask', mask_type, false)
if gun_type then addRow(container, 'Gun type', gun_type, false) end
end
if deflection_angle then addRow(container, 'Deflection', deflection_angle .. '°', false) end
if neck_diameter then addRow(container, 'Neck', neck_diameter .. ' mm', false) end
if pitch then
addRow(container, 'Pitch', pitch .. ' mm', false)
end
if phosphor_type then
addRow(container, 'Phosphors', phosphor_type, false)
end
if gun_type then
addRow(container, 'Gun type', gun_type, false)
end
if deflection_angle then
addRow(container, 'Deflection', deflection_angle .. '°', false)
end
if neck_diameter then
addRow(container, 'Neck', neck_diameter .. ' mm', false)
end
-- Visible picture size
if visible_w and visible_h then
if visible_w and visible_h then
addRow(container, 'Visible area', visible_w .. ' × ' .. visible_h .. ' mm', false)
addRow(container, 'Visible area', visible_w .. ' × ' .. visible_h .. ' mm', false)
Line 458: Line 481:
addRow(container, 'Visible area', visible_diag .. '″ (diagonal)', false)
addRow(container, 'Visible area', visible_diag .. '″ (diagonal)', false)
end
end
-- Show diagonal even if we have W×H, as supplementary info
if visible_diag and visible_w and visible_h then
if visible_diag and visible_w and visible_h then
addRow(container, 'Visible diag.', visible_diag .. '″', false)
addRow(container, 'Visible diag.', visible_diag .. '″', false)
Line 463: Line 488:
end
end


-- Dimensions section
-- Dimensions section: show if we have height/width/depth OR weight
if height or width or depth or weight then
if height or width or depth or weight then
addSectionRow(container, 'Dimensions')
addSectionRow(container, 'Dimensions')
if height or width or depth then
if height or width or depth then
local h = height or '–'
local h = height or '–'
Line 472: Line 498:
addRow(container, 'H × W × D', string.format('%s × %s × %s', h, w, d), false)
addRow(container, 'H × W × D', string.format('%s × %s × %s', h, w, d), false)
end
end
-- Weight row: uses #show, so preprocess it
if weight then
if weight then
local weightWikitext = '{{#show: ' .. fullPageName .. ' |?Weight # lb }} / {{#show: ' .. fullPageName .. ' |?Weight # kg }}'
local weightWikitext = '{{#show: ' .. fullPageName .. ' |?Weight # lb }} / {{#show: ' .. fullPageName .. ' |?Weight # kg }}'
Line 478: Line 506:
end
end


-- Speakers section
-- Speakers section: show if we have any speaker specs
if speaker_type or speaker_watts or subwoofer then
if speaker_type or speaker_watts or subwoofer then
addSectionRow(container, 'Speakers')
addSectionRow(container, 'Speakers')
if speaker_type then addRow(container, 'Type', speaker_type, false) end
if speaker_watts then addRow(container, 'Power', speaker_watts, false) end
if speaker_type then
if subwoofer then addRow(container, 'Subwoofer', subwoofer, false) end
addRow(container, 'Type', speaker_type, false)
end
if speaker_watts then
addRow(container, 'Power', speaker_watts, false)
end
if subwoofer then
addRow(container, 'Subwoofer', subwoofer, false)
end
end
end


-- Power section
-- Power section: query voltage ranges from subobjects
-- First, query for voltage range subobjects
local voltageQueryWikitext =
local voltageQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 500: Line 538:
'}}'
'}}'
local voltageResult = frame:preprocess(voltageQueryWikitext)
local voltageResult = frame:preprocess(voltageQueryWikitext)
-- Parse voltage ranges from broadtable result
local voltageRanges = {}
local voltageRanges = {}
if voltageResult then
if voltageResult then
Line 508: Line 548:
table.insert(cells, trim(cleanContent))
table.insert(cells, trim(cleanContent))
end
end
-- cells[1] = subobject, cells[2] = voltage_min, cells[3] = voltage_max
if #cells >= 3 then
if #cells >= 3 then
local vMin = tonumber(cells[2])
local vMin = tonumber(cells[2])
Line 517: Line 559:
end
end
end
end
local hasVoltageRanges = #voltageRanges > 0
local hasVoltageRanges = #voltageRanges > 0


-- Show Power section if we have voltage ranges, frequency, or power consumption
if hasVoltageRanges or frequency or power_avg or power_max then
if hasVoltageRanges or frequency or power_avg or power_max then
addSectionRow(container, 'Power')
addSectionRow(container, 'Power')
-- Voltage row: display ranges from subobjects
if hasVoltageRanges then
if hasVoltageRanges then
local rangeStrings = {}
local rangeStrings = {}
Line 536: Line 582:
rangeStr = range.max .. 'V'
rangeStr = range.max .. 'V'
end
end
if rangeStr then table.insert(rangeStrings, rangeStr) end
if rangeStr then
table.insert(rangeStrings, rangeStr)
end
end
end
if #rangeStrings > 0 then
if #rangeStrings > 0 then
addRow(container, 'Voltage', table.concat(rangeStrings, ' / '), false)
addRow(container, 'Voltage', table.concat(rangeStrings, ' / '), false)
end
end
end
end
if frequency then addRow(container, 'Frequency', frequency, false) end
-- Frequency row
if frequency then
addRow(container, 'Frequency', frequency, false)
end
-- Power consumption row
if power_avg or power_max then
if power_avg or power_max then
local powerDisplay
local powerDisplay
Line 556: Line 611:
end
end


-- TV Systems section
-- TV Systems section: show if we have AV system or tuner system
if av_system or tuner_system then
if av_system or tuner_system then
addSectionRow(container, 'TV Systems')
addSectionRow(container, 'TV Systems')
if av_system then
if av_system then
local systems = {}
local systems = {}
for system in av_system:gmatch('[^,]+') do
for system in av_system:gmatch('[^,]+') do
local s = trim(system)
local s = trim(system)
if s then table.insert(systems, '[[' .. s .. '|' .. s .. ']]') end
if s then
table.insert(systems, '[[' .. s .. '|' .. s .. ']]')
end
end
if #systems > 0 then
addRow(container, 'AV system', table.concat(systems, ', '), true)
end
end
if #systems > 0 then addRow(container, 'AV system', table.concat(systems, ', '), true) end
end
end
if tuner_system then
if tuner_system then
local systems = {}
local systems = {}
for system in tuner_system:gmatch('[^,]+') do
for system in tuner_system:gmatch('[^,]+') do
local s = trim(system)
local s = trim(system)
if s then table.insert(systems, '[[' .. s .. '|' .. s .. ']]') end
if s then
table.insert(systems, '[[' .. s .. '|' .. s .. ']]')
end
end
if #systems > 0 then
addRow(container, 'Tuner', table.concat(systems, ', '), true)
end
end
if #systems > 0 then addRow(container, 'Tuner', table.concat(systems, ', '), true) end
end
end
end
end
Line 580: Line 645:
if h_scan_min or h_scan_max or v_scan_min or v_scan_max then
if h_scan_min or h_scan_max or v_scan_min or v_scan_max then
addSectionRow(container, 'Scan Range')
addSectionRow(container, 'Scan Range')
if h_scan_min or h_scan_max then
if h_scan_min or h_scan_max then
local hDisplay
local hDisplay
if h_scan_min and h_scan_max then
if h_scan_min and h_scan_max then
hDisplay = (h_scan_min == h_scan_max) and (h_scan_min .. ' kHz') or (h_scan_min .. '–' .. h_scan_max .. ' kHz')
if h_scan_min == h_scan_max then
hDisplay = h_scan_min .. ' kHz'
else
hDisplay = h_scan_min .. '–' .. h_scan_max .. ' kHz'
end
elseif h_scan_min then
hDisplay = h_scan_min .. ' kHz'
else
else
hDisplay = (h_scan_min or h_scan_max) .. ' kHz'
hDisplay = h_scan_max .. ' kHz'
end
end
addRow(container, 'Horizontal', hDisplay, false)
addRow(container, 'Horizontal', hDisplay, false)
end
end
if v_scan_min or v_scan_max then
if v_scan_min or v_scan_max then
local vDisplay
local vDisplay
if v_scan_min and v_scan_max then
if v_scan_min and v_scan_max then
vDisplay = (v_scan_min == v_scan_max) and (v_scan_min .. ' Hz') or (v_scan_min .. '–' .. v_scan_max .. ' Hz')
if v_scan_min == v_scan_max then
vDisplay = v_scan_min .. ' Hz'
else
vDisplay = v_scan_min .. '–' .. v_scan_max .. ' Hz'
end
elseif v_scan_min then
vDisplay = v_scan_min .. ' Hz'
else
else
vDisplay = (v_scan_min or v_scan_max) .. ' Hz'
vDisplay = v_scan_max .. ' Hz'
end
end
addRow(container, 'Vertical', vDisplay, false)
addRow(container, 'Vertical', vDisplay, false)
Line 604: Line 683:
local locations = discoverLocations(frame, fullPageName, ioType)
local locations = discoverLocations(frame, fullPageName, ioType)
local locationData = {}
local locationData = {}
for _, loc in ipairs(locations) do
for _, loc in ipairs(locations) do
local content = queryIOByLocation(frame, fullPageName, ioType, loc)
local content = queryIOByLocation(frame, fullPageName, ioType, loc)
Line 610: Line 690:
end
end
end
end
if #locationData > 0 then
if #locationData > 0 then
addSectionRow(container, sectionTitle)
addSectionRow(container, sectionTitle)
Line 617: Line 698:
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext(locationLabel(data.location))
labelDiv:wikitext(locationLabel(data.location))
local valueDiv = container:tag('div')
local valueDiv = container:tag('div')
valueDiv:addClass('infobox-value')
valueDiv:addClass('infobox-value')
Line 631: Line 713:
-- Accessories section
-- Accessories section
addSectionRow(container, 'Accessories')
addSectionRow(container, 'Accessories')
local addAccessoryUrl = mw.uri.fullUrl("Special:FormEdit", {form = "Accessory", ["Accessory[crt_models]"] = pageName})
 
local addAccessoryUrl = mw.uri.fullUrl(
"Special:FormEdit",
{
form = "Accessory",
["Accessory[crt_models]"] = pageName
}
)
 
local accessoriesCountWikitext =
local accessoriesCountWikitext =
'{{#ask:\n [[Category:Accessories]]\n [[Has related CRT model::' .. fullPageName .. ']]\n [[Has accessory type::!Remote control]]\n |format=count\n}}'
'{{#ask:\n' ..
' [[Category:Accessories]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' [[Has accessory type::!Remote control]]\n' ..
' |format=count\n' ..
'}}'
local accessoryCount = frame:preprocess(accessoriesCountWikitext)
local accessoryCount = frame:preprocess(accessoriesCountWikitext)
local hasAccessories = accessoryCount and tonumber(trim(accessoryCount)) and tonumber(trim(accessoryCount)) > 0
local hasAccessories = accessoryCount and tonumber(trim(accessoryCount)) and tonumber(trim(accessoryCount)) > 0
Line 642: Line 737:
if hasAccessories then
if hasAccessories then
local accessoriesQueryWikitext =
local accessoriesQueryWikitext =
'{{#ask:\n [[Category:Accessories]]\n [[Has related CRT model::' .. fullPageName .. ']]\n [[Has accessory type::!Remote control]]\n |?Has accessory type=type\n |?Has model code=model\n |format=broadtable\n |headers=hide\n |link=none\n}}'
'{{#ask:\n' ..
' [[Category:Accessories]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' [[Has accessory type::!Remote control]]\n' ..
' |?Has accessory type=type\n' ..
' |?Has model code=model\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
local accessoriesResult = frame:preprocess(accessoriesQueryWikitext)
local accessoriesResult = frame:preprocess(accessoriesQueryWikitext)
local accessoriesByType = {}
local accessoriesByType = {}
local typeOrder = {}
local typeOrder = {}
if accessoriesResult then
if accessoriesResult then
for rowContent in accessoriesResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in accessoriesResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
table.insert(cells, trim(cellContent:gsub('<[^>]+>', '')))
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
end
end
if #cells >= 2 then
if #cells >= 2 then
local accPageName = cells[1]
local accPageName = cells[1]
local accType = cells[2] or 'Accessory'
local accType = cells[2] or 'Accessory'
if accPageName then
if accPageName then
if not accessoriesByType[accType] then
if not accessoriesByType[accType] then
Line 660: Line 769:
table.insert(typeOrder, accType)
table.insert(typeOrder, accType)
end
end
table.insert(accessoriesByType[accType], {page = accPageName})
 
table.insert(accessoriesByType[accType], {
page = accPageName
})
end
end
end
end
end
end
end
end
local accGrid = accDiv:tag('div')
local accGrid = accDiv:tag('div')
css(accGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
css(accGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
for _, accType in ipairs(typeOrder) do
for _, accType in ipairs(typeOrder) do
local accs = accessoriesByType[accType]
local accs = accessoriesByType[accType]
if accs and #accs > 0 then
if accs and #accs > 0 then
local accLinks = {}
local accLinks = {}
for _, acc in ipairs(accs) do table.insert(accLinks, '[[' .. acc.page .. ']]') end
for _, acc in ipairs(accs) do
table.insert(accLinks, '[[' .. acc.page .. ']]')
end
 
local labelDiv = accGrid:tag('div')
local labelDiv = accGrid:tag('div')
labelDiv:addClass('infobox-label')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext(accType)
labelDiv:wikitext(accType)
local valueDiv = accGrid:tag('div')
local valueDiv = accGrid:tag('div')
valueDiv:addClass('infobox-value')
valueDiv:addClass('infobox-value')
Line 682: Line 800:
end
end
end
end
local addAccDiv = mw.html.create('div')
local addAccDiv = mw.html.create('div')
addAccDiv:css('margin-top', '0.5em'):css('text-align', 'center')
addAccDiv:css('margin-top', '0.5em'):css('text-align', 'center')
Line 695: Line 814:
-- Parts section
-- Parts section
addSectionRow(container, 'Parts')
addSectionRow(container, 'Parts')
local addPartUrl = mw.uri.fullUrl("Special:FormEdit", {form = "Part", ["Part[crt_models]"] = pageName})
local addPartUrl = mw.uri.fullUrl(
"Special:FormEdit",
{
form = "Part",
["Part[crt_models]"] = pageName
}
)
local partsCountWikitext =
local partsCountWikitext =
'{{#ask:\n [[Category:Parts]]\n [[Has related CRT model::' .. fullPageName .. ']]\n |format=count\n}}'
'{{#ask:\n' ..
' [[Category:Parts]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' |format=count\n' ..
'}}'
local partsCount = frame:preprocess(partsCountWikitext)
local partsCount = frame:preprocess(partsCountWikitext)
local hasParts = partsCount and tonumber(trim(partsCount)) and tonumber(trim(partsCount)) > 0
local hasParts = partsCount and tonumber(trim(partsCount)) and tonumber(trim(partsCount)) > 0
local partsDiv = container:tag('div')
local partsDiv = container:tag('div')
css(partsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
css(partsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
 
if hasParts then
if hasParts then
local partsQueryWikitext =
local partsQueryWikitext =
'{{#ask:\n [[Category:Parts]]\n [[Has related CRT model::' .. fullPageName .. ']]\n |?Has part type=type\n |?Has part subtype=subtype\n |?Has model code=model\n |format=broadtable\n |headers=hide\n |link=none\n}}'
'{{#ask:\n' ..
' [[Category:Parts]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' |?Has part type=type\n' ..
' |?Has part subtype=subtype\n' ..
' |?Has model code=model\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
local partsResult = frame:preprocess(partsQueryWikitext)
local partsResult = frame:preprocess(partsQueryWikitext)
local partsByType = {}
local partsByType = {}
local partTypeOrder = {}
local partTypeOrder = {}
if partsResult then
if partsResult then
for rowContent in partsResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in partsResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
table.insert(cells, trim(cellContent:gsub('<[^>]+>', '')))
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
end
end
if #cells >= 2 then
if #cells >= 2 then
local partPageName = cells[1]
local partPageName = cells[1]
local partType = cells[2] or 'Part'
local partType = cells[2] or 'Part'
local partSubtype = cells[3]
local partSubtype = cells[3]
local groupKey = partType
local groupKey = partType
if partSubtype and partSubtype ~= '' then groupKey = partSubtype .. ' ' .. partType end
if partSubtype and partSubtype ~= '' then
groupKey = partSubtype .. ' ' .. partType
end
if partPageName then
if partPageName then
if not partsByType[groupKey] then
if not partsByType[groupKey] then
Line 726: Line 875:
table.insert(partTypeOrder, groupKey)
table.insert(partTypeOrder, groupKey)
end
end
table.insert(partsByType[groupKey], {page = partPageName})
table.insert(partsByType[groupKey], {
page = partPageName
})
end
end
end
end
end
end
end
end
local partsGrid = partsDiv:tag('div')
local partsGrid = partsDiv:tag('div')
css(partsGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
css(partsGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
for _, partType in ipairs(partTypeOrder) do
for _, partType in ipairs(partTypeOrder) do
local parts = partsByType[partType]
local parts = partsByType[partType]
if parts and #parts > 0 then
if parts and #parts > 0 then
local partLinks = {}
local partLinks = {}
for _, part in ipairs(parts) do table.insert(partLinks, '[[' .. part.page .. ']]') end
for _, part in ipairs(parts) do
table.insert(partLinks, '[[' .. part.page .. ']]')
end
local labelDiv = partsGrid:tag('div')
local labelDiv = partsGrid:tag('div')
labelDiv:addClass('infobox-label')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext(partType)
labelDiv:wikitext(partType)
local valueDiv = partsGrid:tag('div')
local valueDiv = partsGrid:tag('div')
valueDiv:addClass('infobox-value')
valueDiv:addClass('infobox-value')
Line 748: Line 906:
end
end
end
end
local addPartDiv = mw.html.create('div')
local addPartDiv = mw.html.create('div')
addPartDiv:css('margin-top', '0.5em'):css('text-align', 'center')
addPartDiv:css('margin-top', '0.5em'):css('text-align', 'center')
Line 761: Line 920:
-- Mods section
-- Mods section
local modsQueryWikitext =
local modsQueryWikitext =
'{{#ask:\n [[Has CRT model::' .. fullPageName .. ']]\n [[Has mod URL::+]]\n |?Has mod type=type\n |?Has mod description=description\n |?Has mod feasible=feasible\n |?Has mod URL=url\n |format=broadtable\n |headers=hide\n |link=none\n}}'
'{{#ask:\n' ..
' [[Has CRT model::' .. fullPageName .. ']]\n' ..
' [[Has mod URL::+]]\n' ..
' |?Has mod type=type\n' ..
' |?Has mod description=description\n' ..
' |?Has mod feasible=feasible\n' ..
' |?Has mod URL=url\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
local modsResult = frame:preprocess(modsQueryWikitext)
local modsResult = frame:preprocess(modsQueryWikitext)
local mods = {}
local mods = {}
if modsResult then
if modsResult then
for rowContent in modsResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in modsResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
table.insert(cells, trim(cellContent:gsub('<[^>]+>', '')))
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
end
end
if #cells >= 3 then
if #cells >= 3 then
local modData = {type = nil, description = nil, feasible = nil, url = nil}
local modData = {
type = nil,
description = nil,
feasible = nil,
url = nil
}
for i = 2, #cells do
for i = 2, #cells do
local cell = cells[i]
local cell = cells[i]
if cell then
if cell then
if cell:match('^https?://') then modData.url = cell
if cell:match('^https?://') then
elseif cell == 'Yes' or cell == 'No' then modData.feasible = cell
modData.url = cell
elseif cell == 'RGB' or cell == 'S-video' or cell == 'Other' then modData.type = cell
elseif cell == 'Yes' or cell == 'No' then
else modData.description = cell end
modData.feasible = cell
elseif cell == 'RGB' or cell == 'S-video' or cell == 'Other' then
modData.type = cell
else
modData.description = cell
end
end
end
end
end
if modData.url and modData.type then table.insert(mods, modData) end
if modData.url and modData.type then
table.insert(mods, modData)
end
end
end
end
end
end
end
if #mods > 0 then
if #mods > 0 then
addSectionRow(container, 'Mods')
addSectionRow(container, 'Mods')
local modsDiv = container:tag('div')
local modsDiv = container:tag('div')
css(modsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
css(modsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
local ul = modsDiv:tag('ul')
local ul = modsDiv:tag('ul')
ul:css('margin', '0'):css('padding-left', '1.5em')
ul:css('margin', '0'):css('padding-left', '1.5em')
for _, mod in ipairs(mods) do
for _, mod in ipairs(mods) do
local li = ul:tag('li')
local li = ul:tag('li')
local displayText = mod.description or mod.type
local displayText = mod.description or mod.type
local isFeasible = mod.feasible ~= 'No'
local isFeasible = mod.feasible ~= 'No'
if isFeasible then
if isFeasible then
li:wikitext('[' .. mod.url .. ' ' .. displayText .. ']')
li:wikitext('[' .. mod.url .. ' ' .. displayText .. ']')
Line 810: Line 1,003:
-- Documents section
-- Documents section
addSectionRow(container, 'Documents')
addSectionRow(container, 'Documents')
local timestamp = os.time()
local timestamp = os.time()
math.randomseed(timestamp + pageId)
math.randomseed(timestamp + pageId)
local random = math.random(1000, 9999)
local random = math.random(1000, 9999)
local target = "Document:" .. timestamp .. "-" .. random
local target = "Document:" .. timestamp .. "-" .. random
local uploadUrl = mw.uri.fullUrl("Special:FormEdit", {form = "Document", target = target, ["Document[crt_models]"] = pageName})
local uploadUrl = mw.uri.fullUrl(
"Special:FormEdit",
{
form = "Document",
target = target,
["Document[crt_models]"] = pageName
}
)
local documentsCountWikitext =
local documentsCountWikitext =
'{{#ask:\n [[Category:Documents]]\n [[Has related CRT model::' .. fullPageName .. ']]\n |format=count\n}}'
'{{#ask:\n' ..
' [[Category:Documents]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' |format=count\n' ..
'}}'
local documentCount = frame:preprocess(documentsCountWikitext)
local documentCount = frame:preprocess(documentsCountWikitext)
local hasDocuments = documentCount and tonumber(trim(documentCount)) and tonumber(trim(documentCount)) > 0
local hasDocuments = documentCount and tonumber(trim(documentCount)) and tonumber(trim(documentCount)) > 0
local docsDiv = container:tag('div')
local docsDiv = container:tag('div')
css(docsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
css(docsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
 
if hasDocuments then
if hasDocuments then
local docsQueryWikitext =
local docsQueryWikitext =
'{{#ask:\n [[Category:Documents]]\n [[Has related CRT model::' .. fullPageName .. ']]\n |?Has document type\n |?Has document URL\n |?Has document file\n |?Has document title\n |format=broadtable\n |headers=hide\n |link=none\n}}'
'{{#ask:\n' ..
' [[Category:Documents]]\n' ..
' [[Has related CRT model::' .. fullPageName .. ']]\n' ..
' |?Has document type\n' ..
' |?Has document URL\n' ..
' |?Has document file\n' ..
' |?Has document title\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
local docsResult = frame:preprocess(docsQueryWikitext)
local docsResult = frame:preprocess(docsQueryWikitext)
local ul = mw.html.create('ul')
local ul = mw.html.create('ul')
ul:css('margin', '0'):css('padding-left', '1.5em')
ul:css('margin', '0'):css('padding-left', '1.5em')
if docsResult then
if docsResult then
for rowContent in docsResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in docsResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
table.insert(cells, cellContent:gsub('<[^>]+>', ''))
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, cleanContent)
end
end
if #cells >= 2 then
if #cells >= 2 then
local docType = trim(cells[2])
local docType = trim(cells[2])
Line 839: Line 1,060:
local docFile = trim(cells[4])
local docFile = trim(cells[4])
local docTitle = trim(cells[5])
local docTitle = trim(cells[5])
local linkTarget = nil
if docUrl then
linkTarget = docUrl
elseif docFile then
local filename = docFile:match('File:(.+)') or docFile
linkTarget = tostring(mw.uri.fullUrl('File:' .. filename))
end
local docPageName = trim(cells[1])
local docPageName = trim(cells[1])
if docPageName then
if docPageName then
local displayText = 'Document'
local displayText = 'Document'
if docTitle then displayText = docTitle
if docTitle then
elseif docType then displayText = docType end
displayText = docTitle
elseif docType then
displayText = docType
end
local li = ul:tag('li')
local li = ul:tag('li')
li:wikitext('[[' .. docPageName .. '|' .. displayText .. ']]')
li:wikitext('[[' .. docPageName .. '|' .. displayText .. ']]')
Line 850: Line 1,085:
end
end
end
end
docsDiv:node(ul)
docsDiv:node(ul)
local uploadDiv = mw.html.create('div')
local uploadDiv = mw.html.create('div')
uploadDiv:css('margin-top', '0.5em'):css('text-align', 'center')
uploadDiv:css('margin-top', '0.5em'):css('text-align', 'center')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
docsDiv:node(uploadDiv)
docsDiv:node(uploadDiv)
else
else
Line 859: Line 1,097:
uploadDiv:css('text-align', 'center')
uploadDiv:css('text-align', 'center')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
docsDiv:node(uploadDiv)
docsDiv:node(uploadDiv)
end
end
Line 864: Line 1,103:
-- Links section
-- Links section
local linksQueryWikitext =
local linksQueryWikitext =
'{{#ask:\n [[CRT model::' .. fullPageName .. ']]\n |?Model link type\n |?Model link source\n |?Model link URL\n |format=broadtable\n |headers=hide\n |link=none\n}}'
'{{#ask:\n' ..
' [[CRT model::' .. fullPageName .. ']]\n' ..
' |?Model link type\n' ..
' |?Model link source\n' ..
' |?Model link URL\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
local linksResult = frame:preprocess(linksQueryWikitext)
local linksResult = frame:preprocess(linksQueryWikitext)
local linksByType = {Manufacturer = {}, Retailer = {}, Database = {}}
local linksByType = {
Manufacturer = {},
Retailer = {},
Database = {}
}
local hasLinks = false
local hasLinks = false
if linksResult then
if linksResult then
for rowContent in linksResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in linksResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
table.insert(cells, trim(cellContent:gsub('<[^>]+>', '')))
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
end
end
if #cells >= 4 then
if #cells >= 4 then
local linkType = cells[2]
local linkType = cells[2]
local linkSource = cells[3]
local linkSource = cells[3]
local linkUrl = cells[4]
local linkUrl = cells[4]
if linkType and linkSource and linkUrl and linkUrl ~= '' and linksByType[linkType] then
table.insert(linksByType[linkType], {source = linkSource, url = linkUrl})
if linkType and linkSource and linkUrl and linkUrl ~= '' then
hasLinks = true
if linksByType[linkType] then
table.insert(linksByType[linkType], {source = linkSource, url = linkUrl})
hasLinks = true
end
end
end
end
end
end
end
end
end
if hasLinks then
if hasLinks then
addSectionRow(container, 'Archival Links')
addSectionRow(container, 'Archival Links')
local linkTypeOrder = {'Database', 'Manufacturer', 'Retailer'}
local linkTypeOrder = {'Database', 'Manufacturer', 'Retailer'}
for _, linkType in ipairs(linkTypeOrder) do
for _, linkType in ipairs(linkTypeOrder) do
Line 901: Line 1,161:
-- Contribute section
-- Contribute section
addSectionRow(container, 'Contribute')
addSectionRow(container, 'Contribute')
local editUrl = mw.uri.fullUrl("Special:FormStart", {form = "CRT model", page_name = pageName})
local editUrl = mw.uri.fullUrl(
"Special:FormStart",
{
form = "CRT model",
page_name = pageName
}
)
local editDiv = container:tag('div')
local editDiv = container:tag('div')
css(editDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em; text-align:center;')
css(editDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em; text-align:center;')
editDiv:wikitext('[' .. tostring(editUrl) .. ' <span class="infobox-button infobox-button-primary">Edit this data</span>]')
editDiv:wikitext('[' .. tostring(editUrl) .. ' <span class="infobox-button infobox-button-primary">Edit this data</span>]')


MediaWiki Appliance - Powered by TurnKey Linux