Module:直播周表
来自久远澪Wiki
更多操作
此模块的文档可以在Module:直播周表/doc创建
-- 直播周表渲染模块:读取 久远澪:直播周表/Data 的 JSON 数据并渲染。
--
-- 用法:
-- {{#invoke:直播周表|render}} → 表格(久远澪:直播周表 页使用)
-- {{#invoke:直播周表|preview}} → 首页/每周直播预告 卡片块预览
--
-- /Data 页 JSON 结构:
-- {
-- "caption": "本周周表",
-- "rows": [
-- {"date": "24日", "weekday": "周一", "time": "18:30",
-- "content": "神厨小澪", "note": "做饭游戏"},
-- ...
-- ]
-- }
local p = {}
local DATA_PAGE = '久远澪:直播周表/Data'
local HEADER = '! 日期 !! 星期 !! 时间 !! 内容 !! 备注'
-- 星期 → 数字(1~7),用于配色:周一~周四主题色,周五~周日强调色
local WEEKDAY_NUM = {
['周一'] = 1, ['周二'] = 2, ['周三'] = 3, ['周四'] = 4,
['周五'] = 5, ['周六'] = 6, ['周日'] = 7,
['星期一'] = 1, ['星期二'] = 2, ['星期三'] = 3, ['星期四'] = 4,
['星期五'] = 5, ['星期六'] = 6, ['星期日'] = 7,
}
-- HTML 转义
local function esc(s)
s = tostring(s or '')
s = s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>')
:gsub('"', '"'):gsub("'", ''')
return s
end
-- 读取并解析数据页,返回 (data, err)
local function loadData()
local dataTitle = mw.title.new(DATA_PAGE)
if not dataTitle or not dataTitle.exists then
return nil, '<span class="error">数据页 [[:' .. DATA_PAGE .. ']] 不存在</span>'
end
local ok, data = pcall(mw.text.jsonDecode, dataTitle:getContent())
if not ok or type(data) ~= 'table' then
return nil, '<span class="error">数据页 [[:' .. DATA_PAGE
.. ']] JSON 解析失败,请检查格式</span>'
end
return data, nil
end
function p.render(frame)
local data, err = loadData()
if err then return err end
local rows = data.rows or {}
local lines = {}
table.insert(lines, '{| class="wikitable" style="text-align:center"')
if data.caption and data.caption ~= '' then
table.insert(lines, '|+ ' .. data.caption)
end
table.insert(lines, HEADER)
for _, row in ipairs(rows) do
table.insert(lines, '|-')
table.insert(lines,
'| ' .. (row.date or '')
.. ' || ' .. (row.weekday or '')
.. ' || ' .. (row.time or '')
.. ' || ' .. (row.content or '')
.. ' || ' .. (row.note or ''))
end
table.insert(lines, '|}')
return table.concat(lines, '\n')
end
-- 首页/每周直播预告:每个日期一个独立卡片块
function p.preview(frame)
local data, err = loadData()
if err then return err end
local rows = data.rows or {}
if #rows == 0 then
return '<div class="ws-empty">本周暂无公开直播安排,具体时间请以[[久远澪]]页面与 B 站动态为准。</div>'
end
local blocks = {}
for _, row in ipairs(rows) do
local date = esc(row.date)
local weekday = esc(row.weekday)
local time = esc(row.time)
local note = esc(row.note)
-- content 允许 wiki 标记(如 [[链接]]),交给解析器处理
local content = frame:preprocess(tostring(row.content or ''))
local num = WEEKDAY_NUM[row.weekday] or 0
local b = { '<div class="ws-day ws-d' .. num .. '">' }
table.insert(b, '<div class="ws-head"><span class="ws-date">' .. date .. '</span>')
if weekday ~= '' then
table.insert(b, '<span class="ws-weekday">' .. weekday .. '</span>')
end
table.insert(b, '</div>')
if content ~= '' then
table.insert(b, '<div class="ws-body">' .. content .. '</div>')
end
if time ~= '' and time ~= '-' then
table.insert(b, '<span class="ws-time">' .. time .. '</span>')
end
if note ~= '' then
table.insert(b, '<span class="ws-note">' .. note .. '</span>')
end
table.insert(b, '</div>')
table.insert(blocks, table.concat(b))
end
return '<div class="ws-wrap">' .. table.concat(blocks, '\n') .. '</div>'
end
return p