Модуль:CatalogSection
Внешний вид
Для документации этого модуля может быть создана страница Модуль:CatalogSection/doc
-- Модуль:CatalogSection
-- Универсальный модуль: выводит разделы либо подразделы и оборачивает их в шаблон «Заглавная страница/Раздел».
-- Для каталога (главных полок) сохраняет статические списки.
-- Для страниц Полка:… (неглавных полок) вместо списка дочерних ссылок вставляет DPL.
-- ID в шаблоне жёстко = "tfa".
local p = {}
function p.render(frame)
local title = mw.title.getCurrentTitle()
local full = title.prefixedText
-- Загружаем исходный список
local listTitle = mw.title.new('Викиучебник:Каталог учебников/Список')
if not listTitle or not listTitle.exists then
return ''
end
local content = listTitle:getContent()
-- Извлекаем строки после {{Шапка}}
local lines = {}
local start = false
for _, line in ipairs(mw.text.split(content, '\n')) do
if start then
table.insert(lines, line)
elseif line:find('Викиучебник:Каталог учебников/Шапка', 1, true) then
start = true
end
end
-- Собираем секции и дочерние элементы
local sections = {}
for _, line in ipairs(lines) do
local stars, text = line:match('^(%*+)%s*(.+)')
if stars == '*' then
table.insert(sections, { header = text, children = {} })
elseif stars == '**' then
local last = sections[#sections]
if last then table.insert(last.children, text) end
end
end
-- Определяем контекст: catalog или shelf
local isShelf = full:match('^Полка:')
local targets = {}
if full == 'Викиучебник:Каталог учебников' then
targets = sections
elseif isShelf then
local shelfName = full:match('^Полка:(.+)$') or ''
for _, sec in ipairs(sections) do
if sec.header:find('Полка:' .. shelfName, 1, true) then
-- создаём отдельные секции по дочерним элементам
for _, child in ipairs(sec.children) do
table.insert(targets, { header = child, children = {} })
end
break
end
end
else
return ''
end
-- Функция генерации колонок
local function makeBlocks(list)
local blocks = {}
local iconPattern = '(%[%[Файл:[^|%]]+)%|%d+px'
for _, sec in ipairs(list) do
-- Заголовок с иконкой 25px
local headerIcon = sec.header:gsub(iconPattern, '%1|25px')
-- Получаем чистое имя полки
local pageName = sec.header:match('%[%[Полка:([^|%]]+)') or ''
local body
if isShelf then
-- Для неглавных полок вставляем DPL
local dpl = table.concat({
'{{#tag:DynamicPageList|',
'category = ' .. pageName,
'namespace = Основной',
'shownamespace = false',
'suppresserrors = true',
'ordermethod = categorysortkey',
'order = ascending',
'}}'
}, '\n')
body = '<h2>' .. headerIcon .. '</h2>\n' .. dpl
else
-- Для каталога: статический список дочерних ссылок, если есть
local items = {}
for _, child in ipairs(sec.children) do
table.insert(items, '* ' .. child)
end
local listText = items[1] and table.concat(items, '\n') or ''
body = '<h2>' .. headerIcon .. '</h2>\n' .. listText
end
-- Параметры шаблона
local args = {
ID = 'tfa',
['Содержание'] = body,
['Читателям'] = '*[[Полка:' .. pageName .. '|<span class="mw-ui-button mw-ui-quiet">Все учебники на полке</span>]]'
}
local tpl = frame:expandTemplate{ title = 'Заглавная страница/Раздел', args = args }
table.insert(blocks, '<div class="main-wrapper-column">' .. tpl .. '</div>')
end
return blocks
end
-- Собираем и группируем их по 3
local columnBlocks = makeBlocks(targets)
local wrapped = {}
for i, block in ipairs(columnBlocks) do
if (i-1) % 3 == 0 then table.insert(wrapped, '<div class="main-wrapper">') end
table.insert(wrapped, block)
if i % 3 == 0 or i == #columnBlocks then table.insert(wrapped, '</div>') end
end
-- Возвращаем с препроцессингом
local result = table.concat(wrapped, '\n')
return frame:preprocess(result)
end
return p