Модуль:NumberOf
Перейти к навигации
Перейти к поиску
Этот модуль оценён как готовый к использованию. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, используйте песочницу. |
Данный модуль используется для отображения и обновления шаблонов {{NUMBEROF}} и {{TODAYNUMBEROF}}, использующихся для отображения статистики по другим разделам Тептар. Помимо этого, с помощью данного модуля отображается список Тептар. Подстраницы с данными этого модуля периодично обновляются ботом Adam.
Функции и параметры
Доступные функции:
Editions
— функция (без параметров) для вывода таблиц с языковыми разделами Тептар, отсортированными по количеству статей (используется на странице Тептар:Список Тептар). Использует страницу Модуль:NumberOf/today в качестве списка данных (обновляется ботом ежедневно) и страницу Модуль:NumberOf/lang для отображения названий языков.Now
— функция для вывода наиболее актуальной статистики (используется в шаблоне {{NUMBEROF}}). Использует Модуль:NumberOf/data (обновляется ботом раз в 2 часа) в качестве списка данных.Today
— функция для вывода статистики по состоянию на начало текущего UTC-дня (используется в шаблоне {{TODAYNUMBEROF}}). Использует Модуль:NumberOf/today (обновляется ботом ежедневно) в качестве списка данных.
Параметры, используемые функциями Now
и Today
:
wiki
— код раздела Тептар (обязательный параметр; список кодов доступен в списке разделов Тептар);param
— необходимые данные (обязательный параметр):articles
— количество статей в разделе,admins
— количество администраторов,activeusers
— количество активных участников,date
— дата обновления данных в модуле,depth
— глубина раздела,edits
— количество правок в разделе,files
— количество файлов,pages
— количество страниц,pos
— место раздела по количеству статей (см. список Тептар),users
— количество участников.
fmt
— форматирование числа (принимает любое непустое значение).
Использование
Формат использования:
{{#invoke:NumberOf|Editions}}
{{#invoke:NumberOf|Now|wiki=
— 6451528 (неформатированное значение)en
|param=articles
}}{{#invoke:NumberOf|Now|wiki=
— 6 451 528 (форматированное значение)en
|param=articles
|fmt=N
}}
Дату последнего обновления страницы с данными можно узнать с помощью конструкции {{#invoke:NumberOf|Now|wiki=
(11 февраля 2022, 10:00 (UTC); параметр en
|param=date
}}wiki
может содержать любое непустое значение). На страницах с данными дата обновления шаблона представлена в UNIX-времени.
Представленные примеры с функцией Now
работают и с функцией Today
.
-- Модуль для шаблонов серии NUMBEROF и страницы [[Тептар:Список Тептар]]
local p = {}
-- Важнейшие переменные
local mwlang = mw.getContentLanguage()
local langs = mw.loadData('Module:NumberOf/lang')
-- Разделы Тептар, закрытые от редактирования
local readOnly = {
aa = true,
cho = true,
ho = true,
hz = true,
ii = true,
kj = true,
kr = true,
mh = true,
mus = true,
ng = true
}
-- Проверка пустоты параметра
local function isEmpty(s)
return s == nil or s == ''
end
-- Округление до сотых
local function round(n)
return math.floor(n * 100) / 100
end
-- Форматирование даты
local function formatDate(val)
return mwlang:formatDate('j xg Y, G:i', val) .. ' (UTC)'
end
-- Длина таблицы
local function tableLength(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
-- Рендеринг необходимого параметра из страницы с данными
local function renderNum(f, info)
-- Парсинг параметров шаблона
local wiki = f.wiki
local param = f.param
local fmt = f.fmt
-- Если нет обязательных параметров, выводится ноль
local result
if isEmpty(wiki) or isEmpty(param) then
result = 0
else
if param == 'date' then
result = formatDate(info['total']['date'])
return result
end
-- Расчёты для общего числа разделов
if wiki == 'total' then
if param == 'all' then
result = tableLength(info) - 1
end
if param == 'active' then
result = tableLength(info) - 1 - tableLength(readOnly)
end
end
local obj = info[wiki]
if obj ~= nil then
-- Убираем NUMBEROF из легаси-кода параметров
param = param:lower():gsub('numberof','')
if param ~= nil and info[wiki][param] ~= nil then
result = info[wiki][param]
-- Форматируем значение, если задан параметр
if not isEmpty(fmt) and type(result) == 'number' then
if param == 'depth' then
result = math.floor(result * 100) / 100
end
result = mwlang:formatNum(result)
end
end
else
result = 0
end
end
return tostring(result)
end
-- Вывод ссылки на языковой раздел
local function renderLink(val, text)
local text = (isEmpty(text) and val or text)
local result = ''
if val ~= mwlang:getCode() then
result = result .. '[[:' .. val .. ':|'
if readOnly[val] == true then
result = result .. '<span style="color:#202122; text-decoration:inherit; text-decoration-color:#202122;"><s title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s></span>'
else
result = result .. text
end
result = result .. ']]'
else
result = result .. text
end
return result
end
-- Вывод названия языка
local function renderLang(val, frame)
local text = ''
local result = ''
local hasArticle = false
if not isEmpty(langs[val]) then
text = langs[val][1]
if not isEmpty(langs[val][2]) then
result = '[[' .. langs[val][2] .. '|'
hasArticle = true
else
result = frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), text }
}
end
else
text = mwlang:ucfirst(mw.language.fetchLanguageName(val))
result = frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), text }
}
end
if readOnly[val] == true then
result = frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), '<span title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s>' }
}
result = '<s>' .. result .. '</s>'
end
if hasArticle then
result = result .. text .. ']]'
end
if val == mwlang:getCode() then
result = result .. '<span class="nomobile" style="margin-left:4px;">[[File:Mw-unwatch-icon.svg|16px|text-top|alt=★|link=]]</span>'
end
return result
end
-- Функция для вывода ячейки
local function createCell(val, style, fmt, stats, frame)
local result = '|'
if not isEmpty(fmt) then
result = result .. 'data-sort-value="' .. val .. '" '
end
result = result .. 'style="border:0; ' .. (not isEmpty(style) and style or 'padding:4px 24px 4px 0;') .. '"| '
if not isEmpty(stats) then
result = result .. frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', stats, (not isEmpty(fmt) and mwlang:formatNum(val) or val) }
}
else
result = result .. (not isEmpty(fmt) and mwlang:formatNum(val) or val) .. ' '
end
return result
end
-- Функция для вывода ряда таблицы
local function createRow(key, val, frame)
local result = '|- style="'
local style, originalStyle = ''
if key == mwlang:getCode() then
result = result .. 'font-weight:bold; '
style = 'background:#d5fdf4; '
originalStyle = style .. 'padding:4px 24px 4px 0;'
end
result = result .. 'text-align:right; vertical-align:top;"\n'
result = result .. createCell(val['pos'], style .. 'font-weight:normal; padding:4px 24px 4px 0;')
.. '|' .. createCell(renderLink(key), style .. 'font-weight:normal; padding:4px 24px 4px 0; white-space:nowrap;')
.. '|' .. createCell(renderLang(key, frame), style .. 'padding:4px 24px 4px 0; text-align:left;')
.. '|' .. createCell(val['articles'], originalStyle, true, key .. ':' .. 'Special:Statistics', frame)
.. '|' .. createCell(val['pages'], originalStyle, true)
.. '|' .. createCell(val['edits'], originalStyle, true)
.. '|' .. createCell(round(val['depth']), originalStyle, true)
.. '|' .. createCell(val['users'], originalStyle, true, key .. ':' .. 'Special:ListUsers', frame)
.. '|' .. createCell(val['activeusers'], originalStyle, true, key .. ':' .. 'Special:ActiveUsers', frame)
.. '|' .. createCell(val['admins'], originalStyle, true, key .. ':' .. 'Special:ListAdmins', frame)
.. '|' .. createCell(val['files'], originalStyle, true)
return result .. '\n'
end
-- Функция для вывода шапки таблицы
local function createHeader()
local cell = 'background-color:transparent; padding-bottom:2px; padding-right:24px;'
local cellLang = 'background-color:transparent; padding-bottom:2px; text-align:left; width:25%;'
local result = '\n{| class="mw-datatable sortable" style="border:0; font-feature-settings:\'tnum\' 1; margin:4px 0 0; width:100%;"\n'
.. '|- style="border-bottom:1px solid #a2a9b1; text-align:right;"\n'
.. '!style="border:0; ' .. cell .. '"| №'
.. '|' .. createCell('Код', cell)
.. '|' .. createCell('Язык', cellLang)
.. '|' .. createCell('Статей', cell)
.. '|' .. createCell('Страниц', cell)
.. '|' .. createCell('Правок', cell)
.. '|' .. createCell('<abbr title="Глубина">Глуб.</abbr>', cell)
.. '|' .. createCell('Участников', cell)
.. '|' .. createCell('(<abbr title="Активных участников">акт.</abbr>)', cell)
.. '|' .. createCell('<abbr title="Администраторов">Адм.</abbr>', cell)
.. '|' .. createCell('Файлов', cell)
return result .. '\n'
end
-- Функция для вывода подвала таблицы
local function createFooter(frame, hide)
-- Параметр hide отвечает за оптическое выравнивание таблиц
local val = frame['total']
local cell = 'background:transparent; padding-right:24px; ' .. (hide and '' or 'padding-top:2px;')
local cellHide = 'padding-right:24px;' .. (hide and '' or ' padding-top:2px;') .. ' visibility:hidden; white-space:nowrap;'
-- aa — закрытый раздел с самой большой глубиной
local num = tableLength(frame) - 1
local depth = (hide and round(frame['aa']['depth']) or round(val['depth']))
local result = '\n|- style="border-top:1px solid; font-weight:bold; text-align:right; vertical-align:top;'
.. (hide and ' line-height:0; visibility:hidden; border-top-color:transparent;' or ' border-top-color:#a2a9b1;') .. '"'
.. (hide and ' class="nomobile"' or '') .. '\n'
.. '!style="border:0; ' .. cellHide .. '"| ' .. num
-- zh-classical — самое длинное название раздела
result = result .. '|' .. createCell('zh-classical', cellHide)
.. '|' .. createCell('Всего', cell .. ' text-align:left;')
.. '|' .. createCell(val['articles'], cell, true)
.. '|' .. createCell(val['pages'], cell, true)
.. '|' .. createCell(val['edits'], cell, true)
.. '|' .. createCell(depth, cell, true)
.. '|' .. createCell(val['users'], cell, true)
.. '|' .. createCell(val['activeusers'], cell, true)
.. '|' .. createCell(val['admins'], cell, true)
.. '|' .. createCell(val['files'], cell, true)
return result
end
-- Функция для вывода в {{NUMBEROF}}
function p.Now(frame)
local data = mw.loadData('Модуль:NumberOf/data')
return renderNum(frame.args, data)
end
-- Функция для вывода в {{TODAYNUMBEROF}}
function p.Today(frame)
local data = mw.loadData('Модуль:NumberOf/today')
return renderNum(frame.args, data)
end
-- Функция для вывода в [[Тептар:Список Тептар]]
function p.Editions(frame)
local data = mw.loadData('Модуль:NumberOf/today')
local length = tableLength(data)
local result = ''
-- Таблица для сбора разделов по величине
local sorted = {
[1000000] = {},
[100000] = {},
[10000] = {},
[1000] = {},
[0] = {}
}
local sortedKeys = { 0, 1000, 10000, 100000, 1000000 }
-- Заполняем пустыми элементами каждую таблицу
for i = #sortedKeys, 1, -1 do
local n = sortedKeys[i]
for j = 1, length, 1 do
table.insert(sorted[n], false)
end
end
-- Сортировка разделов по позиции и величине
for key, val in pairs(data) do
local curr = data[key]
if key ~= 'total' then
if curr['articles'] <= 1000 then
sorted[ 0 ][ tonumber(curr['pos']) ] = key
else
for i = #sortedKeys, 2, -1 do
local n = sortedKeys[i]
if curr['articles'] / n > 1 then
sorted[ n ][ tonumber(curr['pos']) ] = key
break
end
end
end
end
end
-- Вывод таблицы
for i = #sortedKeys, 1, -1 do
if i ~= #sortedKeys then
result = result .. '\n'
end
local n = sortedKeys[i]
if n == 0 then
result = result .. '=== Менее 1000 статей ==='
else
result = result .. string.format('=== Более %s статей ===', mwlang:formatNum(n))
end
-- Автоматический скролл для недостаточно широких мониторов
result = result .. '\n<div style="overflow-x:auto; overflow-y:hidden;">\n' .. createHeader()
-- Вывод рядов таблицы
for _, val in ipairs(sorted[n]) do
if val ~= false then
local curr = data[val]
result = result .. createRow(val, curr, frame)
end
end
-- Вывод подвала таблицы
result = result .. createFooter(data, (n ~= 0))
result = result .. '\n|}\n</div>'
end
return result
end
return p