Feature Wiki

Information about planned and released features

Tabs

Use Mustache in Mail Template Configuration

1 Initial Problem

By now (v7), most placeholders and text sections in mail templates can only be used or not used at all but they cannot be used under certain condidtions.
In some few cases (in "Administration > User Management > Settings > New Account Mail") ILIAS already offers the option to do so:

  • [IF_PASSWORD]
  • [IF_TARGET]
  • [IF_TIMELIMIT]
And with [IF_NO_PASSWORD] one example exists for a placeholder with a reversed logic, too

However, in the main scene where placeholders are used ("Administration > Mail > Text Templates"), no such option exists at all.
There are many scenarios in which such a conditional behaviour would be an advantage:
  • User data fields may be empty, so placeholders should only be used if the field contains anything (e.g., [SALUTATION]).
    Analogously, object data fields may be empty (e.g. [COURSE_PERIOD_START]).
  • In case fields are empty, it would be useful to have some special text inserted like "You can complete this field in your profile!".
  • Data fields describing a user-object relationship might be supposed to show their content only under specific circumstances (e.g., [COURSE_STATUS] shouldn't display the "in progress" status because this status already arises if you opened the course one single time, so "in progress" might give a wrong impression).
Moreover, there are more sophisticated scenarios:
  • Data you want to appear in the mail has to be calculated from other data (e.g., points still lacking, calculated from [STUDY_PROGRAMME_POINTS_REQUIRED] and [STUDY_PROGRAMME_POINTS_CURRENT]).
  • Data consist of lists with individual items (e.g., Study Programmes might consist of different numbers of subnodes as some nodes are irrelevant to specific users).

2 Conceptual Summary

We propose to replace the existing placeholder implementation with with Mustache (Syntax)
Mustache allows a lot more than we can offer with the current placeholder implementation:

Sections render blocks of text one or more times, depending on the value of the key in the current context.
A section begins with a pound and ends with a slash. That is, {{#person}} begins a "person" section while {{/person}} ends it.
The behavior of the section is determined by the value of the key.
False Values or Empty Lists
If the person key exists and has a value of false or an empty list, the HTML between the pound and slash will not be displayed.
Template:
Shown.{{#person}} Never shown!{{/person}}
Hash:
{ "person": false}
Output:
Shown.

An inverted section begins with a caret (hat) and ends with a slash. That is {{^person}} begins a "person" inverted section while {{/person}} ends it.
While sections can be used to render text one or more times based on the value of the key, inverted sections may render text once based on the inverse value of the key. That is, they will be rendered if the key doesn't exist, is false, or is an empty list.
Template:
{{#repo}} <b>{{name}}</b>{{/repo}}{{^repo}} No repos :({{/repo}}
Hash:
{ "repo": []}
Output:
No repos :(

If the person key exists and has a value of false or an empty list, the HTML between the pound and slash will not be displayed.
Template:
Shown.{{#person}} Never shown!{{/person}}
Hash:
{ "person": false}
Output:
Shown.

If the person key exists and has a non-false value, the HTML between the pound and slash will be rendered and displayed one or more times.
When the value is a non-empty list, the text in the block will be displayed once for each item in the list. The context of the block will be set to the current item for each iteration. In this way we can loop over collections.
Template:
{{#repo}} <b>{{name}}</b>{{/repo}}
Hash:
{ "repo": [ { "name": "resque" }, { "name": "hub" }, { "name": "rip" } ]}
Output:
<b>resque</b><b>hub</b><b>rip</b>

Hello {{name}}You have just won {{value}} dollars!{{#in_ca}}Well, {{taxed_value}} dollars, after taxes.{{/in_ca}}
Given the following hash:
{ "name": "Chris", "value": 10000, "taxed_value": 10000 - (10000 * 0.4), "in_ca": true}
Will produce the following:
Hello ChrisYou have just won 10000 dollars!Well, 6000.0 dollars, after taxes.

In a first step (this FR) the implementation mustache should take place, including the use of the currently available placeholders, only with curly brackets.
Thus, the use of the form is the same for non-experts.
However, experts can use the extended options of mustache.

When introducing Mustache, a migration must take place that transforms the square brackets in existing mail templates to curly brackets.

3 User Interface Modifications

3.1 List of Affected Views

Administration > Mail > Text Templates

Mail > Compose

3.2 User Interface Details

The syntax of the placeholders below the text field will be adopted to the Mustache syntax.

3.3 New User Interface Concepts

No new user interface concepts are planned.

3.4 Accessibility Implications

There are no implications in regards to web accessibility.

---

However users have to learn a new template engine syntax to use the Mustache expressions, which will have an impact to the amount of time needed by users to create a text template with the new ILIAS versions. But the learning curve is not steep.

4 Technical Information

We suggest to add mustach.php to our production dependencies.

5 Privacy

No personal data will be stored to implement this feature.

6 Security

The current implementation for placeholders uses a simple "search and replace" approach for rendering data into the mail. The implementation of mustache in php surely is more complicated. Since user input will be passed more or less directly to this implementation, we should recognize this as a possible attack vector. The implementation is widely used and gets regular updates to fix security issues. The feature set of mustache is stable, so updating to the most recent version should be simple. Still, when implementing mustache, special care should be taken to only expose a minimum set of data to the engine. Also, we should limit the access to closures and other executable code.

7 Contact

8 Funding

If you are interest in funding this feature, please add your name and institution to this list.

9 Discussion

JourFixe, ILIAS [jourfixe], 16 MAY 2022 : We highly appreciate this suggestion and accept the feature for ILIAS 9. Please clarify how HTML escaping could be realised to prevent unexpected / undesired escaping by Mustache.

JourFixe, ILIAS [jourfixe], 10 JUL 2023 : We prefer to substitute the placeholders by the related title of the placeholders ( {MAIL_SALUTATION} → Mail Salutation ). Otherwise, ILIAS would send a CC mail to all CC recipients for _every_ recipient in the TO field (when placeholders would be substituted by the real user names).

10 Implementation

Implemented as described above.

Test Cases

New unit tests have been added.

Approval

Approved a 2023-10-25 by Jansen, Michael [mjansen].

Last edited: 25. Oct 2023, 12:34, Jansen, Michael [mjansen]