Jump to content

Module:DailyFeatured: Difference between revisions

From the Vrienden Universe, a fictional wiki
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 cleaned ~= ""
if not isIgnoredLine(raw, cleaned) then
and not cleaned:match("^__%u+__$")
and not cleaned:match("^%[%[[Cc]ategory:") 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 cleaned = cleanWikitext(line)
local raw = mw.text.trim(line)


if cleaned:match("^==+%s*[^=].-==+%s*$") then
if raw:match("^==+%s*[^=].-==+%s*$") then
cleaned = cleaned:gsub("^=+%s*", ""):gsub("%s*=+$", "")
local cleaned = raw:gsub("^=+%s*", ""):gsub("%s*=+$", "")
cleaned = mw.text.trim(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 cleaned ~= ""
if not isIgnoredLine(raw, cleaned) then
and not cleaned:match("^__%u+__$")
and not cleaned:match("^%[%[[Cc]ategory:") then
return shorten(cleaned)
return shorten(cleaned)
end
end
Line 105: Line 124:
end
end


function p.main(frame)
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 args = (frame and frame.args) or {}
if args.titleonly == "1" then
return title
end


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