Module:InfoboxNeue

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 (%s) ', 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( '' )

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', 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( '%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