Skip to main content

Overview & FAQs: Merge Tags

What are Merge Tags?

Transaction-specific data/code that you can insert into your HTML Email and Ticket Templates.


This could be data such as Event Name, Customer Name, Ticket price, etc.


What are the different kinds of Merge Tags I can use?

There are different kinds of Tags depending on the data that you want to include:

Global Tags

These are singular values that are unrelated to a specific item in a transaction, but related to the transaction as a whole, e.g:

  • Organisation name

    • {{ ORGANISATION.NAME }}

  • Customer name

    • {{ CUSTOMER.FIRST_NAME }}

    • {{ CUSTOMER.LAST_NAME }}

  • Total value of transaction

    • {{:,.2f}".format(TRANSACTION.GROSS) }}

Loop Tags

These are values that tend to be related to a specific item in a transaction, e.g.:

  • Event Name

    • {{ ticket.EVENT.NAME }}

  • Event Venue

    • {{ ticket.EVENT.VENUE_NAME }}

    • {{ ticket.EVENT.VENUE_ADDRESS }}

  • Ticket price for event

    • {{:,.2f}".format(ticket.GROSS) }}

Loop tags need to be placed into a Loop in your HTML for it to work properly. See our Guide for how to do this.

Conditionals

These are Tags that are conditional depending on what has been ordered, e.g.:

  • Discount value - if a discount has been applied

  • External price adjusters (external only - not internal)

    • {% if adjuster.EXTERNAL %}
      {{ adjuster.NAME }}
      {% endif % }

These can be achieved by using 'if' statements on your HTML.


FAQs

Why isn't my Merge Tag working?

This may be because Loop tags are being placed outside of Loops, or there's an incorrectly formatted Merge Tag/bit of HTML code.

NOTE - As the ticketing software provider, we deliver and maintain the ticketing system. We do not provide template design and as such we would suggest going to an external HTML designer for detailed help with HTML templates.

We recommend unlayer for designing HTML templates.


ChatGPT is also very helpful for specific HTML queries.

How do I stop Event information appearing for every Ticket in my template?

By adding a if loop.first statement, followed by the Event Merge Tags you don't to appear for every ticket.

Example:

{% for ticket in TRANSACTION.TICKETS %} 
{% if loop.first %}


{% endif %}
{% endfor %}

This ensures that Venue Name and Address only appears once/for the first ticket.

You'd then need to remove and from the Event information in your template.

How do I exclude returned items on my Emails/Tickets?

By adding this bit of HTML before your Event/Ticket information:

{% for ticket in TRANSACTION.TICKETS | selectattr("TRANSACTION_TYPE", "equalto", "SALE") %}

You just have to make sure the close the loop with an {% endfor %} Merge Tag.

You may want to include this in the templates that you're using for Exchanges.

Here's an example whereby you'd only want the customer to see the Performance Date/Time for their new tickets, not the old tickets they exchanged:

{% for ticket in TRANSACTION.TICKETS | selectattr("TRANSACTION_TYPE", "equalto", "SALE") %}

'%I:%M %p')}} ON '%a %d%b') }}

{% endfor %}

How do I add the total number of Tickets in an order?

By adding this bit of code:

{% set count = TRANSACTION.TICKETS|length %}

Can I remove the Line-Up logo from my Templates?

Yes, just need to remove the img section from the default templates:

Screenshot 2024-04-29 at 11.52.10.png

Can I add my own Organisation logo instead?

Yes, you just need need to change img src from the logo URL:

Screenshot 2024-08-14 at 17.25.30.png

To the {{ ORGANISATION.IMAGE }} Merge Tag :

Screenshot 2024-08-14 at 17.28.30.png

This will mean that the Organisation image from your Settings page will pull through onto the Email Template instead of the Line-Up logo.

NOTE - if you are using your Org image in your template, this Merge Tag is safer to use than a hosting link. This is because some email servers may treat external hosting links as cold domains and may block the emails from being received.

Here's a video of these steps:

How do I group tickets together and show "Quantity"?

By adding a "Qty" column in your Items table and using our Merge Tag. Below are the steps to add this to your Items table in your Template.

NOTE - this will group tickets together by Price Variant. Because of this, it works best for GA events, where there is no Seat Label for your tickets.

  1. Add the Qty header cell in the table header row (after the Item cell, before Price):

    <td   
    width="10%"
    align="left"
    bgcolor="#eeeeee"
    style="
    font-family: Arial, sans-serif;
    font-size: 16px;
    font-weight: 700;
    line-height: 24px;
    padding: 10px;
    text-align: right;
    " >
    Qty
    </td>

  2. Adjust the Item column from width="65%" to width="55%" and Price from width="35%" to width="25%" in the header row, to make room.

  3. Add the namespace and deduplication logic at the top of the ticket loop (replacing the existing {% for ticket in TRANSACTION.TICKETS %} block):

    {% set ns_tickets = namespace(seen=[]) %} 
    {% for ticket in TRANSACTION.TICKETS %}
    {% set ticket_key = ticket.PERFORMANCE_START_DATE.strftime('%Y-%m-%d') + ticket.PERFORMANCE_START_TIME.strftime('%H:%M') + '|' + ticket.BAND_NAME %} {% if ticket_key not in ns_tickets.seen %}
    {% set ns_tickets.seen = ns_tickets.seen + [ticket_key] %} {% set count = TRANSACTION.TICKETS | selectattr('PERFORMANCE_START_DATE', 'equalto', ticket.PERFORMANCE_START_DATE) | selectattr('PERFORMANCE_START_TIME', 'equalto', ticket.PERFORMANCE_START_TIME) | selectattr('BAND_NAME', 'equalto', ticket.BAND_NAME) | list | length %}

  4. Add a Qty <td> cell inside the ticket row, between the Item and Price cells:

    <td   
    width="10%"
    align="right"
    style="
    font-family: Arial, sans-serif;
    font-size: 16px;
    font-weight: 400;
    line-height: 24px;
    padding: 15px 10px 5px 10px;
    text-align: center;
    vertical-align: text-top;
    " >

    </td>

  5. Close the deduplication block by adding {% endif %} before {% endfor %} in the ticket loop.

  6. Repeat steps 3–5 for the Products loop
    Same pattern, keying on product.PRODUCT_TITLE + '|' + product.VARIANT_NAME.

How can I change the start time to 24hr format?

  • In the line ticket.PERFORMANCE_START_TIME.strftime('%I:%M %p')

  • Updating ('%I:%M %p') to ('%H:%M') will change the format to 24h.

  • If you want to retain the AM/PM format, update the ('%I:%M %p') to ('%-I:%M %p') and that will remove the leading zero.

Is there a Merge Tag for Performance Day of the Week?

We don't have a specific Merge Tag for Day of the Week, however we do have {{ ticket.PERFORMANCE_START_DATE }} which you can use for if statements.

If you wanted to only show text only if an order contains tickets for a certain Performance Day, e.g. Tuesday, then the code you would want is:

{% if ticket.PERFORMANCE_START_DATE.strftime('%A') == 'Tuesday' %}
TEXT
{% endif %}

Is there a way to group tickets together in a template?

Yes, you can use a groupby filter as part of your code. groupby allows you to group tickets that have the same characteristics together in sections.

You can choose which parts of the ticket info/Merge Tag to group by:

Field

Groups by

{{ EVENT.ID }}

Event

{{ ticket.PERFORMANCE_START_DATE.strftime('%a %d %b') }}

Performance Start Date

{{ ticket.SEAT_GROUP_AREA }}

Area, e.g. Stalls

{{ ticket.BAND_NAME }}

Band Name

{{ ticket.VARIANT_NAME }}

Variant Name

{{ ticket.SEAT_TYPE }}

Seat Type

{{ ticket.SEAT_GROUP_ROW }}

Row

For example, if grouped by Event, the line of code would be:

{% for event_id, event_tickets in TRANSACTION.TICKETS | groupby('EVENT.ID') %}

A common setup in templates is grouping by event, then performance, then band and ticket type. This displays one line per price band with the rows listed beneath.

So the code would look like this:

{% for event_id, event_tickets in TRANSACTION.TICKETS | groupby('EVENT.ID') %}
{% for perf_date, perf_tickets in event_tickets | groupby('PERFORMANCE_START_DATE') %}
{% set header = perf_tickets | first %}

<!-- Event, venue and performance time go here, printed once -->

{% for band_name, band_tickets in perf_tickets | groupby('BAND_NAME') %}
{% for variant_name, variant_tickets in band_tickets | groupby('VARIANT_NAME') %}
{% set band_ticket = variant_tickets | first %}

<!-- One line per band and ticket type -->
{{ band_ticket.BAND_NAME }} - {{ band_ticket.VARIANT_NAME }}

{% for row_name, row_tickets in variant_tickets | groupby('SEAT_GROUP_ROW') %}
Row {{ row_name }}, Seats ...
{% endfor %}

{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}

And it would appear in your email like this:

If you have Reserved Seating and want seats to appear in one seat range rather than individually (as above), the make sure you add this line:

{% for row_name, row_tickets in variant_tickets | groupby('SEAT_GROUP_ROW') %}
Row {{ row_name }}, Seat{% if row_tickets | length > 1 %}s{% endif %} {% for group_id, tickets in row_tickets | groupby('GROUP_BY_ID') %}{% set first_seat = tickets | first %}{% set last_seat = tickets | last %}{{ first_seat.SEAT_LABEL }}{% if tickets | length > 1 %}&ndash;{{ last_seat.SEAT_LABEL }}{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}<br />

This also ensures that each row of seats are grouped as separate lines but underneath their Area and Band.

If you'd like to use a full example template with ticket grouping, our Example Templates here all include ticket grouping.

Are there Merge Tags I can use to show info for an entire Order instead of an individual Transaction?

Yes, we have Order Merge Tags you can use for this. See here for the Full List of Tags you can use.

Did this answer your question?