Module:RelatedNews
From TwogPedia
Documentation for this module may be created at Module:RelatedNews/doc
local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo
local p = {}
local function sanitize(input)
if not input then return '' end
return mw.ustring.gsub(input, '"', '""')
end
local function splitCsv(str)
if not str then return {} end
local parts = {}
for word in mw.text.gsplit(str, ',') do
table.insert(parts, mw.text.trim(word))
end
return parts
end
local function getContentSnippet(content)
local words = mw.text.split(content or '', ' ')
return table.concat(words, ' ', 1, math.min(20, #words)) .. (#words > 20 and '...' or '')
end
local function formatDate(dateStr)
local y, m, d = dateStr:match("(%d+)%-(%d+)%-(%d+)")
local ok, time = pcall(os.time, {year = y, month = m, day = d})
return ok and os.date("%b %d, %Y", time) or 'Unknown'
end
local function getRelatedNewsBy(tagsOrCats, field, exclude, limit)
local terms = splitCsv(tagsOrCats)
if #terms == 0 then return {} end
local where = {}
if exclude then
for _, name in ipairs(exclude) do
table.insert(where, '_pageName != "' .. sanitize(name) .. '"')
end
end
local orClause = {}
for _, val in ipairs(terms) do
table.insert(orClause, field .. ' HOLDS "' .. sanitize(val) .. '"')
end
table.insert(where, '(' .. table.concat(orClause, ' OR ') .. ')')
local args = {
where = table.concat(where, ' AND '),
orderBy = 'date DESC',
limit = limit or 5
}
return cargo.query('News', '_pageName, date, tags, image, category, content', args)
end
local function renderArticle(result)
local link = result._pageName
local image = result.image or 'News placeholder.png'
local category = mw.text.split(result.category or 'Uncategorized', ',')[1]
local categoryClassMap = {
['News'] = 'news-category-news',
['Transfer Market'] = 'news-category-transfer',
['Drama'] = 'news-category-drama',
['Business'] = 'news-category-business',
['Sponsorships'] = 'news-category-sponsorships'
}
local categoryClass = categoryClassMap[category] or 'default-category-class'
local wrapper = mw.html.create('div'):addClass('related__article')
wrapper:tag('div'):addClass('news-image-container')
:wikitext('[[File:' .. image .. '|link=' .. link .. '|800px|class=news-image|alt=News Image]]')
wrapper:tag('div'):addClass('news-title-twogpedia'):wikitext(link)
wrapper:tag('p'):addClass('news-content'):wikitext(getContentSnippet(result.content))
local meta = mw.html.create('div'):addClass('news-meta-container')
meta:tag('p'):addClass('news-meta news-category-meta ' .. categoryClass):wikitext(category)
meta:tag('p'):addClass('news-meta news-date'):wikitext(formatDate(result.date))
wrapper:node(meta)
return wrapper
end
function p.main(frame)
local args = getArgs(frame)
local currentPage = mw.title.getCurrentTitle().text
local tagNews = getRelatedNewsBy(args.tags, 'tags', {currentPage}, 5)
local newsItemContainer = mw.html.create('div'):addClass('related__news')
for _, result in ipairs(tagNews) do
newsItemContainer:node(renderArticle(result))
end
if #tagNews < 5 then
local excludeList = {}
for _, r in ipairs(tagNews) do table.insert(excludeList, r._pageName) end
table.insert(excludeList, currentPage)
local catNews = getRelatedNewsBy(args.categories, 'category', excludeList, 5 - #tagNews)
for _, result in ipairs(catNews) do
newsItemContainer:node(renderArticle(result))
end
end
local container = mw.html.create('div'):addClass('related__news__container')
local titleRow = mw.html.create('div')
:addClass('related__news__title-container')
:attr('style', 'display: flex; align-items: center;')
titleRow:tag('h3'):addClass('news-icon')
:wikitext('[[File:News-icon.png|30px|alt=Related News Icon]] Related news')
titleRow:tag('div'):addClass('related__news__view-all'):attr('id', 'view-all-button'):wikitext('View All')
container:node(titleRow):node(newsItemContainer)
return tostring(container)
end
return p
No categories