Module:PersonRelatedNews

From TwogPedia

Documentation for this module may be created at Module:PersonRelatedNews/doc

local cargo = mw.ext.cargo
local p = {}

function p.main(frame)
    local newsItemContainer = mw.html.create('div'):addClass('related__news')

    local title = mw.title.getCurrentTitle().fullText
    local newsTitle = "Related news"
    -- if title:match("^Companies/") then
    --     newsTitle = "Team News"
    -- end

    local iconHtml = '[[File:News-icon.png|30px|alt=' .. newsTitle .. ' Icon]]'
    local iconElement = mw.html.create('h3'):addClass('news-icon'):wikitext(iconHtml .. ' ' .. newsTitle)

    local titleContainer = mw.html.create('div'):addClass('related__news__title-container'):attr('style', 'display: flex; align-items: center;')
    titleContainer:node(iconElement)

    local viewAllElement = mw.html.create('div'):addClass('related__news__view-all'):attr('id', 'view-all-button'):wikitext('View All')
    titleContainer:node(viewAllElement)

    local container = mw.html.create('div'):addClass('related__news__container'):node(titleContainer):node(newsItemContainer)

    local relatedNews = getRelatedNews(4, title)

    if #relatedNews > 0 then
        for i = 1, #relatedNews do
            addArticleToContainer(relatedNews[i], newsItemContainer)
        end
    end

    return container
end

function addArticleToContainer(result, container)
    local image = result.image or 'News placeholder.png'
    local link = result._pageName
    local category = result.category and mw.text.split(result.category, ',')[1] or 'Uncategorized'

    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 date = result.date and formatDate(result.date) or 'Unknown date'
    
    local title = mw.html.create('div'):addClass('news-title-twogpedia'):wikitext(mw.ext.displaytitle.get(result._pageName))

    local metaContainer = mw.html.create('div'):addClass('news-meta-container')
    local categoryElement = mw.html.create('p'):addClass('news-meta news-category-meta ' .. categoryClass):wikitext(category)
    local dateElement = mw.html.create('p'):addClass('news-meta news-date'):wikitext(date)
    
    metaContainer:node(categoryElement):node(dateElement)

    local contentSnippet = getContentSnippet(result.content)
    local contentElement = mw.html.create('p'):addClass('news-content'):wikitext(contentSnippet)

    local imageHtml = '[[File:' .. image .. '|link=' .. link .. '|800px|class=news-image|alt=News Image]]'
    
    local imageContainer = mw.html.create('div'):addClass('news-image-container'):wikitext(imageHtml)
    
    local newsItem = mw.html.create('div')
        :addClass('related__article')
        :node(imageContainer)
        :node(title)
        :node(contentElement)
        :node(metaContainer)

    container:node(newsItem)
end

function getContentSnippet(content)
    local words = mw.text.split(content, ' ')
    local snippet = table.concat(words, ' ', 1, math.min(20, #words))
    return snippet .. ( #words > 20 and '...' or '' ) 
end

function formatDate(dateStr)
    local year, month, day = dateStr:match("(%d+)%-(%d+)%-(%d+)")
    local time = os.time({year = year, month = month, day = day})
    return os.date("%b %d, %Y", time)
end

function getRelatedNews(limit, title)
    local tables = 'News'
    local fields = '_pageName, date, tags, image, category, content'

    local words = mw.text.split(title, ' ')
    local conditions = {}

    for _, word in ipairs(words) do
        if #word > 2 then 
            table.insert(conditions, '_pageName LIKE "%' .. word .. '%"')
        end
    end

    local whereClause = table.concat(conditions, ' OR ')

    local cargoArgs = {
        where = whereClause,
        orderBy = 'date DESC',
        limit = limit
    }

    local results = cargo.query(tables, fields, cargoArgs)
    return results or {}
end

return p