Closed (fixed)
Project:
Mailer Plus (DSM+)
Version:
1.x-dev
Component:
Code
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
13 Dec 2021 at 11:12 UTC
Updated:
4 Jan 2022 at 12:49 UTC
Jump to comment: Most recent
When using mailsystem module, it is possible to set the theme to be used for outgoing mails. This ensures mails sent by a platform are styled in a characteristic manner (no matter if sent directly, by a queue or when other themes are being used; think admin pages, use of module for altering the active theme based on conditions ... ). As far as I can see the currently active theme is selected when using symfony mailer.
I'm eager to provide a patch - but would love some hints as to what kind of implementation would fit the module intent / philosophy.
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
balis_m commented@attisan, I've also wanted this functionality and I created a new email adjustment.
Now, the user can select the theme that wants to render the email from each mailer policy.
Comment #5
attisan💖 thank you @balis_m
perhaps we keep an eye on #3103382: Allow specifying which theme should be used for rendering a render array as that might optimize the process and could prevent switching active themes (as "historically" already done by the mailsystem module and thankfully implemented by your patch).
Comment #6
adamps commentedGreat thanks, yes this is a very good idea. I added some comments.
Comment #7
balis_m commented@attisan, I agree that we should prevent switching active themes but I think that this approach is more user friendly.
@AdamPS, I've made the changes that you suggest and added the theme switch back functionality. Also, I can confirm that the DefaultsEmailAdjuster occurs between the switch and switch back.
Comment #8
adamps commentedGreat thanks.
I've been thinking some more at the strategy level. It feels like the theme for an email is a really important concept and maybe we need to handle it more explicitly. We could add functions to UnrenderedEmailInterface:
setTheme(),getTheme(). ThemeEmailAdjuster would just callsetTheme()and DefaultsEmailAdjuster would call getTheme(), which should return the active theme if none has been set. Then we move the code to change themes into the Mailer class much like the existing code for language, creating achangeActiveTheme()method.Advantages:
We need to take care with the timing of changing theme. Some proxy EmailBuilder implementations such as SimplenewsNewsletterEmailBuilder cheat and render the body during the
preRender()stage. This suggests we should change theme at the same time as changing language, beforepreRender(), which feels right. However it creates a problem because ThemeEmailAdjuster is then too late to set the language. I wonder if we should add apreBuild()method to EmailProcessorInterface which is called along with the pre_build hook. It feels reasonable and makes things symmetrical with 3 hooks and 3 corresponding processor functions.What does anyone else think?
Comment #9
balis_m commentedIt is a good idea to add a
preBuild()method to EmailProcessorInterface.In that way, the subtle relationship of timing between DefaultsEmailAdjuster and ThemeEmailAdjuster will be removed and the email adjusters will be more flexible for future features.
Comment #10
adamps commentedOK I will add
preBuild()and let you know. Or maybe better to call itinit()?Comment #11
balis_m commentedI think
preBuild()is better.https://git.drupalcode.org/project/symfony_mailer/-/blob/1.x/src/Mailer....
Comment #12
adamps commentedOK, done, see #3253847: Improvements to Email interface. So I think the remaining steps here are:
setTheme(string $theme_name)andgetTheme()(put just before the library ones?)Mailer::changeTheme(string $theme_name)called at same times aschangeActiveLanguage()We need to think carefully about the default behaviour of
getTheme(). Using the active theme is buggy because in various hard-to-predict circumstances the admin theme is active. I wonder if we should make the default behaviour of getTheme() this: use the active theme, unless it's the admin theme in which case use the default theme. Although this seems a little complex, the advantage is that it ought to cover the requirement of a high percentage of sites. Then we can remove the special case entirely from ThemeEmailAdjuster and it just lists the actual themes (which obviously includes the current default theme). What do you think?Comment #13
balis_m commentedI think that the default behavior of getTheme() should use the active theme only.
In that way, we prevent switching active themes by default.
Comment #14
adamps commentedOK I agree that Email.php / Mailer.php should default to leaving the theme unchanged.
However I believe the scenario I am discussing is still relevant and should be handled somehow, most likely in an adjuster. The problem is that the admin theme can be active in unexpected scenarios. For example, the developers test that the commerce order receipt is working correctly from within checkout. However then the sales team uses "resend order receipt email" from the orders view within the admin theme and the email loses theming. Similarly the admin theme will be active for simplenews test emails and some but not all user emails.
Most likely the admin theme has no mail CSS and this could be true of other themes too. Before this patch, there is code in DefaultsEmailAdjuster that detects this case and falls back to the default theme instead.
Perhaps there could be a checkbox setting on ThemeEmailAdjuster called something like "fallback": if blank, the theme is changed unconditionally, if ticked, the theme is changed only if the active theme has no mail CSS.
What do you think? It would be nice to cover this case, however I'm willing to defer it to a separate issue if you really aren't interested.
Comment #15
balis_m commentedI understand your concern. There is no need to create a separate issue.
We can add an extra option (Active with fallback?) on ThemeEmailAdjuster that will act as you described.
What do you think?
Comment #16
adamps commentedOK that would be great. Thank you very much for your support of this module.
Comment #17
attisanadding my 5 cent - as a developer (integrator, when using drupal / modules 9 out of 10 times) you are usually looking for the combo of easy preset (default) and all possibilities at hand in the config.
when it comes to sending mails, I would argue that using the admin theme is never the desired standard (except when it is set to be through the UI). Instead I would "assume" that the site-wide default theme is being used - no matter if I provide a mail.css with my admin theme or not. having the mail module trying to be surprisingly smart, doing some fancy lookups or "assumptions" would probably even lead to frustration (think: not knowing, that the admin theme has in fact a mail.css ... ).
having the default page theme applied (potentially following overrides done with / by 3rd party modules based on roles or other condition) and having the option to force a specific theme (like with the given patch) but "ignoring" the admin theme - would be what I would "want" (what I would be pleased to use 😄).
Comment #18
adamps commentedThanks for joining the discussion @attisan
Certainly I would agree with that.
We should consider the case that the admin theme is also a valid page theme. I cannot imagine any reason to add mail CSS to a theme and then assume it would not be used to send emails. I feel that whoever writes code in this way has only themselves to blame.
Applying the default [page] theme is good if a site has only one page theme. If a site has 2 pages theme, then it seems a perfectly reasonable configuration to send emails in the active page theme rather than forcing the default one.
The current proposed preset/default it: if the active theme has mail CSS, then use it; otherwise use the default theme.
As far as I can see, this works correctly for the widest possible set of scenarios where it is reasonably possible to predict the desired behaviour:
Does that make sense?
Comment #19
adamps commented@balis_m I made some more commits so please do a git pull.
Comment #20
adamps commented@balis_m. I would like to create a new alpha very soon. I can wait 1-2 days if you would be able to finish this one off. If you have other priorities then I'll make the release now and this can go in the next one.
Comment #21
balis_m commented@AdamPS I've made all the changes that we discussed.
Also, there was a bug on
preBuild()call that I fixed.https://git.drupalcode.org/issue/symfony_mailer-3254125/-/blob/3254125-s...
This will work when the Active with fallback option is selected on ThemeEmailAdjuster.
This will work by default (without the ThemeEmailAdjuster).
This will work when the Default or any active theme option is selected on ThemeEmailAdjuster.
This will work by default (without the ThemeEmailAdjuster).
Comment #22
adamps commentedGreat many thanks, new code looks good. I made a few minor comments.
This would also work when the Active with fallback option is selected on ThemeEmailAdjuster.
Therefore the Active with fallback option works for all the main cases I outlined, which is great. So I feel we could usefully add that option to the default root policy ('_'). What do you think?
Comment #23
balis_m commentedI'm not sure that the Active with fallback option should be active by default, because, in that way, we switching themes by default.
Comment #24
adamps commentedI realise that I perhaps missed a part of the comment from @attisan. I had imagined a theme could only have email CSS if the site owner added it. However if this module becomes popular, eventually contrib themes might start to ship with email CSS. In this case, a site owner might install a theme without realising that is contains email CSS that is actually not the desired email CSS. It still seems a strange thing to do for an admin theme, but I guess it could happen.
So we might get the scenario that "the set of desired themes for email" is not equal to "the set of themes that contain email CSS". If there is a single desired theme, then this adjuster works well. If there are multiple desired themes, and also some non-desired themes that nevertheless contain email CSS then it's beyond the scope of what this adjuster allows. However that seems like a pretty subtle complex case, so I think it's OK for to leave it out for now - a site can write their own adjuster/hook of course.
Comment #25
adamps commentedThanks see answers in the comments.
True, but it's a much softer default - it is explicitly visible in the policy configuration and can be deleted.
I agree with @attisan when he said:
.
Without this default policy, then simplenews test mails, commerce resend receipts, etc will likely be wrong, and people can easily miss this case in testing. I feel that more people will be thankful (without evening knowing) that we have this code in than will be upset by it.
I guess we could add one more safeguard: the fallback only occurs if the active theme has no mail CSS and the default theme has some?
Comment #26
balis_m commentedI've added a comment here https://git.drupalcode.org/project/symfony_mailer/-/merge_requests/10#no.... We could make a check on DefaultsEmailAdjuster and add the default theme library. But, I don't think that is a good approach because the
getTheme()can be used in various ways (ie. hooks, EmailAdjusters) and it's not a good idea to have duplicate code.The rest of the changes have been made and the Active with fallback option added to the default root policy ('_').
Comment #27
adamps commentedOK I would like to get this checked in, so I hope you don't mind I'm going to change it myself to add the underscores.
Comment #28
balis_m commentedI just added the underscores on ThemeEmailAdjuster. It was a really good idea.
Of course, you can make any change you want.
Comment #29
adamps commentedAh you did it, thanks. I also tried to do it, and I find these new MR in git confusing and I have no idea where my changes went to! Hopefully I didn't create any problem.
Comment #30
adamps commentedComment #32
adamps commented@balis_m Many thanks for working on this one.