Module:曲包列表:修订间差异
AnoKodokushi(留言 | 贡献) "#"修正 |
输出加 __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 | local data, dataErr = validator.load(DATA_TITLE) | ||
if not | if not data then | ||
return dataErr | |||
return | |||
end | end | ||
| 第99行: | 第96行: | ||
local links = {} | local links = {} | ||
for _, song in ipairs(songs) do | for _, song in ipairs(songs) do | ||
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 | ||