Difference between revisions of "Module:Video game reviews/sandbox"

From blackwiki
Jump to navigation Jump to search
blackwiki>Jackmcbarn
m (fix indentation)
m (195 revisions imported)
 
(112 intermediate revisions by 10 users not shown)
Line 1: Line 1:
--
 
-- Module layout for reviewer section in the work
 
--
 
-- 1 get args
 
-- 2 extract all reviewer args
 
-- 3 sort args for reviewer then system
 
-- 4 output args value where reviewer + system correlate
 
--
 
 
 
require('Module:No globals')
 
require('Module:No globals')
  
 
local p = {}
 
local p = {}
 
+
local data = require('Module:Video game reviews/data/sandbox')
local data = mw.loadData('Module:Video game reviews/data')
+
local yesno = require('Module:Yesno')
 
+
local vgwd = require('Module:Video game wikidata/sandbox')
local HtmlBuilder = require('Module:HtmlBuilder')
+
local getArgs
  
 
local function getActiveSystems(args)
 
local function getActiveSystems(args)
 
local activeSystems = {}
 
local activeSystems = {}
for k,v in pairs(args) do
+
for k, v in pairs(args) do
if data.systems[k] and v:lower() == 'true' then
+
if data.systems[k] and yesno(v) then
 
table.insert(activeSystems, k)
 
table.insert(activeSystems, k)
 
end
 
end
Line 29: Line 20:
 
end
 
end
  
local function getArgKeyTables(orderedKeys)
+
local function getArgKeyTables(args)
 
local reviewers, aggregators, awards = {}, {}, {}
 
local reviewers, aggregators, awards = {}, {}, {}
for _,v in ipairs(orderedKeys) do
+
for k in pairs(args) do
if v:match('^rev(%d+)$') then
+
if string.match(k, '^rev%d+$') then
table.insert(reviewers, v)
+
table.insert(reviewers, k)
elseif v:match('^agg(%d+)$') then
+
elseif string.match(k, '^agg%d+$') then
table.insert(aggregators, v)
+
table.insert(aggregators, k)
elseif v:match('^award(%d+)$') then
+
elseif string.match(k, '^award%d+$') then
table.insert(awards, v)
+
table.insert(awards, k)
 
end
 
end
 
end
 
end
 +
local function comparator(a, b)
 +
return tonumber(a:match('%d+')) < tonumber(b:match('%d+'))
 +
end
 +
 +
table.sort(reviewers, comparator)
 +
table.sort(aggregators, comparator)
 +
table.sort(awards, comparator)
 
return reviewers, aggregators, awards
 
return reviewers, aggregators, awards
 
end
 
end
  
local function renderTitleRow(tbl, plain, title)
+
local function getProvidedReviewersAndAggregators(args, usePlatforms)
local titleCell = tbl.tag('tr').tag('th').css('font-size', '120%')
+
local providedReviewers, 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.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.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(providedAggregators, function(a, b)
 +
return data.aggregators[a].sortkey < data.aggregators[b].sortkey
 +
end)
 +
return providedReviewers, providedAggregators
 +
end
  
if plain then
+
local function renderTitle(aside, title)
titleCell
+
local titleElement = aside:tag('div')
.tag('span')
+
:attr('id', 'reception-title')
.css('padding-left', '5.7em')
+
:css('font-weight', 'bold')
.wikitext('&nbsp;')
 
end
 
  
 
if title then
 
if title then
titleCell
+
titleElement
.wikitext(title)
+
:wikitext(title)
 
else
 
else
titleCell
+
titleElement
.addClass('Reception')
+
:addClass('Reception')
.wikitext('Reception')
+
:wikitext(data.i18n.reception)
 
end
 
end
 
end
 
end
  
local function renderMainHeading(builder, colspan, headingText)
+
local function renderCaption(builder, captionText, borderTop)
builder.tag('tr').tag('th')
+
builder:tag('caption')
.attr('colspan', colspan)
+
:css('font-size', 'inherit')
.css('background', '#d1dbdf')
+
:css('background', '#d1dbdf')
.css('font-size', '120%')
+
:css('border-top', borderTop or '1px solid #a2a9b1')
.wikitext(headingText)
+
:css('border-left', '1px solid #a2a9b1')
 +
:css('border-right', '1px solid #a2a9b1')
 +
:wikitext(captionText)
 
end
 
end
  
local function renderHeadingRowWithSystems(builder, mainHeading, columnHeading, activeSystems)
+
local function renderHeadingRowWithSystems(builder, captionText, activeSystems)
renderMainHeading(builder, #activeSystems + 1, mainHeading)
+
renderCaption(builder, captionText)
builder.tag('tr')
+
builder:tag('tr')
.tag('th')
+
:tag('th')
.attr('rowspan', '2')
+
:attr('scope', 'col')
.css('background', '#e8f4f8')
+
:attr('rowspan', '2')
.css('text-align', 'center')
+
:css('background', '#e8f4f8')
.css('vertical-align', 'middle')
+
:css('text-align', 'center')
.wikitext('Publication')
+
:css('vertical-align', 'middle')
.done()
+
:wikitext(data.i18n.publication)
.tag('th')
+
:done()
.attr('colspan', #activeSystems)
+
:tag('th')
.css('background', '#e8f4f8')
+
:attr('scope', 'col')
.css('vertical-align', 'middle')
+
:attr('colspan', #activeSystems)
.wikitext(columnHeading)
+
:css('background', '#e8f4f8')
builder = builder.tag('tr')
+
:css('vertical-align', 'middle')
for _,v in ipairs(activeSystems) do
+
:wikitext(data.i18n.score)
builder.tag('th').wikitext(data.systems[v].name)
+
builder = builder:tag('tr')
 +
for _, v in ipairs(activeSystems) do
 +
builder:tag('th')
 +
:attr('scope', 'col')
 +
:wikitext(data.systems[v].name)
 
end
 
end
 
end
 
end
  
local function renderHeadingRow(builder, mainHeading, nameHeading, columnHeading)
+
local function renderHeadingRow(builder, captionText, nameHeading)
renderMainHeading(builder, 2, mainHeading)
+
renderCaption(builder, captionText)
builder
+
builder:tag('tr')
.tag('tr')
+
:tag('th')
.tag('th')
+
:attr('scope', 'col')
.css('background', '#e8f4f8')
+
:css('background', '#e8f4f8')
.css('text-align', 'center')
+
:css('text-align', 'center')
.css('vertical-align', 'middle')
+
:css('vertical-align', 'middle')
.wikitext(nameHeading)
+
:wikitext(nameHeading)
.done()
+
:done()
.tag('th')
+
:tag('th')
.css('background', '#e8f4f8')
+
:attr('scope', 'col')
.css('vertical-align', 'middle')
+
:css('background', '#e8f4f8')
.wikitext(columnHeading)
+
:css('vertical-align', 'middle')
 +
:wikitext(data.i18n.score)
 
end
 
end
  
local function renderRatingsBySystem(builder, code, name, activeSystems, args)
+
local function renderRatingsBySystem(builder, code, name, activeSystems, args, na)
builder = builder.tag('tr')
+
builder = builder:tag('tr')
builder.tag('td')
+
builder:tag('td')
.css('vertical-align','middle')
+
:css('vertical-align', 'middle')
.wikitext(name)
+
:wikitext(name)
  
for _,v in ipairs(activeSystems) do
+
for _, v in ipairs(activeSystems) do
 
local combinedCode = code .. '_' .. v
 
local combinedCode = code .. '_' .. v
local cell = builder.tag('td')
+
local cell = builder:tag('td')
 
if args[combinedCode] then
 
if args[combinedCode] then
cell
+
cell:css('vertical-align', 'middle')
.css('vertical-align', 'middle')
+
:wikitext(args[combinedCode])
.wikitext(args[combinedCode])
+
elseif na then
elseif args.na and args.na:lower() == 'true' then
+
cell:css('color', '#707070')
cell
+
:css('vertical-align', 'middle')
.css('color', 'lightgray')
+
:css('text-align', 'center')
.css('vertical-align','middle')
+
:addClass('table-na')
.css('text-align', 'center')
+
:wikitext(data.i18n.na)
.addClass('table-na')
 
.wikitext('N/A')
 
 
end
 
end
 
end
 
end
Line 133: Line 169:
  
 
local function renderRating(builder, name, rating)
 
local function renderRating(builder, name, rating)
builder.tag('tr')
+
builder:tag('tr')
.tag('td')
+
:tag('td')
.css('text-align', 'center')
+
:css('text-align', 'center')
.css('vertical-align', 'middle')
+
:css('vertical-align', 'middle')
.wikitext(name)
+
:wikitext(name)
.done()
+
:done()
.tag('td')
+
:tag('td')
.css('text-align', 'center')
+
:css('text-align', 'center')
.css('font-size', '110%')
+
:wikitext(rating)
.wikitext(rating)
 
 
end
 
end
  
 
local function renderReviews(builder, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
 
local function renderReviews(builder, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
local arg_system
+
builder = builder:tag('table')
local tbl2 = builder.tag('table')
+
:addClass('infobox wikitable')
.addClass('infobox wikitable')
+
:css('border-spacing', 0)
.attr('cellpadding', 0)
+
:css('width', '100%')
.attr('cellspacing', 0)
+
:css('border-bottom', 'none')
.css('width', '100%')
+
:css('margin', '0em')
.css('border-bottom', 'none')
+
 
.css('margin', '0em')
+
local reviewerCount = #providedReviewers + #customReviewerKeys
if #activeSystems == 0 then
+
local aggregatorCount = #providedAggregators + #customAggregatorKeys
tbl2.css('font-size', '100%')
+
local reviewScore = data.i18n[reviewerCount == 1 and 'reviewScore' or 'reviewScores']
end
+
local aggregateScore = data.i18n[aggregatorCount == 1 and 'aggregateScore' or 'aggregateScores']
if #providedReviewers > 0 and (#activeSystems > 1 or (args.showplatforms and args.showplatforms:lower() == 'true')) then
+
if #activeSystems ~= 0 then
renderHeadingRowWithSystems(tbl2, 'Review scores', 'Score', activeSystems)
+
builder:wikitext(data.i18n.multiplatformCategory)
elseif #providedReviewers > 0 and #activeSystems == 1 and (not args.showplatforms or args.showplatforms:lower() ~= 'true') then
+
local na = yesno(args.na)
renderHeadingRow(tbl2, 'Review scores', 'Publication', 'Score')
+
local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
end
+
if reviewerCount ~= 0 then
if #activeSystems >= 1 then
+
if showplatforms then
for _,v in ipairs(providedReviewers) do
+
renderHeadingRowWithSystems(builder, reviewScore, activeSystems)
renderRatingsBySystem(tbl2, v, data.reviewers[v].name, activeSystems, args)
+
else
 +
renderHeadingRow(builder, reviewScore, 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
 
end
for _,v in ipairs(customReviewerKeys) do
+
if aggregatorCount ~= 0 then
renderRatingsBySystem(tbl2, v, args[v], activeSystems, args)
+
if reviewerCount ~= 0 then
 +
renderCaption(builder, aggregateScore)
 +
elseif showplatforms then
 +
renderHeadingRowWithSystems(builder, aggregateScore, activeSystems)
 +
else
 +
renderHeadingRow(builder, aggregateScore, 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
 
end
if (#providedAggregators > 0 and #activeSystems > 1) and #providedReviewers == 0 then
+
else
renderHeadingRowWithSystems(tbl2, 'Aggregate scores', 'Score', activeSystems)
+
builder:wikitext(data.i18n.singleplatformCategory)
elseif (#providedAggregators > 0 and #providedReviewers > 0) or (#providedAggregators > 0 and #activeSystems == 1)then
+
if aggregatorCount ~= 0 then
renderMainHeading(tbl2, #activeSystems+1, 'Aggregate scores')
+
renderHeadingRow(builder, aggregateScore, data.i18n.aggregator)
end
+
for _, v in ipairs(providedAggregators) do
for _,v in ipairs(providedAggregators) do
+
renderRating(builder, data.aggregators[v].name, args[v])
renderRatingsBySystem(tbl2, v, data.aggregators[v].name, activeSystems, args)
+
end
end
+
for _, v in ipairs(customAggregatorKeys) do
elseif #activeSystems == 0 then
+
renderRating(builder, args[v], args[v .. 'Score'])
if #providedAggregators > 0 or #customAggregatorKeys > 0 then
+
end
renderHeadingRow(tbl2, 'Aggregate scores', 'Aggregator', 'Score')
 
end
 
for _,v in ipairs(providedAggregators) do
 
renderRating(tbl2, data.aggregators[v].name, args[v])
 
end
 
for _,v in ipairs(customAggregatorKeys) do
 
renderRating(tbl2, args[v], args[v .. 'Score'])
 
 
end
 
end
if #providedReviewers > 0 or #customReviewerKeys > 0 then
+
if reviewerCount ~= 0 then
renderHeadingRow(tbl2, 'Review scores', 'Publication', 'Score')
+
renderHeadingRow(builder, reviewScore, data.i18n.publication)
for _,v in ipairs(providedReviewers) do
+
for _, v in ipairs(providedReviewers) do
renderRating(tbl2, data.reviewers[v].name, args[v])
+
renderRating(builder, data.reviewers[v].name, args[v])
 
end
 
end
for _,v in ipairs(customReviewerKeys) do
+
for _, v in ipairs(customReviewerKeys) do
renderRating(tbl2, args[v], args[v .. 'Score'])
+
renderRating(builder, args[v], args[v .. 'Score'])
 
end
 
end
 
end
 
end
Line 199: Line 249:
 
end
 
end
  
local function renderAwards(builder, args, awardKeys)
+
local function renderAwards(builder, args, awardKeys, borderTop)
local Cell = builder.tag('table')
+
builder = builder:tag('table')
.addClass('infobox wikitable')
+
:addClass('infobox wikitable')
.css('width', '100%')
+
:css('width', '100%')
.css('margin', '0em')
+
:css('margin', '0em')
.css('border-top', 'none')
+
:css('border-top', borderTop)
.attr('cellpadding', 3)
+
:css('border-spacing', 0)
.attr('cellspacing', 0)
+
 
.tag('tr')
+
renderCaption(builder, data.i18n[#awardKeys == 1 and 'award' or 'awards'], borderTop)
.tag('th')
+
 
.attr('colspan', 2)
+
builder:tag('tr')
.css('background', '#d1dbdf')
+
:tag('th')
.css('font-size', '120%')
+
:attr('scope', 'col')
.css('border-top', 'none')
+
:wikitext(data.i18n.publication)
.wikitext('Awards')
+
:done()
.done()
+
:tag('th')
.done()
+
:attr('scope', 'col')
.tag('tr')
+
:wikitext(data.i18n.award)
.tag('th')
 
.wikitext('Publication')
 
.done()
 
.tag('th')
 
.wikitext('Award')
 
.done()
 
.done()
 
  
for _,v in ipairs(awardKeys) do
+
for _, v in ipairs(awardKeys) do
Cell.tag('tr')
+
builder:tag('tr')
.tag('td')
+
:tag('td')
.css('font-weight','bold')
+
:css('font-weight', 'bold')
.css('background-color','#f2f2f2')
+
:css('background-color', '#f2f2f2')
.wikitext(args[v .. 'Pub'])
+
:wikitext(args[v .. 'Pub'])
.done()
+
:done()
.tag('td')
+
:tag('td')
.css('background-color','#f2f2f2')
+
:css('background-color', '#f2f2f2')
.wikitext(args[v])
+
:wikitext(args[v])
 
end
 
end
 
end
 
end
  
local function renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args)
+
local function renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
local tbl = HtmlBuilder.create('table')
+
local aside = mw.html.create('div')
.attr('cellpadding', 0)
+
:attr('role', 'complementary')
.attr('cellspacing', 0)
+
:attr('aria-labelledby', 'reception-title')
.addClass(args.state or 'collapsible')
+
:css('margin', args.align and ((args.align == 'left' or args.align == 'none') and '0em 1em 1em 0em') or '0em 1em 1em 1em')
.css('background', 'transparent')
+
:css('text-align', 'center')
.css('padding', '0em')
+
:css('float', args.align or 'right')
.css('margin', '0em 1em 1em 1em')
+
:css('clear', args.align or 'right')
.css('text-align', 'center')
 
.css('font-size', '80%')
 
.css('float', args.align or 'right')
 
.css('clear', args.align or 'right')
 
  
 
if #activeSystems == 0 then
 
if #activeSystems == 0 then
 
-- Width: 20% Seems better since it scales with the article size.
 
-- Width: 20% Seems better since it scales with the article size.
tbl
+
aside:css('width', args.width or '23em')
.css('width', args.width or '23em')
 
 
end
 
end
  
if args.title and args.state ~= 'plain' and args.state ~= 'off' then
+
if args.title and args.state and (args.state == 'autocollapse'
tbl
+
or args.state == 'collapsed' or args.state == 'expanded') then
.addClass('collapsible')
+
aside:addClass('mw-collapsible')
.addClass(args.state)
+
:addClass(args.state == 'collapsed' and 'mw-collapsed' or args.state)
 
end
 
end
renderTitleRow(tbl, args.state == 'plain', args.title)
+
renderTitle(aside, args.title)
  
 
if args.subtitle then
 
if args.subtitle then
tbl
+
aside:tag('div')
.tag('tr')
+
:css('font-weight', 'bold')
.tag('th')
+
:wikitext(args.subtitle)
.css('font-size', '120%')
 
.wikitext(args.subtitle)
 
 
end
 
end
  
renderReviews(tbl.tag('tr').tag('td'), providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
+
renderReviews(aside:tag('div'), providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
 
if #awardKeys ~= 0 then
 
if #awardKeys ~= 0 then
renderAwards(tbl.tag('tr').tag('td'), args, awardKeys)
+
renderAwards(aside:tag('div'), args, awardKeys, (#customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0) and 'none' or nil)
 
end
 
end
return tbl
+
 
 +
if wikidata == true then
 +
aside:tag('div')
 +
:tag('table')
 +
:addClass('infobox wikitable noprint')
 +
:attr('role', 'presentation')
 +
:css('width', '100%')
 +
:css('margin', '0em')
 +
:css('border-top', 'none')
 +
:css('border-spacing', 0)
 +
:tag('tr')
 +
:tag('td')
 +
:css('border-top', 'none')
 +
:css('background', '#d1dbdf')
 +
:css('text-align', 'center')
 +
:css('font-weight', 'bold')
 +
:wikitext(vgwd.getUpdateLink())
 +
end
 +
 
 +
return aside
 
end
 
end
  
local function getProvidedReviewersAndAggregators(args, usePlatforms)
+
local function checkForWikidata(frame, args, activeSystems, providedAggregators)
local providedReviewers, providedAggregators = {}, {}
+
local wikidata = false
if usePlatforms then
+
 
local seen = {}
+
vgwd.setDateFormat(args["df"])
for k in pairs(args) do
+
vgwd.setGame(args["qid"])
local splitPos = string.find(k, '_')
+
vgwd.setSystem(nil)
if splitPos then
+
vgwd.setGenerateReferences(true)
local halfarg = string.sub(k, 1, splitPos - 1)
+
vgwd.setShowUpdateLink(false)
if not seen[halfarg] then
+
vgwd.setUpdateLinkStyle("text and pen")
seen[halfarg] = true
+
vgwd.setSystemFormat(args["systemFormat"])
if data.reviewers[halfarg] then
+
 
table.insert(providedReviewers, halfarg)
+
-- Loop through aggregators if we have any.
elseif data.aggregators[halfarg] then
+
if #providedAggregators ~= 0 then
table.insert(providedAggregators, halfarg)
+
for _i, aggr in ipairs(providedAggregators) do
 +
-- Check if vgwd knows this aggregator.
 +
if vgwd.setReviewer(aggr) == nil then
 +
-- Loop through active systems
 +
if #activeSystems ~= 0 then
 +
for _j, sys in ipairs(activeSystems) do
 +
local combinedCode = aggr .. '_' .. sys
 +
if args[combinedCode] == 'wikidata' then
 +
vgwd.setSystem(sys)
 +
vgwd.setShowSystem(false)
 +
local vgwdScore = vgwd.printReviewScores(frame)
 +
if vgwdScore then
 +
args[combinedCode] = vgwdScore
 +
end
 +
wikidata = true
 +
end
 +
end
 +
else
 +
vgwd.setShowSystem(true)
 +
if args[aggr] == 'wikidata' then
 +
local vgwdScore = vgwd.printReviewScores(frame)
 +
if vgwdScore then
 +
args[aggr] = vgwdScore
 +
end
 +
wikidata = true
 
end
 
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.aggregators[k] then
 
table.insert(providedAggregators, k)
 
 
end
 
end
 
end
 
end
 
end
 
end
 
end
 
end
table.sort(providedReviewers, function(a, b)
+
 
return data.reviewers[a].sortkey < data.reviewers[b].sortkey
+
return wikidata
end)
 
table.sort(providedAggregators, function(a, b)
 
return data.aggregators[a].sortkey < data.aggregators[b].sortkey
 
end)
 
return providedReviewers, providedAggregators
 
 
end
 
end
  
function p._reviewbox(args)
+
function p._reviewbox(frame, args)
local sortedArgKeys = {}
 
for k in pairs(args) do
 
if type(k) == 'string' then
 
table.insert(sortedArgKeys, k)
 
end
 
end
 
table.sort(sortedArgKeys)
 
 
 
 
local activeSystems = getActiveSystems(args)
 
local activeSystems = getActiveSystems(args)
local customReviewerKeys, customAggregatorKeys, awardKeys = getArgKeyTables(sortedArgKeys)
+
local customReviewerKeys, customAggregatorKeys, awardKeys = getArgKeyTables(args)
 
local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
 
local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
 +
local wikidata = checkForWikidata(frame, args, activeSystems, providedAggregators)
 
if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
 
if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
return renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args)
+
return renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
 
elseif mw.title.getCurrentTitle().namespace == 0 then
 
elseif mw.title.getCurrentTitle().namespace == 0 then
return '[[Category:Empty templates on articles]]'
+
return data.i18n.emptyCategory
 
end
 
end
 
end
 
end
  
 
function p.reviewbox(frame)
 
function p.reviewbox(frame)
-- ParserFunctions considers the empty string to be false, so to preserve the previous
+
if not getArgs then
-- behavior of {{Video game multiple console reviews}}, change any empty arguments to nil, so Lua will consider
+
getArgs = require('Module:Arguments').getArgs
-- them false too.
 
local args = {}
 
local parent_args = frame:getParent().args;
 
for k, v in pairs(parent_args) do
 
if v ~= '' then
 
args[k] = v
 
end
 
 
end
 
end
 
+
return p._reviewbox(frame, getArgs(frame, { wrappers = data.i18n.wrapper, trim = false, translate = data.argi18n }))
return p._reviewbox(args)
 
 
end
 
end
  
 
return p
 
return p

Latest revision as of 05:10, 30 September 2020

Documentation for this module may be created at Module:Video game reviews/sandbox/doc

require('Module:No globals')

local p = {}
local data = require('Module:Video game reviews/data/sandbox')
local yesno = require('Module:Yesno')
local vgwd = require('Module:Video game wikidata/sandbox')
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, aggregators, awards = {}, {}, {}
	for k in pairs(args) do
		if 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)
		end
	end
	local function comparator(a, b)
		return tonumber(a:match('%d+')) < tonumber(b:match('%d+'))
	end

	table.sort(reviewers, comparator)
	table.sort(aggregators, comparator)
	table.sort(awards, comparator)
	return reviewers, aggregators, awards
end

local function getProvidedReviewersAndAggregators(args, usePlatforms)
	local providedReviewers, 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.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.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(providedAggregators, function(a, b)
		return data.aggregators[a].sortkey < data.aggregators[b].sortkey
	end)
	return providedReviewers, providedAggregators
end

local function renderTitle(aside, title)
	local titleElement = aside:tag('div')
		:attr('id', 'reception-title')
		:css('font-weight', 'bold')

	if title then
		titleElement
			:wikitext(title)
	else
		titleElement
			:addClass('Reception')
			:wikitext(data.i18n.reception)
	end
end

local function renderCaption(builder, captionText, borderTop)
	builder:tag('caption')
		:css('font-size', 'inherit')
		:css('background', '#d1dbdf')
		:css('border-top', borderTop or '1px solid #a2a9b1')
		:css('border-left', '1px solid #a2a9b1')
		:css('border-right', '1px solid #a2a9b1')
		:wikitext(captionText)
end

local function renderHeadingRowWithSystems(builder, captionText, activeSystems)
	renderCaption(builder, captionText)
	builder:tag('tr')
		:tag('th')
			:attr('scope', 'col')
			:attr('rowspan', '2')
			:css('background', '#e8f4f8')
			:css('text-align', 'center')
			:css('vertical-align', 'middle')
			:wikitext(data.i18n.publication)
		:done()
		:tag('th')
			:attr('scope', 'col')
			:attr('colspan', #activeSystems)
			:css('background', '#e8f4f8')
			:css('vertical-align', 'middle')
			: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, captionText, nameHeading)
	renderCaption(builder, captionText)
	builder:tag('tr')
		:tag('th')
			:attr('scope', 'col')
			:css('background', '#e8f4f8')
			:css('text-align', 'center')
			:css('vertical-align', 'middle')
			:wikitext(nameHeading)
		:done()
		:tag('th')
			:attr('scope', 'col')
			:css('background', '#e8f4f8')
			:css('vertical-align', 'middle')
			: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')
				:wikitext(args[combinedCode])
		elseif na then
			cell:css('color', '#707070')
				:css('vertical-align', 'middle')
				:css('text-align', 'center')
				: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')
			:wikitext(rating)
end

local function renderReviews(builder, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
	builder = builder:tag('table')
		:addClass('infobox wikitable')
		:css('border-spacing', 0)
		:css('width', '100%')
		:css('border-bottom', 'none')
		:css('margin', '0em')

	local reviewerCount = #providedReviewers + #customReviewerKeys
	local aggregatorCount = #providedAggregators + #customAggregatorKeys
	local reviewScore = data.i18n[reviewerCount == 1 and 'reviewScore' or 'reviewScores']
	local aggregateScore = data.i18n[aggregatorCount == 1 and 'aggregateScore' or 'aggregateScores']
	if #activeSystems ~= 0 then
		builder:wikitext(data.i18n.multiplatformCategory)
		local na = yesno(args.na)
		local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
		if reviewerCount ~= 0 then
			if showplatforms then
				renderHeadingRowWithSystems(builder, reviewScore, activeSystems)
			else
				renderHeadingRow(builder, reviewScore, 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 aggregatorCount ~= 0 then
			if reviewerCount ~= 0 then
				renderCaption(builder, aggregateScore)
			elseif showplatforms then
				renderHeadingRowWithSystems(builder, aggregateScore, activeSystems)
			else
				renderHeadingRow(builder, aggregateScore, 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
	else
		builder:wikitext(data.i18n.singleplatformCategory)
		if aggregatorCount ~= 0 then
			renderHeadingRow(builder, aggregateScore, 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 reviewerCount ~= 0 then
			renderHeadingRow(builder, reviewScore, 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
	end
end

local function renderAwards(builder, args, awardKeys, borderTop)
	builder = builder:tag('table')
		:addClass('infobox wikitable')
		:css('width', '100%')
		:css('margin', '0em')
		:css('border-top', borderTop)
		:css('border-spacing', 0)

	renderCaption(builder, data.i18n[#awardKeys == 1 and 'award' or 'awards'], borderTop)

	builder:tag('tr')
		:tag('th')
			:attr('scope', 'col')
			:wikitext(data.i18n.publication)
		:done()
		:tag('th')
			:attr('scope', 'col')
			:wikitext(data.i18n.award)

	for _, v in ipairs(awardKeys) do
		builder:tag('tr')
			:tag('td')
				:css('font-weight', 'bold')
				:css('background-color', '#f2f2f2')
				:wikitext(args[v .. 'Pub'])
			:done()
			:tag('td')
				:css('background-color', '#f2f2f2')
				:wikitext(args[v])
	end
end

local function renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
	local aside = mw.html.create('div')
		:attr('role', 'complementary')
		:attr('aria-labelledby', 'reception-title')
		:css('margin', args.align and ((args.align == 'left' or args.align == 'none') and '0em 1em 1em 0em') or '0em 1em 1em 1em')
		:css('text-align', 'center')
		: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.
		aside:css('width', args.width or '23em')
	end

	if args.title and args.state and (args.state == 'autocollapse'
			or args.state == 'collapsed' or args.state == 'expanded') then
		aside:addClass('mw-collapsible')
			:addClass(args.state == 'collapsed' and 'mw-collapsed' or args.state)
	end
	renderTitle(aside, args.title)

	if args.subtitle then
		aside:tag('div')
			:css('font-weight', 'bold')
			:wikitext(args.subtitle)
	end

	renderReviews(aside:tag('div'), providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
	if #awardKeys ~= 0 then
		renderAwards(aside:tag('div'), args, awardKeys, (#customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0) and 'none' or nil)
	end

	if wikidata == true then
		aside:tag('div')
			:tag('table')
				:addClass('infobox wikitable noprint')
				:attr('role', 'presentation')
				:css('width', '100%')
				:css('margin', '0em')
				:css('border-top', 'none')
				:css('border-spacing', 0)
				:tag('tr')
					:tag('td')
						:css('border-top', 'none')
						:css('background', '#d1dbdf')
						:css('text-align', 'center')
						:css('font-weight', 'bold')
						:wikitext(vgwd.getUpdateLink())
	end

	return aside
end

local function checkForWikidata(frame, args, activeSystems, providedAggregators)
	local wikidata = false

	vgwd.setDateFormat(args["df"])
	vgwd.setGame(args["qid"])
	vgwd.setSystem(nil)
	vgwd.setGenerateReferences(true)
	vgwd.setShowUpdateLink(false)
	vgwd.setUpdateLinkStyle("text and pen")
	vgwd.setSystemFormat(args["systemFormat"])

	-- Loop through aggregators if we have any.
	if #providedAggregators ~= 0 then
		for _i, aggr in ipairs(providedAggregators) do
			-- Check if vgwd knows this aggregator.
			if vgwd.setReviewer(aggr) == nil then
				-- Loop through active systems
				if #activeSystems ~= 0 then
					for _j, sys in ipairs(activeSystems) do
						local combinedCode = aggr .. '_' .. sys
						if args[combinedCode] == 'wikidata' then
							vgwd.setSystem(sys)
							vgwd.setShowSystem(false)
							local vgwdScore = vgwd.printReviewScores(frame)
							if vgwdScore then
								args[combinedCode] = vgwdScore
							end
							wikidata = true
						end
					end
				else
					vgwd.setShowSystem(true)
					if args[aggr] == 'wikidata' then
						local vgwdScore = vgwd.printReviewScores(frame)
						if vgwdScore then
							args[aggr] = vgwdScore
						end
						wikidata = true
					end
				end
			end
		end
	end

	return wikidata
end

function p._reviewbox(frame, args)
	local activeSystems = getActiveSystems(args)
	local customReviewerKeys, customAggregatorKeys, awardKeys = getArgKeyTables(args)
	local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
	local wikidata = checkForWikidata(frame, args, activeSystems, providedAggregators)
	if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
		return renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
	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(frame, getArgs(frame, { wrappers = data.i18n.wrapper, trim = false, translate = data.argi18n }))
end

return p