Skip to content

Other Features

Beyond variables, conditionals, loops, and filters, NLT includes several additional features that are handy for building real-world templates -- ternary expressions, comments, built-in date variables, macros, and more.


Ternary Expressions

For compact inline conditionals, use the ternary syntax. It's a one-liner alternative to {if}...{else}...{end if}:

Example: Ternary: plan check

Template:

{the user's Plan is premium ? "VIP Member" : "Standard Member"}

Output:

VIP Member

Example: Ternary: score check

Template:

{the user's Score is more than 80 ? "Pass" : "Fail"}

Output:

Pass

Example: Ternary: existence check

Template:

{the user's Email is set ? "Verified" : "Unverified"}

Output:

Verified

The format is:

{condition ? "value if true" : "value if false"}

The condition part supports all the same operators as {if} blocks -- equality, numeric comparisons, date checks, containment, and more.

Tip

Use ternary expressions for short, inline labels or badges. For longer content blocks with HTML, stick with the full {if}...{else}...{end if} syntax.


Comments

Add notes to your templates that won't appear in the final email. Comments are completely removed during rendering:

{# This is a comment -- it won't appear in the email #}
{# TODO: update this section next quarter #}

Example: Comment is invisible in output

Template:

Hello {the user's First Name}!
{# This greeting was last updated in Q1 #}

Output:

Hello Jane!

Comments are useful for:

  • Leaving notes for your team about why a section exists
  • Temporarily disabling a section without deleting it
  • Adding TODO reminders for future updates

Built-in Date Variables

Two date variables are always available, no contact data needed:

Example: Today's date

Template:

{today}

Output:

2026-04-07

Example: Today formatted as long date

Template:

{today, as "long date"}

Output:

April 7, 2026

Example: Today formatted as short date

Template:

{today, as "short date"}

Output:

07 Apr 2026

Example: Current time

Template:

{now, as "time"}

Output:

3:30 PM

Both {today} and {now} use UTC time. All format modifiers (like as "long date" or custom date tokens) work the same as with any other date value.

{today} 2026-04-07
{today, as "long date"} April 7, 2026
{today, as "short date"} 07 Apr 2026
{now} 2026-04-07T15:30:45+00:00
{now, as "time"} 3:30 PM
Tip

Use {today} in email footers to show when the email was sent, or in conditional checks to compare against contact dates.


Pluralization

Automatically handle singular and plural word forms based on a number:

Example: Pluralize: multiple items

Template:

{the user's Order Count, pluralize "order"}

Output:

3 orders

Example: Pluralize: single item

Template:

{count of the user's Items, pluralize "item"}

Output:

1 item

NLT handles common English pluralization rules:

SingularPluralRule
itemitemsDefault: add s
boxboxesEnds in s/x/z/sh/ch: add es
categorycategoriesEnds in consonant+y: change to ies
{the user's Order Count, pluralize "order"} 3 orders / 1 order
{count of the user's Items, pluralize "item"} 5 items / 1 item

Raw Blocks

Content between {raw} and {end raw} passes through exactly as written, with no NLT processing at all:

{raw}
This {will not} be parsed as an NLT expression.
Even {if this looks like} a conditional, it's literal text.
{end raw}

Example: Raw block preserves curly braces

Template:

{raw}Hello {world}!{end raw}

Output:

Hello {world}!

Raw blocks are useful when you need to include literal curly braces in your output, or when you want to temporarily disable NLT processing for a section of your template during debugging.

Note

Absolutely nothing inside a {raw} block is processed -- not even comments or other NLT expressions. Everything comes through as literal text.


Macros

Macros let you define reusable template fragments with parameters. Define a macro once, then use it anywhere in your template.

Defining a Macro

{define greeting(name, title)}
<h1>Hello {name}, {title}!</h1>
{end define}

The {define} block registers the macro but produces no visible output. Parameters are referenced by name inside the macro body.

Using a Macro

{use greeting("Jane", "Manager")}

Example: Macro definition and usage

Template:

{define greeting(name, title)}
<h1>Hello {name}, {title}!</h1>
{end define}
{use greeting("Jane", "Manager")}

Output:

<h1>Hello Jane, Manager!</h1>

Arguments can be literal strings (in double quotes) or NLT expressions that resolve before being passed:

{use greeting(the user's First Name, the user's Title)}
Note

If a macro is used before it's defined, or called with the wrong number of arguments, it gracefully produces no output rather than causing an error.


Template Inheritance

Build template hierarchies where child templates override specific blocks from a parent template. This is great for maintaining consistent layouts across many email templates.

Base Template

The base template defines blocks with default content:

<html>
<head><title>{block title}Default Title{end block}</title></head>
<body>
<header>{block header}Default Header{end block}</header>
<main>{block content}Default Content{end block}</main>
</body>
</html>

Child Template

The child template extends the base and overrides specific blocks:

{extends "base.html"}
 
{block title}My Custom Title{end block}
 
{block content}
<p>This overrides the content block.</p>
{end block}

Blocks not overridden in the child template use the parent's default content. In this example, the header block keeps its default content since the child doesn't override it.

Including Parent Content

Use {parent} inside a child block to include the parent's original content alongside your additions:

{block header}
{parent}
<nav>Extra navigation</nav>
{end block}

This renders the parent's header content first, followed by the extra navigation.

Note

Template inheritance requires a template loader to be configured in the rendering engine. This is typically set up by your development team as part of the email delivery pipeline.