Module:LibraryRows: Difference between revisions
From Bodhicitta
(Keep the glossary out of the deferred row chunks (each is its own parse)) |
(Placeholder carries the total) |
||
| Line 55: | Line 55: | ||
-- makes MediaWiki wrap the run in a <p>, which then becomes the only flex child. | -- makes MediaWiki wrap the run in a <p>, which then becomes the only flex child. | ||
return '<div class="topic-biblio-controls"><div class="topic-biblio-filter">' .. | return '<div class="topic-biblio-controls"><div class="topic-biblio-filter">' .. | ||
frame:preprocess('{{#widget:filterInput|placeholder=' .. (trim(args.placeholder) or 'Filter | frame:preprocess('{{#widget:filterInput|placeholder=' .. (trim(args.placeholder) or | ||
('Filter ' .. mw.language.getContentLanguage():formatNum(total) .. ' items…')) .. '}}') .. | |||
'</div><div class="topic-biblio-pills">' .. all .. table.concat(pills) .. '</div></div>' | '</div><div class="topic-biblio-pills">' .. all .. table.concat(pills) .. '</div></div>' | ||
end | end | ||
Latest revision as of 19:41, 2 October 2026
Documentation for this module may be created at Module:LibraryRows/doc
-- Bibliographic rows for the library hub pages (Library, Library/Books, ...).
--
-- The same rows the topic pages use (Template:TopicBiblioRow): cover, citation,
-- class and date, an "About this item" disclosure. They replace the tile grid,
-- which was heavier to render and showed less.
--
-- {{#invoke:LibraryRows|controls|classes=Books;Articles;Classical Works|q:Multimedia=[[...]]}}
-- text filter plus class pills, as on topic pages (tws.js drives both)
-- {{#invoke:LibraryRows|section|heading=Books|link=Library/Books|query=[[Category:Books]]|title=yes}}
-- one class: a counted heading, then the rows (title=yes: title line above the citation)
--
-- Rows load in deferred chunks of CHUNK, so a long class does not hold up the
-- page; the number of chunks comes from the count, so nothing is truncated (the
-- old tile chunks stopped at a fixed 1,100).
local p = {}
local CHUNK = 100
-- Printout names must match Template:TopicBiblioRow's parameters (named args).
-- BcaAuthor is taken raw (#) so the row can build the link itself.
local PRINTOUTS = '|?Citation|?BcaAuthor#=BcaAuthor|?Class|?Title|?FrontCoverImg|?Pubdate|?TileDescription|?Description'
local function trim(s)
s = mw.text.trim(s or '')
return s ~= '' and s or nil
end
local function count(frame, query)
local n = frame:preprocess('{{#ask:' .. query .. '|format=count}}')
return tonumber((n or ''):match('%d+')) or 0
end
function p.controls(frame)
local args = frame.args
local classes = trim(args.classes) or ''
local base = trim(args.base) or '[[Category:Library Items]]'
local pills = {}
local total = 0
for class in mw.text.gsplit(classes, '%s*;%s*') do
if class ~= '' then
-- A pill counts what its section lists: pass q:<Class>=<query> when the
-- section uses a narrower query than "every item of this class".
local n = count(frame, trim(args['q:' .. class]) or (base .. '[[Class::' .. class .. ']]'))
if n > 0 then
total = total + n
table.insert(pills, '<span class="topic-biblio-pill" data-filter-class="' .. mw.text.encode(class) ..
'">' .. class .. ' <span class="rel-count">' .. mw.language.getContentLanguage():formatNum(n) .. '</span></span>')
end
end
end
local all = '<span class="topic-biblio-pill is-active" data-filter-class="">All <span class="rel-count">' ..
mw.language.getContentLanguage():formatNum(total) .. '</span></span>'
-- No whitespace between the containers and their children: a newline there
-- makes MediaWiki wrap the run in a <p>, which then becomes the only flex child.
return '<div class="topic-biblio-controls"><div class="topic-biblio-filter">' ..
frame:preprocess('{{#widget:filterInput|placeholder=' .. (trim(args.placeholder) or
('Filter ' .. mw.language.getContentLanguage():formatNum(total) .. ' items…')) .. '}}') ..
'</div><div class="topic-biblio-pills">' .. all .. table.concat(pills) .. '</div></div>'
end
function p.section(frame)
local args = frame.args
local query = trim(args.query)
if not query then return '' end
local heading = trim(args.heading)
local link = trim(args.link)
local sort = trim(args.sort) or 'Citation'
local order = trim(args.order) or 'asc'
-- title=yes: each row leads with the work's title above the citation.
local userparam = (trim(args.title) == 'yes') and '|userparam=title' or ''
local n = count(frame, query)
if n == 0 then return '' end
local out = { '<div class="topic-biblio-section">' }
if heading then
local label = link and ('[[' .. link .. '|' .. heading .. ']]') or heading
table.insert(out, '<h2 class="link-no-border"><span class="rel-count">' ..
mw.language.getContentLanguage():formatNum(n) .. '</span> ' .. label .. '</h2>')
end
table.insert(out, '<div class="topic-biblio-list">')
for offset = 0, n - 1, CHUNK do
table.insert(out, frame:preprocess('{{#ask:' .. query .. PRINTOUTS ..
'|format=template|template=TopicBiblioRow|named args=yes|link=none' ..
'|sort=' .. sort .. '|order=' .. order ..
userparam ..
'|limit=' .. CHUNK .. '|offset=' .. offset ..
-- Each deferred chunk is parsed on its own, so the page's __NOGLOSSARY__
-- would not reach it: the glossary would mark up every chunk (~2,300
-- terms across the Library). A wrapper whose class is exactly
-- "noglossary" keeps it out: measured 800 -> 440 ms and 388 -> 285 KB
-- for a chunk of 100 rows.
'|intro=<div class="noglossary">|outro=</div>' ..
'|searchlabel=|default=|@deferred}}'))
end
table.insert(out, '</div></div>')
return table.concat(out)
end
return p