将twig渲染为html文件,避免重复代码添加变量
Posted
技术标签:
【中文标题】将twig渲染为html文件,避免重复代码添加变量【英文标题】:Rendering twig to html file, avoid duplicate code to add a variable 【发布时间】:2021-12-08 21:43:24 【问题描述】:由于我有重复的代码,有没有更好的方法来做到这一点?
我有一个电子邮件分支,其中包含在浏览器中打开电子邮件的链接。
目前我必须渲染模板两次。
一次获取内容并将其保存到 S3 中的 html 文件。第二次在发送的邮件中添加S3链接,方便在线查看邮件。
$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,
]);
在树枝上我是这样渲染的
% 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 %
【问题讨论】:
为什么不添加一个占位符,例如模板中的s3html
并使用str_replace
更改呈现的html?这样你只需要渲染一次并做两次str_replace
s
【参考方案1】:
IMO,我认为你可能为了一点好处而把事情复杂化了。
两次渲染模板对性能没有太大影响,无论如何都会被缓存。我想这个问题主要是因为代码“更整洁”,没有不必要的重复,这很好,但不是一个重要的问题。
但如果您想避免为同一个模板调用两次render()
...
只要有一个不包含“在浏览器上读取”位的模板,然后只渲染它。
对于电子邮件版本,请添加“在浏览器上阅读”链接。
$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);
如果需要,您可以简单地将这两个部分存储在不同的模板中,并在发送电子邮件时连接结果。
$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);
【讨论】:
【参考方案2】:您可以使用 3 个模板而不是一个模板:类似于 base_mail.html.twig
的主要邮件内容,以及两个瘦包装器,例如 email_s3.html.twig
和 email.html.twig
,您可以在其中将基本邮件原始 HTML 作为参数提供。
这会在控制器中给出类似的东西(未经测试,抱歉错别字):
$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
薄包装看起来像这样:
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>
【讨论】:
我的意思是,你有点从 2 个渲染到 3 个渲染。无论如何,这太复杂了,如果 OP 想要这样的方法,那么我建议创建一个基本模板,其中包含一个空块s3html
和第二个模板,该模板扩展主模板并使用 URLs3html 块/跨度>
@DarkBee 我的方法避免了两次渲染可能很长的模板(电子邮件“基础”)。您基于块覆盖的建议仍然会两次呈现这个“可能很长的模板”。我不认为使用 3 个渲染而不是 2 个渲染会影响性能,尤其是对于像上面的包装器这样的小模板。
我不认为渲染模板会成为瓶颈,但我想有一天应该对这一点进行基准测试以上是关于将twig渲染为html文件,避免重复代码添加变量的主要内容,如果未能解决你的问题,请参考以下文章