Module:DailyFeatured: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 7: | Line 7: | ||
for line in mw.text.gsplit(content or "", "\n", true) do | for line in mw.text.gsplit(content or "", "\n", true) do | ||
line = mw.text.trim(line) | line = mw.text.trim(line) | ||
line = line:gsub("<!%-%-.-%-%->", "") | line = line:gsub("<!%-%-.-%-%->", "") | ||
line = mw.text.trim(line) | line = mw.text.trim(line) | ||
| Line 57: | Line 56: | ||
return s | return s | ||
end | |||
local function isIgnoredLine(raw, cleaned) | |||
raw = raw or "" | |||
cleaned = cleaned or "" | |||
if cleaned == "" then | |||
return true | |||
end | |||
if raw:match("^%s*{{") or raw:match("^%s*|") or raw:match("^%s*}}") then | |||
return true | |||
end | |||
if cleaned:match("^__%u+__$") then | |||
return true | |||
end | |||
if cleaned:match("^%[%[[Cc]ategory:") then | |||
return true | |||
end | |||
return false | |||
end | end | ||
| Line 72: | Line 94: | ||
end | end | ||
if | if not isIgnoredLine(raw, cleaned) then | ||
return shorten(cleaned) | return shorten(cleaned) | ||
end | end | ||
| Line 80: | Line 100: | ||
for line in mw.text.gsplit(wikitext, "\n", true) do | for line in mw.text.gsplit(wikitext, "\n", true) do | ||
local | local raw = mw.text.trim(line) | ||
if | if raw:match("^==+%s*[^=].-==+%s*$") then | ||
cleaned = | local cleaned = raw:gsub("^=+%s*", ""):gsub("%s*=+$", "") | ||
cleaned = | cleaned = cleanWikitext(cleaned) | ||
if cleaned ~= "" then | if cleaned ~= "" then | ||
| Line 93: | Line 113: | ||
for line in mw.text.gsplit(wikitext, "\n", true) do | for line in mw.text.gsplit(wikitext, "\n", true) do | ||
local raw = line | |||
local cleaned = cleanWikitext(line) | local cleaned = cleanWikitext(line) | ||
if | if not isIgnoredLine(raw, cleaned) then | ||
return shorten(cleaned) | return shorten(cleaned) | ||
end | end | ||
| Line 105: | Line 124: | ||
end | end | ||
function | local function normalizeFileName(value) | ||
if not value or value == "" then | |||
return nil | |||
end | |||
value = mw.text.trim(value) | |||
value = value:gsub("<!%-%-.-%-%->", "") | |||
value = mw.text.trim(value) | |||
if value == "" then | |||
return nil | |||
end | |||
local linkedFile = value:match("%[%[%s*[Ff]ile%s*:%s*([^%]|%]]+)") | |||
or value:match("%[%[%s*[Ii]mage%s*:%s*([^%]|%]]+)") | |||
if linkedFile then | |||
value = linkedFile | |||
else | |||
value = value:gsub("^%s*[Ff]ile%s*:%s*", "") | |||
value = value:gsub("^%s*[Ii]mage%s*:%s*", "") | |||
value = value:gsub("|.*$", "") | |||
value = value:gsub("%]%].*$", "") | |||
end | |||
value = mw.text.trim(value) | |||
if value == "" then | |||
return nil | |||
end | |||
if value:lower() == "none" or value:lower() == "no" then | |||
return nil | |||
end | |||
return "File:" .. value | |||
end | |||
local function extractImageFromContent(wikitext) | |||
if not wikitext or wikitext == "" then | |||
return nil | |||
end | |||
for line in mw.text.gsplit(wikitext, "\n", true) do | |||
local value = line:match("^%s*|%s*image%d*%s*=%s*(.-)%s*$") | |||
if value then | |||
local file = normalizeFileName(value) | |||
if file then | |||
return file | |||
end | |||
end | |||
end | |||
local fallback = wikitext:match("%[%[%s*[Ff]ile%s*:%s*([^%]|%]]+)") | |||
or wikitext:match("%[%[%s*[Ii]mage%s*:%s*([^%]|%]]+)") | |||
if fallback then | |||
return normalizeFileName(fallback) | |||
end | |||
return nil | |||
end | |||
local function getFeaturedData() | |||
local pages = getPool() | local pages = getPool() | ||
if #pages == 0 then | if #pages == 0 then | ||
return "No featured pages defined." | return nil, "No featured pages defined." | ||
end | end | ||
| Line 115: | Line 199: | ||
local index = ((day - 1) % #pages) + 1 | local index = ((day - 1) % #pages) + 1 | ||
local title = pages[index] | local title = pages[index] | ||
local page = mw.title.new(title) | local page = mw.title.new(title) | ||
local headline = "" | local headline = "" | ||
local image = nil | |||
if page and page.exists then | if page and page.exists then | ||
local content = page:getContent() or "" | local content = page:getContent() or "" | ||
headline = extractHeadlineFromContent(content) | headline = extractHeadlineFromContent(content) | ||
image = extractImageFromContent(content) | |||
end | end | ||
if headline == "" then | if headline == "" then | ||
headline = "Featured page for " .. os.date("%d %B %Y") .. "." | headline = "Featured page for " .. os.date("%d %B %Y") .. "." | ||
end | |||
return { | |||
title = title, | |||
page = page, | |||
headline = headline, | |||
image = image | |||
} | |||
end | |||
function p.main(frame) | |||
local args = frame and frame.args or {} | |||
local data, err = getFeaturedData() | |||
if not data then | |||
return err | |||
end | |||
if args.titleonly == "1" then | |||
return data.title | |||
end | |||
if args.imageonly == "1" then | |||
return data.image or "" | |||
end | end | ||
return string.format( | return string.format( | ||
"'''[[%s]]'''<div style=\"margin-top:0.35em;\"><small>%s</small></div>", | "'''[[%s]]'''<div style=\"margin-top:0.35em;\"><small>%s</small></div>", | ||
title, | data.title, | ||
headline | mw.text.nowiki(data.headline) | ||
) | |||
end | |||
function p.box() | |||
local data, err = getFeaturedData() | |||
if not data then | |||
return '<div class="featured-box"><div class="featured-box-title">Featured page</div><div class="featured-box-body">' .. err .. '</div></div>' | |||
end | |||
local page = mw.title.new(data.title) | |||
local pool = mw.title.new("Template:Featured pool") | |||
local current = mw.title.getCurrentTitle() | |||
local pageUrl = page and page:fullUrl() or "" | |||
local editUrl = page and page:fullUrl("action=edit") or "" | |||
local poolUrl = pool and pool:fullUrl() or "" | |||
local purgeUrl = current and current:fullUrl("action=purge") or "" | |||
local imageBlock = "" | |||
if data.image then | |||
imageBlock = string.format( | |||
'<div class="featured-box-image">[[%s|frameless|160x160px|link=%s|%s]]</div>', | |||
data.image, | |||
data.title, | |||
data.title | |||
) | |||
end | |||
return string.format( | |||
'<div class="featured-box">' .. | |||
'<div class="featured-box-title">Featured page</div>' .. | |||
'<div class="featured-box-body">' .. | |||
'%s' .. | |||
'<div class="featured-box-text">' .. | |||
'<div class="featured-box-name">\'\'\'[[%s]]\'\'\'</div>' .. | |||
'<div class="featured-box-headline"><small>%s</small></div>' .. | |||
'<div class="featured-box-actions">[%s Open page] [%s Edit page] [%s Featured pool] [%s Refresh]</div>' .. | |||
'</div>' .. | |||
'</div>' .. | |||
'</div>', | |||
imageBlock, | |||
data.title, | |||
mw.text.nowiki(data.headline), | |||
pageUrl, | |||
editUrl, | |||
poolUrl, | |||
purgeUrl | |||
) | ) | ||
end | end | ||
return p | return p | ||
Revision as of 09:53, 14 May 2026
local p = {}
local function getPool()
local content = mw.getCurrentFrame():expandTemplate{ title = "Featured pool" }
local pages = {}
for line in mw.text.gsplit(content or "", "\n", true) do
line = mw.text.trim(line)
line = line:gsub("<!%-%-.-%-%->", "")
line = mw.text.trim(line)
if line ~= "" then
line = line:gsub("^%*%s*", "")
line = mw.text.trim(line)
local linkedTitle = line:match("^%[%[([^%]|]+)|?.-%]%]$")
if linkedTitle then
line = linkedTitle
end
if line ~= "" then
table.insert(pages, line)
end
end
end
return pages
end
local function cleanWikitext(s)
if not s or s == "" then
return ""
end
s = s:gsub("<!%-%-.-%-%->", "")
s = s:gsub("<ref[^>/]-/>", "")
s = s:gsub("<ref.->.-</ref>", "")
s = s:gsub("<ref.->", "")
s = s:gsub("%[%[File:.-%]%]", "")
s = s:gsub("%[%[Image:.-%]%]", "")
s = s:gsub("%{%b{}%}", "")
s = s:gsub("'''", "")
s = s:gsub("''", "")
s = s:gsub("%[%[([^%]|]+)|([^%]]+)%]%]", "%2")
s = s:gsub("%[%[([^%]]+)%]%]", "%1")
s = s:gsub("\r", "")
s = s:gsub("[ \t]+", " ")
return mw.text.trim(s)
end
local function shorten(s)
if mw.ustring.len(s) > 200 then
return mw.ustring.sub(s, 1, 197) .. "…"
end
return s
end
local function isIgnoredLine(raw, cleaned)
raw = raw or ""
cleaned = cleaned or ""
if cleaned == "" then
return true
end
if raw:match("^%s*{{") or raw:match("^%s*|") or raw:match("^%s*}}") then
return true
end
if cleaned:match("^__%u+__$") then
return true
end
if cleaned:match("^%[%[[Cc]ategory:") then
return true
end
return false
end
local function extractHeadlineFromContent(wikitext)
if not wikitext or wikitext == "" then
return ""
end
for line in mw.text.gsplit(wikitext, "\n", true) do
local raw = line
local cleaned = cleanWikitext(line)
if raw:match("^==+%s*[^=].-==+%s*$") then
break
end
if not isIgnoredLine(raw, cleaned) then
return shorten(cleaned)
end
end
for line in mw.text.gsplit(wikitext, "\n", true) do
local raw = mw.text.trim(line)
if raw:match("^==+%s*[^=].-==+%s*$") then
local cleaned = raw:gsub("^=+%s*", ""):gsub("%s*=+$", "")
cleaned = cleanWikitext(cleaned)
if cleaned ~= "" then
return shorten(cleaned)
end
end
end
for line in mw.text.gsplit(wikitext, "\n", true) do
local raw = line
local cleaned = cleanWikitext(line)
if not isIgnoredLine(raw, cleaned) then
return shorten(cleaned)
end
end
return ""
end
local function normalizeFileName(value)
if not value or value == "" then
return nil
end
value = mw.text.trim(value)
value = value:gsub("<!%-%-.-%-%->", "")
value = mw.text.trim(value)
if value == "" then
return nil
end
local linkedFile = value:match("%[%[%s*[Ff]ile%s*:%s*([^%]|%]]+)")
or value:match("%[%[%s*[Ii]mage%s*:%s*([^%]|%]]+)")
if linkedFile then
value = linkedFile
else
value = value:gsub("^%s*[Ff]ile%s*:%s*", "")
value = value:gsub("^%s*[Ii]mage%s*:%s*", "")
value = value:gsub("|.*$", "")
value = value:gsub("%]%].*$", "")
end
value = mw.text.trim(value)
if value == "" then
return nil
end
if value:lower() == "none" or value:lower() == "no" then
return nil
end
return "File:" .. value
end
local function extractImageFromContent(wikitext)
if not wikitext or wikitext == "" then
return nil
end
for line in mw.text.gsplit(wikitext, "\n", true) do
local value = line:match("^%s*|%s*image%d*%s*=%s*(.-)%s*$")
if value then
local file = normalizeFileName(value)
if file then
return file
end
end
end
local fallback = wikitext:match("%[%[%s*[Ff]ile%s*:%s*([^%]|%]]+)")
or wikitext:match("%[%[%s*[Ii]mage%s*:%s*([^%]|%]]+)")
if fallback then
return normalizeFileName(fallback)
end
return nil
end
local function getFeaturedData()
local pages = getPool()
if #pages == 0 then
return nil, "No featured pages defined."
end
local day = tonumber(os.date("%j")) or 1
local index = ((day - 1) % #pages) + 1
local title = pages[index]
local page = mw.title.new(title)
local headline = ""
local image = nil
if page and page.exists then
local content = page:getContent() or ""
headline = extractHeadlineFromContent(content)
image = extractImageFromContent(content)
end
if headline == "" then
headline = "Featured page for " .. os.date("%d %B %Y") .. "."
end
return {
title = title,
page = page,
headline = headline,
image = image
}
end
function p.main(frame)
local args = frame and frame.args or {}
local data, err = getFeaturedData()
if not data then
return err
end
if args.titleonly == "1" then
return data.title
end
if args.imageonly == "1" then
return data.image or ""
end
return string.format(
"'''[[%s]]'''<div style=\"margin-top:0.35em;\"><small>%s</small></div>",
data.title,
mw.text.nowiki(data.headline)
)
end
function p.box()
local data, err = getFeaturedData()
if not data then
return '<div class="featured-box"><div class="featured-box-title">Featured page</div><div class="featured-box-body">' .. err .. '</div></div>'
end
local page = mw.title.new(data.title)
local pool = mw.title.new("Template:Featured pool")
local current = mw.title.getCurrentTitle()
local pageUrl = page and page:fullUrl() or ""
local editUrl = page and page:fullUrl("action=edit") or ""
local poolUrl = pool and pool:fullUrl() or ""
local purgeUrl = current and current:fullUrl("action=purge") or ""
local imageBlock = ""
if data.image then
imageBlock = string.format(
'<div class="featured-box-image">[[%s|frameless|160x160px|link=%s|%s]]</div>',
data.image,
data.title,
data.title
)
end
return string.format(
'<div class="featured-box">' ..
'<div class="featured-box-title">Featured page</div>' ..
'<div class="featured-box-body">' ..
'%s' ..
'<div class="featured-box-text">' ..
'<div class="featured-box-name">\'\'\'[[%s]]\'\'\'</div>' ..
'<div class="featured-box-headline"><small>%s</small></div>' ..
'<div class="featured-box-actions">[%s Open page] [%s Edit page] [%s Featured pool] [%s Refresh]</div>' ..
'</div>' ..
'</div>' ..
'</div>',
imageBlock,
data.title,
mw.text.nowiki(data.headline),
pageUrl,
editUrl,
poolUrl,
purgeUrl
)
end
return p