Module:Area
From The Observatory
Documentation for this module may be created at Module:Area/doc
-- Module:Area (orchestrator)
-- Wires Query → IO → Render for area portal pages.
local data = require('Module:AreaData')
local q = require('Module:Area/Query')
local io = require('Module:Area/IO')
local r = require('Module:Area/Render')
local imageConfig = mw.loadData('Module:ImageConfig')
local p = {}
-- Main area portal renderer
function p.areas(frame)
local page = (mw and mw.title and mw.title.getCurrentTitle and mw.title.getCurrentTitle().baseText) or 'Animals'
local parentFrame = frame and frame.getParent and frame:getParent()
local template = (parentFrame and parentFrame.args) or (frame and frame.args) or {}
local html = mw.html.create()
local banner = template['Area banner background'] or ''
local bannerpath = io.resolvePhotoUrl(frame, banner, imageConfig.defaultCoverImage, nil)
local description = template['Area description'] or ''
local card_image = template['Area card image'] or imageConfig.defaultCoverImage
local featured = template['Area featured articles'] or ''
local featuredList = data.splitString(featured, ';')
-- Set SMW properties (pcall'd — SMW hiccup won't crash the page)
if mw.smw and mw.smw.set then
pcall(mw.smw.set, {
'Has description=' .. description,
'Has parent page=All Areas',
'Area card image=' .. card_image,
'Area banner background=' .. banner
})
end
-- Widgets (notitle, nopagemenupanel)
local notitle = io.getWidget(frame, 'notitle')
local nopagemenupanel = io.getWidget(frame, 'nopagemenupanel')
-- Query for conditional tabs (guides, news, feeds, events)
local guides = q.areaGuides(page) or {}
local news = q.areaNews(page) or {}
local feeds = q.areaFeeds(page) or {}
local events = q.areaEvents(page) or {}
local tabOpts = {
guides = #guides > 0,
news = #news > 0,
feeds = #feeds > 0,
events = #events > 0,
page = page,
}
html:node(r.areaTabs(tabOpts))
local tab_content = html:tag('div'):attr('id', 'area-tab-content'):addClass('tab-content')
if banner ~= '' then
local bEl = r.areaBanner(bannerpath)
if bEl then tab_content:node(bEl) end
end
tab_content:tag('h1'):addClass('mb-3'):wikitext(page)
local articles = q.areaArticles(page, 500)
local cards = {}
for _, rawArt in ipairs(articles or {}) do
local art = data.normalizeArticle(rawArt)
local isFeatured = data.hasValue(featuredList, art.Article)
if not isFeatured then
art._imagepath = io.resolvePhotoUrl(frame, art['Cover image'], card_image, '800')
local subtitle = art.Teaser or ''
local notes = art['Notes by the editor'] or subtitle
if subtitle ~= '' and subtitle ~= notes then
art._teaserHtml = string.format('<div class="interface mb-2">%s</div><div>%s</div>', subtitle, notes)
else
art._teaserHtml = string.format('<div>%s</div>', notes)
end
if art['Text author'] and art['Text author'] ~= '' then
art._authorsHtml = io.formredlinks(frame, 'Author', art['Text author'], 'By ')
end
if art.Source and art.Source ~= '' then
art._sourcesHtml = io.formredlinks(frame, 'Organization', art.Source, '')
end
if art['Display date'] and art['Display date'] ~= '' then
art._formattedDate = io.formatDate(frame, art['Display date'], 'F j, Y')
end
table.insert(cards, r.articleCard(art, false))
end
end
local wall = r.cardWall(cards)
local sectionDiv = tab_content:tag('div'):attr('id', 'observatory-articles'):addClass('tab-pane active border-0 p-0')
sectionDiv:node(wall)
-- Authors sidebar
local rawAuthors = q.areaAuthors(page, 50)
local authorCards = {}
for _, rawAuth in ipairs(rawAuthors or {}) do
local auth = {
title = rawAuth.title or '',
name = rawAuth.name or rawAuth.title or '',
_imagepath = io.resolvePhotoUrl(frame, rawAuth.image or 'File:Johndoe.png', 'Observatory_Logo_for_Writers_bg.png', nil)
}
table.insert(authorCards, r.authorCard(auth, false))
end
sectionDiv:node(r.authorSidebar(authorCards))
return tostring(html)
end
-- Classics portal renderer
function p.classics(frame)
local page = 'Classics'
local parentFrame = frame and frame.getParent and frame:getParent()
local template = (parentFrame and parentFrame.args) or (frame and frame.args) or {}
local html = mw.html.create()
local banner = template['Area banner background'] or ''
local bannerpath = io.resolvePhotoUrl(frame, banner, imageConfig.defaultCoverImage, nil)
local card_image = template['Area card image'] or imageConfig.defaultCoverImage
html:node(r.areaTabs({}))
local tab_content = html:tag('div'):attr('id', 'area-tab-content'):addClass('tab-content')
if banner ~= '' then
local bEl = r.areaBanner(bannerpath)
if bEl then tab_content:node(bEl) end
end
tab_content:tag('h1'):addClass('mb-3'):wikitext(page)
local articles = q.classicsArticles(500)
local cards = {}
for _, rawArt in ipairs(articles or {}) do
local art = data.normalizeArticle(rawArt)
art._imagepath = io.resolvePhotoUrl(frame, art['Cover image'], card_image, '800')
local subtitle = art.Teaser or ''
local notes = art['Notes by the editor'] or subtitle
if subtitle ~= '' and subtitle ~= notes then
art._teaserHtml = string.format('<div class="interface mb-2">%s</div><div>%s</div>', subtitle, notes)
else
art._teaserHtml = string.format('<div>%s</div>', notes)
end
if art['Text author'] and art['Text author'] ~= '' then
art._authorsHtml = io.formredlinks(frame, 'Author', art['Text author'], 'By ')
end
if art['Display date'] and art['Display date'] ~= '' then
art._formattedDate = io.formatDate(frame, art['Display date'], 'Y')
end
table.insert(cards, r.articleCard(art, true))
end
local wall = r.cardWall(cards)
local sectionDiv = tab_content:tag('div'):attr('id', 'observatory-articles'):addClass('tab-pane active border-0 p-0')
sectionDiv:node(wall)
return tostring(html)
end
p.main = p.areas
return p