Message Templates

Templates define how chat messages are displayed. They control colors, badges, icons, formatting, and layout.

Template Builder System

The theme builder (T) makes creating templates simple:

Config.Theme = {
    ['cmd:me'] = T.build()
        :bg('#ffffff20')
        :tag('ME', 'warning')
        :author({ bold = true })
        :text(': ', { color = '#999' })
        :message()
        :done(),
}

Available Components

T.tag(text, [color])

Display a badge/label:

T.tag('ME')                    -- Uses theme.brand color
T.tag('ADMIN', '#e74c3c')      -- Red badge
T.tag('INFO', 'warning')       -- Pre-defined color alias

Color aliases: default, info, success, warning, danger

T.author([opts])

Show the sender's name (consumes args[1]):

T.author()
T.author({ bold = true, color = '#ffffff' })
T.author({ style = 'text-transform: uppercase' })

T.message([opts])

Show the message content (consumes next available args[]):

T.message()
T.message({ bold = true })
T.message({ color = '#ffffff', italic = true })

T.text(content, [opts])

Static text (does NOT consume args):

T.text(': ')
T.text(' → ')
T.text(' at ')
T.text('Hello {Placeholder:ServerId}')  -- Can use placeholders

T.icon(svgString, [opts])

Display an SVG icon:

T.icon(Config.Svgs.taxi_car)
T.icon(Config.Svgs.announce, { style = 'margin-right: 5px' })

Store SVGs in Config.Svgs table.

T.spacer()

Add spacing between components:

T.build()
    :tag('INFO')
    :spacer()
    :message()
    :done()

T.bold(text) / T.italic(text)

Apply formatting to static text:

T.bold('IMPORTANT: ')
T.italic('Loading...')

Styling Options

All components accept an opts table with these properties:

{
    color   = '#ffffff',                    -- Text color
    bg      = '#00000080',                  -- Background color
    bold    = true,                         -- font-weight: 700
    italic  = true,                         -- font-style: italic
    style   = 'font-size: 0.9em;'          -- Raw CSS (last)
}

Built-in Presets

Presets are ready-made templates:

T.Presets.ooc()

Out-of-character chat:

-- Usage: args = { playerName, message }
T.Presets.ooc()

T.Presets.me()

Roleplay action:

-- Usage: args = { playerName, action }
T.Presets.me()

T.Presets.do_()

Environment description:

-- Usage: args = { playerName, description }
T.Presets.do_()

T.Presets.whisper()

Private message:

-- Usage: args = { fromName, message }
T.Presets.whisper()

T.Presets.announce(tag, tagColor, bg)

Server announcement:

T.Presets.announce('POLICE', '#3498db', 'rgba(52,152,219,0.12)')
-- Usage: args = { message }

T.Presets.system(tag, tagColor, bg)

System message:

T.Presets.system('SERVER', '#2ecc71', 'rgba(46,204,113,0.12)')

T.Presets.jobWhisper(tag, tagColor)

Job-specific radio/whisper:

T.Presets.jobWhisper('RADIO', '#3498db')

T.Presets.playerJoin() / T.Presets.playerLeave()

Player join/leave announcements:

T.Presets.playerJoin()
T.Presets.playerLeave()

T.Presets.dice()

Dice roll result:

-- Usage: args = { maxValue, playerName, result }
T.Presets.dice()

T.Presets.trySuccess() / T.Presets.tryFail()

Try command results:

-- Usage: args = { playerName, action }
T.Presets.trySuccess()
T.Presets.tryFail()

Full Example

Here's a complete custom template:

Config.Theme['my:fancy'] = T.build()
    :bg('rgba(100, 150, 200, 0.15)')      -- Light blue background
    :icon(Config.Svgs.announce)           -- Icon on left
    :tag('SYSTEM', '#2ecc71')             -- Green "SYSTEM" badge
    :author({                             -- Player name
        bold = true,
        color = '#ffffff',
        style = 'vertical-align: middle'
    })
    :text(': ', { color = 'rgba(255,255,255,0.5)' })
    :message({                            -- Message content
        style = 'vertical-align: middle'
    })
    :done()

-- Send it
TriggerEvent('chat:addMessage', {
    templateId = 'my:fancy',
    args = { GetPlayerName(PlayerId()), "Hello world!" }
})

Server-Side Templates (dont_register)

Templates prefixed with dont_register: are resolved server-side and can use framework functions:

Config.Theme['dont_register:announce'] = T.build()
    :bg('#f39c12')
    :text('Down Town Cab - {Framework.Functions.GetPlayerName}', {
        color = '#1a1a1a',
        bold = true,
    })
    :message({ bold = true })
    :done()

Send from server:

TriggerClientEvent('chat:addMessage', -1, {
    template = resolvedHtml,  -- Pre-rendered HTML
    args = { "Looking for taxi drivers" }
})

Component Consumption Example

Components consume args in order:

local template = T.build()
    :tag('TEST')          -- Consumes nothing
    :author()             -- ← consumes args[1]
    :text(': ')           -- Consumes nothing
    :message()            -- ← consumes args[2]
    :done()

-- Send with args
TriggerEvent('chat:addMessage', {
    template = HTML.createTemplate(template),
    args = { "PlayerName", "This is the message" }
})

Non-consuming components: T.tag, T.text, T.bold, T.italic, T.icon, T.spacer, T.bg

Configuration
../configuration/
Placeholders
../placeholders/