Содержит специфичные для компьютерных игр функции форматирования.
formatReleaseDate
Альтернатива formatStatementDefault()
для форматирования дат выхода (P577). Выводит даты с разбивкой по платформам и с указанием раннего доступа.
Пример вызова:
{{wikidata|p577|property-module=Wikidata/VideoGames|property-function=formatReleaseDate|...}}
Стандартное форматирование | Форматирование этого модуля |
---|---|
25 марта 2021, 28 апреля 2022[1] и 29 сентября 2022 |
|
При подгрузке дат в Викиданных модуль также автоматически категоризует игру по году выпуска (например, Категория:Компьютерные игры 2022 года).
local mwlang = mw.getLanguage( 'ru' )
local p = {}
local platform_aliases = {
Q1406 = 'Windows',
Q172742 = 'NES',
Q183259 = 'SNES',
Q13522376 = 'Mac OS',
Q174666 = ''
}
-- Форматирует подгруженную с Викиданных дату в зависимости от её точности.
-- Возвращает строку или Nil.
local function formatDate( value )
-- We can't just use value.time to format the date because the
-- high-precision part would affect the result. E. g.:
-- formatDate( 'F Y', '+1997-09-01T00:00:00Z' ) -> 'September 1997'
-- formatDate( 'F Y', '+1997-09-00T00:00:00Z' ) -> 'August 1997'
-- Wikidata (with precision == 10) consider both of these to be September
-- though, and can store either of these without additional normalization.
local Y, M, D = mw.ustring.match( value.time, "(%d+)%-(%d+)%-(%d+)T" )
local precision = tonumber( value.precision )
if value.precision >= 11 then
return mwlang:formatDate( 'j xg Y', Y .. '-' .. M .. '-' .. D )
end
if value.precision == 10 then
return mwlang:formatDate( 'F Y', Y .. '-' .. M )
end
if value.precision == 9 then
return Y
end
return nil
end
-- Достаёт из квалификаторов к утверждению на Викиданных список платформ.
-- Возвращает строку.
local function getPlatforms( statement )
if not statement.qualifiers or not statement.qualifiers.P400 then
-- no 'platform' qualifiers
return ''
end
local platforms = {}
for _, qualifier in ipairs( statement.qualifiers.P400 ) do
if qualifier.datavalue then
local label
if platform_aliases[qualifier.datavalue.value.id] then
label = platform_aliases[qualifier.datavalue.value.id]
else
label = mw.wikibase.getLabel( qualifier.datavalue.value.id )
end
if label ~= '' then
table.insert( platforms, label )
end
end
end
table.sort( platforms )
return table.concat( platforms, ', ' )
end
-- Определяет по квалификаторам к утверждению на Викиданных, относится ли
-- данное утверждение к раннему доступу.
local function isEarlyAccess( statement )
if not statement.qualifiers or not statement.qualifiers.P3831 then
-- no 'object has role' qualifiers
return false
end
for _, qualifier in ipairs( statement.qualifiers.P3831 ) do
if qualifier.datavalue and qualifier.datavalue.value.id == 'Q17042291' then
-- object has role == early access
return true
end
end
return false
end
-- Рендерит один блок (заголовок-платформа со списком дат), возвращает строку.
local function renderBlock( header, rows )
local result
local listtype
if header == '' then
result = ''
listtype = '* '
else
result = '; ' .. header .. '\n'
listtype = ': '
end
for _, data in ipairs(rows) do
result = result .. listtype .. data[2] .. '\n'
end
return result
end
-- Используется для сортировки массива из массивов, в качестве ключа сортировки
-- берётся первый элемент.
local function comparer( a, b )
return a[1] < b[1]
end
-- Форматирует дату выпуска (P577) с разбивкой по платформам и указанием раннего
-- доступа.
function p.formatReleaseDate( context, options )
local entity = context.entity
if not entity or not entity.claims.P577 then
return ''
end
-- Step 1: gather data as a table:
-- 'platform' → { { 'sortkey1', 'datarow1' }, { 'sortkey2', 'datarow2' }, ... }
local data = {}
local data_length = 0
local release_year = nil
for _, statement in ipairs( entity.claims.P577 ) do
if statement
and statement.mainsnak
and statement.mainsnak.datavalue
and statement.mainsnak.datavalue.type == 'time'
and statement.rank ~= 'deprecated'
then
local value = statement.mainsnak.datavalue.value
local datarow = formatDate( value )
if datarow then
local sortkey = value.time
local platforms = getPlatforms( statement )
datarow = datarow .. context.formatRefs( options, statement )
if isEarlyAccess( statement ) then
datarow = datarow .. ' <small>(ранний доступ)</small>'
else
-- extract release year for further categorization
local current_year = mw.ustring.match( value.time, "(%d+)%-%d+%-%d+T" )
if not release_year or current_year < release_year then
release_year = current_year
end
end
if data[platforms] then
table.insert( data[platforms], { sortkey, datarow } )
else
data[platforms] = { { sortkey, datarow } }
data_length = data_length + 1
end
end
end
end
-- Step 2: sort data
local data_indices = {}
for platform, datarows in pairs(data) do
table.sort( datarows, comparer )
local sortkey = datarows[1][1] -- earliest release date
if platform == '' then
-- dates with no platform specified should be rendered first tho
sortkey = ''
end
table.insert( data_indices, { sortkey, platform } )
end
table.sort( data_indices, comparer )
-- Step 3: render data
local result = ''
for _, index in pairs(data_indices) do
local platform = index[2]
if data_length == 1 then
-- If there's only one block, no need to render the header
result = result .. renderBlock( '', data[platform] )
else
result = result .. renderBlock( platform, data[platform] )
end
end
if release_year
and mw.title.getCurrentTitle().namespace == 0
and not options.nocat
then
result = result .. '[[Категория:Компьютерные игры ' .. release_year .. ' года]]'
end
return result
end
return p