SignetMail docs Open portal →

#Template reference

Signatures are written in HTML with Liquid placeholders. Liquid is a simple, safe templating language: it can print values, test conditions and loop over lists, but it cannot run code or access the server.

#Printing values

Wrap a variable in double braces:

<b>{{ user.displayName }}</b>

Every printed value is HTML-encoded automatically, so a name containing < or & can never break or inject markup. You do not need (and should not use) an escape filter.

A variable without a value is empty (nil): it prints nothing and counts as false in conditions.

#User data — user.*

Read from Microsoft Entra ID.

Variable Entra attribute Example
user.displayName Display name Jane Doe
user.givenName First name Jane
user.surname Last name Doe
user.jobTitle Job title Head of Sales
user.department Department Sales
user.companyName Company name Example Ltd.
user.officeLocation Office Ljubljana
user.mail E-mail address jane.doe@example.com
user.upn User principal name jane.doe@example.com
user.mobilePhone Mobile phone +386 41 123 456
user.businessPhone Business phone +386 1 234 5678
user.ext.ext1 … user.ext.ext15 Extension attributes 1–15 any text

Extension attributes are the place for data that has no standard field — for example a second language title, a licence number or a direct-dial extension. Fill them in Entra ID / Active Directory (extensionAttribute1…15) and use {{ user.ext.ext3 }}.

Leading and trailing spaces are trimmed; empty strings become empty values.

#Organization data — org.*

Set in the portal under Organizations and inherited down the tree.

Variable Meaning
org.name Company name
org.address Address
org.website Website (display text)
org.websiteUrl Website (link)
org.logoUrl Logo address (https://…)
org.accentColor Accent colour, for example #0f766e
org.<yourField> Any custom field you added

#Conditions

Hide lines that would otherwise be empty:

{% if user.mobilePhone %}
  M {{ user.mobilePhone }}<br>
{% endif %}

Other forms:

{% if user.department == "Sales" %} … {% elsif user.department == "Support" %} … {% else %} … {% endif %}
{% unless user.jobTitle %} (no title) {% endunless %}
{% if user.jobTitle and user.department %} … {% endif %}
{% if user.mail contains "@example.com" %} … {% endif %}

#Assigning variables and defaults

{% assign accent = org.accentColor | default: "#0f766e" %}
{% assign company = user.companyName | default: org.name %}
<span style="color:{{ accent }}">{{ company }}</span>

#Filters

Filters transform a value: {{ value | filter: argument }}. Commonly useful ones:

Filter Example Result
default {{ user.jobTitle | default: "Employee" }} fallback when empty
remove {{ user.mobilePhone | remove: " " }} +38641123456 (for tel: links)
replace {{ user.department | replace: "&", "and" }} substitute text
upcase, downcase, capitalize {{ user.surname | upcase }} DOE
truncate {{ user.jobTitle | truncate: 40 }} shortened text
append, prepend {{ user.mail | prepend: "mailto:" }} add text
strip, size {{ user.displayName | size }} trim, length

The standard Liquid filter set is available.

#What is not allowed

For security and stability SignetMail restricts templates:

  • No ranges such as (1..100); they are rejected when the template is saved. Loops over data ({% for … %}) are allowed, but total work is capped (step limit and nesting depth).
  • No access to .NET objects or server data beyond user.* and org.*.
  • No scripts in the output: <script>, event attributes (onclick…) and javascript: links are rejected on save/publish.
  • Output is always HTML-encoded; there is no "raw" output.
  • Templates that are too complex fail with a clear error instead of hanging the server.

#HTML for e-mail

Mail clients are not browsers. The most reliable rules:

  1. Tables for layout, no div grids, no flex/grid.
  2. Inline styles on every element (the CSS tab inlines for you).
  3. Images with absolute https:// URLs, width, height, alt and style="display:block;border:0".
  4. Safe fonts: Arial, Helvetica, Calibri, Verdana, Georgia, Times New Roman.
  5. Links with https://, mailto: or tel: (use | remove: " " for phone numbers).
  6. Keep the HTML small (under 60 KB).

#A complete example

{%- assign accent = org.accentColor | default: "#0f766e" -%}
<table cellpadding="0" cellspacing="0" border="0" role="presentation"
       style="border-collapse:collapse;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px;color:#1f2937;">
  <tr>
    {%- if org.logoUrl %}
    <td valign="top" style="padding:0 16px 0 0;">
      <img src="{{ org.logoUrl }}" width="80" height="80" alt="{{ org.name }}" style="display:block;border:0;">
    </td>
    {%- endif %}
    <td valign="top" style="padding-left:14px;border-left:3px solid {{ accent }};">
      <div style="font-size:15px;font-weight:bold;">{{ user.displayName }}</div>
      {%- if user.jobTitle %}<div>{{ user.jobTitle }}</div>{% endif %}
      {%- if user.businessPhone %}<div>T {{ user.businessPhone }}</div>{% endif %}
      {%- if user.mail %}<div><a href="mailto:{{ user.mail }}">{{ user.mail }}</a></div>{% endif %}
    </td>
  </tr>
</table>

#Plain-text parts

The text parts use the same variables and conditions but no HTML:

{{ user.displayName }}
{%- if user.jobTitle %}
{{ user.jobTitle }}{% endif %}
{{ org.name }}

#Campaign banners

When a campaign applies to a person, SignetMail appends the banner to the end of the rendered signature automatically (and its alternative text to the plain-text version). You do not add anything to the template for that.

SignetMail documentation · version main