Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email template params interpolation #1345

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

avifatal
Copy link

@avifatal avifatal commented Oct 6, 2018

will now allow params to be interpolated in body strig (not from file) and subject.

@CLAassistant
Copy link

CLAassistant commented Oct 6, 2018

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@jreznot jreznot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not try to process something as template if template params is empty.
There could be special symbols in caption / description that are used in Freemarker as commands.

@@ -138,23 +139,37 @@ protected void prepareEmailInfo(EmailInfo emailInfo) {
}
}

protected void processCaptionTemplate(EmailInfo emailInfo) {
String caption = buildStringWithTemplateParams(emailInfo, emailInfo.getCaption());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call can break valid caption if template params are empty in case of caption contains FreeMarker reserved symbols.
Probably we should add test for this case

}

templateContents = buildStringWithTemplateParams(info, templateContents);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here too. Do not try to call template processor if params are empty, this will break existing code

Copy link
Author

@avifatal avifatal Oct 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildStringWithTemplateParams initialize the map if its null. isn't that ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still call > TemplateHelper.processTemplate(templateContents, params);
even for empty maps.

FreeMarker will process it even if Map is empty. It is not OK. Body/subject can contain symbols that will be interpreted as FreeMarker commands.

Copy link
Author

@avifatal avifatal Oct 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, processBodyTemplate is not performed for body and subject if templatePath is null.

Please pass <#assign link = "x"> as subject to your code without template params (empty template params). It should be inserted to email subject as is, but your code performs processing in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks compatibility with existing code where developers do not pass parameters

@jreznot
Copy link
Contributor

jreznot commented Oct 6, 2018

Before running tests, create and start DB:

gradlew startDb createTestDb

@jreznot jreznot self-assigned this Oct 6, 2018
@jreznot jreznot added the type: enhancement New feature or request label Oct 6, 2018
@jreznot
Copy link
Contributor

jreznot commented Oct 6, 2018

Now code still is not correct for the situation: templatePath + empty parameters. This is a valid case in the current implementation. String loaded from templatePath must always be processed with FreeMarker.

@jreznot
Copy link
Contributor

jreznot commented Oct 6, 2018

Moreover, it seems that we cannot and should not decide whether body should be processed automatically. It should be a parameter of EmailInfo object.

@avifatal
Copy link
Author

avifatal commented Oct 6, 2018

Now code still is not correct for the situation: templatePath + empty parameters. This is a valid case in the current implementation. String loaded from templatePath must always be processed with FreeMarker.

Isn't that the opposite of what you told me? see here: #1345 (comment)

@avifatal
Copy link
Author

avifatal commented Oct 6, 2018

Moreover, it seems that we cannot and should not decide whether body should be processed automatically. It should be a parameter of EmailInfo object.

I disagree, the template is dynamic, sometimes you have params and sometimes not. you dont have this knowledge at compile time in most cases. WDYT?

@jreznot
Copy link
Contributor

jreznot commented Oct 6, 2018

I disagree, the template is dynamic, sometimes you have params and sometimes not.

I mean that only developer who creates EmailInfo should specify whether or not body must be processed. It cannot be derived from empty / non-empty parameters. Now, I see clearly that there is a lack of an additional parameter for that.

And also, body/subject must be plain (non processed as template) by default in order to not break compatibility. Template path, as its name states, must be used always as template, even if params are empty.

@avifatal
Copy link
Author

avifatal commented Oct 6, 2018

I disagree, the template is dynamic, sometimes you have params and sometimes not.

I mean, that only developer who creates EmailInfo should specify whether or not body must be processed. It cannot be derived from empty/non-empty parameters. Now, I see clearly that there is a lack of additional parameter for that.

And also, body/subject must be plain (non processed as template) by default in order to not break compatibility. Template path, as its name states, must be used always as template, even if params are empty.

In my opinion, this is pitfally API, let's say that I have a UI to manage the templates (email text) and the params.
The content manager / employee, at runtime, sometimes decides to have params and sometimes not. Sometimes the template contains ${param} and sometimes not. it supposed to be implicitly decided by the API, if you have Map of params, it means it should be processed and if not it is not. Unless Im missing something about freemarker (this is new to me.)
Sorry for taking to much of your time.

@jreznot
Copy link
Contributor

jreznot commented Oct 7, 2018

By design, FreeMaker template can be used even without parameters. It supports loops, variables, comments, etc. There is no guarantee that existing systems do not use this behaviour. Moreover, existing static templates use symbol escaping for FreeMarker control symbols in templates. That's why files from templatePath should always be processed as templates.

The content manager / employee, at runtime, sometimes decides to have params and sometimes not.

If you are planning to use it in your high level feature you can simply preprocess message body yourself. In EmailInfo we have only API, and developers should decide if they want to use template processing with body or not. If we are talking about templatePath - it is obvious from the property name, in case of body and subject it is not obvious at all.

@jreznot jreznot changed the title Email template params interpolation. Email template params interpolation Oct 7, 2018
@MeyersJeff
Copy link

MeyersJeff commented Nov 1, 2018

I do not know the reason for this change, but would like to add a comment from a user's perspective. My application makes heavy use of emails and FreeMarker templates.

I agree with @jreznot, the developer can pre-process the template and build the email body themselves. I had to do this because my templates are stored in DB with a CUBA screen for easy editing. I submitted a request for a feature like this last year and was told it was not necessary as I could build the email body myself.

It would be nice, however, to have a templateString in addition to templatePath. templateString would hold the string contents of the FreeMarker template and would be used to build the email body. That would have saved me from writing my own custom template loader methods for FreeMarker. Someone would need to decide how to handle the case when both are populated.

The ability to process the email caption as a FreeMarker template would be nice, but for me is not necessary. Like the email body, the developer can choose to pre-process before assigning the caption to emailInfo.

@jreznot jreznot removed their assignment Apr 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants