DOCUMENTATION

Advanced Template Tag Methods

Advanced Template Tag Methods

All of the examples above are part of our basic usage of template tags. We have other complex methods that show all the possibilities inside our application. Note that usage of these advanced methods may require knowledge with Django Template Tags.

Data Conditionals

The Rejoiner templating language gives you the ability to show or hide sections in your email based on conditional criteria. This criteria can be defined out of viewed_item data and cart_item data. Below we will show you 3 of our most popular examples.

Cart Data Conditionals

Our most popular use of this example is showing a code or text when a user qualifies for Free Shipping based on a customer's total cart value. We will use this example as a guide, but feel free to experiment.

To start off let's set some rules. Let's say that if a customer's order equals or is greater than $150 in total value, they get free shipping. However, you want to offer these customers Expedited Shipping via a promotional code to encourage a purchase.

We will start by creating our conditional via a loop tag. This conditional should say if: cart.value is >= (greater than) $150 - show this. To do so we'd use:

{% if cart.value >= 15000 %} {% endif %}

Note: We're not using the curly brackets that are part of the cart.value merge tag, instead we're just using the data and value it represents.

Also note that the $150 value in our conditional is being translated to CENTS. Hence why it is 15000

This means that we want to show the code ONLY to those that qualify using the snippet below:

<!-- Expedited Shipping Conditional Snippet -->
{% if cart.value >= 15000 %}
  Use code: FASTSHIP today and get free Expedited Shipping on us!
{% endif %}
<!-- end Expedited Shipping Snippet -->

Now, let's say that you want to show the promo code to all that qualify, and a reminder of your free shipping terms to those that don't. Then we'd want to use the snippet below with an else statement for those that do not qualify.

<!-- Expedited Shipping Conditional Snippet -->
{% if cart.value >= 15000 %}
  Use code: FREESHIP today and get free shipping on us!
{% else %}
  Remember, all orders above $150 qualify for free shipping!
{% endif %}
<!-- end Expedited Shipping Snippet -->

<!-- Expedited Shipping Conditional Snippet -->
{% if cart.value >= 15000 %}
<table>
    <tr>
        <td>
           Use code: FREESHIP today and get free shipping on us!
        </td>
    </tr>
</table>
{% else %}
<table>
    <tr>
        <td>
            Remember, all orders above $150 qualify for free shipping!
        </td>
    </tr>
</table>
{% endif %}
<!-- end Expedited Shipping Snippet -->

Product Data Conditionals

Our most popular use of this example is showing a code snippet, or text when a user has a specific item in their shopping cart. Let's say that you have a new product called: Expandable Photography Bag, which is a new item in your catalogue and so you want to promote the item without segmenting your customers.

To start off let's set some rules. Let's say that if a customer's abandoned order contains the product name of Expandable Photography Bag, they will see a new product image alert.

We will start by creating our conditional via a loop tag. This conditional should say if cart_item.name is == Expandable Photography Bag — show new product alert.

To do so we'd do:

{% if cart_item.name == "Expandable Photography Bag" %}{% endif %}

To show the code ONLY to those that qualify we'd use the snippet below:

{% for cart_item in cart_items %}
  Name: {{cart.item.name}}
  Product Image: {{cart.item.image_url}}

  <!-- New Product Conditional Image -->
  {% if cart_item..name == "Expandable Photography Bag" %}
    <img src="http://www.mystore.com/images/new-product-alert.png" >
  {% endif %}
  <!-- end New Product Conditional Image -->

  Product URL: {{cart.item.product_url}}
{% endfor %}

<!-- Cart Section -->
{% for cart_item in cart_items %}
<table>
    <tr>
        <td>
            <img src="{{cart_item.image_url}}" />
        </td>
    </tr>
    <!-- new product conditional -->
    {% if cart_item.name == "Expandable Photography Bag" %}
    <tr>
        <td>
            <img src="http://www.mystore.com/images/new-product-alert.png" />
        </td>
    </tr>
    {% endif %}
    <!-- end new product conditional -->
    <tr>
        <td>
            <p>{{cart_item.name}}</p>
            <a href="{{cart_item.product_url}}" target="_blank">View Product</a>
        </td>
    </tr>
</table>
{% endfor %}
<!-- end -->

Just as we used cart_item.name we can create any other conditional using item data. Thus, if you have two new products with the same name you could always target the product to promote using the item's SKU via cart_item.product_id.

Plural vs Singular Text

Let's say that the text in your email template has some copy that could benefit from accuracy in depicting how many items are were left behind. This is another one of our most popular cases. The text below, reflects this issue, as you'd like to implement something that better personalizes the email for your customers.

Hey Dan,

My name is Sandra and I noticed that you left  some products in your shopping bag. 

Perhaps you had questions about a product, a specific beauty concern, shipping 
options or maybe you had some trouble checking out?  

Drop me a line. I’m a trained beauty specialist so just reply to this email if you have 
a query and I will do my best to help. By the way, here’s a quick reminder of what 
you left behind. If you’re ready to complete your order click here.

So you'd want to solve this issue by creating a conditional with the following rules:

If Customer's Order Has One Item, Say: ...you left something in your shopping bag... If Customer's Order Has More Than One Item, Say: ...you left some products in your shopping bag...

For that we will use the conditional below, which uses the data gathered about the customer's order and use the injection of the cart.item_count merge tag.

{% if cart.item_count > 1 %} some products {% else %} something {% endif %}

<table>
    <tr>
        <td>
            <p>Hey {{name}},<p>
            <!-- plural - singular text conditional -->
            {% if cart.item_count > 1 %}
            <p>My name is Sandra and I noticed that you left some products in your shopping bag.</p>
            {% else %}
            <p>My name is Sandra and I noticed that you left something in your shopping bag.</p>
            {% endif %}
            <!-- end conditional -->
            <p>Perhaps you had questions about a product, a specific beauty concern, shipping options 
           or maybe you had some trouble checking out?</p> 
            <p>Drop me a line. I’m a trained beauty specialist so just reply to this email if you have a query 
            and I will do my best to help. By the way, here’s a quick reminder of what you left behind. 
            If you’re ready to complete your order click here.
        </td>
    </tr>
</table>

Defining Variables

In Rejoiner we will want to create variables to re-use in an email's code using the {% with %} built in, which caches a complex variable under a simpler name. This is useful when accessing an “expensive” method (e.g., one that hits the database) multiple times.

In order to help you understand the power of this, we'll create a variable that will simplify the method of injecting the last item a customer abandoned in their cart.

Last Item with Defined Variable

First we will create a name for our variable, let's say we call it last_item

Next we will want to define the variable and set the definition inside our template using {% with %}. We know that items are injected in a descending order so if we want to inject only the last item that a customer abandoned (for example), we will have to call in the 1st item in the list. For this we can use Django's first builtin method while calling the list of cart_items. We do this as follows:

{% with last_item=cart_items|last %} {% endwith %}

Now that our variable is set, we can call it inside our template tags. Thus instead of using the dataset of cart_item, we'll be using last_item as the dataset to call. We also do not need to use a forloop because we've already defined the cart_items list inside our variable's definitions.

Meaning that now cart_item.name can be called by using last_item.name.

This may sound a bit technical, but it saves time, uses less code and it's easier to read.

Below we have a full example of how to implement this in a campaign along a live example.

<!-- cart section -->
{% with last_item=cart_items|last %}
<table>
    <tr>
        <td>
            <p>Here's a quick reminder of your cart:</p>
        </td>
    </tr>
    <tr>
        <td>
            <img src="{{last_item.image_url}}" alt="{{last_item.name}}" />
        </td>
    </tr>
    <tr>
        <td>
            <p>{{last_item.name}}</p>
        </td>
    </tr>
    <tr>
        <td>
            <p>Quantity: {{last_item.item_qty}}</p>
            <p>Price: ${{last_item.price|cents_to_dollars}}</p>
            <p>Item Code:{{last_item.product_id}}</p>
        </td>
    </tr>
</table>
{% endwith %}
<!-- end section -->

This time we are only giving you one use case/example as creating these variables is easy, but these can be very difficult to implement without knowledge on Django or the Rejoiner templating language. Thus, we recommend using them with caution.

As you go through the rest of this document, you'll see other cases where the {% with %} built in is used. Thus, this section is mostly meant to be an introduction so that other uses make more sense.

Exclude Filters

Exclude filters are powerful builtins part of the Rejoiner templating language. You will only be needing an exclusion filter when implementing several injection types at once.

The exclude filter looks like so |exclude:products_to_exclude. This filter can only be used to exclude products and should cover any possible use case.

Exclusions Common Cases

Exclusion filters have the following most common cases:

Case #1: You want to inject last viewed_items along cart_items without having these overlap*.

Case #2: You want to inject abandoned cart_items and product recommendations without having these overlap*.

Case #3: You want to inject last viewed_items and browse product recommendations without having these overlap*.


  • By overlap we mean: having the same products show up in several sections.
Primary Data Set Secondary Data Set Exclude Filter Usage
cart_items viewed_items {% for viewed_item in viewed_items|exclude:injected_items %}
cart_items recommendations.top_sellers {% for product in recommendations.top_sellers|exclude:injected_items %}
cart_items recommendations.category_top_sellers {% for product in recommendations.top_sellers|exclude:injected_items %}
cart_items recommendations.purchased_together {% for product in recommendations.purchased_togethers|exclude:injected_items %}
viewed_items recommendations.browsed_category_top_sellers {% for product in recommendations.browsed_category_top_sellers|exclude:injected_items %}
viewed_items recommendations.viewed_together {% for product in recommendations.viewed_together|exclude:injected_items %}
viewed_items recommendations.top_sellers {% for product in recommendations.top_sellers|exclude:injected_items %}

Note: You can only use ONE exclude filter at a time. Emails that contain multiple filters will not send.

Example Usage

Since an email's content depends on a customer's session we need to avoid duplicates on the fly. To do so we use the exclusion filter to avoid showing the same product(s) in two different parts of an email.

For this example, let's say that you wanted to inject a customer's last viewed_items along cart_items without any duplicates. To do this, we'd need to follow the steps below:

1First, we need to inject the cart_items as we normally would.

{% for cart_item in cart_items %}
  <img src="{{cart_item.image_url}}" width="200" />
  Name: {{cart_item.name}}
  SKU: {{cart_item.product_id}}
  Price: {{cart_item.price}}

  <a href="{{cart_item.product_url}}">Complete Order</a>
{% endfor %}
2 Next, we need to add the loop tags and corresponding merge tags for injecting viewed_items.

Note that in this example, we will be adding a conditional that only shows viewed_items if a customer browsed other items that were not added to cart
<!-- Show Only If Viewed Items -->
{% if viewed_items %}
  {% for viewed_item in viewed_items %}
    <img src="{{viewed_item.product.image_url}}" width="200" />
    Name: {{viewed_item.product.name}}
    SKU: {{viewed_item.product.product_id}}
    Price: {{viewed_item.product.price}}

    <a href="{{viewed_item.product.product_url}}">Add to Cart</a>
  {% endfor %}
{% endif %}
<!-- end Conditional Content -->
3Next, we'll add the exclusion filter to avoid any cart_items duplicated in the viewed_items for loop tag.

<!-- Show Only If Viewed Items -->
{% if viewed_items %}
  {% for viewed_item in viewed_items|exclude:cart_items %}
    <img src="{{viewed_item.product.image_url}}" width="200" />
    Name: {{viewed_item.product.name}}
    SKU: {{viewed_item.product.product_id}}
    Price: {{viewed_item.product.price}}

    <a href="{{viewed_item.product.product_url}}">Add to Cart</a>
  {% endfor %}
{% endif %}
<!-- end Conditional Content -->

Below you can see a better example of the above.


<!-- Inject Cart Items -->
{% for cart_item in cart_items|slice:":3" %}
<table>
    <tr>
        <td>
            <img src="{{cart_item.image_url}}" width="200" />
        </td>
        <td>
            {{cart_item.name}}
        </td>
    </tr>
    <tr>
        <td>
            SKU: {{cart_item.product_id}}
        </td>
    </tr>
    <tr>
        <td>
            Price: {{cart_item.price}}
        </td>
    </tr>
    <tr>
        <td>
            <a href="{{cart_item.product_url}}">Complete Order</a>
        </td>
    </tr>
</table>
{% endfor %}
<!-- end Cart Items -->

<!-- Show Only If Viewed Items --> 
{% if viewed_items %}
  {% for viewed_item in viewed_items|exclude:cart_items|slice:":3" %}
    <table>
        <tr>
            <td>
                <img src="{{viewed_item.product.image_url}}" width="200" />
            </td>
            <td>
                {{viewed_item.product.name}}
            </td>
        </tr>
        <tr>
            <td>
                SKU: {{viewed_item.product.product_id}}
            </td>
        </tr>
        <tr>
            <td>
                Price: {{viewed_item.product.price}}
            </td>
        </tr>
        <tr>
            <td>
                <a href="{{viewed_item.product.product_url}}">Add to Cart</a>
            </td>
        </tr>
    </table>
    {% endfor %}
{% endif %}
<!-- end Conditional Content -->
Back to Top