local p = {}
local Arguments = require('Module:Arguments')
local function trim(s) return mw.text.trim(tostring(s or "")) end
local function safe(s) return tostring(s or "") end
local function now(s) return mw.text.nowiki(tostring(s or "")) end
-- 安全展开模板(使用 frame:expandTemplate{ title=..., args = {...} })
local function expand_template_safe(frame, title, args_table)
local ok, res = pcall(function()
return frame:expandTemplate{ title = title, args = args_table }
end)
if ok and res and tostring(res) ~= "" then
return trim(res)
end
return ""
end
-- 根据稀有度计算左/右/top 偏移(模仿原模板的 #switch 逻辑)
local function compute_offsets(azur_level)
azur_level = trim(azur_level)
local left_right = "0"
local top = "0"
if azur_level == "14" then
left_right = "-8px"
else
left_right = "0"
end
if azur_level == "7" then
top = "5px"
elseif azur_level == "13" or azur_level == "14" then
top = "10px"
else
top = "0"
end
return left_right, top
end
-- 用 Module:Arguments 获取参数并从中收集名称列表
local function collect_names_with_arguments(frame)
-- getArgs options:如需让 Arguments 只读父模板参数,可以设置 wrappers 或 parentFirst
local args_options = {
-- wrappers = "Template:碧蓝航线图鉴", -- 如果你有包装模板,取消注释并改名以优化(可选)
-- parentFirst = true, -- 如果希望父模板参数优先(可选)
}
local args = Arguments.getArgs(frame, args_options)
local names = {}
-- 1) 优先读取位置参数 args[1], args[2], ...
local max_pos = 200
for i = 1, max_pos do
local v = args[i]
if not v or trim(v) == "" then break end
table.insert(names, trim(v))
end
if #names > 0 then return names end
-- 2) 读取 name1,name2,...
for i = 1, max_pos do
local k = "name" .. i
if not args[k] or trim(args[k]) == "" then break end
table.insert(names, trim(args[k]))
end
if #names > 0 then return names end
-- 3) 回退到 prefix + index (如传入 num + name 前缀)
if args.num and args.name and trim(args.name) ~= "" then
local n = tonumber(args.num) or 0
local prefix = trim(args.name)
for i = 1, n do
local key = prefix .. tostring(i)
if args[key] and trim(args[key]) ~= "" then
table.insert(names, trim(args[key]))
end
end
if #names > 0 then return names end
end
-- 4) 最后尝试扫描 args 中可能的 nameN 风格键(更宽松的匹配)
local indexed = {}
for k, v in pairs(args) do
local idx = k:match("^name(%d+)$")
if idx and trim(v) ~= "" then
indexed[tonumber(idx)] = trim(v)
end
end
for i = 1, max_pos do
if indexed[i] then table.insert(names, indexed[i]) else break end
end
return names
end
-- 主渲染入口:保持与原模板的输出结构一致
function p.render(frame)
frame = frame or mw.getCurrentFrame()
-- 收集名称
local names = collect_names_with_arguments(frame)
if not names or #names == 0 then
return "" -- 没有名字则返回空
end
local out = {}
table.insert(out, '<ul style="float:none; text-align:center; list-style-image:none; list-style-type:none; width:100%; max-width:1300px; line-height:130%; margin:auto; padding:0;">')
for _, raw_name in ipairs(names) do
local name = trim(raw_name)
if name == "" then
-- skip empty
else
-- 取得稀有度(等价于 {{碧蓝航线稀有度|name}})
local rarity = expand_template_safe(frame, "碧蓝航线稀有度", { [1] = name })
if rarity == "" then rarity = "0" end
-- 取得文件拼音(等价于 {{碧蓝航线文件拼音|name}})
local pinyin = expand_template_safe(frame, "碧蓝航线文件拼音", { [1] = name })
if pinyin == "" then pinyin = trim(name) end
-- 计算偏移
local leftRight, top = compute_offsets(rarity)
-- 开始构造 li
table.insert(out, '<li style="position:relative; float:left; margin:2px; width:174px; height:252px;">')
-- 背景卡片
local bg_file = string.format('[[File:BLHX_level_card_%s.png|class=azurlane-bgc|link=]]', now(rarity))
table.insert(out, '<div style="position:absolute; top:15px; left:5px; right:5px; bottom:20px; margin:auto; background-color:#222222;">' .. bg_file .. '</div>')
-- 角色图标
local char_file = string.format('[[File:AzurLane_icon_%s.png|class=azurlane-char|link=]]', now(pinyin))
table.insert(out, '<div style="position:absolute;top:15px; left:5px; right:5px; bottom:5px;">' .. char_file .. '</div>')
-- 链接区(调用 碧蓝航线links 并传 css)
local links_expanded = expand_template_safe(frame, "碧蓝航线links", { [1] = name, css = "font-size:116%" })
if links_expanded == "" then links_expanded = mw.text.nowiki(name) end
table.insert(out, '<div style="position:absolute; bottom:34px; background-color:rgb(0,0,0,0.5); left:5px; right:5px; margin:auto; text-shadow: -1px -1px 0 #FFFFFF, 1px -1px 0 #FFFFFF, -1px 1px 0 #FFFFFF, 1px 1px 0 #FFFFFF, -2px -2px 4px #FFFFFF, 2px -2px 4px #FFFFFF, -2px 2px 4px #FFFFFF, 2px 2px 4px #FFFFFF;">' .. "''' " .. links_expanded .. " '''" .. '</div>')
-- 边框图层
local border_file = string.format('[[File:BLHX_level_border_%s.png|class=azurlane-border|link=]]', now(rarity))
table.insert(out, string.format('<div style="position:absolute; bottom:5px; left:%s; right:%s; top:%s; pointer-events:none;">%s</div>', leftRight, leftRight, top, border_file))
table.insert(out, '</li>')
end
end
table.insert(out, '</ul>')
return table.concat(out)
end
return p