Module:Organization
Documentation for this module may be created at Module:Organization/doc
local p = {}
-- Helper function to check if a value exists in the tabs_table
local function tabExists(tabName, tabTable)
for _, tab in ipairs(tabTable) do
if tab:gsub("^%s*(.-)%s*$", "%1") == tabName then
return true
end
end
return false
end
-- Helper function to split a string by a delimiter
local function splitString(input, delimiter)
local result = {}
for value in string.gmatch(input, "([^" .. delimiter .. "]+)") do
table.insert(result, value)
end
return result
end
-- Helper function to trim whitespace
local function trimString(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
-- Helper message extractor
local function getMessage(msg)
return mw.message.new(msg):plain()
end
function p.main(frame)
local page = tostring(mw.title.getCurrentTitle())
local args = frame.args
local template = frame:getParent().args
local display_title = template['Display title'] or ''
local sort_as = template['Sort as'] or display_title or page
local cover_image_caption = template['Cover image caption'] or ''
local orgtabs = template['Tabs'] or ''
local tabs_table = splitString(orgtabs, ",")
local has_photo = template['Photo'] or 'Johndoe.png'
local filename = frame:preprocess('{{PAGENAME:' .. has_photo .. '}}')
local photo = string.format('File:%s', filename )
local homepage = template['Homepage'] or ''
local category = '[[Category:Organizations]]'
-- Remove title
local notitle = args.notitle or ''
if notitle ~= '' then
local widget_notitle = frame:callParserFunction( '#widget', 'notitle' )
end
-- Get Areas
local areas_add = template['Areas'] or ''
local areas_pre = mw.smw.ask( '[[Category:Articles]][[Modification date::+]][[Area::+]][[Source::' .. page .. ']]|mainlabel=-|?Area|limit=500|searchlabel=|valuesep=;' )
-- Function to join and deduplicate areas
local function joinAndMakeUnique(existing, inputTable)
local seen = {}
local all_areas = {}
-- Start with the existing areas string
if existing ~= "" then
for _, area in ipairs(splitString(existing, ";")) do
area = trimString(area)
if area ~= "" and not seen[area] then
seen[area] = true
table.insert(all_areas, area)
end
end
end
-- Add areas from the input table
if inputTable ~= nil then
for _, v in ipairs(inputTable) do
if v.Area then
local area = trimString(v.Area)
if area ~= "" and not seen[area] then
seen[area] = true
table.insert(all_areas, area)
end
end
end
end
-- Return the unique, concatenated string
return table.concat(all_areas, ";")
end
-- Combine areas_add and areas_pre, making the result unique
areas_add = joinAndMakeUnique(areas_add, areas_pre)
-- Set properties
local page_properties = frame:callParserFunction(
'#set',
'Area=' .. areas_add,
'+sep=;',
'Cover image caption=' .. cover_image_caption,
'Has photo=' .. photo,
'Homepage=' .. homepage
)
if display_title ~= '' then
frame:preprocess('{{DISPLAYTITLE:' .. display_title .. '|noerror}}')
end
if sort_as ~= '' then
frame:preprocess('{{DEFAULTSORT:' .. sort_as .. '}}')
end
-- Assemble
local output = {}
local html = mw.html.create()
local properties = html:tag('div')
:addClass('d-none')
:wikitext(page_properties)
-- MAIN CONTENT
local maincontent = html:tag('div')
:addClass('card w-100 border-0 mb-3')
local mainbody = maincontent:tag('div')
:addClass('card-body px-0')
:css('flex', '0 0 auto')
local organization_bio = mainbody:tag('div')
:addClass('author-biography mb-3')
:wikitext(cover_image_caption)
-- TABS
if #orgtabs > 0 then
local orgtabs_list = mainbody:tag('ul')
:attr('id', 'author-tabs')
:addClass('nav nav-tabs pl-0')
-- Add tabs dynamically
if tabExists("Articles", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=observatory-articles-show',
'class=nav-link interface active',
'toggle=tab',
'href=#observatory-articles',
'linktext=Observatory Articles'
))
end
if tabExists("Full Bio", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=fullbio-show',
'class=nav-link interface',
'toggle=tab',
'href=#fullbio',
'linktext=Full Bio'
))
end
if tabExists("Authors", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=authors-show',
'class=nav-link interface',
'toggle=tab',
'href=#authors',
'linktext=Authors'
))
end
-- Check if there are guides related to the current page
local guides = mw.smw.ask('[[Category:Guides]][[Source::' .. page .. ']]')
if guides and #guides > 0 then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=paths-show',
'class=nav-link interface',
'toggle=tab',
'href=#paths',
'linktext=Guides'
))
end
if tabExists("Commentary", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=commentary-show',
'class=nav-link interface',
'toggle=tab',
'href=#commentary',
'linktext=Commentary'
))
end
if tabExists("Books and Research", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=books-research-show',
'class=nav-link interface',
'toggle=tab',
'href=#books-research',
'linktext=Books & Research'
))
end
if tabExists("Multimedia", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=multimedia-show',
'class=nav-link interface',
'toggle=tab',
'href=#multimedia',
'linktext=Multimedia'
))
end
if tabExists("Events", tabs_table) then
orgtabs_list:tag('li')
:addClass('nav-item')
:wikitext(frame:callParserFunction('#widget',
'a',
'id=events-show',
'class=nav-link interface',
'toggle=tab',
'href=#events',
'linktext=Events'
))
end
end
-- TAB PANES
local tab_panes = mainbody:tag('div')
:attr('id', 'author-tab-content')
:addClass('tab-content')
if tabExists("Articles", tabs_table) then
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container active')
:attr('id', 'observatory-articles')
local tab_heading = tab_pane:tag('div')
:addClass('h3 my-4')
:wikitext('Latest from this source')
local smw_query = frame:callParserFunction('#ask', {
'[[Category:Articles]][[Source::' .. page .. '||Secondary source::' .. page .. ']] OR ' ..
'[[Category:Work in progress]][[Secondary source::' .. page .. '||Source::' .. page .. ']]',
'format=plainlist',
'template=Article item',
'sort=Date published',
'order=desc',
'mainlabel=Article',
'?Subtitle',
'?Source',
'?Credit line',
'?Teaser',
'?Modification date',
'?Display date',
'?Area',
'?Is featured',
'?Is collaborative research',
'?Has map label',
'?Text author=Author',
'named args=yes',
'headers=hide',
'link=none',
'limit=200',
'valuesep=;'
}
)
local tab_result = tab_pane:tag('div')
:wikitext(smw_query)
end
if tabExists("Full Bio", tabs_table) then
local about = template['About']
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container py-4')
:attr('id', 'fullbio')
:newline()
:wikitext(about)
end
if tabExists("Authors", tabs_table) then
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container')
:attr('id', 'authors')
local tab_heading = tab_pane:tag('div')
:addClass('h3 my-4')
:wikitext('Associated Authors')
local smw_query = frame:callParserFunction('#ask', {
'[[Category:Authors]][[Source::' .. page .. ']]',
'format=plainlist',
'template=Source author box',
'named args=yes',
'mainlabel=page',
'?Has photo=image',
'?Biography=info',
'order=random',
'limit=100',
'searchlabel=',
'link=none'
}
)
local tab_result = tab_pane:tag('div')
:wikitext(smw_query)
end
-- GUIDES
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container py-4')
:attr('id', 'paths')
local smw_query = frame:callParserFunction('#ask', {
'[[Category:Guides]][[Source::' .. page .. ']]',
'mainlabel=Path',
'named args=yes',
'link=none',
'format=plainlist',
'template=Path record'
})
tab_heading = tab_pane:tag('div')
:addClass('h3 mb-4')
:wikitext('The Observatory Guides')
local tab_result = tab_pane:tag('div')
:wikitext(smw_query)
-- COMMENTARY
if tabExists("Commentary", tabs_table) then
local commentary = template['Commentary']
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container pt-4')
:attr('id', 'commentary')
:wikitext(commentary)
end
if tabExists("Books and Research", tabs_table) then
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container')
:attr('id', 'books-research')
local tab_heading = tab_pane:tag('div')
:addClass('h3 my-4')
:wikitext('Publications by this organization')
local books = template['Books and Research']
end
if tabExists("Multimedia", tabs_table) then
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container')
:attr('id', 'multimedia')
local tab_heading = tab_pane:tag('div')
:addClass('h3 my-4')
:wikitext('Videos by this organization')
local multimedia = template['Multimedia']
local tab_content = tab_pane:tag('div')
:wikitext('\n' .. multimedia)
end
if tabExists("Events", tabs_table) then
local tab_pane = tab_panes:tag('div')
:addClass('tab-pane container')
:attr('id', 'events')
local tab_heading = tab_pane:tag('div')
:addClass('h3 my-4')
:wikitext('Events with this organization')
local events = template['Events']
local tab_content = tab_pane:tag('div')
:wikitext('\n' .. events)
local display_calendar = template['Display calendar'] or ''
local calendar_id = template['Calendar ID'] or ''
if display_calendar == 'Yes' then
if calendar_id ~= '' then
frame:callParserFunction('#widget',
'id=' .. calendar_id,
'style=border: 0 !important;'
)
end
end
end
-- Initialize the sideblock
local sideblock = html:tag('div')
:attr('id', 'article-sources')
:css('flex', '0 0 280px')
:wikitext('[[' .. photo .. '|class=w-100 h-auto object-fit-contain|300px|link=' .. homepage .. ']]')
-- Create the area tabs container
local area_tabs = sideblock:tag('div')
:addClass('author-research-areas mt-3 d-none d-md-block')
-- Add tabs if `area_add` is defined
if areas_add and areas_add ~= "" then
local tabs = area_tabs:tag('ul')
:addClass('nav nav-tabs mt-3')
:attr('id', 'coverage-tabs')
local tab = tabs:tag('li')
:addClass('nav-item')
:attr('role', 'presentation')
local tab_label = tab:tag('div')
:addClass('nav-link interface border-0 w-100')
:wikitext('Coverage')
-- Check and process areas_add
if areas_add and areas_add ~= "" then
local tiles = area_tabs:tag('div')
:addClass('observatory-tile-deck')
local areas_table = splitString(areas_add, ";")
for _, area in ipairs(areas_table) do
local item = tiles:tag('div')
:addClass('tile d-flex align-items-center gap-3')
local item_label = item:tag('div')
:addClass('tile-caption w-100')
:wikitext('[[' .. area .. ']]')
end
end
end
local organization = tostring(maincontent) .. category .. tostring(sideblock)
return organization
end
return p
