模块:Infobox settlement:修订间差异
来自Blockland Wiki
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
local p = {} | local p = {} | ||
-- | -- ==================================================================== | ||
-- 辅助函数 (Helper Functions) | |||
-- ==================================================================== | |||
-- 检查参数是否存在且不为空字符串 | |||
local function hasValue(arg) | local function hasValue(arg) | ||
return arg and arg:match('%S') | return arg and arg:match('%S') | ||
end | end | ||
-- 构建分组子标题行 ( | -- ==================================================================== | ||
-- 构建函数 (Builder Functions) | |||
-- ==================================================================== | |||
-- 构建分组子标题行 (例如“地理”、“政府”等) | |||
-- @param label string - 子标题的文本 | |||
-- @return string - HTML <tr> 元素 | |||
local function buildSubheader(label) | local function buildSubheader(label) | ||
if hasValue(label) then | if hasValue(label) then | ||
| 第12行: | 第22行: | ||
row:tag('th') | row:tag('th') | ||
:attr('colspan', '2') | :attr('colspan', '2') | ||
:css('background', '#f0f0f0') | :css('background', '#f0f0f0') | ||
:css('text-align', 'left') | :css('text-align', 'left') | ||
:css('padding-left', '0.4em') | :css('padding-left', '0.4em') | ||
| 第23行: | 第33行: | ||
-- 构建信息框的单行数据(标签+数据) | -- 构建信息框的单行数据(标签+数据) | ||
-- @param label string - 左侧的标签 | |||
-- @param data string - 右侧的数据 | |||
-- @return string - HTML <tr> 元素 | |||
local function buildRow(label, data) | local function buildRow(label, data) | ||
if hasValue(data) then | if hasValue(data) then | ||
local row = mw.html.create('tr') | local row = mw.html.create('tr') | ||
row:tag('th') | |||
row:tag('th'):css('width', ' | :css('width', '35%') -- 调整标签宽度 | ||
row:tag('td'):wikitext(data) | :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) | return tostring(row) | ||
end | end | ||
| 第34行: | 第89行: | ||
end | end | ||
-- | |||
-- ==================================================================== | |||
-- 主函数 (Main Function) | |||
-- ==================================================================== | |||
function p.main(frame) | function p.main(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
| 第41行: | 第100行: | ||
:css('width', '300px') | :css('width', '300px') | ||
:css('font-size', '90%') | :css('font-size', '90%') | ||
:css('border-spacing', '3px') | |||
-- 存放所有行的数组 | |||
local rows = {} | |||
-- 1. 标题 和 | -- 1. 标题 和 官方名称 | ||
local title = args.name or mw.title.getCurrentTitle().text | local title = args.name or mw.title.getCurrentTitle().text | ||
local title_cell = | local title_cell = mw.html.create('tr'):tag('th') | ||
:attr('colspan', '2') | :attr('colspan', '2') | ||
:css('text-align', 'center') | :css('text-align', 'center') | ||
| 第50行: | 第113行: | ||
:css('padding', '0.2em') | :css('padding', '0.2em') | ||
:wikitext(title) | :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 | if hasValue(args.native_name) then | ||
title_cell:wikitext('<br /><span style="font-size:85%; font-weight:normal;">' .. args.native_name .. '</span>') | title_cell:wikitext('<br /><span style="font-size:85%; font-weight:normal; font-style:italic;">' .. args.native_name .. '</span>') | ||
end | end | ||
table.insert(rows, tostring(title_cell)) | |||
-- 2. | |||
if hasValue(args. | -- 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') | local type_row = mw.html.create('tr') | ||
type_row:tag('th') | type_row:tag('th') | ||
:attr('colspan', '2') | :attr('colspan', '2') | ||
:css('background', '# | :css('background', '#d0e4fe') -- 维基百科风格的淡蓝色 | ||
:css('text-align', 'center') | :css('text-align', 'center') | ||
:css('font-weight', 'bold') | :css('font-weight', 'bold') | ||
:wikitext(args. | :wikitext(args.settlement_type) | ||
table.insert(rows, tostring(type_row)) | |||
end | end | ||
-- | -- 4. 主图片 和 图注 | ||
if hasValue(args. | table.insert(rows, buildImageRow(args.image, args.image_size, args.image_caption, false)) | ||
local | |||
-- 5. 市徽、市旗、标志 | |||
if hasValue(args.seal) or hasValue(args.logo) or hasValue(args.flag) then | |||
local | local symbol_row = mw.html.create('tr') | ||
if hasValue(args. | 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 | 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 | end | ||
-- | -- 6. 地图 和 坐标 | ||
if hasValue(args.lon) | table.insert(rows, buildImageRow(args.pushpin_map, args.map_size, args.map_caption, true)) | ||
local coord_row = mw.html.create('tr') | |||
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') | :attr('colspan', '2') | ||
:css('text-align', 'center') | :css('text-align', 'center') | ||
:css('font-size', '95%') | :css('font-size', '95%') | ||
:wikitext( | :wikitext(coord_str) | ||
table.insert(rows, tostring(coord_row)) | |||
end | end | ||
-- | -- 7. 行政区划 | ||
table.insert(rows, buildSubheader('行政')) | |||
table.insert(rows, buildRow('国家', args.country)) | table.insert(rows, buildRow('国家', args.country)) | ||
table.insert(rows, buildRow(' | for i = 1, 5 do -- 支持最多5级行政区划 | ||
table.insert(rows, buildRow(' | local type_key = 'subdivision_type' .. i | ||
table.insert(rows, buildRow(' | 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])) | ||
if hasValue(args. | 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 = '人口' | local pop_header_text = '人口' | ||
if hasValue(args.population_as_of) then | if hasValue(args.population_as_of) then | ||
| 第105行: | 第214行: | ||
end | end | ||
table.insert(rows, buildSubheader(pop_header_text)) | table.insert(rows, buildSubheader(pop_header_text)) | ||
table.insert(rows, buildRow(' • 总计', args. | 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 | end | ||
-- | -- 12. 时区 | ||
if hasValue(args. | if hasValue(args.timezone1) then | ||
table.insert(rows, buildSubheader('时区')) | table.insert(rows, buildSubheader('时区')) | ||
local tz_data = args. | local tz_data = args.timezone1 | ||
if hasValue(args. | if hasValue(args.utc_offset1) then | ||
tz_data = tz_data .. ' (' .. args. | tz_data = tz_data .. ' (' .. args.utc_offset1 .. ')' | ||
end | end | ||
table.insert(rows, buildRow(' ', tz_data)) -- 标签留空,让内容靠左 | table.insert(rows, buildRow(' ', tz_data)) -- 标签留空,让内容靠左 | ||
if hasValue(args. | if hasValue(args.timezone1_DST) then | ||
local tz_dst_data = args. | local tz_dst_data = args.timezone1_DST | ||
if hasValue(args. | if hasValue(args.utc_offset1_DST) then | ||
tz_dst_data = tz_dst_data .. ' (' .. args. | tz_dst_data = tz_dst_data .. ' (' .. args.utc_offset1_DST .. ')' | ||
end | end | ||
table.insert(rows, buildRow(' • 夏时制', tz_dst_data)) | table.insert(rows, buildRow(' • 夏时制', tz_dst_data)) | ||
end | end | ||
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)) | root:wikitext(table.concat(rows, '\n')) | ||
return tostring(root) | return tostring(root) | ||
2025年11月18日 (二) 17:40的版本
此模块的文档可以在模块: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