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 | -- Helper to discover all distinct location values for a given IO type | ||
local function | -- Returns an ordered list of location strings, sorted with common locations first | ||
local | local function discoverLocations(frame, fullPageName, ioType) | ||
local locationProp, signalProp | |||
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 queryWikitext = | |||
local | |||
'{{#ask:\n' .. | '{{#ask:\n' .. | ||
' [[Has AV device::' .. fullPageName .. ']]\n' .. | ' [[Has AV device::' .. fullPageName .. ']]\n' .. | ||
' [[' .. signalProp .. '::+]]\n' .. | ' [[' .. signalProp .. '::+]]\n' .. | ||
' [[' .. locationProp .. '::+]]\n' .. | |||
' |format= | ' |?' .. locationProp .. '=location\n' .. | ||
' |format=broadtable\n' .. | |||
' |headers=hide\n' .. | |||
' |link=none\n' .. | |||
'}}' | '}}' | ||
-- | local result = frame:preprocess(queryWikitext) | ||
-- | |||
local | -- Parse distinct locations from broadtable rows | ||
local seen = {} | |||
local locations = {} | |||
-- Preferred display order for common locations | |||
local preferredOrder = {rear = 1, front = 2, side = 3, top = 4, bottom = 5, internal = 6} | |||
if | if result then | ||
for rowContent in result:gmatch('<tr[^>]*>(.-)</tr>') do | |||
local cells = {} | |||
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do | |||
local cleanContent = cellContent:gsub('<[^>]+>', '') | |||
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 | -- Sort: preferred locations first (in defined order), then remaining alphabetically | ||
return | 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 | ||
- | -- Inputs and Outputs sections (matching CRT model style) | ||
local function renderIOSection(sectionTitle, ioType) | |||
local | local locations = discoverLocations(frame, fullPageName, ioType) | ||
local locationData = {} | |||
for _, loc in ipairs(locations) do | |||
local content = queryIOByLocation(frame, fullPageName, ioType, loc) | |||
if content and content ~= '' then | |||
table.insert(locationData, {location = loc, content = content}) | |||
end | |||
end | |||
local | |||
if #locationData > 0 then | |||
addSectionRow(container, sectionTitle) | |||
for _, data in ipairs(locationData) do | |||
local labelDiv = container:tag('div') | |||
labelDiv:addClass('infobox-label') | |||
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;') | |||
labelDiv:wikitext(locationLabel(data.location)) | |||
local valueDiv = container:tag('div') | |||
valueDiv:addClass('infobox-value') | |||
css(valueDiv, 'padding:0.2em 0.4em;') | |||
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 | ||
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 | ||
table.insert(partLinks, '[[' .. part.page .. ']]') | table.insert(partLinks, '[[' .. part.page .. ']]') | ||
end | end | ||