Module:UnSignpost wrapper
Jump to navigation
Jump to search
local p = {}
local getArgs = require('Module:Arguments').getArgs
-- ==================================================
-- Utilities
-- ==================================================
--- Build a no-ping user link, replicating {{no ping|Username}}.
--- Uses the same mw.uri.fullUrl approach as Module:No ping.
local function noPing(username)
if not username or username == '' then
return ''
end
local url = tostring(mw.uri.fullUrl(mw.site.namespaces.User.name .. ':' .. username))
return '<span class="plainlinks">[' .. url .. ' ' .. username .. ']</span>'
end
--- Format a list of author names with proper comma/and joining.
--- Uses noPing to avoid triggering talk page notifications.
--- 1 author: "By Author1"
--- 2 authors: "By Author1 and Author2"
--- 3 authors: "By Author1, Author2 and Author3"
local function formatAuthors(authors)
if not authors or #authors == 0 then
return nil
end
local links = {}
for i, name in ipairs(authors) do
links[i] = noPing(name)
end
local n = #links
if n == 1 then
return 'By ' .. links[1]
elseif n == 2 then
return 'By ' .. links[1] .. ' and ' .. links[2]
else
return 'By ' .. table.concat(links, ', ', 1, n - 1) ..
' and ' .. links[n]
end
end
local function collectNumbered(args, prefix)
local t = {}
local i = 1
while args[prefix .. i] do
t[#t + 1] = args[prefix .. i]
i = i + 1
end
return t
end
-- ==================================================
-- Data Collection
-- ==================================================
--- Collect all authors for a given story index.
--- Primary author: "authorN", additional: "authorN-2", "authorN-3", ...
local function collectAuthors(args, storyIndex)
local authors = {}
local primary = args['author' .. storyIndex]
if not primary or primary == '' then
return authors
end
authors[1] = primary
local j = 2
while true do
local a = args['author' .. storyIndex .. '-' .. j]
if not a or a == '' then break end
authors[#authors + 1] = a
j = j + 1
end
return authors
end
local function collectStories(args)
local t = {}
local i = 1
while args['headline' .. i] do
t[#t + 1] = {
headline = args['headline' .. i],
authors = collectAuthors(args, i),
story = args['story' .. i]
}
i = i + 1
end
return t
end
local function collectQA(args)
local t = {}
local i = 1
while args['q' .. i] do
t[#t + 1] = {
q = args['q' .. i],
u = args['u' .. i],
a = args['a' .. i]
}
i = i + 1
end
return t
end
local function collectLogs(args)
local t = {}
for i = 1, 5 do
t[i] = args['log' .. i]
end
return t
end
local function collectVFH(args)
if not args.vfh1 then
return nil
end
return {
top = {
{args.vfh1, args.for1, args.against1},
{args.vfh2, args.for2, args.against2},
{args.vfh3, args.for3, args.against3}
},
highlight = {args.vfh4, args.for4, args.against4}
}
end
-- ==================================================
-- Renderers
-- ==================================================
local function renderStories(frame, parent, stories)
for _, s in ipairs(stories) do
parent:tag('div')
:addClass('unsignpost-headline')
:wikitext(s.headline)
local byline = formatAuthors(s.authors)
if byline then
parent:tag('div')
:addClass('unsignpost-author')
:wikitext(byline)
end
parent:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. (s.story or '') .. '\n')
end
end
local function renderBiopic(parent, args)
if not args.biopic then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-biopic')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('Biopic')
if args['biopic-about'] then
section:tag('div')
:addClass('unsignpost-author')
:wikitext('Who is ' .. args['biopic-about'] .. '?')
end
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. args.biopic .. '\n')
end
local function renderQA(frame, parent, args)
local qa = collectQA(args)
if #qa == 0 then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-ask')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext(args.ask or '[[Forum:Ask Turb0|Ask Turb0]]')
local story = section:tag('div')
:addClass('unsignpost-story')
local ul = story:tag('ul')
for i, item in ipairs(qa) do
ul:tag('li')
:wikitext(item.q .. ' — ' .. noPing(item.u))
ul:tag('li')
:css('margin-left', '1rem')
:tag('b')
:wikitext(item.a or '')
if i < #qa then
ul:wikitext('\n'):tag('hr')
ul:wikitext('\n')
end
end
end
local function renderLogs(parent, args)
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-logs')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('From The Logs')
local story = section:tag('div')
:addClass('unsignpost-story')
local logs = collectLogs(args)
local defaults = {
'[[File:Tumbleweed01.gif|120px]]',
'[[File:Tumbleweed01.gif|120px]]',
'[[File:tumbleweed01.gif|120px]]',
'[[File:tumbleweed01.gif|120px]]',
'[[File:tumbleweed01.gif|120px]]'
}
story:wikitext('\n')
for i = 1, 5 do
story:wikitext('* ' .. (logs[i] or defaults[i]) .. '\n')
if i < 5 then
story:wikitext('<hr>\n')
end
end
story:wikitext('\n')
end
local function renderDeemox(parent, args)
if not args.deemox then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-deemox')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext("Deemox's Gossip Corner")
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. args.deemox .. '\n')
end
local function renderVFH(parent, args)
local vfh = collectVFH(args)
if not vfh then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-vfh')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('Top VFH Competitors')
local story = section:tag('div')
:addClass('unsignpost-story')
story:wikitext('\n')
for _, item in ipairs(vfh.top) do
if item[1] then
story:wikitext('* [[' .. item[1] .. ']] (' ..
(item[2] or '') .. '/' .. (item[3] or '') .. ')\n')
end
end
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('VFH Highlight Of The Week')
local highlight = section:tag('div')
:addClass('unsignpost-story')
highlight:wikitext('\n')
if vfh.highlight[1] then
highlight:wikitext('* [[' .. vfh.highlight[1] .. ']] (' ..
(vfh.highlight[2] or '') .. '/' ..
(vfh.highlight[3] or '') .. ')\n')
end
highlight:wikitext('\n')
end
local function renderForums(parent, args)
local forums = collectNumbered(args, 'forum')
if #forums == 0 then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-forum')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('From The Forums')
local story = section:tag('div')
:addClass('unsignpost-story')
story:wikitext('\n')
for _, f in ipairs(forums) do
story:wikitext('* [[' .. f .. ']]\n')
end
story:wikitext('\n')
end
local function renderSignpostNews(parent, args)
if not args.signpostnews then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-meta')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('UnSignpost News')
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. args.signpostnews .. '\n')
end
local function renderQuote(frame, parent, args)
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-quotes')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('Quote(s) of the Week')
local quoteText = args.quote
if not quoteText or quoteText == '' then
quoteText = args.ircquote
if not quoteText or quoteText == '' then
-- Default: {{Q|{{WildeQuotes}}|[[Oscar Wilde]]}}
local wildeQuote = frame:expandTemplate{
title = 'WildeQuotes'
}
quoteText = frame:expandTemplate{
title = 'Q',
args = { wildeQuote, '[[Oscar Wilde]]' }
}
end
end
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. quoteText .. '\n')
end
local function renderThing(parent, args)
if not args.thing then return end
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-thing')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext(args.thing .. ' of the week #' .. (args.thingnumber or '1'))
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. (args.thing2 or 'Because this is here now') .. '\n')
end
local function renderFootnotes(frame, parent)
local section = parent:tag('div')
:addClass('unsignpost-section unsignpost-footnotes')
section:tag('div')
:addClass('unsignpost-headline')
:wikitext('Notes')
local refs = frame:expandTemplate{
title = 'reflist',
args = { group = 'note' }
}
section:tag('div')
:addClass('unsignpost-story')
:wikitext('\n' .. (refs or '') .. '\n')
end
-- ==================================================
-- Main
-- ==================================================
function p.main(frame)
local args = getArgs(frame)
local stories = collectStories(args)
local styles = frame:extensionTag(
'templatestyles',
'',
{ src = 'Template:UnSignpost wrapper/styles.css' }
)
-- Use expandTemplate for the slogan
local slogan = frame:expandTemplate{
title = 'Uncyclopedia:UnSignpost/slogan',
args = { '1' }
}
-- Default for funny param matches template: {{Uncyclopedia:UnSignpost/slogan}}
local funny = args.funny
if not funny or funny == '' then
funny = frame:expandTemplate{
title = 'Uncyclopedia:UnSignpost/slogan'
}
end
local root = mw.html.create('div')
:addClass('unsignpost-container')
root:tag('div')
:addClass('unsignpost-banner')
:wikitext('[[Uncyclopedia:UnSignpost|The UnSignpost]]')
root:tag('div')
:addClass('unsignpost-slogan')
:wikitext(slogan)
local body = root:tag('div')
:addClass('unsignpost-body NavFrame')
body:tag('div')
:addClass('unsignpost-head NavHead')
:wikitext((args.date or 'January 1, 1970') ..
' • Issue #' .. (args.number or '') ..
' • ' .. funny ..
'<hr>' ..
'[[Uncyclopedia:UnSignpost/current|Current issue]] • ' ..
'[[Uncyclopedia:UnSignpost/Archives|Archives]] • ' ..
'[[Uncyclopedia:UnSignpost/Press Room|Press Room]]')
local content = body:tag('div')
:addClass('unsignpost-content NavContent')
:css('scrollbar-width', 'thin')
local storiesSection = content:tag('div')
:addClass('unsignpost-section unsignpost-stories')
renderStories(frame, storiesSection, stories)
renderBiopic(content, args)
renderQA(frame, content, args)
renderLogs(content, args)
renderDeemox(content, args)
renderVFH(content, args)
renderForums(content, args)
renderSignpostNews(content, args)
renderQuote(frame, content, args)
renderThing(content, args)
renderFootnotes(frame, content)
return styles .. tostring(root)
end
return p