Important
You are browsing the documentation for version 1.6 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
Templates
With the Oro applications, you can easily send numerous personalized emails using one template. For example, you can make a single template that welcomes {username}, assign it to an email campaign, and each of your subscribers will get a mail sent specifically to them.
Create a New Email Template
Navigate to System > Emails > Templates.
Click Create Template.
Define the general settings for the template.
The following fields are mandatory and must be defined:
- Template Name — Name used to refer to the template in the system.
- Type — Use html or plain text.
- Owner — Limits the list of users that can manage the template, subject to the access and permission settings.
Optional field Entity Name is used to define an entity, variables whereof can be used in the template. If no entity name is defined, only system variables are available.
Important
If you want to use the template for autoresponses, the Entity Name field value should be Email.
Define the email template. Click on the necessary variable to add it to the text box.
Note
In the example below, the template contains a link to the website page composed with a piece of tracking code. Every time a user follows the link, visit event will be tracked for the campaign.
Click Preview to check your template.
Click Save if you are satisfied with the preview.
Note
You can delete , edit , and clone email templates on the page of all templates.
Important
Keep in mind that the ability to view, edit, clone, or delete email templates depends on specific roles and permissions defined in the system configuration. For more information about available access levels and permissions, see the Understand Roles and Permissions guide.
Hint
If you want to track the user-activity related to the emails sent within the email campaign, add a piece of tracking website code to the email template.
View Available Template Variables and Functions
For the security reasons, the only available variables are currently the ones listed on the Email Templates edit page in the back-office. However, there are a few exceptions. These are several Twig functions enabled in email templates that can be used to obtain some specific data in email templates.
The full list of these functions is the following:
- Functions
- date
- oro_config_value
- calendar_date_range
- calendar_date_range_organization
- get_event_recurrence_pattern
- website_path
- website_secure_path
- url
- path
- get_payment_methods (OroCommerce Only)
- get_payment_status_label (OroCommerce only)
- get_payment_status (OroCommerce only)
- oro_order_shipping_method_label (OroCommerce only)
- rfp_products (OroCommerce Only)
- line_items_discounts (OroCommerce only)
- order_line_items (OroCommerce only)
- Filters
- Tags
Important
Keep in mind that when editing HTML email templates, you pass them to the WYSIWYG editor. WYSIWYG automatically tries to modify the given HTML template against the HTML specifications. Therefore, the text and tags that violate the HTML specifications should be wrapped up in the HTML comment. For example, there should not be any other tags or text between the <table></table> tags except thead, tbody, tfoot, th, tr, td.
Examples:
Invalid template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <table>
<thead>
<tr>
<th><strong>ACME</strong></th>
</tr>
</thead>
{% for item in collection %}
<tbody>
{% for subItem in item %}
<tr>
{% if loop.first %}
<td>{{ subItem.key }}</td>
<td>{{ subItem.value }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
|
Valid template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <table>
<thead>
<tr>
<th><strong>ACME</strong></th>
</tr>
</thead>
<!--{% for item in collection %}-->
<tbody>
<!--{% for subItem in item %}-->
<tr>
<!--{% if loop.first %}-->
<td>{{ subItem.key }}</td>
<td>{{ subItem.value }}</td>
<!--{% endif %}-->
</tr>
<!--{% endfor %}-->
</tbody>
<!--{% endfor %}-->
</table>
|
Functions
date
1 | date()
|
Description: Converts an argument into a date to allow date comparison.
Example: See the Twig doc
oro_config_value
1 | oro_config_value(string $configSettingName)
|
Description: Returns the Oro config setting value.
Returns: string
Example: See https://oroinc.com/orocrm/doc/current/dev-guide/getting-started-book/configuration#in-templates
calendar_date_range
1 2 3 4 5 6 7 8 9 | calendar_date_range(
\DateTime $startDate = null,
\DateTime $endDate = null,
$skipTime = false,
$dateType = null, \\IntlDateFormatter constant or it's string name
$timeType = null, \\IntlDateFormatter constant or it's string name
$locale = null,
$timeZone = null
)
|
Description: Returns a string that represents a range between $startDate and $endDate, formatted according the given parameters.
Returns: string
- $endDate is not specified
- Thu Oct 17, 2013 - when $skipTime = true
- Thu Oct 17, 2013 5:30pm - when $skipTime = false
- $startDate equals to $endDate
- Thu Oct 17, 2013 - when $skipTime = true
- Thu Oct 17, 2013 5:30pm - when $skipTime = false
- $startDate and $endDate are the same day
- Thu Oct 17, 2013 - when $skipTime = true
- Thu Oct 17, 2013 5:00pm – 5:30pm - when $skipTime = false
- $startDate and $endDate are different days
- Thu Oct 17, 2013 5:00pm – Thu Oct 18, 2013 5:00pm - when $skipTime = false
- Thu Oct 17, 2013 – Thu Oct 18, 2013 - when $skipTime = true
Example:
1 | calendar_date_range(entity.start, entity.end, entity.allDay, 'F j, Y', 1)
|
calendar_date_range_organization
1 2 3 4 5 6 7 8 9 10 | calendar_date_range_organization(
\DateTime $startDate = null,
\DateTime $endDate = null,
$skipTime = false,
$dateType = null, \\IntlDateFormatter constant or it's string name
$timeType = null, \\IntlDateFormatter constant or it's string name
$locale = null,
$timeZone = null,
OrganizationInterface $organization = null
)
|
Description: The same as ‘calendar_date_range’ but for a specific organization.
Returns: string
get_event_recurrence_pattern
1 | get_event_recurrence_pattern(Entity\CalendarEvent $event)
|
Description: This method is aimed at showing text description of a recurring event in email invitations.
Returns: string
Example:
1 2 3 4 5 6 | <!--{% if get_event_recurrence_pattern(entity) %}-->
<tr>
<td style="width: 65pt; padding: 0 5pt 0 9pt; line-height: 1.3em; font-family: Arial, Helvetica, sans-serif; font-size: 10pt; vertical-align: top"><strong>Repeats:</strong></td>
<td style="padding: 0 9pt 0 0; line-height: 1.3em; font-family: Arial, Helvetica, sans-serif; font-size: 10pt; vertical-align: top">{{ get_event_recurrence_pattern(entity) }}</td>
</tr>
<!--{% endif %}-->
|
website_path
1 | website_path(string $route, array $routeParams, Website|null $website = null)
|
Description: Returns the absolute path for a specific route and parameters.
Returns: string
Example:
1 | <p>Please follow this link to confirm your email address: <a href="{{ website_path('oro_customer_frontend_customer_user_confirmation', {'username': entity.username, 'token': token}, entity.website) }}">Confirm</a></p>
|
website_secure_path
1 | website_secure_path()
|
Description: The same as ‘website_path’ but returns Secure (HTTPS) URL.
url
1 | url()
|
Description: Returns the absolute URL (with scheme and host) for the given route.
Example: See the Symfony Twig Extensions (URL)
path
1 | path()
|
Description: Returns the relative URL (without the scheme and host) for the given route.
Example: See the Symfony Twig Extensions (Path)
get_payment_methods (OroCommerce Only)
1 | get_payment_methods(Order $entity)
|
Description: Returns the allowed payment methods for orders.
Returns: array of OroBundlePaymentBundleTwigDTOPaymentMethodObject objests with payment method label and options (can be used as array of strings thanks to PaymentMethodObject::__toString method)
Example:
1 2 3 4 5 6 7 8 9 | {% set payment_methods = get_payment_methods(entity) %}
<!--{% if payment_methods|length == 1 %}-->
<h4>Payment Method:</h4>
<!--{{ payment_methods[0] }}-->
<!--{% elseif payment_methods|length > 1 %}-->
<h4>Payment Methods:</h4>
<!--{{ payment_methods|join(', ') }}-->
<!--{% endif %}-->
|
Alternative example:
1 2 3 4 5 6 7 8 9 10 11 12 13 | {% set payment_methods = get_payment_methods(entity) %}
{% if payment_methods|length == 1 %}
<strong>Payment Method: </strong>
{% elseif payment_methods|length > 1 %}
<strong>Payment Methods: </strong>
{% endif %}
{% for payment_method in payment_methods %}
{{ payment_method.label }}
{% if payment_method.options|length > 0 %}
{{- ' (' ~ payment_method.options|join(', ') ~ ')' -}}
{% endif %}
<br/>
{% endfor %}
|
get_payment_status_label (OroCommerce only)
1 | get_payment_status_label(Order $entity)
|
Description: Returns the translated label for the payment status.
See the \Oro\Bundle\PaymentBundle\Formatter\PaymentStatusLabelFormatter::formatPaymentStatusLabel
method for details.
Returns: string
Example: See an example for the get_payment_status (OroCommerce only) method.
get_payment_status (OroCommerce only)
1 | get_payment_status(Order $entity)
|
Description: Returns the payment status for requested order.
Returns: string, one of OroBundlePaymentBundleProviderPaymentStatusProvider class statuses (‘full’, ‘partially’, ‘invoiced’, ‘authorized’, ‘declined’, ‘pending’)
Example:
1 | <strong>Payment Status: </strong>{{ get_payment_status_label(get_payment_status(entity)) }}
|
oro_order_shipping_method_label (OroCommerce only)
1 | oro_order_shipping_method_label(string $shippingMethod, string $shippingMethodType)
|
Description: Returns the translated label of the order`s shipping method.
Returns: string
Example:
1 2 | {% set shipping_method = oro_order_shipping_method_label(entity.shippingMethod, entity.shippingMethodType) %}
<strong>Shipping Method: </strong>{{ shipping_method }}<br/>
|
rfp_products (OroCommerce Only)
1 | rfp_products(Oro\Bundle\RFPBundle\Entity\Request $entity)
|
Description: Returns a list of products requested by a buyer in this request for quote.
Returns:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | array: [
345 => [ \\Product ID
'name' => 'Yarn', \\ string, Product name
'sku' => 'YRN345erer', \\ string, Product SKU
'comment' => 'Most interesting product for us', \\ string, Comment in RFP for this product
'items' => [ \\array, Requested product items
38473 => [ \\Product Item ID
'quantity' => 49.86, \\ float, Product Item quantity
'price' => $price, \\ \Oro\Bundle\CurrencyBundle\Entity\Price object, Product Item price
'unit' => 'ft', \\ string, Product Item unit
],
139473 => [ \\Product Item ID
'quantity' => 21.98, \\ float, Product Item quantity
'price' => $price, \\ \Oro\Bundle\CurrencyBundle\Entity\Price object, Product Item price
'unit' => 'item', \\ string, Product Item unit
],
...
],
],
...
]
|
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | {% set products = rfp_products(entity) %}
{% if products|length %}
<table style="border: 1px solid black;margin-top: 10px">
<thead>
<tr>
<th><strong>SKU</strong></th>
<th><strong>Product</strong></th>
<th><strong>Quantity</strong></th>
<th><strong>Target Price</strong></th>
<th><strong>Comment</strong></th>
</tr>
</thead>
<!--{% for product in products %}-->
<!--{% set numItems = product.items|length %}-->
<tbody>
<!--{% for item in product.items %}-->
<tr>
<!--{% if loop.first %}-->
<td rowspan="{{ numItems }}">{{ product.sku }}</td>
<td rowspan="{{ numItems }}">{{ product.name }}</td>
<!--{% endif %}-->
<td>{{ item.quantity }} {{ item.unit }}</td>
<td>{{ item.price ? item.price|oro_format_price : '' }}</td>
<!--{% if loop.first %}-->
<td rowspan="{{ numItems }}">{{ product.comment }}</td>
<!--{% endif %}-->
</tr>
<!--{% endfor %}-->
</tbody>
<!--{% endfor %}-->
</table>
{% endif %}
|
line_items_discounts (OroCommerce only)
1 | line_items_discounts(Order $entity)
|
Description: Returns array of discount total sum for every order line item.
Returns: array
1 2 3 4 5 6 7 | array: [
'123123' => [ // Line Item ID
'value' => 15.065, \\ float, total sum of discount for the line item
'currency' => 'USD', \\ string, Currency of discount
],
...
]
|
Example: See an example for order_line_items (OroCommerce only) method.
order_line_items (OroCommerce only)
1 | order_line_items(\Oro\Bundle\OrderBundle\Entity\Order $entity)
|
Description: Returns order line items.
Returns:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | array: [
'lineItems' => [
[
'product_name' => 'Boat', \\ string, Product name
'product_sku' => 'BO1BIG', \\ string, Product SKU
'quantity' => 1.00, \\ float, Product quantity
'unit' => 'item', \\ string, Product unit
'price' => $price, \\ \Oro\Bundle\CurrencyBundle\Entity\Price object, Product price
'comment' => 'Comment for this line Item', string
'ship_by' => $price, \\ \DateTime, Line item ship by field
'id' => $id, \\ int|string, Line item identifier value
'subtotal' => $price, \\\Oro\Bundle\CurrencyBundle\Entity\Price object, Line Item subtotal
],
...
],
'subtotals' => [
[
'label' => 'Shipping', \\ string, Subtotal name
'totalPrice' => $price, \\\Oro\Bundle\CurrencyBundle\Entity\Price object, Subtotal Price
],
...
],
'total' => [
'label' => 'Total', \\ string, label for Total
'totalPrice' => $price, \\\Oro\Bundle\CurrencyBundle\Entity\Price object, Total sum Price for all order line items
],
]
|
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <table style="border: 1px solid black;margin-top: 10px">
<thead>
<tr>
<th><strong>Item</strong></th>
<th><strong>Quantity</strong></th>
<th><strong>Price</strong></th>
<th><strong>Subtotal</strong></th>
<th><strong>Ship By</strong></th>
<th><strong>Notes</strong></th>
</tr>
</thead>
<tbody>
<!--{% set data = order_line_items(entity) %}-->
<!--{% set lineItemDiscounts = line_items_discounts(entity) %}-->
<!--{% for item in data.lineItems %}-->
<tr>
<td>
{{ item.product_name }}
<br>
SKU #: {{ item.product_sku }}
<br>
</td>
<td>{{ item.quantity|oro_format_short_product_unit_value(item.unit) }}</td>
<td>{{ item.price|oro_format_price }}</td>
<td>
{{ item.subtotal|oro_format_price }}
{% set matchedDiscount = lineItemDiscounts[item.id] %}
{% if matchedDiscount is not null and matchedDiscount.value > 0 %}
<br/>{{ (-matchedDiscount.value)|oro_format_currency({'currency': matchedDiscount.currency}) }}
{% endif %}
</td>
<td>{{ item.ship_by }}</td>
<td>{{ item.comment }}</td>
</tr>
<!--{% endfor %}-->
</tbody>
</table>
|
Note
If none of these Twig functions cover your cases, you can create a custom Twig function that returns the desired data that you can use in email templates. Please, see OroEmailBundle documentation for details.
Filters
On top of functions, you can use filters in email templates. The full set of these filters is the following:
- default
- date
- escape
- format
- length
- lower
- nl2br
- number_format
- title
- trim
- upper
- oro_html_sanitize
- oro_format
- oro_format_address
- oro_format_date
- oro_format_time
- oro_format_datetime
- oro_format_datetime_organization
- oro_format_name
- oro_format_price
- oro_format_currency
- oro_format_short_product_unit_value
- join
Select Email Template Languages
If several languages have been enabled for the email templates, move from tab to tab to define the template in different languages. Templates in other languages will be used to notify users about events in their preferred language.