模組:TalkIcon
外观
{{#invoke:TalkIcon|main|...arguments...}}
{{{{{|safesubst:}}}#invoke:TalkIcon|main|...arguments...}}
可用參數
icon、匿名參數1:必填,分為單圖片(填入File:XXXXX.jpg形式)、多圖片(填入multi:XXXXX1.jpg/XXXXX2.jpg/XXXXX3.jpg形式)與純文字三種。text、匿名參數2:選填,圖標對應文本。extra、匿名參數3:選填,擴展參數。
包裹圖標相關
type:選填,建議,圖標類型。填寫不存在的類型會被靜默忽略,若不確定請務必檢查輸出的 wikitext 是否包含這些 class。- 可用類型(完整可用列表請參考Module:TalkIcon/data):
type=xfd:存廢討論(zhwiki-xfdicon)type=xfd-delete(zhwiki-xfdicon-delete)、type=xfd-keep(zhwiki-xfdicon-keep)、type=xfd-move(zhwiki-xfdicon-move)
type=vote:投票(zhwiki-voteicon)type=vote-support(zhwiki-voteicon-support)、type=vote-oppose(zhwiki-voteicon-oppose)、type=vote-neutral(zhwiki-voteicon-neutral)
type=spi:傀儡調查(zhwiki-spiicon)type=humor、type=humour:幽默(zhwiki-humoricon)type=discussion:其他可用於討論的圖標(zhwiki-discussionicon)
- 若需使用多個類型,可用半形逗號
,連接,如xfd-delete,humor。
- 可用類型(完整可用列表請參考Module:TalkIcon/data):
id:選填,建議,圖標ID,如Template:Vd對應的ID應填入英文delete。輸出 classzhwiki-talkicon-<id>。iconClass:選填,其他欲包裹圖標的class。模板已自動帶入skin-invert無需傳入。iconColor:選填,懸浮於圖標上時要顯示的文字。iconLang:選填,圖標要適用的 HTML 語言,常見為填入zh-Hant以使用在簡體下不置中但繁體下置中的標點符號。iconStyles:選填,其他要包裹圖標的樣式。iconSpace:選填,是否在圖標正後方插入 。預設值:使用圖片圖標則為真,否則為假。注意空字串會被當成不指定此選項回落到預設值。
純文字圖標
單圖片圖標
size、iconSize:選填,圖標大小,預設20px。alt、iconAlt:選填,圖標替代參數。link、iconLink:選填,圖標目標連結。
多圖片圖標
僅支援單圖片圖標的size參數,如有其他特殊需求請直接傳wikitext當純文本圖標使用。
無法被正確解析成標題的圖片會被自動忽略。
擴展參數
除了 extra 參數外,模組也支援以下包裝 extra 參數的參數:
explain:選填,解釋,相當於|extra=:{{{explain}}}。to:選填,至什麼什麼頁面,相當於|extra={{#if:{{{to|}}}|至(...略)[[{{{to}}}](...略)}}。
雜項
wrapClass:選填,不建議使用,包裹在整個圖標輸出外面的class。wrapStyles:選填,不建議使用,包裹在整個圖標輸出外面的樣式。
範例
| 本章節因幽默而保留,請不要當真。 |
{{#invoke:TalkIcon|main|File:Example.png|text=範例|alt=沙盒|link=Wikipedia:沙盒}}→
範例{{#invoke:TalkIcon|main|(×)|山豬|fg=red|bg=pink|type=xfd-delete,humor|id=delete}}→ (×)山豬{{#invoke:TalkIcon|main|File:Vote.svg|size=24px|alt=投票|link=Project:投票}}→
{{#invoke:TalkIcon|main|(?)|疑問|fg=white|bg=#007fff|iconLang=zh-Hant}}→ (?)疑問{{#invoke:TalkIcon|main|⚠|注意|extra=你的腳下|iconStyles=font-family: 'Noto Color Emoji', 'Segoe UI Emoji', 'sans-serif';}}→ ⚠注意你的腳下{{#invoke:TalkIcon|main|(►)|移动|fg=blue|bg=lightblue|to=Wikipedia:沙盒|wrapTo=q}}→ (►)移动至「Wikipedia:沙盒」{{#invoke:TalkIcon|main|File:Symbol declined.svg|驳回|explain=用户查核不是在钓鱼}}→
驳回:用户查核不是在钓鱼{{#invoke:TalkIcon|main|multi:WikiProject Council project list icon.svg/書.svg|這是一本書}}→
這是一本書{{#invoke:TalkIcon|main|bg=black|fg=silver|( π )|题外话|iconSpace=false}}→ ( π )题外话{{#invoke:TalkIcon|main|bg=black|fg=silver|( π )|题外话|iconSpace=true}}→ ( π ) 题外话
註釋
local mYesno
local data = require('Module:TalkIcon/data')
local p = {}
local function killEmptyString(value)
return value ~= '' and value or nil
end
local function yesno(value)
if not mYesno then
mYesno = require('Module:Yesno')
end
return mYesno(value)
end
local wrapToTable = {
quote = { '「', '」' },
book = { '《', '》' },
['single-book'] = { '〈', '〉' },
-- [[Wikipedia:格式手册/标点符号#书名号]]
volume = { '-{zh-cn:《;zh-my:《;zh-sg:《;zh-hk:《;zh-mo:《;zh-tw:〈;}-', '-{zh-cn:》;zh-my:》;zh-sg:》;zh-hk:》;zh-mo:》; zh-tw:〉;}-' }, -- [[Template:單雙書名號轉換]]
series = { '-{zh-cn:“; zh-tw:《;}-', '-{zh-cn:”; zh-tw:》;}-' }, -- [[Template:引书号转换]]
}
local wrapToAliasTable = {
q = wrapToTable.quote,
['引号'] = wrapToTable.quote,
['引號'] = wrapToTable.quote,
b = wrapToTable.book,
['书名号'] = wrapToTable.book,
['書名號'] = wrapToTable.book,
['单书名号'] = wrapToTable['single-book'],
['單書名號'] = wrapToTable['single-book'],
['double-book'] = wrapToTable.book,
['双书名号'] = wrapToTable.book,
['雙書名號'] = wrapToTable.book,
v = wrapToTable.volume,
s = wrapToTable.series,
-- 代號參見[[Wikipedia:格式手册/标点符号#书名号]]
['b1'] = wrapToTable.book,
['书1'] = wrapToTable.book,
['書1'] = wrapToTable.book,
['b2'] = wrapToTable.volume,
['书2'] = wrapToTable.volume,
['書2'] = wrapToTable.volume,
['b3'] = wrapToTable.series,
['书3'] = wrapToTable.series,
['書3'] = wrapToTable.series,
}
local function wrapTo(to, opt)
if opt then
opt = mw.ustring.lower(mw.text.trim(opt))
local match = wrapToTable[opt] or wrapToAliasTable[opt]
if match then
to = match[1] .. to .. match[2]
end
end
return to
end
p._wrapTo = wrapTo -- debug only
local function isFile(input, allowNoNs)
local success, title = pcall(mw.title.new, input)
if success and title then
if title.namespace == 0 and allowNoNs then
title = mw.title.new(title.text, 6)
end
if title.namespace == 6 then
return title
end
end
return false
end
p._isFile = isFile -- debug only
local function detectMultipleFiles(input)
if input:sub(1, 6):lower() ~= 'multi:' then
return {}
end
local rawFiles = mw.text.split(input:sub(7), '/') -- 理論上檔名不能包含 / 所以應該安全?
local files = {}
for _, name in ipairs(rawFiles) do
local title = isFile(name, true)
if title then
table.insert(files, title)
end
end
return files
end
p._detectMultipleFiles = detectMultipleFiles -- debug only
local function getTypeClassList(iconTag, type)
if not type or mw.text.trim(type) == '' then
return
end
for _, current in ipairs(mw.text.split(type, ',')) do
current = mw.text.trim(current)
local sp = mw.text.split(current, '-')
if #sp <= 2 then
if data.type[sp[1]] then
local t = data.type[sp[1]]
local typeClass = string.format('zhwiki-%sicon', t.type)
iconTag:addClass(typeClass)
if killEmptyString(sp[2]) and t.sub[sp[2]] then
iconTag:addClass(string.format('%s-%s', typeClass, t.sub[sp[2]]))
end
end
end
end
end
p._getTypeClassList = getTypeClassList -- debug only
function p._main(args)
local icon = killEmptyString(args.icon or args['1'] or args[1]) -- 圖標
if not icon then
error('missing argument "icon".')
end
local out
if killEmptyString(args.wrapClass) or killEmptyString(args.wrapStyles) then
out = mw.html.create('span')
:addClass(killEmptyString(args.wrapClass)) -- # nullable
:cssText(killEmptyString(args.wrapStyles)) -- # nullable
else
out = mw.html.create()
end
local iconTag = out:tag('span')
:addClass('skin-invert zhwiki-talkicon')
if killEmptyString(args.type) then
getTypeClassList(iconTag, args.type)
end
if killEmptyString(args.id) then
iconTag:addClass('zhwiki-talkicon-' .. args.id:gsub(' ', '_'))
end
iconTag
:addClass(killEmptyString(args.iconClass)) -- # nullable
:attr('title', killEmptyString(args.iconTitle)) -- # nullable
:attr('lang', killEmptyString(args.iconLang)) -- # nullable
local iconFiles = detectMultipleFiles(icon)
local iconFile
if #iconFiles > 0 then
local tmp = {}
iconFile = true
for _, file in ipairs(iconFiles) do
-- 多圖模式不支援自定義連結和替代文字
table.insert(tmp, string.format(
'[[File:%s|%s|link=|alt=]]',
file.text,
args.iconSize or args.size or '20px'
))
end
icon = table.concat(tmp, '')
else
iconFile = isFile(icon)
if iconFile then
-- 傳入圖片檔名
icon = string.format(
'[[File:%s|%s|link=%s|alt=%s]]',
iconFile.text,
args.iconSize or args.size or '20px',
args.iconLink or args.link or '',
args.iconAlt or args.alt or ''
)
else
-- 傳入一般內容
iconTag
:css('font-weight', 'bold')
:css('color', killEmptyString(args.iconColor or args.fg)) -- # nullable
:css('background', killEmptyString(args.iconBackground or args.bg)) -- # nullable
end
end
iconTag
:cssText(killEmptyString(args.iconStyles)) -- # nullable
:wikitext(icon)
local text = args.text or args['2'] or args[2] -- 圖標文字
if text then
local iconSpace
if killEmptyString(args.iconSpace) then
iconSpace = yesno(args.iconSpace)
else
iconSpace = iconFile and true or false
end
if iconSpace then
out:wikitext(' ') -- 圖標和文字中間插一個空格
end
local textTag = out:tag('span')
:addClass('zhwiki-talkicontext')
:addClass(killEmptyString(args.textClass)) -- # nullable
:css('font-weight', 'bold')
:cssText(killEmptyString(args.textStyles)) -- # nullable
:wikitext(text)
local extra = killEmptyString(args.extra or args['3'] or args[3])
if extra then
-- 如 (►)'''移動'''到某某標題
out:wikitext(extra)
elseif killEmptyString(args.explain) then
-- 解釋 大多用於 VIP、RFPP、SPI 之類的模板
-- 其實等同於 |extra=:<explain>
-- 但作者認為在參數開頭就莫名加冒號很醜 僅此而已 (2025.08.13)
out:wikitext(':' .. args.explain)
elseif killEmptyString(args.to) then
-- (動作)至XXX
-- 等同於 |extra=至{{#if:{{{to|}}}|{{#switch:{{{wrapTo}}}|q|quote=「|b|book=《|v|volume=(...略)|s|series=(...略)}}[[{{{to}}}]{{#switch:{{{wrap}}}|q|quote=」|b|book=》|v|volume=(...略)|s|series=(...略)}}]}}
-- 模板請務必傳遞 wrapTo 參數以因應需求 避免重複建立大量模板
out:wikitext('至' .. wrapTo(string.format('[[%s]]', args.to), args.wrapTo))
end
end
return tostring(out)
end
function p.main(frame)
local args = frame.args['passThrough'] and ((frame:getParent() or frame).args) or frame.args
return p._main(args)
end
return p