Відкрити головне меню
{{i}} Документація модуля[перегляд] [редагувати] [історія] [очистити кеш]

Цей модуль використовується для робити шаблонів {{NUMBEROF}} та {{TODAYNUMBEROF}}, що відображають статистичні дані про інші мовні розділи Вікіпедії. Підсторінки даного модуля періодично оновлюються ботом MBHbot.

Функція і параметриРедагувати

Функції:

  • Editions — функція (без параметрів) для виводу таблиці з мовними розділами Вікіпедії, відсортованими за кількістю статей. Використовує сторінку Модуль:NumberOf/today як список даних (оновлюється ботом кожен день) і сторінку Модуль:NumberOf/lang для відображення назв мов.
  • Now — функція для виводу найактуальнішої статистики (застосовується в шаблоні {{NUMBEROF}}). Використовує сторінку Модуль:NumberOf/data (оновлюється ботом кожні 3 години) як список даних.
  • 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=en|param=articles}} — 5969705 (неформатоване значення)
  • {{#invoke:NumberOf|Now|wiki=en|param=articles|fmt=N}} — 5 969 705 (форматоване значення)

Дату останнього оновлення сторінки з даними можна дізнатися за допомогою конструкції {{#invoke:NumberOf|Now|wiki=en|param=date}} (14 листопада 2019, 6:00 (UTC); параметр 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:#222; text-decoration:inherit; -moz-text-decoration-color:#222; text-decoration-color:#222;"><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 = { '#222', string.format('%s:', val), text }
			}
		end
	else
		text = mwlang:ucfirst(mw.language.fetchLanguageName(val))
		result = frame:expandTemplate{
			title = 'Кольорове посилання',
			args = { '#222', string.format('%s:', val), text }
		}
	end

	if readOnly[val] == true then
		result = frame:expandTemplate{
			title = 'Кольорове посилання',
			args = { '#222', 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 = { '#222', 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