Skip to content

Email Templates Reference ​

This guide documents the placeholders (merge fields) you can use when customizing four transactional emails. It is written for people editing the email content — not for developers.

TemplateWhen it is sentSent to
User registration (user_register_success)After a new customer account is createdThe customer
Password reset (user_password_reset)When a customer requests a password reset linkThe customer
Quote request — customer (quote_request_customer)When a customer submits a quote requestThe customer
Quote request — admin (quote_request_admin)When a customer submits a quote requestThe shop's contact address

How placeholders work ​

Each template supports merge fields — tokens in the content that are replaced with real values when the email is sent. All templates use the same token style:

  • Dotted style: {{ .firstName }}, {{ .quoteId }}, {{ .shop.name }}.

The tables below show the exact token for each field. If a field is left out or has no value, the token is simply replaced with an empty string.

Shop fields (always available) ​

These describe the shop and can be used in any template:

FieldDescriptionExample
{{ .shop.name }}Shop nameAcme Store
{{ .shop.url }}Shop website addresshttps://shop.example.com
{{ .shop.logo }}Shop logo image URLhttps://shop.example.com/logo.png
{{ .shop.contactEmail }}Shop contact email[email protected]

Only these shop fields are exposed — the underlying tenant configuration (which also holds secrets like mail passwords and API keys) is not available to templates.

Legacy alias: older templates may use {{ .configuration.shop_name }} / .page_url / .shop_logo. Those still work (a filtered, non-sensitive subset), but new templates should use {{ .shop.* }}.

Languages & versioning ​

  • One file per language. Each template is stored per language (en, lt, …); the version for the recipient's language is used. Editing the content for one language does not affect the others.
  • Editing a template in the admin marks it customized — the system will never overwrite your changes when shipped defaults are updated.
  • Shipped updates to the default content are re-applied only to templates you have not customized (tracked by a template version number). Your edits always win.

Related — but separate: order, quote, and proforma PDF documents are produced by the business/ERP system, not by these email templates. Those use a versioned render schema (orderDocument.v1) with a much larger field set. See the ERP guide "Order, Quote, And Proforma PDF Templates" for those merge fields.


1. User registration — user_register_success ​

A welcome email sent to a customer after their account is created.

Subject: [{{ .shop.name }}] Welcome joining {{ .shop.name }} community

Available fields ​

FieldDescriptionExample
{{ .firstName }}Customer first nameJohn
{{ .lastName }}Customer last nameSmith
{{ .email }}Customer email address[email protected]
{{ .shop.name }}Shop nameAcme Store
{{ .shop.url }}Shop website addresshttps://shop.example.com
{{ .shop.logo }}Shop logo image URLhttps://shop.example.com/logo.png

Rendered subject: [Acme Store] Welcome joining Acme Store community

Example ​

html
<img src="{{ .shop.logo }}" alt="{{ .shop.name }}" style="max-height:60px">
<h1>Hello, {{ .firstName }} {{ .lastName }}!</h1>
<p>Thank you for creating an account at {{ .shop.name }}.</p>
<p>Your login email: {{ .email }}</p>
<a href="{{ .shop.url }}">Visit the shop</a>

Renders for John Smith at Acme Store:

[Acme Store logo]Hello, John Smith! Thank you for creating an account at Acme Store. Your login email: [email protected]Visit the shop


2. Password reset — user_password_reset ​

Sent when a customer requests a link to reset their password. The reset link is valid for a limited time after it is sent.

Subject: [{{ .shop.name }}] Password reset

Available fields ​

FieldDescriptionExample
{{ .resetUrl }}Full password reset linkhttps://shop.example.com/reset-password?code=AbC123...
{{ .shop.name }}Shop nameAcme Store
{{ .shop.url }}Shop website addresshttps://shop.example.com
{{ .shop.logo }}Shop logo image URLhttps://shop.example.com/logo.png

Rendered subject: [Acme Store] Password reset

Example ​

html
<img src="{{ .shop.logo }}" alt="{{ .shop.name }}" style="max-height:60px">
<h1>Password reset</h1>
<p>We received a request to reset your {{ .shop.name }} password.</p>
<a href="{{ .resetUrl }}">Reset your password</a>
<p>If you didn't request this, you can ignore this email.</p>

Renders:

[Acme Store logo]Password reset We received a request to reset your Acme Store password. Reset your password If you didn't request this, you can ignore this email.


3. Quote request — customer — quote_request_customer ​

Confirmation to the customer that their quote request was received.

Subject: [{{ .shop.name }}] Quote request no. {{ .quoteId }} received

4. Quote request — admin — quote_request_admin ​

Notification to the shop that a new quote request arrived. It uses the same fields as the customer version, and is sent to the shop's contact email address.

Subject: [{{ .shop.name }}] New quote request no. {{ .quoteId }}

Available fields (both quote templates) ​

FieldDescriptionExample
{{ .quoteId }}Quote request number1042
{{ .token }}Unique quote reference used in linksq_9f3a7c...
{{ .title }}Quote titleOffice refit
{{ .requestMessage }}Message the customer submittedPlease quote for 10 desks
{{ .currency }}Currency codeUSD

Requester — inside {{ with .customer }} ​

Who submitted the request. Most useful in the admin template (so staff can see who to reply to).

FieldDescriptionExample
{{ .customer.name }}Requester nameJohn Smith
{{ .customer.email }}Requester email[email protected]
{{ .customer.phone }}Requester phone (business requests)+1 555 010 1234
{{ .customer.company }}Company name (business requests)Acme Corp
{{ .customer.companyCode }}Company registration code123456789
{{ .customer.vatCode }}VAT codeUS123456789

Cart-based requests populate name and email only; phone/company fields are filled for standalone business requests. Empty fields render blank.

Quote link: {{ .shop.url }}/quotes/{{ .token }} → https://shop.example.com/quotes/q_9f3a7c...

Line items — inside {{ range .lineItems }} ​

Each requested product appears as a line item with these fields:

FieldDescriptionExample
{{ .productName }}Product nameDesk 120cm
{{ .description }}Product descriptionAdjustable-height desk
{{ .articule }}Product code / SKUDSK-120
{{ .quantity }}Quantity requested10
{{ .measurementUnit }}Unit of measurepcs
{{ formatPrice .priceInclTax }}Unit price incl. tax149.00
{{ formatPrice .total }}Line total, excl. tax1400.00
{{ formatPrice .totalInclTax }}Line total, incl. tax1490.00
{{ .vatPercentage }}VAT rate (%)21
{{ formatPrice .discountPerUnit }}Discount per unit10.00
{{ formatPrice .totalDiscount }}Line discount total100.00
{{ .currency }}Currency codeUSD
{{ range .charges }}Line-level charges — each has .chargeName, .chargeAmount, .totalAmountsurcharges/tariffs

Unit vs. line total: priceInclTax is the price of one unit; totalInclTax is the whole line (quantity × price, less discounts). A quote table usually shows both.

Product catalog details — {{ .product }} ​

Each line also carries the full product record under {{ .product }} (the same object the order confirmation uses; also available as {{ .productInfo }}). Commonly useful fields:

FieldDescriptionExample
{{ .product.brand }}Brand name (also {{ .product.brandInfo.name }})Acme
{{ .product.description }}Catalog descriptionAdjustable-height desk
{{ .product.image }}Product image URL (also imageSmall, images)https://shop.example.com/img/desk.jpg
{{ .product.supplierCode1 }}Supplier code (also supplierCode2, supplierCode3)SUP-4471

Optional fields: some fields (e.g. the supplier codes) are only present when the product has them — guard with a conditional, otherwise a missing value shows as <no value>:

{{ if .product.supplierCode1 }}Supplier: {{ .product.supplierCode1 }}{{ end }}

{{ .product }} carries many more fields (weight, categories, price tiers…). The line's own productName, articule, quantity and prices live directly on the line (above), not under .product.

Totals — inside {{ with .totals }} ​

FieldDescriptionExample
{{ formatPrice .totalInclTax }}Order total incl. tax1490.00
{{ formatPrice .total }}Order total1490.00
{{ formatPrice .totalExclTax }}Total excl. tax1400.00
{{ formatPrice .totalTax }}Total tax90.00
{{ formatPrice .totalShippingInclTax }}Shipping total incl. tax0.00
{{ formatPrice .totalDiscountInclTax }}Discount total incl. tax0.00

formatPrice formats a number with two decimals (e.g. 149.00). Use it around any price field.

Example values ​

quoteId         = 1042
token           = q_9f3a7c...
title           = Office refit
requestMessage  = Please quote for 10 desks
currency        = USD

lineItems:
  - productName      = Desk 120cm
    articule         = DSK-120
    priceInclTax     = 149.00
    currency         = USD
    quantity         = 10
    measurementUnit  = pcs

totals:
  total         = 1490.00
  totalInclTax  = 1490.00
  totalExclTax  = 1400.00
  totalTax      = 90.00

Rendered subject (customer): [Acme Store] Quote request no. 1042 received Rendered subject (admin): [Acme Store] New quote request no. 1042

Example (customer) ​

This shows the two things people most often get wrong — a loop over line items and a conditional block:

html
<h1>Quote request no. {{ .quoteId }} received</h1>
<p>Thank you — we received your request and will get back to you shortly.</p>

{{ if .requestMessage }}
<p><strong>Your message:</strong> {{ .requestMessage }}</p>
{{ end }}

<table>
  <tr><th>Product</th><th>Qty</th><th>Price</th></tr>
  {{ range .lineItems }}
  <tr>
    <td>{{ .productName }}</td>
    <td>{{ .quantity }} {{ .measurementUnit }}</td>
    <td>{{ formatPrice .priceInclTax }} {{ .currency }}</td>
  </tr>
  {{ end }}
</table>

{{ with .totals }}
<p><strong>Total: {{ formatPrice .totalInclTax }} {{ $.currency }}</strong></p>
{{ end }}

<a href="{{ .shop.url }}/quotes/{{ .token }}">View your quote</a>

Renders (quote #1042 for 10 desks):

Quote request no. 1042 received Thank you — we received your request and will get back to you shortly. Your message: Please quote for 10 desks

ProductQtyPrice
Desk 120cm10 pcs149.00 USD

Total: 1490.00 USDView your quote

Note on {{ with .totals }}: inside a range or with block, . refers to the current item — use $.currency (with the $) to reach a top-level field from inside the block.

Example (admin) ​

The admin template uses the same fields — only the wording differs (it's a notification, not a confirmation), and it typically shows who the request is from:

html
<h1>New quote request no. {{ .quoteId }}</h1>
{{ with .customer }}
<p>From: {{ .name }} ({{ .email }}){{ if .company }} — {{ .company }}{{ end }}</p>
{{ if .phone }}<p>Phone: {{ .phone }}</p>{{ end }}
{{ end }}

Renders:

New quote request no. 1042 From: John Smith ([email protected]) — Acme Corp Phone: +1 555 010 1234


Quick reference ​

TemplateLanguagesSent to
user_register_successen, ltThe customer
user_password_reseten, ltThe customer
quote_request_customeren, ltThe customer
quote_request_adminen, ltThe shop contact address

All templates use the dotted {{ .field }} token style.

Formatting helpers ​

HelperPurposeExample output
formatPriceFormat a number with 2 decimals149.00
formatDateFormat a date as YYYY-MM-DD2026-07-15
formatDateUSFormat a date as MM/DD/YYYY07/15/2026
formatDatetimeUS / formatDateTimeUSFormat date & time, US style07/15/2026 02:30 PM
nl2brConvert line breaks to <br>multi-line text

Use {{ formatDateUS .someDate }} for US-style dates. formatPrice is mainly used by the quote templates (which carry prices and dates).

Pikselis Business documentation