模組:Selected recent additions
外观
![]() | 此模块已评为alpha版,可接受第三方输入,并可用于少量页面以检查是否存在问题,但需要受到检查。欢迎提供新功能或修改其输入输出机制的建议。 |
![]() | 此模块使用Lua语言: |
用法
{{#invoke:Selected recent additions|main}}
参数将从父模板{{Transclude selected recent additions}}处传递;请见该模板的文档。
参见
local randomModule = require('Module:Random')
-- Helper function to clean table arguments (remove whitespace, empty strings)
function cleanupArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$') -- Trim whitespace
if val ~= '' then
cleanArgs[key] = val
end
else
cleanArgs[key] = val -- Keep non-string values as is
end
end
return cleanArgs
end
-- Helper function to check for affirmative values (yes, true, etc.)
function isAffirmed(val)
if not val then return false end
-- Simplified list, add more if needed for Chinese context, though 'yes'/'true' are common in params
local affirmedWords = ' add added affirm affirmed include included on true yes y '
return string.find(affirmedWords, ' ' .. string.lower(tostring(val)) .. ' ', 1, true) and true or false
end
-- Helper function to generate output string from items
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 -- Added newline before 'more' for better formatting
end
return mw.text.trim(output)
end
-- Helper function to clean wikitext for pattern matching
function cleanForPatternMatching(wikitext)
-- Remove wikilink brackets, keeping the link text (or display text if piped)
local cleaned = mw.ustring.gsub(wikitext, "%[%[([^%]|]-)%]%]", "%1") -- [[Link]] -> Link
cleaned = mw.ustring.gsub(cleaned, "%[%[.-%|(.-)%]%]", "%1") -- [[Article|Display]] -> Display
-- Remove any remaining pipes that might affect matching (e.g. from templates not fully substituted)
cleaned = mw.ustring.gsub(cleaned, "%|"," ")
return cleaned
end
-- Helper function to create a collapsible section
function makeCollapsed(outerText, innerText)
-- Using standard Chinese Wikipedia hidden templates if names differ, adjust as needed.
-- Assuming {{Hidden begin}} and {{Hidden end}} are standard.
return "{{Hidden begin | titlestyle = font-weight:normal | title = " .. outerText .. "}}" .. innerText .. "{{Hidden end}}"
end
-- Get recent additions for a specific subpage (archive month)
function getRecentAdditions(subpagePath, keepPatterns, skipPatterns, showWikitext, contentLang)
local title = mw.title.new(subpagePath)
if not title or not title.exists then
return {} -- Page doesn't exist or invalid title
end
local raw = title:getContent()
if not raw then
return {} -- No content
end
local converter = contentLang:getConverter()
-- Chinese DYK entries are typically list items starting with '*'
-- Each item is usually on its own line.
local itemPattern = '\n%*%s?.*' -- Match lines starting with '*'
local items = {}
for itemLine in mw.ustring.gmatch('\n' .. raw, itemPattern) do -- Prepend newline to match first item
local originalItem = mw.ustring.gsub(itemLine, '^\n%*%s*', '%* ') -- Normalize: ensure it starts with "* "
-- Apply word conversion for matching and for the final display item
local convertedItemForMatching = converter:convert(originalItem)
local textToSearch = cleanForPatternMatching(convertedItemForMatching)
local keep = false
local skip = false
-- Check keep patterns
if #keepPatterns == 0 then -- If no keepPatterns, keep all by default (original module implies this for empty patterns list but it's better to be explicit or error)
keep = true -- Or handle as an error: "Search pattern not set" is handled in main. If patterns is empty, this path shouldn't be hit.
else
for _, keepPatt in ipairs(keepPatterns) do
if mw.ustring.find(textToSearch, keepPatt, 1, false) then -- Plain string find
keep = true
break
end
end
end
-- Check skip patterns if we intend to keep it
if keep and #skipPatterns > 0 then
for _, skipPatt in ipairs(skipPatterns) do
if mw.ustring.find(textToSearch, skipPatt, 1, false) then -- Plain string find
skip = true
break
end
end
end
if keep and not skip then
local displayItem = converter:convert(originalItem) -- Convert the original item again for display to ensure consistency
-- Remove HTML comments from the display item
displayItem = mw.ustring.gsub(displayItem, "%<%!%-%-(.-)%-%-%>", "")
if showWikitext then
-- For 'showWikitext', we show the wikitext of the *converted* item
local itemWikitext = "<pre>" .. mw.text.nowiki(displayItem) .. "</pre>"
displayItem = makeCollapsed(displayItem, itemWikitext)
end
table.insert(items, mw.text.trim(displayItem))
end
end
return items
end
-- Get items from archives over a span of months
function getItems(maxMonths, patterns, skipPatterns, showWikitext)
local allItems = {}
local zhLang = mw.language.new('zh') -- For date formatting specifically for archive paths
local contentLang = mw.language.getContentLanguage() -- For -{}- conversion
local currentYear = tonumber(zhLang:formatDate('Y', 'now'))
local currentMonth = tonumber(zhLang:formatDate('n', 'now'))
for monthsAgo = 0, maxMonths - 1 do
local targetMonth = currentMonth - monthsAgo
local targetYear = currentYear
-- Adjust year and month if targetMonth goes into previous years
while targetMonth <= 0 do
targetMonth = targetMonth + 12
targetYear = targetYear - 1
end
-- Format: Wikipedia:新条目推荐/存档/YYYY年M月
local subpageName = targetYear .. '年' .. targetMonth .. '月'
local pagePath = 'Wikipedia:新条目推荐/存档/' .. subpageName
local monthlyItems = getRecentAdditions(pagePath, patterns, skipPatterns, showWikitext, contentLang)
for _, item in ipairs(monthlyItems) do
table.insert(allItems, item)
end
end
return allItems
end
-- Get patterns from arguments (e.g., 1, 2, 3 or not1, not2, not3)
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
table.insert(patterns, args[key])
else
break
end
i = i + 1
end
return patterns
end
local p = {}
p.main = function(frame)
local parent = frame:getParent()
local parentArgs = parent.args
local args = cleanupArgs(parentArgs)
-- Allow 'not' as an alias for 'not1' if 'not1' isn't set
if args['not'] and not args['not1'] then
args['not1'] = args['not']
end
local patterns = getPatterns(args)
if #patterns < 1 then
return frame:expandTemplate{ title = 'Error', args = { '未设置搜索样式(参数1、2等)。' } } -- Using {{Error}} template for better visibility
end
local skipPatterns = getPatterns(args, 'not')
local months = tonumber(args.months) or 6 -- Default to 6 months, 30 seemed a bit much for DYK
local showWikitext = isAffirmed(args.wikitext)
local allItems = getItems(months, patterns, skipPatterns, showWikitext)
if #allItems < 1 then
return args.header and '' or args.none or '没有找到符合条件的项目。' -- Localized "none" message
end
local maxItems = tonumber(args.max) or 6
local moreLinkText = args.more
if isAffirmed(args.more) or (type(args.more) == 'string' and args.more == '') then -- if 'more=yes' or 'more='
-- Default "more" link for Chinese Wikipedia
moreLinkText = "'''[[Wikipedia:新条目推荐|更多新条目推荐...]]'''"
elseif type(args.more) == 'string' and args.more ~= '' then
-- User provided custom text for 'more'
moreLinkText = args.more
else
moreLinkText = nil -- No 'more' link if not specified or affirmed
end
local nonRandom = isAffirmed(args.latest) -- 'latest' implies not random, show newest first from collected
local output = makeOutput(allItems, maxItems, moreLinkText, nonRandom)
if args.header then
output = args.header .. '\n' .. output
if args.footer then -- Only add footer if header is present and footer is specified
output = output .. '\n' .. args.footer
elseif args.header then -- Default footer if header is present but no custom footer
output = output .. '\n' .. '{{Box-footer}}'
end
end
-- Preprocess the output if it contains templates (e.g., from header, footer, or makeCollapsed)
-- Check for '{', which might indicate a template or other complex wikitext
if mw.ustring.find(output, '{', 1, true) then
return frame:preprocess(output)
else
return output
end
end
return p