模組:Selected recent additions
外观
![]() | 此模块已评为alpha版,可接受第三方输入,并可用于少量页面以检查是否存在问题,但需要受到检查。欢迎提供新功能或修改其输入输出机制的建议。 |
![]() | 此模块使用Lua语言: |
用法
{{#invoke:Selected recent additions|main}}
参数将从父模板{{Transclude selected recent additions}}处传递;请见该模板的文档。
参见
-- Module:Selected recent additions (adapted for Chinese Wikipedia)
local randomModule = require('Module:Random')
function cleanupArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val ~= '' then
cleanArgs[key] = val
end
else
cleanArgs[key] = val
end
end
return cleanArgs
end
function isAffirmed(val)
if not(val) then return false end
local affirmedWords = ' add added affirm affirmed include included on true yes y '
return string.find(affirmedWords, ' '..string.lower(val)..' ', 1, true ) and true or false
end
function makeOutput(allItems, maxItems, more, notRandom)
local output
if notRandom then
output = ''
local itemIndex = 1
local maxCount = math.min(#allItems, maxItems)
while itemIndex <= maxCount do
output = output .. allItems[itemIndex] .. '\n'
itemIndex = itemIndex + 1
end
else
local randomiseArgs = {
['t'] = allItems,
['limit'] = maxItems
}
local randomisedItems = randomModule.main('array', randomiseArgs )
output = table.concat(randomisedItems, '\n')
end
if more then
output = output .. '\n' .. more
end
return mw.text.trim(output)
end
-- 清理wikitext以便进行模式匹配
-- @param wikitext string: 原始wikitext行
-- @param frame table: Scribunto frame对象,用于preprocessString
function cleanForPatternMatching(wikitext, frame)
local cleaned = wikitext
-- 移除 wikilink 的方括号, 保留显示文本或链接目标
-- [[链接目标|显示文本]] -> 显示文本
-- [[链接目标]] -> 链接目标
cleaned = mw.ustring.gsub(cleaned, "%[%[([^%]|]+)%|([^%]]+)%]%]", "%2")
cleaned = mw.ustring.gsub(cleaned, "%[%[([^%]]+)%]%]", "%1")
-- 处理字词转换标记 -{...}- 或 -{R|...}-
-- 使用 frame:preprocessString 将标记转换为当前页面语言环境下的实际显示文本
-- 模式 %-%{R?[^%}]*%}%- 匹配 -{...}-, -{R...}-, -{R|...}- 等形式
if frame then -- 确保 frame 对象存在
cleaned = mw.ustring.gsub(cleaned, "%-%{R?[^%}]*%}%-", function(match)
return frame:preprocessString(match)
end)
else
-- 如果没有 frame 对象 (例如在测试环境中直接调用此函数),
-- 则采取降级策略,例如移除标记或保留原始标记。
-- 这里选择简单移除,但在实际模块调用中 frame 应该总是可用的。
cleaned = mw.ustring.gsub(cleaned, "%-%{R?[^%}]*%}%-", "")
end
-- 移除加粗/斜体标记 ('', ''', ''''')
cleaned = mw.ustring.gsub(cleaned, "['']+", "")
-- 移除HTML注释
cleaned = mw.ustring.gsub(cleaned, "%<%!%-%-(.-)%-%-%>", "")
return cleaned
end
function makeCollapsed(outerText, innerText)
return "{{Hidden begin | titlestyle = font-weight:normal | title = " .. outerText .. "}}" .. innerText .. "{{Hidden end}}"
end
-- 从指定存档子页面获取新条目推荐项目
-- @param frame table: Scribunto frame对象
function getRecentAdditions(archivePagePath, keepPatterns, skipPatterns, showWikitext, frame)
local title = mw.title.new(archivePagePath)
if not title or not title.exists then
return {}
end
local raw = title:getContent()
if not raw then
return {}
end
local items = {}
local lines = mw.text.split(raw, '\n')
for _, line in ipairs(lines) do
line = line:match('^%s*(.-)%s*$')
if line and mw.ustring.match(line, '^%*%s*') then -- 中文维基DYK以 "* " 开头
local originalItemText = line
-- 传递 frame 对象给 cleanForPatternMatching
local textForMatching = cleanForPatternMatching(originalItemText, frame)
local keep = false
if #keepPatterns == 0 then -- 如果没有指定 keepPatterns,则默认保留 (仍需通过 skipPatterns 检查)
keep = true
else
for _, keepPatt in pairs(keepPatterns) do
if mw.ustring.find(textForMatching, keepPatt, 1, false) then
keep = true
break
end
end
end
local skip = false
if #skipPatterns > 0 then
for _, skipPatt in pairs(skipPatterns) do
if mw.ustring.find(textForMatching, skipPatt, 1, false) then
skip = true
break
end
end
end
if keep and not skip then
local cleanItem = originalItemText
cleanItem = mw.ustring.gsub(cleanItem, "%<%!%-%-(.-)%-%-%>", "")
if showWikitext then
local itemWikitext = "<pre>" .. mw.text.nowiki(cleanItem) .. "</pre>"
cleanItem = makeCollapsed(cleanItem, itemWikitext)
end
table.insert(items, cleanItem)
end
end
end
return items
end
-- 获取过去数月的新条目推荐项目
-- @param frame table: Scribunto frame对象
function getItems(maxMonths, patterns, skipPatterns, showWikitext, frame)
local allItems = {}
local currentDateTime = os.date('*t')
local currentYear = tonumber(currentDateTime.year)
local currentMonth = tonumber(currentDateTime.month)
local monthsAgo = 0
while monthsAgo < maxMonths do
local targetYear = currentYear
local targetMonth = currentMonth - monthsAgo
while targetMonth <= 0 do
targetMonth = targetMonth + 12
targetYear = targetYear - 1
end
local archiveSubpage = string.format("%d年%d月", targetYear, targetMonth)
local archivePagePath = 'Wikipedia:新条目推荐/存档/' .. archiveSubpage
-- 传递 frame 对象给 getRecentAdditions
local monthlyItems = getRecentAdditions(archivePagePath, patterns, skipPatterns, showWikitext, frame)
for i, item in ipairs(monthlyItems) do
table.insert(allItems, item)
end
monthsAgo = monthsAgo + 1
end
return allItems
end
function getPatterns(args, prefix)
local patterns = {}
local i = 1
local key
while true do
key = prefix and (prefix .. i) or tostring(i)
if args[key] then
patterns[i] = args[key]
else
break
end
i = i + 1
end
return patterns
end
local p = {}
p.main = function(frame)
local currentInvokeArgs = frame.args
local args = cleanupArgs(currentInvokeArgs)
if args['not'] and not args['not1'] then
args['not1'] = args['not']
end
local patterns = getPatterns(args)
if #patterns < 1 and not isAffirmed(args.showall) then
-- 使用 frame:expandTemplate 来显示标准错误消息模板 (如果适用)
return frame:expandTemplate{ title = 'Error', args = { '未设置搜索关键词 (参数 1, 2, ...),或者设置 <code>showall=yes</code> 来显示所有条目。' } }
end
local skipPatterns = getPatterns(args, 'not')
local months = tonumber(args.months) or 12 -- 默认搜索过去12个月
local showWikitext = isAffirmed(args.wikitext)
-- 传递 frame 对象给 getItems
local allItems = getItems(months, patterns, skipPatterns, showWikitext, frame)
if #allItems < 1 then
return args.header and '' or (args.none or '未找到符合条件的新条目推荐。')
end
local maxItems = tonumber(args.max) or 5 -- 默认最多显示5条
local moreLinkText = args.more
if isAffirmed(args.more) then
moreLinkText = "'''[[Wikipedia:新条目推荐/存档|更多新条目推荐...]]'''"
elseif type(moreLinkText) == 'string' and moreLinkText == '' then -- 如果 more="" (空字符串), 则不显示
moreLinkText = nil
end
local nonRandom = isAffirmed(args.latest)
local output = makeOutput(allItems, maxItems, moreLinkText, nonRandom)
if args.header then
local footer = args.footer or '{{Box-footer}}'
-- 此处逻辑调整:如果allItems为空,在getItems之后已经返回了,所以这里不需要再次检查 #allItems < 1 来插入 'none' 消息
output = args.header .. '\n' .. output .. '\n' .. footer
end
local needsExpansion = mw.ustring.find(output, '{{', 1, true)
if needsExpansion then
return frame:preprocess(output)
else
return output
end
end
return p