模块:GFInfobox:修订间差异
来自OGAS数据中枢
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第9行: | 第9行: | ||
end | end | ||
local function | -- 只用于不含用户输入模板的字段(颜色、稀有度等由 Lua 自己构造的模板调用) | ||
local function expandSafe(frame, s) | |||
if not s then return nil end | if not s then return nil end | ||
return frame:preprocess(s) | return frame:preprocess(s) | ||
| 第30行: | 第31行: | ||
colors[math.floor(num)], | colors[math.floor(num)], | ||
string.rep('★', math.floor(num)) | string.rep('★', math.floor(num)) | ||
) | ), false -- false = 已经是 HTML,不需要 MediaWiki 再展开 | ||
end | end | ||
return rarity | return rarity, false | ||
end | end | ||
function p.main(frame) | function p.main(frame) | ||
local parentFrame = frame:getParent() | local parentFrame = frame:getParent() | ||
local args = parentFrame.args | local args = parentFrame.args | ||
| 第67行: | 第44行: | ||
or mw.title.getCurrentTitle().subpageText | or mw.title.getCurrentTitle().subpageText | ||
-- 颜色字段:由 Lua 构造模板调用字符串,用 preprocess 展开,安全 | |||
local function fmtColor(raw, cType) | local function fmtColor(raw, cType) | ||
raw = cleanParam(raw) | raw = cleanParam(raw) | ||
if not raw then return nil end | if not raw then return nil end | ||
return frame | return expandSafe(frame, '{{' .. cType .. '_color|' .. raw .. '}}') | ||
end | end | ||
local hairColor | local hairColor = fmtColor(args['多种发色'] or args['发色'], 'Hair') | ||
local eyeColor | local eyeColor = fmtColor(args['多种瞳色'] or args['瞳色'], 'Eye') | ||
local rarity | local rarity = p.formatRarity(cleanParam(args['稀有度'])) | ||
local function | ---------- 策略:含用户输入的字段,原样输出 wikitext ---------- | ||
-- MediaWiki 拿到 Lua 模块返回的字符串后,会对其中的 wikitext 语法 | |||
-- (包括 {{模板}}、[[链接]] 等)做完整的二次解析, | |||
-- 因此直接把原始参数值嵌入 HTML 字符串返回, | |||
-- MediaWiki 渲染时会正确展开 {{ruby}} 等模板,不需要 Lua 自己 preprocess。 | |||
-- 注意:这要求这些字段的值不含恶意 HTML,wiki 本身的权限体系负责这一点。 | |||
local function raw(key) | |||
return cleanParam(args[key]) -- 直接返回原始 wikitext,不展开 | |||
end | end | ||
-- 声优字段:纯文字加链接,不太可能含 ruby,但保险起见也走 raw | |||
local function fmtVoice() | local function fmtVoice() | ||
local | local v = cleanParam(args['多位声优'] or args['声优']) | ||
if not | if not v then return nil end | ||
-- 若已含链接语法则原样返回,否则套链接 | |||
if | if v:find('%[%[') then return v end | ||
return '[[' .. v .. ']]' | |||
return '[[' .. | |||
end | end | ||
---------- 拼 wikitext + HTML 混合字符串 ---------- | |||
-- Lua 模块的返回值会被 MediaWiki 当作 wikitext 再解析一次, | |||
-- 所以可以在 HTML 属性/标签里直接夹杂 {{ruby}} 这样的 wikitext, | |||
-- MediaWiki 会先展开模板,再把结果嵌入 DOM。 | |||
local parts = {} | local parts = {} | ||
| 第98行: | 第84行: | ||
push('<div class="gf-infobox">') | push('<div class="gf-infobox">') | ||
push('<div class="gf-title">' .. name .. '</div>') | |||
push('<div class="gf-title">' .. | |||
local image = cleanParam(args['image']) | local image = cleanParam(args['image']) | ||
| 第106行: | 第90行: | ||
if image then | if image then | ||
push('[[File:' .. image .. '|280px]]') | push('[[File:' .. image .. '|280px]]') | ||
local caption = | local caption = raw('图片说明') | ||
if caption then | if caption then | ||
push('<div style="font-size:0.9em;">' .. | push('<div style="font-size:0.9em;">' .. caption .. '</div>') | ||
end | end | ||
end | end | ||
| 第117行: | 第101行: | ||
local fields = { | local fields = { | ||
{ '本名', | { '本名', raw('本名') }, | ||
{ '别名', | { '别名', raw('别名') }, | ||
{ '发色', hairColor }, | { '发色', hairColor }, | ||
{ '瞳色', eyeColor }, | { '瞳色', eyeColor }, | ||
{ '声优', fmtVoice() }, | { '声优', fmtVoice() }, | ||
{ '萌点', | { '萌点', raw('萌点') }, | ||
{ '类型', | { '类型', raw('类型') }, | ||
{ '稀有度', rarity }, | { '稀有度', rarity }, | ||
{ '团体', | { '团体', raw('所属团体') }, | ||
{ '状态', | { '状态', raw('个人状态') }, | ||
} | } | ||
| 第141行: | 第125行: | ||
push('</div>') -- gf-table | push('</div>') -- gf-table | ||
local related = | local related = raw('相关人士') | ||
if related then | if related then | ||
push('<div class="gf-section">亲属或相关人</div>') | push('<div class="gf-section">亲属或相关人</div>') | ||
| 第147行: | 第131行: | ||
end | end | ||
push('</div>') | push('</div>') -- gf-infobox | ||
return table.concat(parts, '\n') | return table.concat(parts, '\n') | ||
2026年5月12日 (二) 22:12的版本
此模块的文档可以在模块:GFInfobox/doc创建
local p = {}
local function cleanParam(s)
if not s then return nil end
s = s:gsub('^[%s\n\r\t]+', ''):gsub('[%s\n\r\t]+$', '')
if s == '' then return nil end
s = s:gsub('^%s*<p[^>]*>', ''):gsub('</p>%s*$', '')
return s
end
-- 只用于不含用户输入模板的字段(颜色、稀有度等由 Lua 自己构造的模板调用)
local function expandSafe(frame, s)
if not s then return nil end
return frame:preprocess(s)
end
function p.formatRarity(rarity)
if not rarity then return nil end
local colors = {
[2] = '#777',
[3] = '#33566f',
[4] = '#7b813f',
[5] = '#a7753b',
[6] = '#ad4229',
}
local num = tonumber(rarity)
or (rarity:find('★') and select(2, rarity:gsub('★', '★')))
if num and colors[math.floor(num)] then
return string.format(
'<span style="color:%s">%s</span>',
colors[math.floor(num)],
string.rep('★', math.floor(num))
), false -- false = 已经是 HTML,不需要 MediaWiki 再展开
end
return rarity, false
end
function p.main(frame)
local parentFrame = frame:getParent()
local args = parentFrame.args
local name = cleanParam(args['标题'])
or cleanParam(args['名字'])
or mw.title.getCurrentTitle().subpageText
-- 颜色字段:由 Lua 构造模板调用字符串,用 preprocess 展开,安全
local function fmtColor(raw, cType)
raw = cleanParam(raw)
if not raw then return nil end
return expandSafe(frame, '{{' .. cType .. '_color|' .. raw .. '}}')
end
local hairColor = fmtColor(args['多种发色'] or args['发色'], 'Hair')
local eyeColor = fmtColor(args['多种瞳色'] or args['瞳色'], 'Eye')
local rarity = p.formatRarity(cleanParam(args['稀有度']))
---------- 策略:含用户输入的字段,原样输出 wikitext ----------
-- MediaWiki 拿到 Lua 模块返回的字符串后,会对其中的 wikitext 语法
-- (包括 {{模板}}、[[链接]] 等)做完整的二次解析,
-- 因此直接把原始参数值嵌入 HTML 字符串返回,
-- MediaWiki 渲染时会正确展开 {{ruby}} 等模板,不需要 Lua 自己 preprocess。
-- 注意:这要求这些字段的值不含恶意 HTML,wiki 本身的权限体系负责这一点。
local function raw(key)
return cleanParam(args[key]) -- 直接返回原始 wikitext,不展开
end
-- 声优字段:纯文字加链接,不太可能含 ruby,但保险起见也走 raw
local function fmtVoice()
local v = cleanParam(args['多位声优'] or args['声优'])
if not v then return nil end
-- 若已含链接语法则原样返回,否则套链接
if v:find('%[%[') then return v end
return '[[' .. v .. ']]'
end
---------- 拼 wikitext + HTML 混合字符串 ----------
-- Lua 模块的返回值会被 MediaWiki 当作 wikitext 再解析一次,
-- 所以可以在 HTML 属性/标签里直接夹杂 {{ruby}} 这样的 wikitext,
-- MediaWiki 会先展开模板,再把结果嵌入 DOM。
local parts = {}
local function push(s) parts[#parts + 1] = s end
push('<div class="gf-infobox">')
push('<div class="gf-title">' .. name .. '</div>')
local image = cleanParam(args['image'])
push('<div class="gf-image-container">')
if image then
push('[[File:' .. image .. '|280px]]')
local caption = raw('图片说明')
if caption then
push('<div style="font-size:0.9em;">' .. caption .. '</div>')
end
end
push('</div>')
push('<div class="gf-section">基础资料</div>')
push('<div class="gf-table">')
local fields = {
{ '本名', raw('本名') },
{ '别名', raw('别名') },
{ '发色', hairColor },
{ '瞳色', eyeColor },
{ '声优', fmtVoice() },
{ '萌点', raw('萌点') },
{ '类型', raw('类型') },
{ '稀有度', rarity },
{ '团体', raw('所属团体') },
{ '状态', raw('个人状态') },
}
for _, field in ipairs(fields) do
local label, value = field[1], field[2]
if value then
push('<div class="gf-row">')
push('<div class="gf-label">' .. label .. '</div>')
push('<div class="gf-value">' .. value .. '</div>')
push('</div>')
end
end
push('</div>') -- gf-table
local related = raw('相关人士')
if related then
push('<div class="gf-section">亲属或相关人</div>')
push('<div class="gf-related">' .. related .. '</div>')
end
push('</div>') -- gf-infobox
return table.concat(parts, '\n')
end
return p