Module:Quickbar

来自维基导游
文档图示 模块文档[创建]
local function renderRow(heading, value)
	return '|-\n| class="info" | \'\'\'' .. heading .. '\'\'\'\n| style="padding-right:5px;" | ' .. value .. '\n'
end

local function renderLinkedClaim(id)
	local linkTarget = mw.wikibase.sitelink(id)
	local linkName = mw.wikibase.label(id)
	if linkTarget == nil then
		return linkName
	else
		return '[[' .. linkTarget .. '|' .. linkName .. ']]'
	end
end


local function rSimple(item, property)
	return item:formatPropertyValues( property ).value
end

local function rPopulation(item, property, frame)
	local s = item:getBestStatements( property )[1]
	local result = mw.wikibase.renderSnak( s.mainsnak )
	
	-- Brainstorming a bit on significant digits:
	-- local result = '' 
	-- local num, sigfig = require('Module:Convert').make_sigfig(frame, s.mainsnak.datavalue.value.amount, 3)
	-- result = result .. num .. ' * 10^'..sigfig
	
	if s.qualifiers ~= nil and s.qualifiers['P585'] ~= nil and #s.qualifiers['P585'] > 0 then
		result = result .. '(' ..  string.match(s.qualifiers['P585'][1].datavalue.value.time, '0*([1-9][0-9]+)\-', 1) .. ')'
	end
	return result
end

local function rElectricity(item, property)
	local claims = item:getBestStatements( property )
	local voltage = {}
	for _,s in pairs(claims) do 
		local v = mw.wikibase.renderSnak( s.mainsnak )
		if s.qualifiers ~= nil and s.qualifiers['P2144'] ~= nil and #s.qualifiers['P2144'] > 0 then
			v = v .. ' / ' .. mw.wikibase.renderSnak(s.qualifiers['P2144'][1])
		end
		table.insert(voltage, v)
	end
	local result = table.concat(voltage, '、')
	if #item:getBestStatements('P2853') > 0 then
		result = result .. '(' .. item:formatPropertyValues( 'P2853' ).value .. ')'
	end
	return result
end

local function claimOrLabel(id, property) 
	local item = mw.wikibase.getEntity( id )
	if #item:getBestStatements( property ) > 0 and item:getBestStatements( property )[1].mainsnak.datavalue ~= nil then
		return mw.wikibase.renderSnak( item:getBestStatements( property )[1].mainsnak )
	end
	return item:getLabel()
end

local function rCurrency(item, property)
	local claims = item:getBestStatements(property)
	local result = {}
	for _, claim in pairs(claims) do
		local id = 'Q' .. claim.mainsnak.datavalue.value['numeric-id']
		local currency = mw.wikibase.getEntity( id )
		local subresult = currency:getLabel()
		local symbol = claimOrLabel( id, 'P498' )
		if symbol ~= currency:getLabel() then
			subresult = subresult .. '(' .. symbol .. ')'
		end
		if #currency:getBestStatements('P2284') > 0 then
			for _, price in pairs(currency:getBestStatements('P2284')) do
				subresult = subresult .. '<br/>1 '..symbol..' = '..  string.format('%.4f', price.mainsnak.datavalue.value.amount ) .. ' ' .. claimOrLabel(string.match(price.mainsnak.datavalue.value.unit , 'Q%d+$'), 'P498')
			end
		end
		table.insert(result, subresult)
	end
	return table.concat(result, '<br/>')
end

local function rEmergency(item, property)
	local claims = item:getBestStatements( property )
	local result = {}
	for _, claim in pairs(claims) do
		local id = 'Q' .. claim.mainsnak.datavalue.value['numeric-id']
		local res = claimOrLabel(id, 'P1329')
		if claim.qualifiers ~= nil and claim.qualifiers['P366'] ~= nil and #claim.qualifiers['P366'] > 0 then
			local usage = {}
			for _, qual in pairs(claim.qualifiers['P366']) do
				table.insert( usage, mw.wikibase.renderSnak(qual) )
			end
			res = res .. '(' .. table.concat(usage, '、') .. ')'
		end
		table.insert(result, res)
	end
	return table.concat(result, '、')
end

local function rTimezones(item, property)
	local claims = item:getBestStatements( property )
	if #claims > 3 then
		local minEntity = nil
		local maxEntity = nil
		local minOffset = 20
		local maxOffset = -20
		local unknownTZs = {}
		for _, claim in pairs(claims) do
			local e = mw.wikibase.getEntity('Q' .. claim.mainsnak.datavalue.value['numeric-id'] )
			if #e:getBestStatements( 'P2907' ) == 1 then
				local val = tonumber( e:getBestStatements( 'P2907' )[1].mainsnak.datavalue.value.amount )
				if val < minOffset then
					minOffset = val
					minEntity = e
				end
				if val > maxOffset then
					maxOffset = val
					maxEntity = e
				end
			else
				table.insert(unknownTZs, e:getLabel())
			end
		end
		if minEntity ~= nil and maxEntity ~= nil and minOffset ~= maxOffset then
			local r = minEntity:getLabel() .. '至' .. maxEntity:getLabel()
			if #unknownTZs > 0 then
				r = r .. ' and ' .. table.concat(unknownTZs, ', ')	
			end
			return r
		end
	end
	return rSimple(item, property)
end

local function rSingleLinked(item, property) 
	if item:getBestStatements( property )[1].mainsnak.datavalue ~= nil then
		return renderLinkedClaim('Q'..item:getBestStatements( property )[1].mainsnak.datavalue.value['numeric-id'])
	else
		return nil
	end
end

local function rLinked(item, property)
	local claims = item.claims[property]
	local result = {}
	for _, claim in pairs(claims) do
		if claim.mainsnak.datavalue ~= nil then
			local id = 'Q' .. claim.mainsnak.datavalue.value['numeric-id']
			table.insert(result, renderLinkedClaim(id))
		end
	end
	return table.concat(result, ', ')
end

local conf = {
	{{'capital','首都'}, '首都', 36, rSingleLinked},
	{{'currency','货币'}, '货币', 38, rCurrency},
	{{'population','人口'}, '人口', 1082, rPopulation},
	{{'electricity','电力','輸電'}, '[[电力系统|-{zh-hans:电力系统; zh-hant:輸電網路;}-]]', 2884, rElectricity},
	{{'callingcode','区号','區號'}, '[[国际电话区号列表|国家区号]]', 474, rSimple},
	{{'timezone','时区','時區'}, '[[时区]]', 421, rTimezones},
	{{'language','語言','语言'}, '语言', 37, rLinked},
	{{'emergencies','紧急','緊急'}, '紧急电话', 2852, rEmergency},
	{{'driving side'}, '驾驶方向', 1622, rSimple}
}

local p = {}

function p.quickbar( frame )
	local parentArgs = frame:getParent().args
	local elements =  {}
	
	local item = mw.wikibase.getEntity(  )
	
	local useWikidata = (item ~= nil and item.claims ~= nil)
	local missingInfo = false
	
	if parentArgs['首府'] == 'yes' then
		conf[1][2]='首府'
	end
	local locationMap = parentArgs['location'] or parentArgs['位置']
	if (locationMap ~= nil and locationMap ~= '') or (useWikidata and item.claims['P242'] ~= nil and item.claims['P242'][1] ~= nil) then
		if useWikidata and (locationMap == nil or locationMap == '') then
			locationMap = mw.wikibase.renderSnak( item:getBestStatements('P242')[1].mainsnak )
		end
		table.insert(elements, '| colspan="2" style="text-align:center;padding:0" | [[File:' .. locationMap  .. '|250px]]\n' )
	else
		missingInfo = true	
	end
	
    for _, params in pairs( conf ) do
        if params[3] ~= 0 then
        	local val = nil
        	for __, paramname in pairs(params[1]) do
        		val = val or parentArgs[paramname]
            end
            if val == '' or val == nil then
            	if useWikidata and #item:getBestStatements('P' .. params[3]) > 0 then
            		val = params[4]( item, 'P' .. params[3], frame)
            		if val ~= nil then
                		table.insert( elements, renderRow(params[2], val) )
                	else
                		missingInfo = true	
                	end
            	else
            		missingInfo = true
            	end
        	else
            	table.insert(elements, renderRow(params[2], val) )	
            end
        end
    end
	
	local editRow = ''
	if item ~= nil then
		editRow = '|-\n| colspan="2" class="info footer" |[[:d:'.. item.id .. '|在维基数据编辑]]\n'
	end
	
	if #elements > 0 then
		if missingInfo == true and mw.title.getCurrentTitle().namespace == 0 then
			table.insert(elements, '[[Category:Quickbar信息不完整的条目]]')	
		end
		if mw.title.getCurrentTitle().namespace == 0 then
			table.insert(elements, '[[Category:使用了Quickbar的條目]]\n')	
		end
		return frame:extensionTag {name = 'templatestyles', args = {src = 'Quickbar/styles.css'}} .. '<div id="quickbar" class="wv-quickbar floatright">\n{| cellpadding="0" cellspacing="0"\n|-\n' ..
			table.concat(elements)	..
			'\n'.. editRow.. '|}</div>'
	else
		if mw.title.getCurrentTitle().namespace == 0 then
			return '[[Category:Quickbar信息不完整的条目]][[Category:使用了Quickbar的條目]]\n'
		end
		return ''
	end
end

return p