Module:Infobox

来自滚动的天空Wiki
文档图示 模块文档[查看] [编辑] [查看历史] [清除缓存]

本模块用于执行{{Infobox}}模板,请到模板页阅读具体用法。

上述文档内容嵌入自Module:Infobox/doc编辑 | 历史
编者可以在本模块的沙盒编辑和测试样例创建页面进行实验。
请将模块自身所属的分类添加在文档中。本模块的子页面
local p = {}

local others = require "module:others"
local newindex = others.newindex
local index = others.index
local addNewline = others.addNewLine

function p.process(args)
	local data = {}
	
	local function process(k,v)
		if type(k) ~= 'string' then return end
		-- 以下代码只检查字符串键
		if k=="name" then
			data[k] = v
		end
		
		for _, prefix in ipairs
		{'title','label','data','body','header'}
		do --对于以上前缀,检查其后缀(可以为空),默认为content
			if k:find "%d" then break end -- include no number
			local suffix = k:match("^" .. prefix .. "(%l*)$")
			if suffix == "" then suffix = "content" end
			if suffix then
				newindex(data,v,prefix,suffix)
				return
			end
			
		end
		
		for _, prefix in ipairs {'header','data','label',"row"} do
			if not k:find("%d") then break end 
			--检查带数字键,没有数字直接退出循环
			local num, suffix = k:match('^' .. prefix .. '(%d+%.?%d*)(%l*)')
			if suffix == ""then
				suffix = "content"
			end
			if suffix then
				num = tonumber(num)
				newindex(data,v,"rows",num,prefix,suffix)
				--这里单独存放在data.rows便于判断是否有任意一行
				return
			end
			
		end
	end
	for k,v in pairs(args) do
		process(k,v)
	end
	return data
end

function p.render(data)
	local root = mw.html.create()
	
	local content = root:tag "div"
		:addClass("infobox")
	
	-- 渲染标题,必须要有内容
	if index(data,"title","content") then
		content:tag "div":addClass("infobox-title-line"):tag "div"
			:addClass "infobox-title"
			:wikitext(data.title.content)
			:addClass(data.title.class)
			:cssText(data.title.style)
	end
	
	-- 渲染框
	if data.rows then
		--检测是否有框的需求
		local rows = content:tag "div"
			:addClass "infobox-rows"
			:addClass(index(data,"body","class"))
			:cssText(index(data,"body","style"))
		local keys = {} --考虑到断层参数的排序以及小数,先进行人工排序再迭代
		for k,v in pairs(data.rows) do
			if index(v,'header','content') or index(v,'data','content') then
				table.insert(keys,k)
			end
		end
		table.sort(keys)
		for i,k in ipairs(keys) do
			local v = data.rows[k]
			local header = v.header
			local label = v.label
			local d = v.data
			local r = v.row
			
			--渲染行
			local row = rows:tag "div"
				:addClass "infobox-row"
				:addClass(index(r,"class"))
				:cssText(index(r,"style"))
				:addClass(index(data,"row","class"))
				:cssText(index(data,"row","style"))
			if index(header,"content") then
				--如果有header
				row:addClass "infobox-header-row"
					:wikitext(header.content)
					:cssText(header.style):cssText(index(data,"header","style"))
					:addClass(header.class):addClass(index(data,"header","class"))
			elseif index(d,"content") then
				--如果没有,渲染带data的行
				row:addClass "infobox-data-row"
				if index(label,"content") then
					--如果有标签内容
					row:tag("div")
						:addClass "infobox-label"
						:addClass(label.class):addClass(index(data,"label","class"))
						:cssText(label.style):cssText(index(data,"label","style"))
						:wikitext(label.content)
				end
					
					--渲染data格
					
				local c
				if not index(label,"content") then c = "data-without-label" end
				row:tag("div")
					:addClass("infobox-data")
					:addClass(c)
					:cssText(d.style):cssText(index(data,"data","style"))
					:addClass(d.class):addClass(index(data,"data","class"))
					:newline()
					:wikitext(d.content)
			end
		end
	end
	
	return tostring(root)
end

function p.infobox(frame)
	local args = {}
	for k, v in pairs(frame:getParent().args) do
		if v and v ~= "" then
			args[k] = v
		end
	end
	
	return p.render(p.process(args))
end

return p