Для документации этого модуля может быть создана страница Модуль:Wikidata/P166/doc

-- https://www.mediawiki.org/wiki/Wikibase/DataModel
-- https://www.wikidata.org/wiki/Wikidata:Glossary/ru
-- https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua/ru
-- https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ru

local p = {}

local function WikiDataValueToArray(strSrc)
	local result = {}
	for str in string.gmatch(strSrc, "[^,]+") do
		str = str:match'^%s*(.*%S)' or '' -- trim
		if str ~= 'значение неизвестно' and str ~= 'значение отсутствует' then
			table.insert(result, str)
		end
	end
	return result
end

local function sortOneRank(medals)
	local result = {
		medals = {},
		orders = {},
		others = {}
	}
	
	for i, value in ipairs(medals) do
		if string.find(value, '[Мм]едаль') ~= nil then
			table.insert(result.medals, value)
		elseif string.find(value, '[Оо]рден') ~= nil then
			table.insert(result.orders, value)
		else
			table.insert(result.others, value)
		end
	end
	
	return result
end

local function getOneMedal(medal, wd, frame)
	local result = ''
	
	if wd == 1 then
		local title = mw.title.new('Халип:' .. medal)
		if title.exists then
			result = frame:expandTemplate{ title = medal, args = {} }
		else
			result = '[[Халип:' .. medal .. ']]'
		end
	else
		result = medal
	end
	
	return result
end

local function formatOneItems(medals, wd, frame)
	local result = ''
	
	for i, value in pairs(medals) do
		result = result .. '|' .. getOneMedal(value, wd, frame) .. '\n'
		if math.fmod(i, 4) == 0 then
			result = result .. '|-\n'
		end
	end
	
	return result .. '|-\n'
end

local function getAllMedals(frame)
	local result = {
		wd    = 0,
		items = {}
	}
	
	for key, value in pairs( frame.args ) do
		if string.sub(value, 0, 1) ~= '{' then
			table.insert(result.items, value)
		end
	end
	
	if next(result.items) == nil then -- если пусто, используем ВД
		result.wd = 1
		
		local entity = mw.wikibase.getEntityObject()
		local valuePref = entity:formatPropertyValues('P166', { mw.wikibase.entity.claimRanks.RANK_PREFERRED } ).value
		local valueNorm = entity:formatPropertyValues('P166', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ).value
		local valueDepr = entity:formatPropertyValues('P166', { mw.wikibase.entity.claimRanks.RANK_DEPRECATED } ).value

		table.insert(result.items, WikiDataValueToArray(valuePref))
		table.insert(result.items, WikiDataValueToArray(valueNorm))
		table.insert(result.items, WikiDataValueToArray(valueDepr))
	end
	
	return result
end

local function sorting(medals)
	local result = {
		wd = medals.wd,
		items = {}
	}
	
	-- Не сортировать, если источник ВП или пусто.
	if medals.wd == 1 and next(medals.items) ~= nil then
		table.insert(result.items, sortOneRank(medals.items[1]))
		table.insert(result.items, sortOneRank(medals.items[2]))
		table.insert(result.items, sortOneRank(medals.items[3]))
	else
		result.items[1] = medals.items
	end
	
	return result
end

local function formatMedals(medal, frame)
	local startStr, result, endStr = '{| style="background:transparent"\n', '', '|}'
	
	if next(medal.items) ~= nil then
		for i, value in ipairs(medal.items) do
			if medal.wd == 1 then
				result = result .. formatOneItems(value.orders, medal.wd, frame)
				result = result .. formatOneItems(value.medals, medal.wd, frame)
				result = result .. formatOneItems(value.others, medal.wd, frame)
			else
				result = result .. formatOneItems(value, medal.wd, frame)
			end
		end
	end
	return startStr .. result .. endStr
end

function p.display(frame)
	local medals = getAllMedals(frame)
	local sortedMedals = sorting(medals)
	return formatMedals(sortedMedals, frame)
end

return p