|
|
| 第1行: |
第1行: |
| 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
| |