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->setHTMLTemplate/setPlainTemplate in combination with SSViewer::get_templates_by_class #11062

Open
beerbohmdo opened this issue Nov 22, 2023 · 4 comments

Comments

@beerbohmdo
Copy link
Contributor

beerbohmdo commented Nov 22, 2023

Version 5.x

Description

The method Email->setHTMLTemplate currently only accepts a single relative template name.

Because it must be a string, you cannot pass the response from SSViewer::get_templates_by_class to it.

And because of this if: https://github.com/silverstripe/silverstripe-framework/blob/5/src/Control/Email/Email.php#L416 you cannot even pass the response of SSViewer::chooseTemplate. Because the .ss extension is stripped from the file and will lead to the error "/absolute/path/to/file_without_extension" does not exists

A workaround I found is to add the .ss extension twice ...

$tmpl = SSViewer::chooseTemplate(SSViewer::get_templates_by_class($myClass, '_MySuffix'));
$email->setHTMLTemplate($tmpl . '.ss');
@beerbohmdo beerbohmdo changed the title Email->setHTMLTemplate in combination with SSViewer::get_templates_by_class Email->setHTMLTemplate/setPlainTemplate in combination with SSViewer::get_templates_by_class Nov 22, 2023
@michalkleiner
Copy link
Contributor

In your snippet I only see the .ss added once and you mention adding it twice. Am I not understanding it correctly or is there something missing?

@beerbohmdo
Copy link
Contributor Author

beerbohmdo commented Nov 22, 2023

The second .ss comes from SSViewer::chooseTemplate. But setHTMLTemplate/setPlainTemplate removes this.

$tmpl = SSViewer::chooseTemplate(SSViewer::get_templates_by_class($myClass, '_MySuffix'));
=> /absolute/path/to/themes/foo/templates/MyClass_MySuffix.ss

$email->setHTMLTemplate($tmpl); // Error: Unknown template /absolute/path/to/themes/foo/templates/MyClass_MySuffix

$email->setHTMLTemplate($tmpl . '.ss'); // Works because with "/absolute/path/to/themes/foo/templates/MyClass_MySuffix.ss.ss" only the second .ss will be removed.

@kinglozzer
Copy link
Member

Semi off-topic, but it might be helpful as an alternative - we’ve all but stopped using Email to render content directly, and instead pre-render and then pass the HTML through like this:

$html = ArrayData::create(['Asset' => $asset, 'Message' => $message])
    ->renderWith(['App\Email\AssetMessageEmail', 'App\Email\Email']);

$email = Email::create()->setBody($html);

It allows us to have a template structure similar to page templates, which can then use $Layout, so we don’t have to duplicate all the boilerplate <table> stuff that emails often need:

templates/App/Email/Email.ss

<html>
<head>
    ... some meta tags, global styles etc might live here
</head>
<body>
    ... shared email header

    {$Layout}

    ... shared email footer
</body>
</html>

templates/App/Email/Layout/AssetMessageEmail.ss

<p><strong>Message:</strong> {$Message}</p>

I wonder if it would be possible to add a setHTMLTemplates() method that accepts an array and could work like this?

@GuySartorelli
Copy link
Member

GuySartorelli commented Nov 23, 2023

I wonder if it would be possible to add a setHTMLTemplates() method that accepts an array and could work like this?

That sounds like a good idea. I'd recommend we also deprecate the current setHTMLTemplate() method at the same time, and allow people to pass through just a single template to setHTMLTemplates() if they do want to use a single specific template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants