Module:BrandSeries: Difference between revisions

Arclight changed the content model of the page Module:BrandSeries from "wikitext" to "Scribunto module"
Tags: content model change Mobile edit Mobile web edit
Use Category:CRTs without series for unassigned link (SMW !+ queries don't work) (via update-page on MediaWiki MCP Server)
 
(16 intermediate revisions by the same user not shown)
Line 10: Line 10:
s = s:gsub('^%s+', ''):gsub('%s+$', '')
s = s:gsub('^%s+', ''):gsub('%s+$', '')
if s == '' then return nil end
if s == '' then return nil end
return s
end
-- Encode a string for use in Special:Ask URL path
local function encodeForAsk(s)
-- Special:Ask uses a custom encoding: [ = -5B, ] = -5D, space = _, etc.
s = s:gsub('%[', '-5B')
s = s:gsub('%]', '-5D')
s = s:gsub(' ', '_')
s = s:gsub('%+', '-2B')
s = s:gsub('!', '-21')
return s
return s
end
end


function p.seriesTable(frame)
function p.seriesTable(frame)
local args = frame.args
-- Try to get brand from frame.args first (direct #invoke call)
local parent = frame:getParent()
-- then from parent.args (called through a template)
if parent then
local brand = trim(frame.args.brand) or trim(frame.args[1])
args = parent.args
if not brand then
local parent = frame:getParent()
if parent then
brand = trim(parent.args.brand) or trim(parent.args[1])
end
end
end
local brand = trim(args.brand) or trim(args[1])
if not brand then
if not brand then
Line 26: Line 40:
end
end
-- First, get all series from Category:Series
-- Query total count of all CRTs for this brand
local seriesQuery = '{{#ask:[[Category:Series]]|format=list|link=none|limit=500|sep=@@|searchlabel=}}'
local totalQuery = string.format(
local seriesResult = frame:preprocess(seriesQuery)
'{{#ask:[[Category:CRT models]][[Has brand::%s]]|format=count}}',
brand
)
local totalResult = frame:preprocess(totalQuery)
local totalCount = tonumber(trim(totalResult)) or 0
if not seriesResult or seriesResult == '' then
-- Query all CRTs for this brand with their series using broadtable
return "''No series found.''"
local crtQuery = string.format(
end
'{{#ask:[[Category:CRT models]][[Has brand::%s]][[Has series::+]]|?Has series|format=broadtable|link=none|headers=hide|limit=1000|searchlabel=}}',
brand
)
local crtResult = frame:preprocess(crtQuery)
-- Parse series names
-- Count occurrences of each series by parsing HTML table
local seriesList = {}
local seriesCounts = {}
for series in seriesResult:gmatch('[^@@]+') do
local assignedCount = 0
local s = trim(series)
if crtResult and crtResult ~= '' then
if s then
-- Parse each table row
table.insert(seriesList, s)
for rowContent in crtResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
-- Strip HTML tags
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
end
-- cells[1] = page name, cells[2] = series
if #cells >= 2 and cells[2] then
local series = cells[2]
-- Filter out invalid series values like "+"
if series and series ~= '' and series ~= '+' then
seriesCounts[series] = (seriesCounts[series] or 0) + 1
assignedCount = assignedCount + 1
end
end
end
end
end
end
-- Sort alphabetically
-- Calculate unassigned as total minus assigned
table.sort(seriesList)
local unassignedCount = totalCount - assignedCount
-- For each series, count how many CRTs belong to this brand
-- Convert to sorted array
local rows = {}
local rows = {}
for _, series in ipairs(seriesList) do
for series, count in pairs(seriesCounts) do
local countQuery = string.format(
table.insert(rows, {
'{{#ask:[[Category:CRT models]][[Has brand::%s]][[Has series::%s]]|format=count}}',
series = series,
brand, series
count = count
)
})
local countResult = frame:preprocess(countQuery)
local count = tonumber(trim(countResult)) or 0
if count > 0 then
-- Build the browse link
local browseLink = string.format(
'{{#queryformlink:form=CRT query|query string=CRT query[brand]=%s&CRT query[series]=%s&_run|link text=Browse}}',
brand, series
)
local browseHtml = frame:preprocess(browseLink)
table.insert(rows, {
series = series,
count = count,
browse = browseHtml
})
end
end
end
-- If no series found for this brand
-- Sort by series name
if #rows == 0 then
table.sort(rows, function(a, b) return a.series < b.series end)
return "''No series-assigned models for this brand.''"
-- If no series found and no unassigned, return nothing
if #rows == 0 and unassignedCount <= 0 then
return ""
end
end
-- Build the table
-- Build the table as wikitext (so links render properly)
local output = {}
local lines = {}
table.insert(output, '{| class="wikitable"')
table.insert(lines, '{| class="wikitable"')
table.insert(output, '|-')
table.insert(lines, '! Series !! Count')
table.insert(output, '! Series !! Count !! Browse')
-- Series rows
for _, row in ipairs(rows) do
for _, row in ipairs(rows) do
table.insert(output, '|-')
local seriesLink = '[[' .. row.series .. ']]'
table.insert(output, string.format('| [[%s]] || %d || %s', row.series, row.count, row.browse))
table.insert(lines, '|-')
table.insert(lines, '| ' .. seriesLink .. ' || ' .. tostring(row.count))
end
-- Unassigned row (if any) with link to Special:Ask
if unassignedCount > 0 then
-- Use Category:CRTs without series instead of [[Has series::!+]]
-- because SMW's negated existence queries don't work correctly
local askQuery = string.format('[[Category:CRTs without series]][[Has brand::%s]]', brand)
local askUrl = 'https://wiki.everycrt.com/wiki/Special:Ask/' .. encodeForAsk(askQuery)
-- Use wikitext external link syntax with full URL
local unassignedLink = "[" .. askUrl .. " ''(Unassigned)'']"
table.insert(lines, '|-')
table.insert(lines, '| ' .. unassignedLink .. ' || ' .. tostring(unassignedCount))
end
end
table.insert(output, '|}')
table.insert(lines, '|}')
return table.concat(output, '\n')
return table.concat(lines, '\n')
end
end


return p
return p
MediaWiki Appliance - Powered by TurnKey Linux