Модуль:GamesSport (Bk;rl,&GamesSport)

Перейти к навигации Перейти к поиску
Документация

Реализует {{Спорт}} как замену куче проставленных вручную пиктограмм в спортивных статьях. Данные перечислены в Модуль:GamesSport/data.json. Страницы с видами спорта вне базы данных добавляются в Википедия:Страницы с ошибками шаблона Спорт.

Страница данных

[править код]

Страница данных имеет следующие параметры данных (под "data") с различными возможными значениями:

  • "icon" — может иметь значение формата Triathlon, что интерпретируется как Триатлон Файл:Triathlon pictogram.svg (или Триатлон Файл:Triathlon pictogram (Paralympics).svg при использовании шаблона с префиксом паралимпиада в названии спорта), или Triathlon pictogram.svg для добавления файла в ином формате.
    • "paraicon" — может иметь значения аналогично icon, а также значение false (без кавычек, если необходимо всегда вызывать иконку паралимпиады для спорта).
    • "paralympic" — при добавлении параметра с true (без кавычек) спорт будет интерпретироваться как паралимпийский по умолчанию (выводить паралимпийскую иконку без указания паралимпиада).
  • "title" — текущее название статьи о спорте в русской Википедии. Будет использовано в статье при стандартном использовании шаблона.
  • "text" — отображаемое название вида спорта. Не следует указывать, если не отличается от "title".

Для добавления нового спорта нужно добавить данные в следующем формате (с дополнениями по необходимости):

"КЛЮЧ СПОРТА": {
	"icon": "ИКОНКА",
	"title": "НАЗВАНИЕ СТАТЬИ"
}

Ключ спорта указывается в строчных буквах и без буквы «ё». Модуль автоматически переводит все значения в строчные и заменяет «ё» на «е» при обработке ключей для простоты работы с данными (но название статьи и отображаемое название следует указывать с буквой «ё»).

Для добавления алиаса (синонима названия) спорта необходимо добавить данные в следующем формате в блок "aliases": "АЛИАС": "КЛЮЧ СПОРТА".

  • Алиасы:
  • Разный регистр:
  • Паралимпиады:
  • Второй и третий параметры:
    • {{#invoke:GamesSport|main|велоспорт|Велоспорт на летних Олимпийских играх 2000}} Велоспорт
      • сокращённо: {{#invoke:GamesSport|main|велоспорт|на летних Олимпийских играх 2000}} Велоспорт
      • ещё более сокращённо: {{#invoke:GamesSport|main|велоспорт|летние 2000}} Велоспорт
    • {{#invoke:GamesSport|main|велоспорт|Велоспорт на летних Олимпийских играх 2000|Велоспорт на ОИ2000}} Велоспорт на ОИ2000
  • Без ссылки: {{#invoke:GamesSport|main|хоккей на траве||Хоккей на траве в 2005 году|ссылка=нет}} Хоккей на траве в 2005 году
  • С числом:
    • {{#invoke:GamesSport|main|хоккей на траве||Хоккей на траве в 2005 году|число=17}} Хоккей на траве в 2005 году (17)
    • {{#invoke:GamesSport|main|хоккей на траве||Хоккей на траве в 2005 году|число=17|ссылка=нет}} Хоккей на траве в 2005 году (17)
  • Только иконка: {{#invoke:GamesSport|main|велоспорт|иконка=да}}Велоспорт
  • Ссылка на {{iw}}: {{#invoke:GamesSport|main|гандбол|{{iw|Чешский гандбол|||Czech handball}}}} Чешский гандбол[англ.]*
--
-- Реализация шаблона {{Sport}}
--
require( 'strict' )
local p = {}

local templateName = 'Template:Спорт'
local errorCat = 'Википедия:Страницы с ошибками шаблона Спорт'

local sportList = mw.loadJsonData( 'Module:GamesSport/data.json' )
local mwLang = mw.getContentLanguage()

local yesno = require( 'Module:Yesno' )
local getArgs = require( 'Module:Arguments' ).getArgs

local function isEmpty( s )
	return s == nil or s == ''
end

local function hasNoLink( args )
	return yesno( args[ 'ссылка' ] or args[ 'link' ] ) == false
end

local function hasOnlyIcon( args )
	return yesno( args[ 'иконка' ] or args[ 'icon' ] ) == true
end

local function getSportKey( sport, noCaseChange )
	if isEmpty( sport ) then
		return ''
	end
	local nbsp = ' '
	local result = mw.ustring.gsub( sport, nbsp, ' ' )
	result = mw.ustring.gsub( result, ' ', ' ' )
	if isEmpty( noCaseChange ) then
		result = mw.ustring.lower( mw.ustring.gsub( sport, 'ё', 'е' ) )
	end
	result = mw.ustring.gsub( result, '^паралимпиада ', '' )
	result = mw.ustring.gsub( result, '^paralympics? ', '' )
	
	return result
end

local function isParalympicSport( sport, override )
	local sport = mw.ustring.lower( sport )
	if override == false then
		return false
	end
	if mw.ustring.find( sport, '^паралимпиада ' ) == 1 or mw.ustring.find( sport, '^paralympics? ' ) == 1 then
		return true
	end
	
	return false
end

local function getSportData( sport )
	if isEmpty( sport ) then
		return nil
	end
	
	local key = getSportKey( sport )
	if sportList.data[ key ] then
		return sportList.data[ key ] or nil
	end
	
	if sportList.aliases[ key ] then
		return sportList.data[ sportList.aliases[ key ] ] or nil
	end
	
	return nil
end

local function getIcon( data, sport, size, altText )
	-- Паралимпийские игры имеют собственные иконки, иногда они указаны прямыми именами в JSON
	local icon = data.icon
	local postfix = ''
	if data.paralympic or isParalympicSport( sport, data.paraicon ) then
		postfix = ' (Paralympics)'
		icon = data.paraicon or data.icon
	end
		
	if not mw.ustring.find( icon, '.svg' ) then
		icon = string.format( '%s pictogram%s.svg', icon, postfix )
	end
	
	return string.format(
		'[[File:%s|%s|class=noresize skin-invert-image|link=|%s]]',
		icon,
		size or '20px',
		altText or 'alt='
	)
end

local function formatLink( title, sport, text, noLink )
	if noLink and not isEmpty( text ) then
		return text
	end
	if noLink then
		return title
	end
	
	-- Поддержка {{iw}} и простых ссылок внутри шаблона
	if title:match('%[%[([^%]%|]+)%]') or title:match('%[%[([^%|]+)%|') then
		return title
	end
	
	if not isEmpty( text ) then
		if title == text then
			text = ''
		else
			text = '|' .. text
		end
	end
	
	-- Хардкодинг как в [[Шаблон:СтранаОИ]]
	if mw.ustring.find( title, 'на летних' ) == 1 or mw.ustring.find( title, 'на зимних' ) == 1 then
		title = sport .. ' ' .. title
	end
	if mw.ustring.find( title, 'летние ' ) == 1 then
		title = mw.ustring.gsub( title, 'летние ', sport .. ' на летних Олимпийских играх ' )
	end
	if mw.ustring.find( title, 'зимние ' ) == 1 then
		title = mw.ustring.gsub( title, 'зимние ', sport .. ' на зимних Олимпийских играх ' )
	end
	
	return string.format( '[[%s%s]]', title, text )
end

local function getError( name, args, nocat )
	local sport = args[ 1 ]
	local title = args[ 2 ]
	local text = args[ 3 ]
	
	-- Подставить максимально верный текст ссылки
	if mw.isSubsting() then
		if hasNoLink( args ) then
			return text or title or sport
		end
		if isEmpty( sport ) then
			sport = isEmpty( title ) and '' or ( '|' .. title )
		else
			sport = '|' .. sport
			text = text or title
		end
		
		return formatLink( text, sport )
	end
	
	local result = getSportKey( name or sport, true )
	if not isEmpty( title ) then
		result = string.format( '[[%s%s]]', title, '|' .. getSportKey( isEmpty( text ) and result or text, true ) )
	end
	result = result .. string.format( ' <sup>[[%s|(?)]]</sup>', templateName )
	
	if not yesno( nocat ) then
		result = result .. string.format( '[[Category:%s|%s]]', errorCat, sport )
	end
	
	return result
end

function p._getLink( args )
	local sport = args[ 1 ]
	local title = args[ 2 ]
	local text = args[ 3 ]
	local noLink = hasNoLink( args )
	local onlyIcon = hasOnlyIcon( args )
	local events = args[ 'число' ] or args[ 'events' ] or args[ 'Events' ]
	local size = args[ 'размер' ] or args[ 'size' ]
	local nocat = args[ 'nocat' ] or false
	
	if isEmpty( sport ) then
		return '<div class="error">Не указан вид спорта</div>'
			.. ( not yesno( nocat ) and string.format( '[[Category:%s|%s]]', errorCat, '*' ) or '' )
	end
	
	local data = getSportData( sport )
	if isEmpty( data ) then
		return getError( sport, args, nocat )
	end
	
	if not isEmpty( events ) then
		events = tonumber( events )
	end
	
	local displayedText = ''
	if title then
		displayedText = data.title
	end
	if not mw.isSubsting() and data.text then
		displayedText = data.text
	end
	if text then
		displayedText = text
	end
	
	if onlyIcon then
		return getIcon( data, sport, size, data.title )
	end
	
	local result = mw.html.create( 'span' )
		:addClass( 'nowrap' )
	
	if mw.isSubsting() then
		result = mw.html.create()
	end
		
	-- No icon when substing
	if not mw.isSubsting() then
		result
			:wikitext( getIcon( data, sport, size ) )
			:wikitext( ' ' )
	end
	
	-- No span wrapper when substing
	local formattedLink = formatLink( title or data.title, data.title, displayedText, noLink )
	if not mw.isSubsting() then
		result:tag( 'span' )
			:addClass( 'wrap' )
			:wikitext( formattedLink )
			:done()
	else
		result:wikitext( formattedLink )
	end
	
	if events then
		result:wikitext( ' ' )
		
		-- Simpler markup when substing
		result:tag( mw.isSubsting() and 'small' or 'span' )
			:addClass( not mw.isSubsting() and 'small' or nil )
			:wikitext( string.format( '(%s)', mwLang:formatNum( events ) ) )
	end
	
	return tostring( result )
end

function p.main( frame )
	local args = getArgs( frame )
	return p._getLink( args )
end

return p