Jump to content

Module:CardLua

From Creopedia

This documentation is transcluded from Module:CardLua/doc.

Lua interface for building a card.

Implements Template:Card.


require( 'strict' )

--- Simplified Lua interface for building a card.
--- Using similar approach to the Codex Card component.

--- @class CardProps
--- @field title ?string
--- @field description ?string
--- @field url ?string
--- @field page ?string
--- @field icon ?string
--- @field class ?string
--- @field thumbnail ?string
--- @field thumbnailSize ?string
local p = {}


--- @param file string
--- @param size string
--- @return string
local function getFileWikitext( file, size )
	-- `metadata` class is needed to be excluded from MultimediaViewer.
	-- `link=` is needed make sure the image is not clickable.
	return string.format( '[[File:%s|%s|class=metadata|link=]]', file, size )
end

--- @param root mw.html
--- @param thumbnail string
--- @param thumbnailSize string
local function renderThumbnail( root, thumbnail, thumbnailSize )
	local html = mw.html.create( 'div' )

	html
		:addClass( 't-card__thumbnail' )
		:wikitext( getFileWikitext( thumbnail, thumbnailSize or '48px' ) )

	root:node( html )
end

--- @param root mw.html
--- @param icon string
local function renderIcon( root, icon )
	local html = mw.html.create( 'div' )

	html
		:addClass( 't-card__icon' )
		:wikitext( getFileWikitext( icon, '20px' ) )

	root:node( html )
end

--- @param root mw.html
--- @param title ?string
--- @param description ?string
local function renderText( root, title, description )
	local html = mw.html.create( 'div' )

	html:addClass( 't-card__text' )

	if type( title ) == 'string' then
		html:tag( 'div' ):addClass( 't-card__title' ):wikitext( title )
	end

	if type( description ) == 'string' then
		html:tag( 'div' ):addClass( 't-card__description' ):wikitext( description )
	end

	root:node( html )
end

--- @param root mw.html
--- @param link string
local function renderInternalLink( root, link )
	local html = mw.html.create( 'div' )

	html
		:addClass( 't-card__link' )
		:wikitext( string.format( '[[%s]]', link ) )

	root:node( html )
	root:addClass( 't-card--is-link' )
end

--- @param root mw.html
--- @param link string
local function renderExternalLink( root, link )
	local html = mw.html.create( 'div' )

	html
		:addClass( 't-card__link' )
		:wikitext( string.format( '[%s]', link ) )

	root:node( html )
	root:addClass( 't-card--is-link' )
end

--- @param props CardProps
--- @return string
function p.render( props )
	local root = mw.html.create( 'div' ):addClass( 't-card' )

	if type( props.class ) == 'string' then
		root:addClass( props.class )
	end

	if type( props.thumbnail ) == 'string' then
		renderThumbnail( root, props.thumbnail, props.thumbnailSize )
	elseif type( props.icon ) == 'string' then
		renderIcon( root, props.icon )
	end

	renderText( root, props.title, props.description )

	if type( props.page ) == 'string' then
		renderInternalLink( root, props.page )
	elseif type( props.url ) == 'string' then
		renderExternalLink( root, props.url )
	end

	return mw.getCurrentFrame():extensionTag {
		name = 'templatestyles', args = { src = 'Module:CardLua/styles.css' }
	} .. tostring( root )
end

--- Wikitext entry point for the module
---
--- @param frame mw.frame
--- @return string
function p.main( frame )
	local getArgs = require( 'Module:Arguments' ).getArgs
	return p.render( getArgs( frame ) )
end


return p