More actions
Documentation for this module may be created at Module:InfoboxNeue/doc
local p = {}
--- Helper function to restore underscore from space
--- so that it does not screw up the external link wikitext syntax
--- For some reason SMW property converts underscore into space
--- mw.uri.encode can't be used on full URL
local function restoreUnderscore( s )
return s:gsub( ' ', '%%5F' )
end
--- Put table values into a comma-separated list
--- @param table t
--- @return string
function p.tableToCommaList( t )
if type( t ) == 'table' then
return table.concat( t, ', ' )
else
return t
end
end
--- Format text to show comparison as desc text if two strings are different
--- @param string s1 base
--- @param string s2 comparsion
--- @return string html
function p.showDescIfDiff( s1, s2 )
if s1 == nil or s2 == nil or s1 == s2 then return s1 end
return string.format( '%s <span class="infobox__desc">(%s)</span>', s1, s2 )
end
--- Shortcut to return the HTML of the infobox message component as string
--- @param table data {title, desc)
--- @return string html
function p.renderMessage( data )
return p.renderSection( { content = p.renderItem( { data = data.title, desc = data.desc } ) } )
end
--- Return the HTML of the infobox image component as string
--- @param string filename
--- @return string html
function p.renderImage( filename )
if filename == nil or filename == '' then return '' end
local html = mw.html.create( 'div' )
:addClass( 'infobox__image' )
:wikitext( '[[File:' .. filename .. '|400px]]' )
return tostring( html );
end
--- Return the HTML of the infobox indicator component as string
--- @param table data {data, desc, class)
--- @return string html
function p.renderIndicator( data )
if data == nil or data[ 'data' ] == nil or data[ 'data' ] == '' then return '' end
local html = mw.html.create( 'div' ):addClass( 'infobox__indicator' )
html:wikitext(
p.renderItem(
{
[ 'data' ] = data[ 'data' ],
[ 'desc' ] = data[ 'desc' ] or nil,
row = true,
spacebetween = true
}
)
)
if data[ 'class' ] then html:addClass( data[ 'class' ] ) end
return tostring( html )
end
--- Return the HTML of the infobox header component as string
--- @param table data {title, subtitle)
--- @return string html
function p.renderHeader( data )
if data == nil or data[ 'title' ] == nil then return '' end
local html = mw.html.create( 'div' ):addClass( 'infobox__header' )
html:tag( 'div' )
:addClass( 'infobox__title' )
:wikitext( data[ 'title' ] )
if data[ 'subtitle' ] then
html:tag( 'div' )
-- Subtitle is always data
:addClass( 'infobox__subtitle infobox__data' )
:wikitext( data[ 'subtitle' ] )
end
return tostring( html )
end
--- Wrap the HTML into an infobox section
--- @param table data {title, subtitle, content, col, class}
--- @return string html
function p.renderSection( data )
if data == nil or data[ 'content' ] == nil or data[ 'content' ] == '' then return '' end
local html = mw.html.create( 'div' ):addClass( 'infobox__section' )
if data[ 'title' ] then
local header = html:tag( 'div' ):addClass( 'infobox__sectionHeader' )
header:tag( 'div' )
:addClass( 'infobox__sectionTitle' )
:wikitext( data[ 'title' ] )
if data[ 'subtitle' ] then
header:tag( 'div' )
:addClass( 'infobox__sectionSubtitle' )
:wikitext( data[ 'subtitle' ] )
end
end
local content = html:tag( 'div' )
content:addClass( 'infobox__sectionContent')
:wikitext( data[ 'content' ] )
if data[ 'col' ] then content:addClass( 'infobox__grid--cols-' .. data[ 'col' ] ) end
if data[ 'class' ] then html:addClass( data[ 'class' ] ) end
return tostring( html )
end
--- Return the HTML of the infobox link button component as string
--- @param table data {label, link, page}
--- @return string html
function p.renderLinkButton( data )
if data == nil or data[ 'label' ] == nil or ( data[ 'link' ] == nil and data[ 'page' ] == nil ) then return '' end
--- Render multiple linkButton when link is a table
if type( data[ 'link' ] ) == 'table' then
local htmls = {}
for i, url in ipairs( data[ 'link' ] ) do
table.insert( htmls,
p.renderLinkButton( {
label = string.format( '%s %d', data[ 'label' ], i ),
link = url
} )
)
end
return table.concat( htmls )
end
local html = mw.html.create( 'div' ):addClass( 'infobox__linkButton' )
if data[ 'link' ] then
html:wikitext( string.format( '[%s %s]', restoreUnderscore( data[ 'link' ] ), data[ 'label' ] ) )
elseif data[ 'page' ] then
html:wikitext( string.format( '[[%s|%s]]', data[ 'page' ], data[ 'label' ] ) )
end
return tostring( html )
end
--- Return the HTML of the infobox footer button component as string
--- @param table data {icon, label, type, content}
--- @return string html
function p.renderFooterButton( data )
if data == nil or data[ 'label' ] == nil or data[ 'type' ] == nil or data[ 'content' ] == nil or data[ 'content' ] == '' then return '' end
local html = mw.html.create( 'div' ):addClass( 'infobox__footer' )
local button = html:tag( 'div' ):addClass( 'infobox__button' )
local label = button:tag( 'div' ):addClass( 'infobox__buttonLabel' )
if data[ 'icon' ] ~= nil then
label:wikitext( string.format( '[[File:%s|16px|link=]]%s', data[ 'icon' ], data[ 'label' ] ) )
else
label:wikitext( data[ 'label' ] )
end
if data[ 'type' ] == 'link' then
button:tag( 'div' )
:addClass( 'infobox__buttonLink' )
:wikitext( data[ 'content' ] )
elseif data[ 'type' ] == 'popup' then
button:tag( 'div' )
:addClass( 'infobox__buttonCard' )
:wikitext( data[ 'content' ] )
end
return tostring( html )
end
--- Return the HTML of the infobox item component as string
--- @param table data {label, data, desc, row, spacebetween, colspan)
--- @return string html
function p.renderItem( data )
if data == nil or data[ 'data' ] == nil or data[ 'data' ] == '' then return '' end
local html = mw.html.create( 'div' ):addClass( 'infobox__item' )
if data[ 'row' ] == true then html:addClass( 'infobox__grid--row' ) end
if data[ 'spacebetween' ] == true then html:addClass( 'infobox__grid--space-between' ) end
if data[ 'colspan' ] then html:addClass( 'infobox__grid--col-span-' .. data[ 'colspan' ] ) end
local dataOrder = { 'label', 'data', 'desc' }
for _, key in pairs( dataOrder ) do
if data[ key ] then
html:tag( 'div' )
:addClass( 'infobox__' .. key )
:wikitext( data[ key ] )
end
end
return tostring( html );
end
--- Wrap the infobox HTML
--- @param string innerHtml inner html of the infobox
--- @param string snippetText text used in snippet in mobile view
--- @return string html infobox html with templatestyles
function p.renderInfobox( innerHtml, snippetText )
local function renderSnippet()
if snippetText == nil then snippetText = mw.title.getCurrentTitle().rootText end
local html = mw.html.create( 'div' )
html
:addClass( 'infobox__snippet mw-collapsible-toggle' )
:tag( 'div' )
:addClass( 'citizen-ui-icon mw-ui-icon-wikimedia-collapse' )
:done()
:tag( 'div' )
:addClass( 'infobox__data' )
:wikitext( 'Quick facts:' )
:done()
:tag( 'div' )
:addClass( 'infobox__desc' )
:wikitext( snippetText )
return tostring( html )
end
local html = mw.html.create( 'div' )
html
:addClass( 'infobox floatright mw-collapsible' )
:wikitext( renderSnippet() )
:tag( 'div' )
:addClass( 'infobox__content mw-collapsible-content' )
:wikitext( innerHtml )
return tostring( html ) .. mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Module:InfoboxNeue/styles.css' }
}
end
return p