Skip to main content

The 'foreach' functionality: when do you use it and how does it work?

in What is Smarty?
Authors list
Published: Oct 10, 2024|Last updated: Nov 22, 2024
Note


This function offers endless possibilities but can be tricky to set up. Would you like assistance from our Campaign Services experts? Send an email to project-inbox@deployteq.com!

The purpose of the foreach functionCopy link to The purpose of the foreach function to clipboard

The purpose of this function is to retrieve data from the data model to display it in an email or page, for example, order information in a confirmation email.

How does it work?Copy link to How does it work? to clipboard

We will explain how the foreach works using a table with order data. Below is an example of what a foreach code might look like:

{{foreach from=$selection.Orders item='Orders_item'}} {{$Orders_item.OrderNumber}} {{$Orders_item.OrderSource}} {{$Orders_item.OrderDate}} {{$Orders_item.OrderStatus}} {{$Orders_item.OrderIncVAT}} {{$Orders_item.OrderExVAT}} {{$Orders_item.ShippingDate}} {{/foreach}}
copy

Everything you place between {foreach} and {/foreach}is repeated for each item within the table you selected.

If your order has three products, the code within the foreach will be executed three times, once for each product. In other words, the foreach function works like a machine that repeatedly performs the same task for each item in a list until no items are left.

In this code, the ‘from’ element indicates the source from which data should be retrieved, and the code repeats for each row that is found. After the ‘from’, you specify the data source. Here you indicate which table you will search through and the scope within that table.

Example: from=$selection.Orders

This refers to a previously made selection within the table named ‘Orders’. Below, we explain how such a selection is made. Everything before the dot specifies the scope, and everything after the dot specifies the name of the table.

There are three options for scope:

$selectionCopy link to $selection to clipboard

The scope here is a previously made selection within the customer record, for example, from a data model profile, or order data that was stored via a webhook and then ended up in the campaign (and is later used in the email sent from that campaign).

$customerCopy link to $customer to clipboard

The scope here is the entire customer record. Every order made by this specific customer will be displayed by the code.

$lookupCopy link to $lookup to clipboard

A third option is $lookup. The scope is then the entire data model table, so this function searches all customer records. This option cannot be added through the interface; you must add it manually.

With $lookup, you need to be very sure of what you’re doing and what you want to use it for, as you can retrieve and display all customer data at once. Usually, this isn’t necessary. It can be used to look up a specific product.

Note


Remember! The scope of the foreach is never larger than one data model table.

item='Orders_item'Copy link to item='Orders_item' to clipboard

This part of the code is a reference to the stored data of the order.

This code sets up a variable that you can refer to within the foreach loop to retrieve the data.

A variable is a reference to something else. With a variable, you can retrieve data that you’ve stored elsewhere.

With the element item='Orders_item', you specify the name of the variable that allows you to read the values of the order line within the foreach loop.

{{foreach from=$selection.Orders item='Orders_item'}} {{$Orders_item.OrderNumber}} {{$Orders_item.OrderSource}} {{$Orders_item.OrderDate}} {{$Orders_item.OrderStatus}} {{$Orders_item.OrderIncVAT}} {{$Orders_item.OrderExVAT}} {{$Orders_item.ShippingDate}} {{/foreach}}
copy

A data model profile in your selectionCopy link to A data model profile in your selection to clipboard

What should you pay attention to when using a data model profile in your selection?Copy link to What should you pay attention to when using a data model profile in your selection? to clipboard

As we mentioned above, when using $selection, you need a previously made selection to which the content can be sent. You can use a data model profile for this, which is a profile based on the data in your data model.

The context of a profile selection is either the customer or a data model table. $selection can only work if you’ve set the context in the used profile on the table name where the specific records were found.

That sounds complicated, so let's illustrate with an example!

In this profile, we only want to use data model records of orders with the status ‘Paid (Betaald)’:

image.png

You can see that the context of the first column is still set to ‘Customer’, and 4 customers meet the criteria.

Now we change the context from Customer to the table name, using the dropdown:

image.png

When we save and recalculate the profile, we see the following:

image.png

In a campaign where you want to use the function ‘foreach from=$selection’ to display certain data in an email, you start with a 'Start campaign' object.

Then, you select the customers with the ‘Select customers’ object, where you choose the data model profile (with the context on the relevant table) as the source.

Next, you add the ‘Send email’ object. The email containing the ‘foreach from=$selection’ will ‘understand’ which information can be displayed in the email to the customer.

How do I add the foreach?Copy link to How do I add the foreach? to clipboard

Anywhere you can add text in an email or on a page, you’ll see the Insert button. In this example, we add the code to a page.

Note


NB: if you're skilled enough with Smarty, you can write the code yourself, of course.

The code is added at the place where you position the cursor.

A pop-up opens, where you first select the table in which to search.

image.png

Then you select the scope, as described above:

  • Use data from selection ($selection)

  • Use all available customer data ($customer)

As mentioned earlier, the $lookup option, which allows you to search the entire data model, cannot be added via the interface. You must do this manually.

Finally, you choose how the data should be displayed:

  • in a table

  • in a list

  • without formatting

In this example, all information from the Orders table is selected, using all available data, in list format:

image.png

In the HTML source code of the email, you can see the actual Smarty code:

Hallo {{customer field='firstname' default='jij'}}<br /><br />Je bestelling:<br /> <ul><!--{foreach from=$customer.Orders item='Orders_item'}--> <li>Bestelnummer: {{$Orders_item.order_ID}}</li> <li>Besteldatum: {{$Orders_item.order_date}}</li> <li>Totaal: {{$Orders_item.order_total}}</li> <li>Betaalmethode: {{$Orders_item.payment_method}}</li> <li>Verzendkosten: {{$Orders_item.shipping_costs}}</li> <li>Bestelstatus: {{$Orders_item.order_status}}</li> <!--{/foreach}--></ul>
copy

ModifiersCopy link to Modifiers to clipboard

Within a foreach, modifiers sort and filter can be used to sort the list/array of data or filter specific data.

  • Within a $lookup, you can filter on certain data (e.g., only order 15).

  • If there are multiple rows, you can also sort the data (e.g., from lowest to highest).

  • A modifier always starts with the |- sign. After that, you specify whether to sort or filter, using |filter: or |sort:. Then you specify the value to be sorted or filtered.

ExamplesCopy link to Examples to clipboard

Example: only show the order items that come from the webshop:

{{foreach from=$selection.Orders|filter:'OrderSource':'Webshop' item='Orders_item'}} {{$Orders_item.OrderNumber}} {{$Orders_item.OrderSource}} {{$Orders_item.OrderDate}} {{$Orders_item.OrderStatus}} {{$Orders_item.OrderIncVAT}} {{$Orders_item.OrderExVAT}} {{$Orders_item.ShippingDate}} {{/foreach}}
copy

Instead of a fixed value, you can also filter with a smarty variable. So, if you stored the order number in the variable $ordernummer somewhere earlier in the code, you can perform a foreach over

$lookup.Orders|filter:'OrderNumber':$ordernummer

This is the way to retrieve ad hoc data from tables.

Example: reading the foreach in a specific order. For instance, showing the newest ShippingDate first, followed by older data:

{{foreach from=$selection.Orders|sort:'ShippingDate':'desc' item='Orders_item'}} {{$Orders_item.OrderNumber}} {{$Orders_item.OrderSource}} {{$Orders_item.OrderDate}} {{$Orders_item.OrderStatus}} {{$Orders_item.OrderIncVAT}} {{$Orders_item.OrderExVAT}} {{$Orders_item.ShippingDate}} {{/foreach}}
copy

If you want the oldest data first, use |sort:'field':'asc'.

Modifiers can also be combined, and you can apply several at once.

{{foreach from=$selection.Orders|filter:'OrderSource':'Webshop'|filter:'OrderStatus':'Cancelled'|sort:'ShippingDate':'desc' item='Orders_item'}} {{$Orders_item.OrderNumber}} {{$Orders_item.OrderSource}} {{$Orders_item.OrderDate}} {{$Orders_item.OrderStatus}} {{$Orders_item.OrderIncVAT}} {{$Orders_item.OrderExVAT}} {{$Orders_item.ShippingDate}} {{/foreach}}
copy

The above foreach shows all canceled webshop orders, starting with the newest.

Foreach within a foreachCopy link to Foreach within a foreach to clipboard

If you have an order with multiple items, and you want to show them all in the same confirmation email, you use a foreach within a foreach.

From the orders table, there will be a contains-relationship to the orderlines table, and you need that data to correctly populate the email with all the product details of the order.

Summarized once again:Copy link to Summarized once again: to clipboard

  • If you choose ‘Show all review requests with $customer’, the scope is the customer record.

  • If you choose $selection, you choose a previously made selection, such as a data model profile or a selection within the context of a webhook. The scope is still within a customer record.

  • If you choose the $lookup function, it searches the entire data model table, so you can potentially retrieve and display all customer data.

next page$smarty.now
previous pageSmarty explained

Please log in or register to submit a comment.