模块:Infobox settlement
来自Blockland Wiki
更多操作
此模块的文档可以在模块:Infobox settlement/doc创建
local p = {}
-- ====================================================================
-- 辅助函数 (Helper Functions)
-- ====================================================================
-- 检查参数是否存在且不为空字符串
local function hasValue(arg)
return arg and arg:match('%S')
end
-- ====================================================================
-- 构建函数 (Builder Functions)
-- ====================================================================
-- 构建分组子标题行 (例如“地理”、“政府”等)
-- @param label string - 子标题的文本
-- @return string - HTML <tr> 元素
local function buildSubheader(label)
if hasValue(label) then
local row = mw.html.create('tr')
row:tag('th')
:attr('colspan', '2')
:css('background', '#f0f0f0')
:css('text-align', 'left')
:css('padding-left', '0.4em')
:css('font-weight', 'bold')
:wikitext(label)
return tostring(row)
end
return ''
end
-- 构建信息框的单行数据(标签+数据)
-- @param label string - 左侧的标签
-- @param data string - 右侧的数据
-- @return string - HTML <tr> 元素
local function buildRow(label, data)
if hasValue(data) then
local row = mw.html.create('tr')
row:tag('th')
:css('width', '35%') -- 调整标签宽度
:css('text-align', 'left')
:css('vertical-align', 'top')
:css('padding-left', '0.4em')
:wikitext(label)
row:tag('td')
:css('text-align', 'left')
:wikitext(data)
return tostring(row)
end
return ''
end
-- 构建图片或地图行
-- @param image string - 文件名
-- @param size string - 图片尺寸 (例如 '280px')
-- @param caption string - 图片下方的说明文字
-- @param isMap boolean - 是否为地图 (地图通常没有边框)
-- @return string - HTML <tr> 元素
local function buildImageRow(image, size, caption, isMap)
if hasValue(image) then
local row = mw.html.create('tr')
local cell = row:tag('td')
:attr('colspan', '2')
:css('text-align', 'center')
:css('padding', '0.2em 0')
local imageOptions = {
'frameless',
'center',
size or '280px'
}
if isMap then
-- 地图通常没有边框,可以添加 border 样式
-- table.insert(imageOptions, 'border')
end
local imageWikitext = string.format('[[File:%s|%s]]', image, table.concat(imageOptions, '|'))
if hasValue(caption) then
imageWikitext = imageWikitext .. '<div style="font-size:90%; padding:0.2em 0.4em;">' .. caption .. '</div>'
end
cell:wikitext(imageWikitext)
return tostring(row)
end
return ''
end
-- ====================================================================
-- 主函数 (Main Function)
-- ====================================================================
function p.main(frame)
local args = frame:getParent().args
local root = mw.html.create('table')
root:addClass('infobox')
:css('width', '300px')
:css('font-size', '90%')
:css('border-spacing', '3px')
-- 存放所有行的数组
local rows = {}
-- 1. 标题 和 官方名称
local title = args.name or mw.title.getCurrentTitle().text
local title_cell = mw.html.create('tr'):tag('th')
:attr('colspan', '2')
:css('text-align', 'center')
:css('font-size', '125%')
:css('padding', '0.2em')
:wikitext(title)
if hasValue(args.official_name) then
title_cell:wikitext('<br /><span style="font-size:85%; font-weight:normal;">' .. args.official_name .. '</span>')
end
if hasValue(args.native_name) then
title_cell:wikitext('<br /><span style="font-size:85%; font-weight:normal; font-style:italic;">' .. args.native_name .. '</span>')
end
table.insert(rows, tostring(title_cell))
-- 2. 别称和格言
table.insert(rows, buildRow('别称', args.nickname))
table.insert(rows, buildRow('格言', args.motto))
-- 3. 行政区划类型 (例如: “市”、“县”)
if hasValue(args.settlement_type) then
local type_row = mw.html.create('tr')
type_row:tag('th')
:attr('colspan', '2')
:css('background', '#d0e4fe') -- 维基百科风格的淡蓝色
:css('text-align', 'center')
:css('font-weight', 'bold')
:wikitext(args.settlement_type)
table.insert(rows, tostring(type_row))
end
-- 4. 主图片 和 图注
table.insert(rows, buildImageRow(args.image, args.image_size, args.image_caption, false))
-- 5. 市徽、市旗、标志
if hasValue(args.seal) or hasValue(args.logo) or hasValue(args.flag) then
local symbol_row = mw.html.create('tr')
local cell = symbol_row:tag('td'):attr('colspan', '2'):css('text-align', 'center')
local content = {}
if hasValue(args.flag) then
table.insert(content, string.format('<div>[[File:%s|120px|border]]<br><small>市旗</small></div>', args.flag))
end
if hasValue(args.seal) then
table.insert(content, string.format('<div>[[File:%s|100px]]<br><small>市徽</small></div>', args.seal))
end
if hasValue(args.logo) then
table.insert(content, string.format('<div>[[File:%s|120px]]<br><small>标志</small></div>', args.logo))
end
cell:wikitext('<div style="display:flex; justify-content:space-around; padding:0.3em;">' .. table.concat(content, '') .. '</div>')
table.insert(rows, tostring(symbol_row))
end
-- 6. 地图 和 坐标
table.insert(rows, buildImageRow(args.pushpin_map, args.map_size, args.map_caption, true))
if hasValue(args.lat) and hasValue(args.lon) then
local coord_str = string.format("坐标:%s°N %s°E", args.lat, args.lon) -- 示例格式,可替换为更复杂的坐标模板
local coord_row = mw.html.create('tr'):tag('td')
:attr('colspan', '2')
:css('text-align', 'center')
:css('font-size', '95%')
:wikitext(coord_str)
table.insert(rows, tostring(coord_row))
end
-- 7. 行政区划
table.insert(rows, buildSubheader('行政'))
table.insert(rows, buildRow('国家', args.country))
for i = 1, 5 do -- 支持最多5级行政区划
local type_key = 'subdivision_type' .. i
local name_key = 'subdivision_name' .. i
if hasValue(args[type_key]) and hasValue(args[name_key]) then
table.insert(rows, buildRow(args[type_key], args[name_key]))
else
break -- 如果有一级中断,则停止
end
end
table.insert(rows, buildRow('建城', args.established_date))
-- 8. 政府
table.insert(rows, buildSubheader('政府'))
for i = 1, 4 do -- 支持最多4个领导职位
local title_key = 'leader_title' .. i
local name_key = 'leader_name' .. i
if hasValue(args[title_key]) and hasValue(args[name_key]) then
table.insert(rows, buildRow(' • ' .. args[title_key], args[name_key]))
end
end
-- 9. 面积
if hasValue(args.area_total) or hasValue(args.area_urban) or hasValue(args.area_metro) then
table.insert(rows, buildSubheader('面积'))
table.insert(rows, buildRow(' • 总计', args.area_total))
table.insert(rows, buildRow(' • 市区', args.area_urban))
table.insert(rows, buildRow(' • 都会区', args.area_metro))
end
-- 10. 海拔
table.insert(rows, buildRow('海拔', args.elevation))
-- 11. 人口
if hasValue(args.population_total) or hasValue(args.population_urban) or hasValue(args.population_metro) then
local pop_header_text = '人口'
if hasValue(args.population_as_of) then
pop_header_text = pop_header_text .. ' (' .. args.population_as_of .. ')'
end
table.insert(rows, buildSubheader(pop_header_text))
table.insert(rows, buildRow(' • 总计', args.population_total))
table.insert(rows, buildRow(' • 排名', args.population_rank))
table.insert(rows, buildRow(' • 密度', args.population_density))
table.insert(rows, buildRow(' • 市区', args.population_urban))
table.insert(rows, buildRow(' • 都会区', args.population_metro))
end
-- 12. 时区
if hasValue(args.timezone1) then
table.insert(rows, buildSubheader('时区'))
local tz_data = args.timezone1
if hasValue(args.utc_offset1) then
tz_data = tz_data .. ' (' .. args.utc_offset1 .. ')'
end
table.insert(rows, buildRow(' ', tz_data)) -- 标签留空,让内容靠左
if hasValue(args.timezone1_DST) then
local tz_dst_data = args.timezone1_DST
if hasValue(args.utc_offset1_DST) then
tz_dst_data = tz_dst_data .. ' (' .. args.utc_offset1_DST .. ')'
end
table.insert(rows, buildRow(' • 夏时制', tz_dst_data))
end
end
-- 13. 邮政编码和电话区号
table.insert(rows, buildRow('邮政编码', args.postal_code))
table.insert(rows, buildRow('电话区号', args.area_code))
-- 14. 网站
table.insert(rows, buildRow('网站', args.website))
-- 将所有行添加到表格中
root:wikitext(table.concat(rows, '\n'))
return tostring(root)
end
return p