Is there a better way to do this as I have duplicate code?
I have an email twig with a link to open the email in the browser.
Currently I'm having to render the template twice.
Once to get the content and save it to a html file in S3. The second time to add the S3 link to the sent email for viewing the email online.
$emailBody = $this->twig->render('EmailRo/incomplete-listing-moderation/accept-incomplete-listing.email.twig', [
'user' => $admin,
'avatar' => AmazonS3Service::URL_PREFIX.$admin->getPhoto(),
's3html' => '',
]);
$s3 = $this->container->get('s3storage');
$fileName = rand(1000, 999999) . time() . '.html';
file_put_contents($fileName, $emailBody);
$file = $this->container->get('request_stack')->getCurrentRequest()->server->get('DOCUMENT_ROOT').'/'.$fileName;
$s3->upload('users/' . $fileName,
file_get_contents($file),
mime_content_type($file));
$s3html = AmazonS3Service::URL_PREFIX . 'emails/' . $fileName;
$emailBody = $this->twig->render('EmailRo/incomplete-listing-moderation/accept-incomplete-listing.email.twig', [
'user' => $admin,
'avatar' => AmazonS3Service::URL_PREFIX.$admin->getPhoto(),
's3html' => $s3html,
]);
In the twig I render it like so
{% if s3html %}
<a href="{{ s3html }}" style="text-decoration: none;"><span style="font-family:'Montserrat','Arial','Helvetica', sans-serif !important; font-weight: normal; font-size:13px; line-height: 15px; color: #27AAE1; font-weight: 400;">
Email not displayed correctly? Read the online version in your browser.
</span></a>
{% endif %}
CodePudding user response:
IMO, I think you could be overcomplicating things for little benefit.
There is no big performance hit for rendering the template twice, those are cached in any case. I imagine the concern is mostly so the code is "neater" without unnecessary repetitions, which is fine but not a significant concern.
But if you want to avoid calling render()
twice for the same template...
Just have a template that does not include the "read on a browser" bit, and render only that.
For the email version prepend the "read on a browser" link.
$htmlBody = $this->twig->render('EmailRo/incomplete-listing-moderation/accept-incomplete-listing.email.twig', [
'user' => $admin,
'avatar' => AmazonS3Service::URL_PREFIX.$admin->getPhoto(),
]);
// all the S3 logic, which returns an URL
$emailUrl = storeEmailHtmlSomewhere($emailBody);
$emailBody = <<< HTML
<a href="$emailUrl" style="text-decoration: none;"><span style="font-family:'Montserrat','Arial','Helvetica', sans-serif !important; font-weight: normal; font-size:13px; line-height: 15px; color: #27AAE1; font-weight: 400;">
Email not displayed correctly? Read the online version in your browser.
</span></a>
HTML;
// do what you need with that email
sendEmail($emailHeader . $emailBody);
Of you could simply store the two parts in different templates, if it comes to it, and concatenate the result when sending the email.
$emailHtmlBody = $this->twig->render('EmailRo/incomplete-listing-moderation/accept-incomplete-listing.email.twig', [
'user' => $admin,
'avatar' => AmazonS3Service::URL_PREFIX.$admin->getPhoto(),
]);
// all the S3 logic, which returns an URL
$emailUrl = storeEmailHtmlSomewhere($emailBody);
$emailHtmlHead = $this->twig->render('EmailRo/header-with-link.email.twig', [
'emailUrl' => $emailUrl
]);
sendEmail($emailHtmlHead . $emailHtmlBody);
CodePudding user response:
You can use 3 templates instead of one: something like base_mail.html.twig
with the main mail content, and two thin wrappers like email_s3.html.twig
and email.html.twig
where you give the base mail raw HTML as a parameter.
This would give something like this in the controller (not tested, sorry for typos):
$emailBase = $this->twig->render('base_mail.html.twig', [
'user' => $admin,
'avatar' => AmazonS3Service::URL_PREFIX.$admin->getPhoto(),
]);
$emailBodyS3 = $this->twig->render('email_s3.html.twig', [
'base' => $emailBase,
's3html' => /* ... */,
]);
// Handle $emailBodyS3 with S3
$emailBody = $this->twig->render('email.html.twig', [
'base' => $emailBase,
]);
// Send the email with $emailBody
And the thin wrappers would look like this:
email.html.twig
<div>{{ base | raw }}</div>
email_s3.html.twig
<div>
{{ base | raw }}
<a href="{{ s3html }}" style="text-decoration: none;"><span style="font-family:'Montserrat','Arial','Helvetica', sans-serif !important; font-weight: normal; font-size:13px; line-height: 15px; color: #27AAE1; font-weight: 400;">
Email not displayed correctly? Read the online version in your browser.
</span></a>
</div>