Skip to content

Instantly share code, notes, and snippets.

@stof
Last active September 16, 2020 07:46
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save stof/c5aac17a5049dacc4ec3 to your computer and use it in GitHub Desktop.
Save stof/c5aac17a5049dacc4ec3 to your computer and use it in GitHub Desktop.
Rendering twig blocks directly from outside a twig render call, for email purpose
<?php
namespace Incenteev\MailerBundle\Mailer;
class TwigRenderer implements RendererInterface
{
private $twig;
private $styleInliner;
/**
* @param \Twig_Environment $twig
* @param StyleInlinerInterface $styleInliner
*/
public function __construct(\Twig_Environment $twig, StyleInlinerInterface $styleInliner)
{
$this->twig = $twig;
$this->styleInliner = $styleInliner;
}
/**
* {@inheritDoc}
*
* The template must define 3 blocks: subject, body_text and body_html.
*/
public function render(Message $message)
{
/** @var $template \Twig_Template */
$template = $this->twig->loadTemplate($message->getTemplate());
$context = $this->twig->mergeGlobals($message->getContext());
$subject = $this->renderBlock($template, 'subject', $context);
$textBody = $this->renderBlock($template, 'body_text', $context);
$htmlBody = $this->renderBlock($template, 'body_html', $context);
$htmlBody = $this->styleInliner->inlineStyle($htmlBody);
return array(
'subject' => $subject,
'text' => $textBody,
'html' => $htmlBody,
);
}
/**
* Renders a Twig block with error handling.
*
* This avoids getting some leaked buffer when an exception occurs.
* Twig blocks are not taking care of it as they are not meant to be rendered directly.
*
* @param \Twig_Template $template
* @param string $block
* @param array $context
*
* @return string
*
* @throws \Exception
*/
private function renderBlock(\Twig_Template $template, $block, array $context)
{
$level = ob_get_level();
ob_start();
try {
$rendered = $template->renderBlock($block, $context);
ob_end_clean();
return $rendered;
} catch (\Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
throw $e;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment