Module:List of wikis by project

From Meta, a Wikimedia project coordination wiki
Module documentation

This module powers Template:List of wikis by project and Template:Top N languages by project.

local p = {}

local data = mw.loadData('Module:NUMBEROF/data')
local getArgs = require('Module:Arguments').getArgs
local pageLanguage = mw.language.new(mw.getCurrentFrame():preprocess('{{PAGELANGUAGE}}')) -- for the current page, not the default site language

local function getLinkedDataCell(interwiki, specialpage, stats, action)
	return string.format('|| [[%s:Special:%s|%s]]', interwiki, specialpage, pageLanguage:formatNum(stats[data.map[action]]))
end

local function getDepth(stats)
	-- https://meta.wikimedia.org/wiki/Wikipedia_article_depth
	-- This gives silly results if, for example, the number of articles is small.
	local n = { 'articles', 'edits', 'pages' }
	for i, v in ipairs(n) do
		n[i] = data.map[v]
	end
	for i, v in ipairs(n) do
		n[i] = stats[v] or 0
	end
	local articles, edits, pages = n[1], n[2], n[3]
	if pages == 0 or articles == 0 then
		return 0
	end
	return math.floor((edits/pages) * ((pages - articles)/articles)^2)
end

p.main = function(frame)
	local args = getArgs(frame)
	local project = args[1]
	local ranks = mw.loadData('Module:NUMBEROF/' .. (project == 'wikipedia' and 'rank' or 'other'))[project]
	if ranks == nil then
		return '<strong class="error">Invalid project: ' .. (project or '{{{1}}}') .. '</span>'
	else
		local rows = {}
		-- mw.logObject(data)
		for i, lang in ipairs(ranks.rankByIndex) do
			local siteData = data.data[lang .. '.' .. project]
			local row = {
				'| ' .. pageLanguage:formatNum(i),
				string.format(
					'|| [[:en:%s language|%s]]', 
					mw.language.fetchLanguageName(lang, 'en'), 
					mw.language.fetchLanguageName(lang, pageLanguage:getCode())
				),
				'|| ' ..
				frame:preprocess(
					string.format(
						'{{lang|%s|%s}}',
						lang,
						mw.language.fetchLanguageName(lang)
					)
				),
				string.format('|| [[:%s:|%s]]', lang, lang),
			}
			if siteData then
				local interwiki = project == 'wikipedia' and (':' .. lang) or (project .. ':' .. lang)
				table.insert(row, getLinkedDataCell(interwiki, 'Statistics', siteData, 'articles'))
				table.insert(row, getLinkedDataCell(interwiki, 'AllPages', siteData, 'pages'))
				table.insert(row, getLinkedDataCell(interwiki, 'RecentChanges', siteData, 'edits'))
				table.insert(row, getLinkedDataCell(interwiki, 'ListUsers/sysop', siteData, 'admins'))
				table.insert(row, getLinkedDataCell(interwiki, 'ListUsers', siteData, 'users'))
				table.insert(row, getLinkedDataCell(interwiki, 'ActiveUsers', siteData, 'activeusers'))
				table.insert(row, getLinkedDataCell(interwiki, 'NewFiles', siteData, 'files'))
				if project == 'wikipedia' then
					table.insert(row, '|| ' .. pageLanguage:formatNum(getDepth(siteData)))
				end
			else
				table.insert(row, '|| colspan="8" class="error" | No data available')
			end
			table.insert(rows, table.concat(row, ' '))
		end
		return '|-\n' .. table.concat(rows, '\n|-\n')
	end
end

function p.topN(frame)
	local args = getArgs(frame)
	local project = args[1] or ''
	local n = tonumber(args[2]) or -1
	local count = 0
	for site, siteData in pairs(data.data) do
		if site:find('%.' .. project .. '$') and not site:find('^total') and siteData[data.map['articles']] > n then
			count = count + 1
		end
	end
	return count
end

return p