DC 5.10 Mail Templates
This guide gives an overview of the functionality in the Mail Template configuration. It is an extension of the already existing mail documentation DC 5.10 Example - Sending emails showing how emails can be triggered by automations.
If you need a template to use for general mail notifications, you can copy-paste the automation and mail template from the example:
Example
Mail template
The template for the above mail notification can be found here.
{{include 'html-header-start'}}
<title>These assets are expiring within the next 14 days.</title>
{{include 'html-header-end'}}
<span class="preheader">The following assets in the Saether DAM are expiring within the next 14 days</span>
{{include 'standard-header'}}
<h1>Hi {{receiver.name | html.escape}},</h1>
<p>There {{if data.assets.size==1}}
is an asset
{{ else }}
{{if data.assets.size < 100 }}
are {{ data.assets.size }} assets
{{ else }}
are more than 100 assets
{{ end }}
{{ end }}
about to expire within the next 14 days. Please review and take the appropriate action.</p>
<br>
<br>
<!-- Action -->
{{ for id in data.assets limit:12}}
<a href="{{ digizuite.get_link_to_asset_preview("https://media.saether.dk", id) }}">
<img src="{{ digizuite.get_asset_thumbnail_url(id) }}" alt="{{ digizuite.get_title(id) | html.escape}}" width="80" />
</a>
{{ end }}
<br>
{{ if data.assets.size > 12}}
<p> + more. </p>
{{ end }}
<br>
<!-- Sub copy -->
<table class="body-sub">
<tr>
<td>
<p class="sub">
When an asset expires, it will no longer be in the digizuite Media Manager.
If you click on the thumbnails you can go to the assets, or you can navigate to the DAM and utilize the filtering.
<br>
</p>
<p class="sub">
This is an automated email, please do not respond.
</p>
</td>
</tr>
</table>
<br>
{{include 'standard-footer'}}
Automation
Input:
Cron Input: https://www.freeformatter.com/cron-expression-generator-quartz.html
Find Assets
Remember to limit this as much as possible. e.g by not including already expired assets etc.
The dates on which you search can be adapted in the Get Date config.
Negative integers for offset will be in the past. Positive will be in the future.
@from always has to be smaller than @to.
Send Mail (Receiver and template name)
Prerequisites
As a precondition to following the walkthrough, it is expected that the reader has a basic understanding of the following concepts:
HTML
Emails
Basic programming and control structures
The templates are store under the ConfigManager (settings in MM):
Scribans own documentation can be found here: https://github.com/scriban/scriban/blob/master/doc/language.md and can be used for additional examples.
Preparing the mail template
The first thing we will take a look at is the email template. We start out with a pretty simply template that doesn’t do a whole lot, but let us go over how it works either way.
{{include 'html-header-start'}}
<title>Here is what happened since last time!</title>
{{include 'html-header-end'}}
<span class="preheader">Here is what happened since last time!</span>
<h1>Hi {{receiver.name | html.escape}},</h1>
<p>Here is what was uploaded since yesterday </p>
On line 1 you will notice the double curly braces {{
, these denote that some special code should be run, and that it is not just html that to be printed directly into the final mail. In this case we are using a special Scriban structure called an include
. Specifically we are including another mail template here. This allows us to standardize somewhat how mails looks, and allows us to avoid having to repeat ourselves. On line 3 we just output a title for the mail client to display. On line 5 we include another template. Next on line 7 we have the pre-header, which is displayed by some email clients as the first part of the body, before you open the email. The pre-header is not displayed in the actual mail. On line 9 we say hello to the receiver of the email. There are certain parts that are always loaded by the mail system. Specifically the receiver
and sender
. Important to notice is also that we use a pipe operator to call the html.escape
function, to prevent html injection. Whenever you output data you don’t control, always remember to run it through html.escape
. On line 10 we just output yet more text for the user to see.
Displaying a simple table
Next we need to start outputting out assets. As this is just a simple walkthrough, we will not focus on styling the email, and will just output the assets in a simple table.
First thing to do is setup the basic table structure:
<table>
<thread>
<tr>
<th>AssetId</th>
<th>Asset title</th>
<th>Thumbnail</th>
<th>Status</th>
</tr>
</thread>
<tbody>
...
</tbody>
</table>
If you have working with html before, there really shouldn’t be anything surprising about this structure. We simply create a table with 4 rows, AssetId
, Asset title
, Thumbnail
and Status
. The rest is just basic layout for us to put out main output in.
Looping through our assets
Then we get to the interesting parts, we need to actually output some data. To do this we insert a for loop:
<tbody>
{{for assetId in data.assetIds}}
<tr>
...
</tr>
{{end}}
</tbody>
This will run once for every assetId
in data.assetIds
. How does data get into data.assetIds
, you ask? This is handled by automations, which we will get to later in this walkthrough. For now, lets continue looking at how we can output data.
Conditioning
You can add conditions on the data to e.g. show alternative text depending on the length of the array.
<p>There {{if data.assets.size==1}}
is an asset
{{ else }}
{{if data.assets.size < 100 }}
are {{ data.assets.size }} assets
{{ else }}
are more than 100 assets
{{ end }}
{{ end }}
about to expire within the next 14 days. Please review and take the appropriate action.</p>
<br>
Above examples shows three alternative text depending on the number of assets that are about to expire:
1 result:
Between 1 and 99 results
More than 100 results
Showing the asset id
First thing we wanted to display was the asset id. We already have the asset id available from the loop, so we can output it directly:
<tbody>
{{for assetId in data.assetIds}}
<tr>
<td>
{{assetId}}
</td>
...
</tr>
{{end}}
</tbody>
As seen on line 5, all we need to do is to write {{assetId}}
.
Showing the asset title
Next we want to output the title of the asset. As can be seen in the auto-generated documentation below the mail template editor, there is a function called get_title
, that takes an asset id, and returns string. Calling it is as simple as this:
<tbody>
{{for assetId in data.assetIds}}
<tr>
...
<td>
{{digizuite.get_title(assetId) | html.escape}}
</td>
...
</tr>
{{end}}
</tbody>
All the custom functions Digizuite makes available can be found on the digizuite
object in the template. So in this case to call the function and get the title is as simple as {{digizuite.get_title(assetId)}}
, and we simply pass the asset id as an argument to the function. As this is user provided input, we have to remember to escape it using html.escape
, as mentioned earlier.
Showing a thumbnail of the asset
Next we want to display a thumbnail of the asset. To do this we have a function get_asset_thumbnail_url
, which again takes an asset id. So we simply need to do this:
<tbody>
{{for assetId in data.assetIds}}
<tr>
...
<td>
<img src="{{digizuite.get_asset_thumbnail_url(assetId)}}" />
</td>
...
</tr>
{{end}}
</tbody>
And we will get a nice small thumbnail. Notice how we don’t need to escape anything here. The function already returns a well formed URL, so it won’t cause any issues being included in the html like this.
Adding a link to the thumbnail
Next we want to thumbnail to actually take us to that asset in the Media Manager. For this we have a convenience function get_link_to_asset_preview
, which takes a baseUrl
to the Media Manager and an asset id. Because we want to entire image to be clickable, we wrap the entire thumbnail in an a
tag with a link to the image:
<tbody>
{{for assetId in data.assetIds}}
<tr>
...
<td>
<a href="{{digizuite.get_link_to_asset_preview("https://mm.digizuite.com", assetId)}}">
<img src="{{digizuite.get_asset_thumbnail_url(assetId)}}" />
</a>
</td>
...
</tr>
{{end}}
</tbody>
If you have multiple Media Managers installed, you need to enter the link to the correct portal. You can use the config version id of the template to control this. Notice also that we again don’t need extra escaping, since this is again a well formed URL already.
Displaying the asset status
As the last thing in the template we want to include the status of the asset. To do this we need to load the value of a metadata field. During this part we will also see how to do some even more advanced logic to conditionally display output in the template. The Status field is a combo
metafield, so we need to use the get_combo_meta_field_value
function. And as can be seen from the documentation, this function takes an assetId
, which we already have available from the loop, and a metaFieldLabelId
. This is the label id of the metafield, which also means it is language specific. On my system the labelId
for the status field in English is 51550
, so we will use that as an example. On your system it is likely to be different. Last thing we will notice about the function is that it returns a ComboValue
, not a string like the other functions we used above. That means we have to extract a specific property from the ComboValue
and display that. Additionally we want to handle the asset not having a status at all (Usually you have an automation ensuring the asset always have a status, but for the sake of example, we will take a look at how to check)
<tbody>
{{for assetId in data.assetIds}}
<tr>
...
<td>
{{status = digizuite.get_combo_meta_field_value(assetId, 51550)}}
{{if status == null}}
Asset has no status
{{else}}
{{status.label | html.escape}}
{{end}}
</td>
</tr>
{{end}}
</tbody>
On line 6 you can see us calling the get_combo_meta_field_value
function, passing in the assetId
from the loop, and the labelId
of the status metafield, and saving the result in the status
variable. Next we wanted to handle the case of the asset not yet having a status at all. We do this by using an if
statement, outputting Asset has no status
if there is no status, and {{status.label | html.escape}}
if there is. If you look in the documentation for the ComboValue
type, you can see it has a label
property. And again we remember to escape the user input, just to be on the safe side.
This concludes everything we need to do for the mail template. Make sure to save it, and put note down the name you gave the template, since we will need it for configuring the automation.
Sender of email
By default the sender of the email is shown as System Admin <noreply@digizuite.com> with an image of John Burke. The image only shows for internal digizuite mails, however the name (System Admin) is seen by all receivers of the email. It can be adapted by changing the name of the System Admin user. Be careful only to change the First and Last name as changing the System Admin login would potentially break the DAM.
Using the sender-user
In the mail text you can reference the sender as in the one who triggered the action to send this mail (i.e. if a user send the mail due to a collection share). However, if the mail is triggered by an automation, then this will default to System Admin and is therefore not recommended to use.
{{sender.name | html.escape}}
({{sender.email_address | html.escape}}) has invited you to join a shared collection in Digizuite™ Media Manager called <strong>“{{data.collection_name | html.escape}}”</strong>. Enjoy!
Good practices
This section lists some recommendations on good practices with the mail template. It is heavily suggested that you use the below recommendations as it limits toll on the system, makes the templates execute faster and provides a nicer overview for the receiver.
Check that result is not-empty
Users generally don’t want to be notified if nothing happens, so it is a good idea to check that the result returned by the Find Asset in the automation is not-empty before triggering the mail template.
Improving the performance of the mail template
If you run your mail template by loading 10 metadata fields for each assets, and loading 500 assets, it will of course take a bit of time, and put quite a bit of load on your dam center. To optimize your template we provide certain helper functions that will cause data to be bulk preloaded, which is must faster than loading each value as it is necessary.
At the time of writing Digizuite provides 3 functions for this:
preload_title
queue_meta_field_loads_by_item_guid
queue_meta_field_loads_by_label_id
Each of these functions takes the assets to preload. You just need to call them once in the start of the mail, and they are safe to call multiple times.
preload_title
is also recommended to use when using the get_link_to_asset_preview
function, since it requires the title of the asset to work.
Using these functions properly can make almost any mail template execute instantly, with much less load on the dam center.
Iteration limits
Scriban only allows each loop to run a maximum of 1000 times, after which it will stop execution and throw an error. To get around that you can use a limiting operator like this:
for assetId in data.assetIds limit:200
to only display the first 200 items.
It is also generally recommended that you keep the limit low, to both allow the template to execute faster, and to save the receiver some pain, since their mail client won’t start crying from too much mail.
If you cap the items send in the mail template, you might as well also cap the search result in the automation. You can do this by adding the Mac Result Count to be 1 more than the cap in the mail template
You can always add a clause in the mail template like:
{{ if data.assets.size > 100}}
There are more than 100 assets about to expire.
{{ end }}
Html escaping
It has been mentioned several times in this document, but make sure to escape any user input using | html.escape
, otherwise you might introduce security issues. When in doubt, escape the value.
E.g.
{{sender.email_address | html.escape}}
{{sender.name | html.escape}}
{{receiver.name | html.escape}}
{{status.label | html.escape}}
{{ digizuite.get_title(id) | html.escape}}