Модуль:Video game reviews
Перейти к навигации
Перейти к поиску
Этот модуль оценён как готовый к использованию. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, используйте песочницу. |
Реализация {{оценки игры}} на Lua.
Строковые значения используемых полей, заголовков и прочего поставляются из Модуль:Video game reviews/data.
Статические методы
Вызываемые из других модулей через require():
- strict - модуль вызывает ошибку при чтении любых нулевых глобальных переменных или записи в глобальные переменные за исключением arg. Детально смотри mw:Extension:Scribunto/Lua_reference_manual#strict
- Module:Video game reviews/data - данные поставляемые для модуля Video game reviews. Документация по использованию.
- Module:Yesno - модуль предоставляет единый интерфейс для обработки булевых или булевоподобных входных данных детально смотри Модуль:Yesno
require('strict')
local p = {}
local data = require('Module:Video game reviews/data')
local yesno = require('Module:Yesno')
local getArgs
local function getActiveSystems(args)
local activeSystems = {}
for k,v in pairs(args) do
if data.systems[k] and yesno(v) then
table.insert(activeSystems, k)
end
end
table.sort(activeSystems, function(a, b)
return data.systems[a].sortkey < data.systems[b].sortkey
end)
return activeSystems
end
local function getArgKeyTables(args)
local reviewers, reviewersRu, aggregators, awards = {}, {}, {}, {}
local hasObsolete = false
for k in pairs(args) do
if string.match(k, '^revRu%d+$') then
table.insert(reviewersRu, k)
elseif string.match(k, '^rev%d+$') then
table.insert(reviewers, k)
elseif string.match(k, '^agg%d+$') then
table.insert(aggregators, k)
elseif string.match(k, '^award%d+$') then
table.insert(awards, k)
elseif data.obsolete[k] then
hasObsolete = true
end
end
local function comparator(a, b)
return tonumber(a:match('%d+')) < tonumber(b:match('%d+'))
end
table.sort(reviewers, comparator)
table.sort(reviewersRu, comparator)
table.sort(aggregators, comparator)
table.sort(awards, comparator)
return reviewers, reviewersRu, aggregators, awards, hasObsolete
end
local function getProvidedReviewersAndAggregators(args, usePlatforms)
local providedReviewers, providedReviewersRu, providedAggregators = {}, {}, {}
if usePlatforms then
local seen = {}
for k in pairs(args) do
local splitPos = string.find(k, '_')
if splitPos then
local halfarg = string.sub(k, 1, splitPos - 1)
if not seen[halfarg] then
seen[halfarg] = true
if data.reviewers[halfarg] then
table.insert(providedReviewers, halfarg)
elseif data.reviewersRu[halfarg] then
table.insert(providedReviewersRu, halfarg)
elseif data.aggregators[halfarg] then
table.insert(providedAggregators, halfarg)
end
end
end
end
else
for k in pairs(args) do
if not string.find(k, '_') then
if data.reviewers[k] then
table.insert(providedReviewers, k)
elseif data.reviewersRu[k] then
table.insert(providedReviewersRu, k)
elseif data.aggregators[k] then
table.insert(providedAggregators, k)
end
end
end
end
table.sort(providedReviewers, function(a, b)
return data.reviewers[a].sortkey < data.reviewers[b].sortkey
end)
table.sort(providedReviewersRu, function(a, b)
return data.reviewersRu[a].sortkey < data.reviewersRu[b].sortkey
end)
table.sort(providedAggregators, function(a, b)
return data.aggregators[a].sortkey < data.aggregators[b].sortkey
end)
return providedReviewers, providedReviewersRu, providedAggregators
end
local function renderTitleRow(tbl, title, colspan)
local caption = tbl:tag('caption')
if title then
caption
:wikitext(title)
else
caption
:addClass('Reception')
:wikitext(data.i18n.reception)
end
end
local function renderMainHeading(builder, colspan, headingText, borderTop)
builder:tag('tr'):tag('th')
:attr('scope', 'colgroup')
:attr('colspan', colspan)
:attr('class', 'ts-Оценки_игры-header')
:css('border-top', borderTop)
:wikitext(headingText)
end
local function renderHeadingRowWithSystems(builder, mainHeading, activeSystems)
renderMainHeading(builder, #activeSystems + 1, mainHeading)
builder:tag('tr')
:tag('th')
:attr('scope', 'col')
:attr('rowspan', '2')
:attr('class', 'ts-Оценки_игры-subheader')
:wikitext(data.i18n.publication)
:done()
:tag('th')
:attr('scope', 'col')
:attr('colspan', #activeSystems)
:attr('class', 'ts-Оценки_игры-subheader')
:wikitext(data.i18n.score)
builder = builder:tag('tr')
for _,v in ipairs(activeSystems) do
builder:tag('th')
:attr('scope', 'col')
:wikitext(data.systems[v].name)
end
end
local function renderHeadingRow(builder, mainHeading, nameHeading)
renderMainHeading(builder, 2, mainHeading)
builder
:tag('tr')
:tag('th')
:attr('scope', 'col')
:attr('class', 'ts-Оценки_игры-subheader')
:wikitext(nameHeading)
:done()
:tag('th')
:attr('scope', 'col')
:attr('class', 'ts-Оценки_игры-subheader')
:wikitext(data.i18n.score)
end
local function renderRatingsBySystem(builder, code, name, activeSystems, args, na)
builder = builder:tag('tr')
builder:tag('td')
:css('vertical-align','middle')
:wikitext(name)
for _,v in ipairs(activeSystems) do
local combinedCode = code .. '_' .. v
local cell = builder:tag('td')
if args[combinedCode] then
cell
:css('vertical-align', 'middle')
:css('font-size', '105%')
:wikitext(args[combinedCode])
elseif na then
cell
:css('color', 'lightgray')
:css('vertical-align','middle')
:css('text-align', 'center')
:css('font-size', '105%')
:addClass('table-na')
:wikitext(data.i18n.na)
end
end
end
local function renderRating(builder, name, rating)
builder:tag('tr')
:tag('td')
:css('text-align', 'center')
:css('vertical-align', 'middle')
:wikitext(name)
:done()
:tag('td')
:css('text-align', 'center')
:css('font-size', '105%')
:wikitext(rating)
end
local function renderReviews(builder, providedReviewers, providedReviewersRu, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customReviewerRuKeys, args)
local hasReviewers = #providedReviewers ~= 0 or #customReviewerKeys ~= 0
local hasReviewersRu = #providedReviewersRu ~= 0 or #customReviewerRuKeys ~= 0
local hasAggregators = #providedAggregators ~= 0 or #customAggregatorKeys ~= 0
builder:css('font-size', '100%')
if #activeSystems ~= 0 then
-- builder:wikitext(data.i18n.multiplatformCategory)
builder:css('font-size', '85%')
local na = yesno(args.na)
local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
if hasAggregators then
--if hasReviewers then
-- renderMainHeading(builder, #activeSystems+1, data.i18n.aggregateScores)
--end
if showplatforms then
renderHeadingRowWithSystems(builder, data.i18n.aggregateScores, activeSystems)
else
renderHeadingRow(builder, data.i18n.aggregateScores, data.i18n.aggregator)
end
for _,v in ipairs(providedAggregators) do
renderRatingsBySystem(builder, v, data.aggregators[v].name, activeSystems, args, na)
end
for _,v in ipairs(customAggregatorKeys) do
renderRatingsBySystem(builder, v, args[v], activeSystems, args, na)
end
end
if hasReviewers then
if showplatforms then
renderHeadingRowWithSystems(builder, data.i18n.reviewScores, activeSystems)
else
renderHeadingRow(builder, data.i18n.reviewScores, data.i18n.publication)
end
for _,v in ipairs(providedReviewers) do
renderRatingsBySystem(builder, v, data.reviewers[v].name, activeSystems, args, na)
end
for _,v in ipairs(customReviewerKeys) do
renderRatingsBySystem(builder, v, args[v], activeSystems, args, na)
end
end
if hasReviewersRu then
if showplatforms then
renderHeadingRowWithSystems(builder, data.i18n.reviewScoresRu, activeSystems)
else
renderHeadingRow(builder, data.i18n.reviewScoresRu, data.i18n.publication)
end
for _,v in ipairs(providedReviewersRu) do
renderRatingsBySystem(builder, v, data.reviewersRu[v].name, activeSystems, args, na)
end
for _,v in ipairs(customReviewerRuKeys) do
renderRatingsBySystem(builder, v, args[v], activeSystems, args, na)
end
end
else
-- builder:wikitext(data.i18n.singleplatformCategory)
builder:css('font-size', '85%')
if hasAggregators then
renderHeadingRow(builder, data.i18n.aggregateScores, data.i18n.aggregator)
for _,v in ipairs(providedAggregators) do
renderRating(builder, data.aggregators[v].name, args[v])
end
for _,v in ipairs(customAggregatorKeys) do
renderRating(builder, args[v], args[v .. 'Score'])
end
end
if hasReviewers then
renderHeadingRow(builder, data.i18n.reviewScores, data.i18n.publication)
for _,v in ipairs(providedReviewers) do
renderRating(builder, data.reviewers[v].name, args[v])
end
for _,v in ipairs(customReviewerKeys) do
renderRating(builder, args[v], args[v .. 'Score'])
end
end
if hasReviewersRu then
renderHeadingRow(builder, data.i18n.reviewScoresRu, data.i18n.publication)
for _,v in ipairs(providedReviewersRu) do
renderRating(builder, data.reviewersRu[v].name, args[v])
end
for _,v in ipairs(customReviewerRuKeys) do
renderRating(builder, args[v], args[v .. 'Score'])
end
end
end
end
local function renderAwards(builder, args, awardKeys, borderTop, activeSystems)
if #activeSystems == 0 then
renderMainHeading(builder, 2, data.i18n.awards, borderTop)
else
renderMainHeading(builder, #activeSystems + 1, data.i18n.awards, borderTop)
end
if #activeSystems == 0 then
builder:tag('tr')
:tag('th')
:attr('scope', 'col')
:wikitext(data.i18n.awardpublication)
:done()
:tag('th')
:attr('scope', 'col')
:wikitext(data.i18n.award)
for _,v in ipairs(awardKeys) do
if (args[v .. 'Pub'] ~= nil) then
builder:tag('tr')
:tag('td')
:css('font-weight','bold')
:wikitext(args[v .. 'Pub'])
:done()
:tag('td')
:wikitext(args[v])
else
builder:tag('tr')
:tag('td')
:attr('colspan',2)
:wikitext(args[v])
:done()
end
end
else
builder:tag('tr')
:tag('th')
:attr('scope', 'col')
:wikitext(data.i18n.awardpublication)
:done()
:tag('th')
:attr('scope', 'col')
:attr('colspan', #activeSystems)
:wikitext(data.i18n.award)
for _,v in ipairs(awardKeys) do
if (args[v .. 'Pub'] ~= nil) then
builder:tag('tr')
:tag('td')
:css('font-weight','bold')
:wikitext(args[v .. 'Pub'])
:done()
:tag('td')
:attr('colspan', #activeSystems)
:wikitext(args[v])
else
builder:tag('tr')
:tag('td')
:attr('colspan', #activeSystems + 1)
:wikitext(args[v])
:done()
end
end
end
end
local function renderMainTable(providedReviewers, providedReviewersRu, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, customReviewerRuKeys, hasObsolete, args)
local tbl = mw.html.create('table')
:addClass('wikitable mw-collapsible ts-Оценки_игры')
:css('float', args.align or 'right')
:css('clear', args.align or 'right')
if #activeSystems == 0 then
-- Width: 20% Seems better since it scales with the article size.
tbl
:css('width', args.width or '23em')
renderTitleRow(tbl, args.title, 2)
else
renderTitleRow(tbl, args.title, #activeSystems + 1)
end
if args.subtitle then
tbl:tag('tr'):tag('th')
:attr('scope', 'col')
:css('font-size', '112%')
:wikitext(args.subtitle)
end
renderReviews(tbl, providedReviewers, providedReviewersRu, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customReviewerRuKeys, args)
if #awardKeys ~= 0 then
renderAwards(tbl, args, awardKeys, (#customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0) and 'none' or nil, activeSystems)
end
if hasObsolete then
tbl:tag('tr'):tag('td')
:css('color', 'red')
:attr('colspan', 2)
:wikitext(data.i18n.obsoleteText)
if mw.title.getCurrentTitle().namespace == 0 then
tbl:wikitext(data.i18n.obsoleteCategory)
end
end
return tbl
end
function p._reviewbox(args)
local activeSystems = getActiveSystems(args)
local customReviewerKeys, customReviewerRuKeys, customAggregatorKeys, awardKeys, hasObsolete = getArgKeyTables(args)
local providedReviewers, providedReviewersRu, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #customReviewerRuKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #providedReviewersRu ~= 0 or #awardKeys ~= 0 then
return renderMainTable(providedReviewers, providedReviewersRu, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, customReviewerRuKeys, hasObsolete, args)
-- elseif mw.title.getCurrentTitle().namespace == 0 then
-- return data.i18n.emptyCategory
end
end
function p.reviewbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._reviewbox(getArgs(frame, {wrappers = data.i18n.wrapper, trim = false, translate = data.argi18n}))
end
return p