2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module:VG Reviews

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

本模块经过了较多修改以适应萌娘百科。

修改内容包括:

  • 去除了Wikidata(维基数据)相关的部分。
  • 将部分自定义样式修改为MediaWiki自带的类。
  • 表格内可以同时存在各平台的评分(适用于同一媒体为多平台分别打分的情况)和总评分(适用于未明确表述评分对应平台的情况)。
  • 去除了单复数的相关判断(中文一般不明确区分单复数)。
  • 去除了奖项部分,另创建{{VG Awards}}模板。
  • 增加了自定义平台的功能(用于同一平台发售多个版本的情况)。
--[[
本页面原来自中文维基百科的 Module:VG_Reviews,依 CC BY-SA 3.0 授权引入。
经过双方编者的修改,本页面可能已与来源有很大差异。
]]--

local p = {}
local data = require('Module:VG Reviews/data')
local yesno = require('Module:Yesno')
local getArgs = require('Module:Arguments').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, platforms = {}, {}, {}, {}
	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, '^platform%d+$') then
			table.insert(platforms, 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(platforms, comparator)
	return reviewers, aggregators, platforms
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
			elseif data.reviewers[k] then
				table.insert(providedReviewers, k)
			elseif data.aggregators[k] then
				table.insert(providedAggregators, k)
			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'):css('font-size', '117.6470588235294%')

	if title then
		titleCell
			:wikitext(title)
	else
		titleCell
			: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('font-size', '117.6470588235294%')
		:css('border-top', borderTop)
		:wikitext(headingText)
end

local function renderHeadingRowWithSystems(builder, mainHeading, activeSystems, customPlatformKeys, nameHeading, args)
	renderMainHeading(builder, #activeSystems + #customPlatformKeys + 1, mainHeading)
	builder:tag('tr')
		:tag('th')
			:attr('rowspan', '2')
			:wikitext(nameHeading)
		:done()
		:tag('th')
			:attr('colspan', #activeSystems + #customPlatformKeys)
			:wikitext(data.i18n.score)
	builder = builder:tag('tr')
	for _,v in ipairs(activeSystems) do
		builder:tag('th'):wikitext(data.systems[v].name)
	end
	for _,v in ipairs(customPlatformKeys) do
		builder:tag('th'):wikitext(args[v])
	end
end

local function renderHeadingRow(builder, mainHeading, nameHeading)
	renderMainHeading(builder, 2, mainHeading)
	builder
		:tag('tr')
			:tag('th')
				:wikitext(nameHeading)
			:done()
			:tag('th')
				:wikitext(data.i18n.score)
end

local function renderRatingsBySystem(builder, code, name, activeSystems, customPlatformKeys, args, na, isCustom)
	builder = builder:tag('tr')
	builder:tag('td')
		:wikitext(name)

	if args[code] and not isCustom then
		builder:tag('td')
			:attr('colspan', #activeSystems + #customPlatformKeys)
			:wikitext(args[code])
		return
	elseif args[code .. 'Score'] and isCustom then
		builder:tag('td')
			:attr('colspan', #activeSystems + #customPlatformKeys)
			:wikitext(args[code .. 'Score'])
		return
	end

	for _,v in ipairs(activeSystems) do
		local combinedCode = code .. '_' .. v
		local cell = builder:tag('td')
		if args[combinedCode] then
			cell
				:wikitext(args[combinedCode])
		elseif na then
			cell
				:css('color', 'lightgray')
				:addClass('table-na')
				:wikitext(data.i18n.na)
		end
	end

	for _,v in ipairs(customPlatformKeys) do
		local combinedCode = code .. '_' .. v
		local cell = builder:tag('td')
		if args[combinedCode] then
			cell
				:wikitext(args[combinedCode])
		elseif na then
			cell
				:css('color', 'lightgray')
				:addClass('table-na')
				:wikitext(data.i18n.na)
		end
	end
end

local function renderRating(builder, name, rating)
	builder:tag('tr')
		:tag('td')
			:wikitext(name)
		:done()
		:tag('td')
			:wikitext(rating)
end

local function renderReviews(builder, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customPlatformKeys, args)
	local reviewerCount = #providedReviewers + #customReviewerKeys
	local aggregatorCount = #providedAggregators + #customAggregatorKeys
	local reviewScore = data.i18n.reviewScores
	local aggregateScore = data.i18n.aggregateScores
	if (#activeSystems + #customPlatformKeys) ~= 0 then
		local na = yesno(args.na)
		local showplatforms = (#activeSystems + #customPlatformKeys) ~= 1 or yesno(args.showplatforms)
		if aggregatorCount ~= 0 then
			if showplatforms then
				renderHeadingRowWithSystems(builder, aggregateScore, activeSystems, customPlatformKeys, data.i18n.aggregator, args)
			else
				renderHeadingRow(builder, aggregateScore, data.i18n.aggregator)
			end

			for _,v in ipairs(providedAggregators) do
				renderRatingsBySystem(builder, v, data.aggregators[v].name, activeSystems, customPlatformKeys, args, na, false)
			end
			for _,v in ipairs(customAggregatorKeys) do
				renderRatingsBySystem(builder, v, args[v], activeSystems, customPlatformKeys, args, na, true)
			end
		end
		if reviewerCount ~= 0 then
			if showplatforms then
				renderHeadingRowWithSystems(builder, reviewScore, activeSystems, customPlatformKeys, data.i18n.publication, args)
			else
				renderHeadingRow(builder, reviewScore, data.i18n.publication)
			end

			for _,v in ipairs(providedReviewers) do
				renderRatingsBySystem(builder, v, data.reviewers[v].name, activeSystems, customPlatformKeys, args, na, false)
			end
			for _,v in ipairs(customReviewerKeys) do
				renderRatingsBySystem(builder, v, args[v], activeSystems, customPlatformKeys, args, na, true)
			end
		end
	else
		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 renderMainTable(providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customPlatformKeys, args)
	local tbl = mw.html.create('table')
		:addClass('wikitable')
		:addClass('no-min-width-on-mobile')
		:addClass('float' .. (args.align or 'right'))
		:css('text-align', 'center')
		:css('font-size', '85%')
		:css('display', 'table')

	if args.width then
		tbl
			:css('width', args.width)
	elseif (#activeSystems + #customPlatformKeys) == 0 then
		-- Width: 20% Seems better since it scales with the article size.
		tbl
			:css('width', '20em')
	else
		tbl
			:css('min-width', '25em')
	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

	tbl:tag('caption')
			:css('font-size', '117.6470588235294%')
			:css('display', 'table-caption')
			:wikitext(args.title or data.i18n.receptionTitle)

	if args.subtitle then
		tbl:tag('tr'):tag('th')
				:attr('colspan', ((#activeSystems + #customPlatformKeys) or 1) + 1)
				:css('font-size', '117.6470588235294%')
				:wikitext(args.subtitle)
	end

	renderReviews(tbl, providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customPlatformKeys, args)

	local style = mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Template:VG Reviews/styles.css'})

	return tostring(tbl) .. style
end

function p._main(frame, args)
	local activeSystems = getActiveSystems(args)
	local customReviewerKeys, customAggregatorKeys, customPlatformKeys = getArgKeyTables(args)
	local providedReviewers, providedAggregators = getProvidedReviewersAndAggregators(args, (#activeSystems + #customPlatformKeys) ~= 0)
	if #customAggregatorKeys ~= 0 or #customReviewerKeys ~= 0 or #providedAggregators ~= 0 or #providedReviewers ~= 0 then
		return renderMainTable(providedReviewers, providedAggregators, activeSystems, customAggregatorKeys, customReviewerKeys, customPlatformKeys, args)
	elseif mw.title.getCurrentTitle().namespace == 0 then
		return data.i18n.emptyCategory
	end
end

function p.main(frame)
	return p._main(frame, getArgs(frame, {wrappers = "Template:VG Reviews"}))
end

return p