Module:AVDevice: Difference between revisions

Change "Add accessory" button to link to Create_an_accessory with av_devices parameter (via update-page on MediaWiki MCP Server)
Replace Connectivity section with separate Inputs/Outputs sections matching CRT model style. Uses discoverLocations() for dynamic location discovery and renderIOSection() for consistent rendering. Removes countIOByLocation and buildLocationGroupedIO functions. (via update-page on MediaWiki MCP Server)
Line 153: Line 153:
end
end


-- Helper to count inputs/outputs for a specific location
-- Helper to discover all distinct location values for a given IO type
local function countIOByLocation(frame, fullPageName, ioType, location)
-- Returns an ordered list of location strings, sorted with common locations first
local locationFilter = ''
local function discoverLocations(frame, fullPageName, ioType)
if location then
local locationProp, signalProp
locationFilter = ' [[Has ' .. (ioType == 'input' and 'input' or 'output') .. ' location::' .. location .. ']]\n'
if ioType == 'input' then
locationProp = 'Has input location'
signalProp = 'Has video signal format'
else -- output
locationProp = 'Has output location'
signalProp = 'Has output signal format'
end
end
 
local signalProp = ioType == 'input' and 'Has video signal format' or 'Has output signal format'
local queryWikitext =
local countWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
' [[Has AV device::' .. fullPageName .. ']]\n' ..
' [[Has AV device::' .. fullPageName .. ']]\n' ..
' [[' .. signalProp .. '::+]]\n' ..
' [[' .. signalProp .. '::+]]\n' ..
locationFilter ..
' [[' .. locationProp .. '::+]]\n' ..
' |format=count\n' ..
' |?' .. locationProp .. '=location\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |link=none\n' ..
'}}'
'}}'
local result = frame:preprocess(countWikitext)
local count = tonumber(trim(result)) or 0
return count
end


-- Helper to build location-grouped I/O content for a value cell
local result = frame:preprocess(queryWikitext)
-- Returns HTML string with stripe groups per location, or nil if empty
 
local function buildLocationGroupedIO(frame, fullPageName, ioType, locations, locationLabels)
-- Parse distinct locations from broadtable rows
local html = ''
local seen = {}
local locations = {}
for _, loc in ipairs(locations) do
 
local count = countIOByLocation(frame, fullPageName, ioType, loc)
-- Preferred display order for common locations
if count > 0 then
local preferredOrder = {rear = 1, front = 2, side = 3, top = 4, bottom = 5, internal = 6}
local locContent = queryIOByLocation(frame, fullPageName, ioType, loc)
 
if locContent and locContent ~= '' then
if result then
html = html ..
for rowContent in result:gmatch('<tr[^>]*>(.-)</tr>') do
'<div class="infobox-io-location-group">' ..
local cells = {}
'<div class="infobox-io-location-header">' .. locationLabels[loc] .. '</div>' ..
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
'<div class="infobox-io-location-content">' .. locContent .. '</div>' ..
local cleanContent = cellContent:gsub('<[^>]+>', '')
'</div>'
table.insert(cells, trim(cleanContent))
end
-- cells[1] = subobject name, cells[2] = location value
if #cells >= 2 and cells[2] then
local loc = mw.text.trim(cells[2])
-- Normalize to lowercase for deduplication
local locLower = loc:lower()
if locLower ~= '' and not seen[locLower] then
seen[locLower] = true
table.insert(locations, locLower)
end
end
end
end
end
end
end
 
if html == '' then return nil end
-- Sort: preferred locations first (in defined order), then remaining alphabetically
return html
table.sort(locations, function(a, b)
local orderA = preferredOrder[a] or 1000
local orderB = preferredOrder[b] or 1000
if orderA ~= orderB then
return orderA < orderB
end
return a < b
end)
 
return locations
end
 
-- Capitalize first letter of a location string for display
local function locationLabel(loc)
if not loc or loc == '' then return '' end
return loc:sub(1, 1):upper() .. loc:sub(2)
end
end


Line 339: Line 365:
end
end


-- Connectivity section - Inputs and Outputs as main rows,
-- Inputs and Outputs sections (matching CRT model style)
-- with location stripe groups inside each value cell
local function renderIOSection(sectionTitle, ioType)
local locations = {'front', 'rear', 'side'}
local locations = discoverLocations(frame, fullPageName, ioType)
local locationLabels = {front = 'Front', rear = 'Rear', side = 'Side'}
local locationData = {}
local inputsHtml = buildLocationGroupedIO(frame, fullPageName, 'input', locations, locationLabels)
local outputsHtml = buildLocationGroupedIO(frame, fullPageName, 'output', locations, locationLabels)


if inputsHtml or outputsHtml then
for _, loc in ipairs(locations) do
addSectionRow(container, 'Connectivity')
local content = queryIOByLocation(frame, fullPageName, ioType, loc)
if content and content ~= '' then
-- Connectivity rows: label stretches full height (default grid behavior),
table.insert(locationData, {location = loc, content = content})
-- value has no padding so location groups sit flush
end
if inputsHtml then
end
local labelDiv = container:tag('div')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext('Inputs')


local valueDiv = container:tag('div')
if #locationData > 0 then
valueDiv:addClass('infobox-value')
addSectionRow(container, sectionTitle)
css(valueDiv, 'padding:0;')
for _, data in ipairs(locationData) do
valueDiv:node(mw.html.create('span'):wikitext(inputsHtml))
local labelDiv = container:tag('div')
end
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
if outputsHtml then
labelDiv:wikitext(locationLabel(data.location))
local labelDiv = container:tag('div')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext('Outputs')


local valueDiv = container:tag('div')
local valueDiv = container:tag('div')
valueDiv:addClass('infobox-value')
valueDiv:addClass('infobox-value')
css(valueDiv, 'padding:0;')
css(valueDiv, 'padding:0.2em 0.4em;')
valueDiv:node(mw.html.create('span'):wikitext(outputsHtml))
valueDiv:node(mw.html.create('span'):wikitext(data.content))
end
end
end
end
end
renderIOSection('Inputs', 'input')
renderIOSection('Outputs', 'output')


-- Features section
-- Features section
Line 699: Line 718:
-- Use subtype + type as the grouping key if subtype exists
-- Use subtype + type as the grouping key if subtype exists
-- Keep proper capitalization (e.g., "Frame synchronizer IC" not "Frame synchronizer ic")
local groupKey = partType
local groupKey = partType
if partSubtype and partSubtype ~= '' then
if partSubtype and partSubtype ~= '' then
Line 730: Line 748:
local partLinks = {}
local partLinks = {}
for _, part in ipairs(parts) do
for _, part in ipairs(parts) do
-- Just show the page name (which is "Brand Model"), no description
table.insert(partLinks, '[[' .. part.page .. ']]')
table.insert(partLinks, '[[' .. part.page .. ']]')
end
end
MediaWiki Appliance - Powered by TurnKey Linux