跳转到内容
打开/关闭菜单
  • 6 条目
  • 7 文件
  • 13 用户
  • 684 编辑
久远澪Wiki
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

此模块的文档可以在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('&', '&amp;'):gsub('<', '&lt;'):gsub('>', '&gt;')
        :gsub('"', '&quot;'):gsub("'", '&#39;')
    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