Модуль:Даты авторов
Для документации этого модуля может быть создана страница Модуль:Даты авторов/doc
-- Calendar for [[Дни рождения все]]. Paginated read-only Cargo data, no writes.
local p = {}
local months = {'Январь','Февраль','Март','Апрель','Май','Июнь',
'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'}
local function personLink(name)
local title = mw.title.new(name)
if not title then return mw.text.nowiki(name) end
return '[[:' .. title.prefixedText .. '|' .. mw.text.nowiki(name) .. ']]'
end
local function calendar(rows, kind, heading, today, todayLabel)
local key = kind == 'birth' and 'birthkey' or 'deathkey'
local dates = kind == 'birth' and 'birthdate' or 'deathdate'
local events = {}
for _, row in ipairs(rows) do
local value = row[key] or ''
if value:match('^%d%d%-%d%d$') and value >= '01-01' and value <= '12-31' then
events[#events + 1] = row
end
end
table.sort(events, function(a,b)
if a[key] == b[key] then return a.page < b.page end
return a[key] < b[key]
end)
local out = {'\n== ' .. heading .. ' ==\n'}
local currentMonth = tonumber(today:sub(1,2))
for month = 1,12 do
out[#out+1] = '\n=== ' .. months[month] .. ' ===\n'
local list = mw.html.create('ul'):addClass('bw-dates-list')
local marked = false
local count = 0
local function marker()
list:tag('li'):addClass('bw-dates-today'):attr('id','today-'..kind)
:tag('strong'):wikitext(mw.text.nowiki('Сегодня — ' .. todayLabel))
marked = true
end
for _, row in ipairs(events) do
if tonumber(row[key]:sub(1,2)) == month then
if month == currentMonth and not marked and row[key] >= today then marker() end
local item = list:tag('li'):addClass('bw-dates-row')
if row[key] == today then item:addClass('bw-dates-on-today') end
item:tag('span'):addClass('bw-dates-date'):wikitext(mw.text.nowiki((row[dates] or ''):sub(1,5)))
local body = item:tag('span'):addClass('bw-dates-person')
body:wikitext(personLink(row.page))
local born, died = row.birthdate or '', row.deathdate or ''
local lifespan
if died ~= '' then
lifespan = (born ~= '' and born or '?') .. ' — ' .. died
else
lifespan = 'род. ' .. born
end
body:tag('span'):addClass('bw-dates-lifespan'):wikitext(mw.text.nowiki(' (' .. lifespan .. ')'))
count = count + 1
end
end
if month == currentMonth and not marked then marker() end
if count == 0 then list:tag('li'):addClass('bw-dates-empty'):wikitext('Нет указанных дат.') end
out[#out+1] = tostring(list) .. '\n'
end
return table.concat(out)
end
function p.main(frame)
-- #timel follows the wiki timezone (Europe/Moscow) and marks time dependency.
local today = frame:callParserFunction('#timel', {'m-d'})
local label = frame:callParserFunction('#timel', {'j xg Y', 'now', 'ru'})
local fields =
"Persona._pageName=page,DATE_FORMAT(Persona.DateBirth, '%m-%d')=birthkey,"
.. "DATE_FORMAT(Persona.DateBirth, '%d.%m.%Y')=birthdate,"
.. "DATE_FORMAT(Persona.DateDeath, '%m-%d')=deathkey,"
.. "DATE_FORMAT(Persona.DateDeath, '%d.%m.%Y')=deathdate"
-- Respect Cargo's per-query ceiling; never silently cut the calendar at 500.
local rows, offset = {}, 0
while true do
local batch = mw.ext.cargo.query('Persona', fields,
{limit=500, offset=offset, orderBy='Persona._pageID, Persona._ID'})
for _, row in ipairs(batch) do rows[#rows+1] = row end
if #batch < 500 then break end
offset = offset + 500
if offset >= 10000 then error('Слишком много персоналий для календаря; требуется обновление модуля.') end
end
return '<div class="bw-dates-calendar">\n'
.. calendar(rows,'birth','Дни рождения',today,label)
.. calendar(rows,'death','Дни памяти',today,label)
.. '</div>'
end
return p