Module:曲包列表:修订间差异

AnoKodokushi​(留言 | 贡献)
"#"修正
Admin​(留言 | 贡献)
输出加 __NOCONTENTCONVERT__/__NOTITLECONVERT__:署名与曲名保持 UTF-8 原字,不做繁简变体转换(无需给名字加包裹,无 DOM 开销)
 
(未显示2个用户的3个中间版本)
第3行: 第3行:
-- 单一数据源: 曲目列表.json (曲包信息由 songs 的 "曲包" 字段派生)
-- 单一数据源: 曲目列表.json (曲包信息由 songs 的 "曲包" 字段派生)
local DATA_TITLE = '模板:曲目列表.json'
local DATA_TITLE = '模板:曲目列表.json'
local validator = require('模块:数据页校验')


-- 曲包展示顺序 (游戏内上架顺序), 不在表中的曲包按名称排序追加到末尾
-- 曲包展示顺序 (游戏内上架顺序), 不在表中的曲包按名称排序追加到末尾
第46行: 第47行:
function p.render(frame)
function p.render(frame)
local demomode = frame and frame.args['demo']
local demomode = frame and frame.args['demo']
local t = mw.title.new(DATA_TITLE)
local data, dataErr = validator.load(DATA_TITLE)
if not t or not t.exists then
if not data then
return '<span class="error">数据页不存在: [[' .. DATA_TITLE .. ']]</span>'
return dataErr
end
local ok, data = pcall(mw.text.jsonDecode, t:getContent())
if not ok or type(data) ~= 'table' then
return '<span class="error">数据页 JSON 解析失败: [[' .. DATA_TITLE .. ']]</span>'
end
end


第99行: 第96行:
local links = {}
local links = {}
for _, song in ipairs(songs) do
for _, song in ipairs(songs) do
table.insert(links, '[[' .. '曲目:' .. esc(song['曲名']) .. '|' .. langWrap(song) .. ']]')
            table.insert(links, '[[' .. '曲目:' .. esc(pageName(song)) .. '|' .. langWrap(song) .. ']]')
end
end
-- 锚点: 其他页面可 [[曲包列表#<曲包名>]] 跳转到对应行
-- 锚点: 其他页面可 [[曲包列表#<曲包名>]] 跳转到对应行
第107行: 第104行:
end
end
table.insert(out, '|}')
table.insert(out, '|}')
-- 特殊曲包: 教程 / 剧情模式(剧情歌曲+训练场) / 石墩子模式 —— 单一表格
local story = data.story or {}
local specialRows = {
{ name = '教程', list = data.tutorial or {}, note = '教学关卡' },
{ name = '剧情模式', list = story.songs or {}, note = '剧情章节曲目' },
{ name = '训练场', list = story.training or {}, note = '剧情模式中的练习关卡' },
{ name = '石墩子模式', list = data.special or {}, note = '愚人节限定谱面' },
}
local anyRow = false
for _, r in ipairs(specialRows) do if #r.list > 0 then anyRow = true end end
if anyRow then
local function plainName(song)
return song['链接名'] or song['曲名']
end
table.insert(out, '\n== 特殊曲包 ==')
table.insert(out, '以下内容不属于常规曲包,单独列出:\n')
table.insert(out, '{| class="wikitable sortable" style="width:100%"')
table.insert(out, '! 图片 !! 曲包 !! 曲目数 !! 包含曲目')
for _, r in ipairs(specialRows) do
if #r.list > 0 then
local imgFile = '曲包物品-' .. norm(r.name) .. '.png'
local imgTitle = mw.title.new('File:' .. imgFile)
local imgCell = (imgTitle and imgTitle.exists) and ('[[File:' .. esc(imgFile) .. '|80px]]') or '—'
local links = {}
for _, song in ipairs(r.list) do
table.insert(links, '[[' .. '曲目:' .. esc(pageName(song)) .. '|' .. langWrap(song) .. ']]')
end
table.insert(out, '|-\n| id="' .. esc(r.name) .. '" | ' .. imgCell .. ' || ' .. esc(r.name)
.. ' || ' .. tostring(#r.list) .. ' || ' .. table.concat(links, ' / '))
end
end
table.insert(out, '|}')
end


if not demomode then
if not demomode then
第112行: 第143行:
end
end
-- Scribunto 返回文本中的 {{模板}} 不会被自动展开, 必须显式 preprocess
-- Scribunto 返回文本中的 {{模板}} 不会被自动展开, 必须显式 preprocess
return frame:preprocess(table.concat(out, '\n'))
return frame:preprocess('__NOCONTENTCONVERT__\n__NOTITLECONVERT__\n' .. table.concat(out, '\n'))
end
end


return p
return p