Module:Video game reviews: Difference between revisions

From Research Realm
(hate)
(2019 version until we can use css)
Line 23: Line 23:
local reviewers, aggregators, awards = {}, {}, {}
local reviewers, aggregators, awards = {}, {}, {}
for k in pairs(args) do
for k in pairs(args) do
if string.match(k, data.i18n.pattern.reviewer) then
if string.match(k, '^rev%d+$') then
table.insert(reviewers, k)
table.insert(reviewers, k)
elseif string.match(k, data.i18n.pattern.aggregator) then
elseif string.match(k, '^agg%d+$') then
table.insert(aggregators, k)
table.insert(aggregators, k)
elseif string.match(k, data.i18n.pattern.award) then
elseif string.match(k, '^award%d+$') then
table.insert(awards, k)
table.insert(awards, k)
end
end
Line 78: Line 78:
end
end


local function renderHeadingRowWithSystems(builder, activeSystems, headingText)
local function renderTitleRow(tbl, title)
local titleCell = tbl:tag('tr'):tag('th')
 
if title then
titleCell
:wikitext(title)
else
titleCell
:addClass('Reception')
:wikitext(data.i18n.reception)
end
end
 
local function renderMainHeading(builder, colspan, headingText, borderTop)
builder:tag('tr'):tag('th')
  :attr('colspan', colspan)
  :css('background', '#d1dbdf')
  :css('border-top', borderTop)
  :wikitext(headingText)
end
 
local function renderHeadingRowWithSystems(builder, mainHeading, activeSystems)
renderMainHeading(builder, #activeSystems + 1, mainHeading)
builder:tag('tr')
builder:tag('tr')
:addClass(data.i18n.class.headerrow)
  :tag('th')
:tag('th')
  :attr('rowspan', '2')
:attr('scope', 'col')
  :css('background', '#e8f4f8')
:attr('rowspan', '2')
  :css('text-align', 'center')
:wikitext(headingText)
  :css('vertical-align', 'middle')
:done()
  :wikitext(data.i18n.publication)
:tag('th')
  :done()
:attr('scope', 'colgroup')
  :tag('th')
:attr('colspan', #activeSystems)
  :attr('colspan', #activeSystems)
:wikitext(data.i18n.display.score)
  :css('background', '#e8f4f8')
:done()
  :css('vertical-align', 'middle')
  :wikitext(data.i18n.score)
builder = builder:tag('tr')
builder = builder:tag('tr')
for _, v in ipairs(activeSystems) do
for _, v in ipairs(activeSystems) do
builder:tag('th')
builder:tag('th'):wikitext(data.systems[v].name)
:wikitext(data.systems[v].name)
:attr('scope', 'col')
:done()
end
end
end
end


local function renderHeadingRow(builder, nameHeading)
local function renderHeadingRow(builder, mainHeading, nameHeading)
builder:tag('tr')
renderMainHeading(builder, 2, mainHeading)
:addClass(data.i18n.class.headerrow)
builder
:tag('th')
:tag('tr')
:attr('scope', 'col')
:tag('th')
:css('background', '#e8f4f8')
:css('text-align', 'center')
:css('vertical-align', 'middle')
:wikitext(nameHeading)
:wikitext(nameHeading)
:done()
:done()
:tag('th')
:tag('th')
:attr('scope', 'col')
:css('background', '#e8f4f8')
:wikitext(data.i18n.display.score)
:css('vertical-align', 'middle')
:done()
:wikitext(data.i18n.score)
end
end


Line 116: Line 139:
builder = builder:tag('tr')
builder = builder:tag('tr')
builder:tag('td')
builder:tag('td')
:wikitext(name)
  :css('vertical-align', 'middle')
  :wikitext(name)


for _, v in ipairs(activeSystems) do
for _, v in ipairs(activeSystems) do
Line 123: Line 147:
if args[combinedCode] then
if args[combinedCode] then
cell
cell
:wikitext(args[combinedCode])
:css('vertical-align', 'middle')
:done()
:css('text-align', 'center')
:wikitext(args[combinedCode])
elseif na then
elseif na then
cell
cell
:addClass(data.i18n.class.na)
:css('color', '#707070')
:wikitext(data.i18n.display.na)
:css('vertical-align', 'middle')
:done()
:css('text-align', 'center')
:addClass('table-na')
:wikitext(data.i18n.na)
end
end
end
end
Line 136: Line 163:
local function renderRating(builder, name, rating)
local function renderRating(builder, name, rating)
builder:tag('tr')
builder:tag('tr')
:tag('td')
  :tag('td')
:addClass(data.i18n.class.centeredpub)
  :css('text-align', 'center')
:wikitext(name)
  :css('vertical-align', 'middle')
:done()
  :wikitext(name)
:tag('td')
  :done()
:wikitext(rating)
  :tag('td')
:done()
  :css('text-align', 'center')
  :wikitext(rating)
end
end


local function renderAggregators(builder, providedAggregators, activeSystems, customAggregatorKeys, args)
local function renderReviews(builder, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
local aggregatorCount = #providedAggregators + #customAggregatorKeys
if aggregatorCount == 0 then return end
builder = builder:tag('table')
builder = builder:tag('table')
:addClass(data.i18n.class.aggregators)
:addClass('infobox wikitable')
:addClass(data.i18n.class.wikitable)
:attr('cellpadding', 0)
:addClass(args.state and 'mw-collapsible-content' or nil)
:attr('cellspacing', 0)
:tag('caption')
:css('width', '100%')
:wikitext(data.i18n.display[aggregatorCount == 1 and 'aggregateScore' or 'aggregateScores'])
:css('border-bottom', 'none')
:done()
: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
if #activeSystems ~= 0 then
builder:wikitext(data.i18n.multiplatformCategory)
local na = yesno(args.na)
local na = yesno(args.na)
local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
if showplatforms then
if reviewerCount ~= 0 then
renderHeadingRowWithSystems(builder, activeSystems, data.i18n.display.aggregator)
if showplatforms then
else
renderHeadingRowWithSystems(builder, reviewScore, activeSystems)
renderHeadingRow(builder, data.i18n.display.aggregator)
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
if aggregatorCount ~= 0 then
if reviewerCount ~= 0 then
renderMainHeading(builder, #activeSystems + 1, aggregateScore)
elseif showplatforms then
renderHeadingRowWithSystems(builder, aggregateScore, activeSystems)
else
renderHeadingRow(builder, aggregateScore, data.i18n.aggregator)
end


for _, v in ipairs(providedAggregators) do
for _, v in ipairs(providedAggregators) do
renderRatingsBySystem(builder, v, data.aggregators[v].name, activeSystems, args, na)
renderRatingsBySystem(builder, v, data.aggregators[v].name, activeSystems, args, na)
end
end
for _, v in ipairs(customAggregatorKeys) do
for _, v in ipairs(customAggregatorKeys) do
renderRatingsBySystem(builder, v, args[v], activeSystems, args, na)
renderRatingsBySystem(builder, v, args[v], activeSystems, args, na)
end
end
end
else
else
renderHeadingRow(builder, data.i18n.display.aggregator)
builder:wikitext(data.i18n.singleplatformCategory)
for _, v in ipairs(providedAggregators) do
if aggregatorCount ~= 0 then
renderRating(builder, data.aggregators[v].name, args[v])
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
end
for _, v in ipairs(customAggregatorKeys) do
if reviewerCount ~= 0 then
renderRating(builder, args[v], args[v .. 'Score'])
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
end
end
end


local function renderReviews(builder, providedReviewers, activeSystems,
local function renderAwards(builder, args, awardKeys, borderTop)
customReviewerKeys, args, reviewerCount, priorReviewCount)
if reviewerCount == 0 then return end
builder = builder:tag('table')
builder = builder:tag('table')
:addClass(data.i18n.class.reviews)
:addClass('infobox wikitable')
:addClass(data.i18n.class.wikitable)
:css('width', '100%')
:addClass(args.state and 'mw-collapsible-content' or nil)
:css('margin', '0em')
:tag('caption')
:css('border-top', borderTop)
:wikitext(data.i18n.display[reviewerCount == 1 and 'reviewScore' or 'reviewScores'])
:attr('cellpadding', 3)
:addClass(priorReviewCount > 0 and data.i18n.class.stacked or nil)
:attr('cellspacing', 0)
:done()
if #activeSystems ~= 0 then
local na = yesno(args.na)
local showplatforms = #activeSystems ~= 1 or yesno(args.showplatforms)
if showplatforms then
renderHeadingRowWithSystems(builder, activeSystems, data.i18n.display.publication)
else
renderHeadingRow(builder, data.i18n.display.publication)
end


for _, v in ipairs(providedReviewers) do
renderMainHeading(builder, 2, data.i18n[#awardKeys == 1 and 'award' or 'awards'], borderTop)
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
else
renderHeadingRow(builder, data.i18n.display.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


local function renderAwards(builder, args, awardKeys, priorReviewCount)
builder:tag('tr')
if #awardKeys == 0 then return end
  :tag('th')
  :wikitext(data.i18n.publication)
builder = builder:tag('table')
  :done()
:addClass(data.i18n.class.awards)
  :tag('th')
:addClass(data.i18n.class.wikitable)
  :wikitext(data.i18n.award)
:addClass(args.state and 'mw-collapsible-content' or nil)
:tag('caption')
:wikitext(data.i18n.display[#awardKeys == 1 and 'award' or 'awards'])
:addClass(priorReviewCount > 0 and data.i18n.class.stacked or nil)
:done()
:tag('tr')
:tag('th')
:attr('scope', 'col')
:wikitext(data.i18n.display.publication)
:done()
:tag('th')
:attr('scope', 'col')
:wikitext(data.i18n.display.award)
:done()


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


local function renderEditOnWikidata(builder, wikidata, state)
local function renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
if not wikidata then return end
local tbl = mw.html.create('table')
  :attr('cellpadding', 0)
builder:tag('div')
  :attr('cellspacing', 0)
:addClass(data.i18n.class.wikidata)
  :css('background', 'transparent')
:addClass(state and 'mw-collapsible-content' or nil)
  :css('padding', '0em')
:wikitext(vgwd.getUpdateLink())
  :css('margin', args.align and
:done()
((args.align == 'left' or args.align == 'none') and '0em 1em 1em 0em') or
end
'0em 1em 1em 1em')
  :css('text-align', 'center')
  :css('float', args.align or 'right')
  :css('clear', args.align or 'right')


local function categorizePlatformCount(builder, platformCount)
if #activeSystems == 0 then
if platformCount ~= 0 then
-- Width: 20% Seems better since it scales with the article size.
builder:wikitext(data.i18n.category.multiplatform)
tbl
else
:css('width', args.width or '23em')
builder:wikitext(data.i18n.category.singleplatform)
end
end
end


local function renderTitles(builder, title, subtitle)
if args.title and args.state and (args.state == 'autocollapse'
builder:tag('div')
or args.state == 'collapsed' or args.state == 'expanded') then
:addClass(data.i18n.class.title)
tbl
:wikitext(title or data.i18n.display.reception)
:addClass('collapsible')
:done()
:addClass(args.state)
end
renderTitleRow(tbl, args.title)


if subtitle then
if args.subtitle then
builder:tag('div')
tbl:tag('tr'):tag('th')
:addClass(data.i18n.class.subtitle)
  :wikitext(args.subtitle)
-- The only reason to use the subtitle is collapsible content
-- So always add the related class.
:addClass('mw-collapsible-content')
:wikitext(subtitle)
:done()
end
end
end


local function render(providedReviewers, providedAggregators, awardKeys,
renderReviews(tbl:tag('tr'):tag('td'), providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, args)
activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
if #awardKeys ~= 0 then
local is_collapsible = args.title and args.state and
renderAwards(tbl:tag('tr'):tag('td'), args, awardKeys, (#customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0) and 'none' or nil)
(args.state == data.i18n.state.autocollapse or
end
args.state == data.i18n.state.collapsed or
args.state == data.i18n.state.expanded
)
local div = mw.html.create('div')
:attr('role', 'complementary')
:addClass(data.i18n.class.container)
:addClass(#activeSystems == 0 and data.i18n.class.containersingle or nil)
:addClass(args.align == data.i18n.align.left and data.i18n.class.containerleft or nil)
:addClass(args.align == data.i18n.align.none and data.i18n.class.containernone or nil)
:addClass(is_collapsible and 'mw-collapsible' or nil)
:addClass(is_collapsible and args.state == data.i18n.state.collapsed and 'mw-collapsed' or nil)
:addClass(is_collapsible and args.state == data.i18n.state.autocollapse and args.state or nil)


renderTitles(div, args.title, args.subtitle)
if wikidata == true then
tbl:tag('tr'):tag('td')
  :tag('table')
  :addClass('infobox wikitable')
  :css('width', '100%')
  :css('margin', '0em')
  :css('border-top', 'none')
  :attr('cellpadding', 3)
  :attr('cellspacing', 0)
  :tag('tr'):tag('th')
  :css('background', '#d1dbdf')
  :css('border-top', 'none')
  :wikitext('Edit on Wikidata ' .. vgwd.getUpdateLink('nosub'))
end


local aggregatorCount = #providedAggregators + #customAggregatorKeys
return tbl
renderAggregators(
div,
providedAggregators,
activeSystems,
customAggregatorKeys,
args,
aggregatorCount
)
local reviewerCount = #customReviewerKeys + #providedReviewers
renderReviews(
div,
providedReviewers,
activeSystems,
customReviewerKeys,
args,
reviewerCount,
aggregatorCount
)
renderAwards(
div,
args,
awardKeys,
reviewerCount + aggregatorCount
)
renderEditOnWikidata(div, wikidata, args.state)
categorizePlatformCount(div, #activeSystems)
return div
end
end


local function checkForWikidata(frame, args, activeSystems, providedAggregators)
local function checkForWikidata(frame, args, activeSystems, providedAggregators)
local wikidata = false
local wikidata = false
 
if args.qid == 'none' then
if args.qid == 'none' then
return wikidata
return wikidata
end
end
 
vgwd.setDateFormat(args.df)
vgwd.setDateFormat(args["df"])
vgwd.setGame(args.qid)
vgwd.setGame(args["qid"])
vgwd.setSystem(nil)
vgwd.setSystem(nil)
vgwd.setGenerateReferences(true)
vgwd.setGenerateReferences(true)
vgwd.setShowUpdateLink(false)
vgwd.setShowUpdateLink(false)
vgwd.setUpdateLinkStyle("text and pen")
vgwd.setUpdateLinkStyle("pen")
vgwd.setSystemFormat(args.systemFormat)
vgwd.setSystemFormat(args["systemFormat"])


-- Loop through aggregators if we have any.
-- Loop through aggregators if we have any.
Line 399: Line 385:
local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, #activeSystems ~= 0)
local wikidata = checkForWikidata(frame, args, activeSystems, providedAggregators)
local wikidata = checkForWikidata(frame, args, activeSystems, providedAggregators)
if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or
if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
#providedAggregators ~= 0 or #providedReviewers ~= 0 or #awardKeys ~= 0 then
return renderMainTable(providedReviewers, providedAggregators, awardKeys, activeSystems, customAggregatorKeys, customReviewerKeys, args, wikidata)
return frame:extensionTag{
name='templatestyles', args = { src = data.i18n.templatestyles }
} ..  tostring(render(
providedReviewers,
providedAggregators,
awardKeys,
activeSystems,
customAggregatorKeys,
customReviewerKeys,
args,
wikidata
))
elseif mw.title.getCurrentTitle().namespace == 0 then
elseif mw.title.getCurrentTitle().namespace == 0 then
return data.i18n.category.empty
return data.i18n.emptyCategory
end
end
end
end
Line 422: Line 396:
getArgs = require('Module:Arguments').getArgs
getArgs = require('Module:Arguments').getArgs
end
end
return p._reviewbox(frame, getArgs(frame,
return p._reviewbox(frame, getArgs(frame, { wrappers = data.i18n.wrapper, trim = false, translate = data.argi18n }))
{ wrappers = data.i18n.wrapper, trim = false, translate = data.argi18n }
))
end
end


return p
return p

Revision as of 08:56, 1 May 2023

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

require('Module:No globals')

local p = {}
local data = require('Module:Video game reviews/data')
local yesno = require('Module:Yesno')
local vgwd = require('Module:Video game wikidata') -- we don't use wikidata how do i remove this
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 renderTitleRow(tbl, title)
	local titleCell = tbl:tag('tr'):tag('th')

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

local function renderMainHeading(builder, colspan, headingText, borderTop)
	builder:tag('tr'):tag('th')
		   :attr('colspan', colspan)
		   :css('background', '#d1dbdf')
		   :css('border-top', borderTop)
		   :wikitext(headingText)
end

local function renderHeadingRowWithSystems(builder, mainHeading, activeSystems)
	renderMainHeading(builder, #activeSystems + 1, mainHeading)
	builder:tag('tr')
		   :tag('th')
		   :attr('rowspan', '2')
		   :css('background', '#e8f4f8')
		   :css('text-align', 'center')
		   :css('vertical-align', 'middle')
		   :wikitext(data.i18n.publication)
		   :done()
		   :tag('th')
		   :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'):wikitext(data.systems[v].name)
	end
end

local function renderHeadingRow(builder, mainHeading, nameHeading)
	renderMainHeading(builder, 2, mainHeading)
	builder
			:tag('tr')
			:tag('th')
			:css('background', '#e8f4f8')
			:css('text-align', 'center')
			:css('vertical-align', 'middle')
			:wikitext(nameHeading)
			:done()
			:tag('th')
			: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')
					:css('text-align', 'center')					
					: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')
					 :attr('cellpadding', 0)
					 :attr('cellspacing', 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
				renderMainHeading(builder, #activeSystems + 1, 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)
					 :attr('cellpadding', 3)
					 :attr('cellspacing', 0)

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

	builder:tag('tr')
		   :tag('th')
		   :wikitext(data.i18n.publication)
		   :done()
		   :tag('th')
		   :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 tbl = mw.html.create('table')
				  :attr('cellpadding', 0)
				  :attr('cellspacing', 0)
				  :css('background', 'transparent')
				  :css('padding', '0em')
				  :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.
		tbl
				: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
		tbl
				:addClass('collapsible')
				:addClass(args.state)
	end
	renderTitleRow(tbl, args.title)

	if args.subtitle then
		tbl:tag('tr'):tag('th')
		   :wikitext(args.subtitle)
	end

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

	if wikidata == true then
		tbl:tag('tr'):tag('td')
		   :tag('table')
		   :addClass('infobox wikitable')
		   :css('width', '100%')
		   :css('margin', '0em')
		   :css('border-top', 'none')
		   :attr('cellpadding', 3)
		   :attr('cellspacing', 0)
		   :tag('tr'):tag('th')
		   :css('background', '#d1dbdf')
		   :css('border-top', 'none')
		   :wikitext('Edit on Wikidata ' .. vgwd.getUpdateLink('nosub'))
	end

	return tbl
end

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

	if args.qid == 'none' then
		return wikidata
	end
	
	vgwd.setDateFormat(args["df"])
	vgwd.setGame(args["qid"])
	vgwd.setSystem(nil)
	vgwd.setGenerateReferences(true)
	vgwd.setShowUpdateLink(false)
	vgwd.setUpdateLinkStyle("pen")
	vgwd.setSystemFormat(args["systemFormat"])

	-- Loop through aggregators if we have any.
	if #providedAggregators ~= 0 then
		for _, 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 _, 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