Use Twig to personalize Wallet content

Twig is a template language that allows you to personalize and dynamically display content on your Wallet cards and notifications. You can use Twig to show user-specific information, format data, and create conditional content.

❓ What is Twig?

Twig is a flexible template engine that lets you insert dynamic content into your Wallet cards using variables and filters. With Twig, you can display personalized information like names, dates, amounts, and loyalty status.

Before you start

✅ Best practices

  • Always test Twig code with your actual data before deploying to production.
  • Use the |raw filter when displaying text with accents to avoid encoding issues.
  • Keep Twig expressions simple and readable for easier maintenance.

🔡 Character limits

Notifications have a 255 character limit. Simplify your Twig code as much as possible to stay within this limit.

🧪 Test your Twig code

Use the Twig playground to test your code before implementing it.

📄 Complete documentation

For advanced Twig features, refer to the complete documentation at https://twig.symfony.com.

🤖 Use Twig with ChatGPT

You can use ChatGPT to generate Twig code by providing this prompt:

You are a Twig template generator.
I will describe a business requirement in plain language.
Your task is to translate it into valid, clean Twig code.

Rules:
- Output ONLY Twig code
- Do not add explanations or comments
- Use standard Twig syntax
- Assume variables already exist
- Keep the code simple and readable

Business requirement:
[DESCRIBE YOUR NEED HERE]

</> Basic Twig syntax

Twig uses double curly brackets to display variables. For example, to display your user's first name, you should use:

{{user.firstname}}

Discover the basic Twig syntax to start with:

👤 Display user information

Display first name

Input

Output

{{user.firstname}}

Antoine

Display last name

Input

Output

{{user.lastname}}

Dupont

Display loyalty status

Input

Output

{{status.name}}

Gold

Display user balance

Input

Output

{{user.balance}}

1,500

🔡 Format names with capitalization

Display first name with capital letter and accents

Avoid accent display issues

Input

Output

{{user.firstname|raw}}

jérémy

Display the first name with a capital letter and proper accents

Input

Output

{{user.firstname|lower|capitalize|raw}}

Jérémy

Display last name in uppercase

Input

Output

{{user.lastname|upper}}

DUPONT

Display first name with only first letter capitalized

Input

Output

{{user.firstname|capitalize}}

Antoine

^ Handle accent encoding issues

If customer data is not properly encoded in your database, use the replace filter to fix special characters:

Input

Output

{{user.lastname|replace({'ó': 'ó', 'ñ': 'ñ', 'í': 'í', 'é': 'é'})}}

Picó Nuñez Pérez

📆 Format dates

Display date in DD/MM/YYYY format

Input

Output

{{user.cardExpiration|date('d/m/Y')}}

08/11/2026

Display date in DD/MM/YY format

Input

Output

{{user.cardExpiration|date('d/m/y')}}

08/11/26

🔢 Format amounts and numbers

Display amount with comma and 2 decimals

Input

Output

{{user.balance|number_format(2, ',', '.')}} €

1,55 €

Perform calculations on amounts

Perform calculations like subtraction, addition, multiplication, or division

Input

Output

{{(1000 - counters.cashback.value)|number_format(2, '.', ',')}}

36.999999990 > 36.99

🏬 Display store information

Store information must be loaded in the Library beforehand.

Input

Output

{{store.name}}
{{store.address1}} 
{{store.postal_code}}, {{store.city}}
{{store.phone}}

My Super Store
116 Hope Street
99123, Hills
+1 333 0129

Display opening hours

Input

Output

MONDAY TO SATURDAY: {{store.opening_hours.monday}}
SUNDAY: {{store.opening_hours.sunday}}

MONDAY TO SATURDAY: 9am - 7pm
SUNDAY: 10am - 8pm

🫆 Create conditional content

Display content based on gender

Input

Output

{% if user.civility == 1%}M.{%else%}Mme{% endif %} {{user.lastname}}

M. Antoine Dupont
Mme Laura Dupont

Display content when first name is missing

If the customer doesn't have a first name available

Input

Output

{% if user.firstname == NULL%}CUSTOMER{%else%}{{user.firstname}}{% endif %}

Dear CUSTOMER

Display content based on two conditions

{% if user.packCycle == '0' and user.packSki == '0' %} Your content here {% endif %}

Display content based on store identifier

Display store name only if "FR" is present in its identifier

{% if 'FR' in store.identifier %} • {{store.name}} {% endif %}

Display content based on a list of values

{% if store.identifier in ['PSCES066', 'PSCES065', 'PSCES067'] %} This text if store ID is in the list {% else %} This text if store ID is NOT in the list {% endif %}

💲 Display offer information in notifications

To display offer values in notifications (maximum 255 characters):

{{user.firstname}}, As a reward for your purchases, you have a voucher of {% for o in offers.all %}{{o.amount}}€. Valid on any purchase until {{o.expiration_date|date("d/m/y")}}.{% endfor %}

If targeting only users with offers, you can simplify:

{{user.firstname}}, As a present you now have a cheque for {% for o in offers.all %}{{o.amount}}€ valid until {{o.expiration_date|date("d/m/y")}}.{% endfor %}

Check if offers exist

{% if offers.all is null %}
{% else %}
My offers
{% for o in offers.all %}
• Valid from {{o.starts_at|date('d-m-Y')}} and code {{o.code}} 
{% endfor %}
{% endif %}

🔀 Replace or remove text from a value

Remove specific text

Display only 123456 from CT123456

Input

Output

{{user.barcode|replace({"CT": ""})}}

123456

Replace text in multiple locations

Replace "bla" with nothing in bla123bla456bla

Input

Output

{{user.barcode|replace({"CT": ""})}}

123456

🖖 Split long text and keep only a portion

Keep only the first sentence

Display only the first sentence from a long description. This splits the text at the first period and displays only the first part.

{{offer.description|split('.')|first}}

Keep only a portion using a specific keyword

If you receive text with "RDV" as a separator:

{{offer.description|split('RDV')|first}}

🪡 Extract specific characters from a variable

If user.locale = en_FR (language_Country format), then:

Extract only the country (last 2 characters)

Input

Output

{{user.locale|slice(-2)}}

FR

Extract only the language (first 2 characters)

Input

Output

{{user.locale|slice(0,2)}}

en

🔗 URL encode data

To URL encode data

{{user.data|url_encode}}

🟢 Create WhatsApp links

<a href="whatsapp://send?phone=34671015121&text=Hello">671015121</a>