Module:CRTModel: Difference between revisions
Sort inputs/outputs/control ports by label within each location group, so entries with the same label (e.g. "Input 1") appear adjacent (via update-page on MediaWiki MCP Server) Tag: Reverted |
Fix: sort inputs/outputs by label in Lua instead of SMW query (SMW sort drops subobjects missing the sort property, e.g. unlabeled RF inputs) (via update-page on MediaWiki MCP Server) Tag: Reverted |
||
| Line 76: | Line 76: | ||
-- Helper to query inputs/outputs/control ports for a specific location | -- Helper to query inputs/outputs/control ports for a specific location | ||
-- Results are sorted by label in Lua (SMW sort= can drop subobjects missing the sort property) | |||
local function queryIOByLocation(frame, fullPageName, ioType, location) | local function queryIOByLocation(frame, fullPageName, ioType, location) | ||
local locationProp | local locationProp | ||
| Line 93: | Line 94: | ||
local signalProp, countProp, connectorProp, notesProp, labelProp, templateName | local signalProp, countProp, connectorProp, notesProp, labelProp, templateName | ||
local extraProps = '' | local extraProps = '' | ||
local extraAliases = {} | |||
if ioType == 'input' then | if ioType == 'input' then | ||
| Line 104: | Line 106: | ||
' |?Has audio connector=audio_connector\n' .. | ' |?Has audio connector=audio_connector\n' .. | ||
' |?Has audio shared with=audio_shared\n' | ' |?Has audio shared with=audio_shared\n' | ||
extraAliases = {'audio', 'audio_connector', 'audio_shared'} | |||
elseif ioType == 'output' then | elseif ioType == 'output' then | ||
signalProp = 'Has output signal format' | signalProp = 'Has output signal format' | ||
| Line 119: | Line 122: | ||
templateName = 'CRT control port row' | templateName = 'CRT control port row' | ||
extraProps = ' |?Has control port direction=direction\n' | extraProps = ' |?Has control port direction=direction\n' | ||
extraAliases = {'direction'} | |||
end | end | ||
-- Query as broadtable so we can sort in Lua | |||
-- (SMW |sort= can silently drop results that lack the sort property) | |||
local queryWikitext = | local queryWikitext = | ||
'{{#ask:\n' .. | '{{#ask:\n' .. | ||
| Line 132: | Line 138: | ||
' |?' .. notesProp .. '=notes\n' .. | ' |?' .. notesProp .. '=notes\n' .. | ||
extraProps .. | extraProps .. | ||
' |format=broadtable\n' .. | |||
' |headers=hide\n' .. | |||
' |format= | |||
' | | |||
' |link=none\n' .. | ' |link=none\n' .. | ||
'}}' | '}}' | ||
local result = frame:preprocess(queryWikitext) | local result = frame:preprocess(queryWikitext) | ||
return trim( | if not result or result == '' then return nil end | ||
-- Parse broadtable rows into structured data | |||
local rows = {} | |||
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 | |||
-- Columns: [1]=subobject, [2]=count, [3]=signal, [4]=connector, [5]=label, [6]=notes, [7+]=extras | |||
if #cells >= 3 then | |||
local rowData = { | |||
count = cells[2], | |||
signal = cells[3], | |||
connector = cells[4], | |||
label = cells[5], | |||
notes = cells[6], | |||
} | |||
for i, alias in ipairs(extraAliases) do | |||
rowData[alias] = cells[6 + i] | |||
end | |||
table.insert(rows, rowData) | |||
end | |||
end | |||
-- Sort by label: unlabeled entries first, then alphabetical by label | |||
table.sort(rows, function(a, b) | |||
local la = a.label or '' | |||
local lb = b.label or '' | |||
return la < lb | |||
end) | |||
-- Render each row through the display template | |||
local parts = {} | |||
for _, row in ipairs(rows) do | |||
local templateArgs = {} | |||
for k, v in pairs(row) do | |||
if v and v ~= '' then | |||
templateArgs[k] = v | |||
end | |||
end | |||
local rendered = frame:expandTemplate{title = templateName, args = templateArgs} | |||
if rendered and trim(rendered) then | |||
table.insert(parts, rendered) | |||
end | |||
end | |||
if #parts == 0 then return nil end | |||
return trim(table.concat(parts)) | |||
end | end | ||