-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Documented the Mime component #11280
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
Closed
Closed
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
6d9e6f8
Documented the Mime component
javiereguiluz 958e4d8
Added a placeholder article for the Mailer component
javiereguiluz fe48193
Finished the first version of the docs
javiereguiluz 69ff0e2
Added a section about serializing messages
javiereguiluz cf6ff0b
Documented the Twig integration
javiereguiluz 426b864
Minor tweak
javiereguiluz b21dfb7
Removed all references to template() (to be removed soon)
javiereguiluz 46cfc54
Fixes
javiereguiluz ec9f858
Added the MIME Types Utilities section
javiereguiluz 8b3c0d7
Minor tweak in an example
javiereguiluz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,9 +123,11 @@ result of rendering some template) or PHP resources:: | |
->html(fopen('/path/to/emails/user_signup.html', 'r')) | ||
; | ||
|
||
The :doc:`Mailer component </components/mailer>` provides deep integration with | ||
the :doc:`Twig template engine </templating>` to give you features such as CSS | ||
style inlining and HTML/CSS frameworks to create complex HTML email messages. | ||
.. tip:: | ||
|
||
You can also use Twig templates to render the HTML and text contents. Read | ||
the :ref:`mime-component-twig-integration` section later in this article to | ||
learn more. | ||
|
||
Embedding Images | ||
---------------- | ||
|
@@ -284,4 +286,317 @@ include them in a message sent with the :doc:`Messenger component | |
// later, recreate the original message to actually send it | ||
$message = new RawMessage($serializedEmail); | ||
|
||
.. _mime-component-twig-integration: | ||
|
||
Twig Integration | ||
---------------- | ||
|
||
The Mime component integrates with the :doc:`Twig template engine </templating>` | ||
to provide advanced features such as CSS style inlining and support for HTML/CSS | ||
frameworks to create complex HTML email messages. | ||
|
||
Rendering Email Contents with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
If you define the contents of your email in Twig templates, use the | ||
:class:`Symfony\\Bridge\\Twig\\Mime\\TemplatedEmail` class. This class extends | ||
from the :class:`Symfony\\Component\\Mime\\Email` class explained above and adds | ||
some utility methods for Twig templates:: | ||
|
||
use Symfony\Bridge\Twig\Mime\TemplatedEmail; | ||
|
||
$email = (new TemplatedEmail()) | ||
->from('[email protected]') | ||
->fo('[email protected]') | ||
// ... | ||
|
||
// this method defines the path of the Twig template to render | ||
->template('messages/user/signup.html.twig') | ||
|
||
// this method defines the parameters (name => value) passed to templates | ||
->context([ | ||
'expiration_date' => new \DateTime('+7 days'), | ||
'username' => 'foo', | ||
]) | ||
; | ||
|
||
Once the email object has been created, use the | ||
:class:`Symfony\\Bridge\\Twig\\Mime\\BodyRenderer` class to render the template | ||
and update the email message contents with the results. Previously you need to | ||
`set up Twig`_ to define where templates are located:: | ||
|
||
// ... | ||
use Symfony\Bridge\Twig\Mime\BodyRenderer; | ||
use Twig\Environment; | ||
use Twig\Loader\FilesystemLoader; | ||
|
||
// when using the Mime component inside a full-stack Symfony application, you | ||
// don't need to do this Twig setup. You only have to inject the 'twig' service | ||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
$twig = new Environment($templateLoader); | ||
|
||
$renderer = new BodyRenderer($twig); | ||
// this updates the $email object contents with the result of rendering | ||
// the template defined earlier with the given context | ||
$renderer->render($email); | ||
|
||
The last step is to create the Twig template used to render the contents: | ||
|
||
.. code-block:: html+twig | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
|
||
<p>You signed up to our site using the following email:</p> | ||
<p><code>{{ email.to }}</code></p> | ||
|
||
<p><a href="{{ url('...') }}">Click here to activate your account</a></p> | ||
|
||
The Twig template has access to any of the parameters passed in the ``context`` | ||
method of the ``TemplatedEmail`` class and also to a special variable called | ||
``email`` which gives access to any of the email message properties. | ||
javiereguiluz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If you don't define the text content of the message, the ``BodyRenderer()`` | ||
class generates it automatically converting the HTML contents into text. If you | ||
prefer to define the text content yourself, use the ``text()`` method explained | ||
in the previous sections or replace the ``template()`` method with these other | ||
methods:: | ||
|
||
use Symfony\Bridge\Twig\Mime\TemplatedEmail; | ||
|
||
$email = (new TemplatedEmail()) | ||
->from('[email protected]') | ||
->fo('[email protected]') | ||
// ... | ||
|
||
->textTemplate('messages/user/signup.txt.twig') | ||
->htmlTemplate('messages/user/signup.html.twig') | ||
|
||
// this method defines the parameters (name => value) passed to templates | ||
->context([ | ||
// same as before... | ||
]) | ||
; | ||
|
||
Embedding Images in Emails with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Instead of dealing with the ``<img src="cid: ..." />`` syntax explained in the | ||
previous sections, when using Twig to render email contents you can refer to | ||
image files as usual. First, define a Twig namespace called ``images`` to | ||
simplify things later:: | ||
|
||
// ... | ||
|
||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
$templatedLoader->addPath(__DIR__.'/images', 'images'); | ||
$twig = new Environment($templateLoader); | ||
|
||
Now, use the special ``email.image()`` Twig helper to embed the images inside | ||
the email contents: | ||
|
||
.. code-block:: html+twig | ||
|
||
{# '@images/' refers to the Twig namespace defined earlier #} | ||
<img src="{{ email.image('@images/logo.png') }}" /> | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
{# ... #} | ||
|
||
Attaching Files in Emails with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Similar to embedding images, the first step to attach files using Twig templates | ||
is to define a dedicated Twig namespace (e.g. ``documents``) to simplify things | ||
later:: | ||
|
||
// ... | ||
|
||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
$templatedLoader->addPath(__DIR__.'/documents', 'documents'); | ||
$twig = new Environment($templateLoader); | ||
|
||
Now, use the special ``email.attach()`` Twig helper to attach files to the email | ||
message within the Twig template: | ||
|
||
.. code-block:: html+twig | ||
|
||
{# '@documents/' refers to the Twig namespace defined earlier #} | ||
{% do email.attach('@documents/terms-of-use.pdf') %} | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
{# ... #} | ||
|
||
.. note:: | ||
|
||
The `Twig do tag`_ is similar to the ``{{ ... }}`` syntax used to evaluate | ||
expressions, but it doesn't generate any output. You can use it to set other | ||
email properties: | ||
|
||
.. code-block:: html+twig | ||
|
||
{% do email.priority(3) %} | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
{# ... #} | ||
|
||
Inlining CSS Styles in Emails with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Designing the HTML contents of an email is very different from designing a | ||
normal HTML page. For starters, most email clients only support a subset of all | ||
CSS features. In addition, popular email clients such as Gmail don't support | ||
defining styles inside ``<style> ... </style>`` sections and you must **inline | ||
all the CSS styles**. | ||
|
||
CSS inlining means that every HTML tag must define a ``style`` attribute with | ||
all its CSS styles. This not only increases the email byte size significantly | ||
but also makes it impossible to manage for complex emails. That's why Twig | ||
provides a ``CssInlinerExtension`` that automates everything for you. First, | ||
install the Twig extension in your application: | ||
|
||
.. code-block:: terminal | ||
|
||
$ composer require twig/cssinliner-extension | ||
|
||
Now, enable the extension (this is done automatically in Symfony applications):: | ||
|
||
// ... | ||
use Twig\CssInliner\CssInlinerExtension; | ||
|
||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
javiereguiluz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$twig = new Environment($templateLoader); | ||
$twig->addExtension(new CssInlinerExtension()); | ||
|
||
Finally, wrap the entire template contents with the ``inline_css`` filter | ||
(to do so, it's better to use the `{% filter %} Twig tag`_ instead of the | ||
traditional ``...|filter`` notation): | ||
javiereguiluz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
.. code-block:: html+twig | ||
|
||
{% filter inline_css %} | ||
<style> | ||
{# here, define your CSS styles as usual #} | ||
</style> | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
{# ... #} | ||
{% endfilter %} | ||
|
||
You can also define some or all CSS style in external files and pass them as | ||
javiereguiluz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
arguments of the filter: | ||
|
||
.. code-block:: html+twig | ||
|
||
{# '@css/' refers to the Twig namespace defined earlier #} | ||
{% filter inline_css('@css/mailing.css') %} | ||
<style> | ||
{# here, define your CSS styles as usual #} | ||
</style> | ||
|
||
<h1>Welcome {{ username }}!</h1> | ||
{# ... #} | ||
{% endfilter %} | ||
|
||
Rendering Markdown Contents in Emails with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Twig provides another extension called ``MarkdownExtension`` that lets you | ||
define the email contents using the `Markdown syntax`_. In addition to the | ||
extension, you must also install a Markdown conversion library (the extension is | ||
compatible with all the popular libraries): | ||
|
||
.. code-block:: terminal | ||
|
||
$ composer require twig/markdown-extension | ||
|
||
# these libraries are compatible too: erusev/parsedown, michelf/php-markdown | ||
$ composer require league/commonmark | ||
|
||
Now, enable the extension (this is done automatically in Symfony applications):: | ||
|
||
// ... | ||
use Twig\Markdown\MarkdownExtension; | ||
|
||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
$twig = new Environment($templateLoader); | ||
$twig->addExtension(new MarkdownExtension()); | ||
|
||
Finally, use the ``markdown`` filter to convert parts or the entire email | ||
contents from Markdown to HTML: | ||
|
||
.. code-block:: html+twig | ||
|
||
{% filter markdown %} | ||
Welcome {{ username }}! | ||
======================= | ||
|
||
You signed up to our site using the following email: | ||
`{{ email.to }}` | ||
|
||
[Click here to activate your account]({{ url('...') }}) | ||
{% endfilter %} | ||
|
||
javiereguiluz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Using the Inky Email Templating Language with Twig | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Creating beautifully designed emails that work on every email client is so | ||
complex that there are HTML/CSS frameworks dedicated to that. One of the most | ||
popular frameworks is called `Inky`_. It defines a syntax based on some simple | ||
tags which are later transformed into the real HTML code sent to users: | ||
|
||
.. code-block:: html | ||
|
||
<!-- a simplified example of the Inky syntax --> | ||
<container> | ||
<row> | ||
<columns>This is a column.</columns> | ||
</row> | ||
</container> | ||
|
||
Twig provides integration with Inky via the ``InkyExtension``. First, install | ||
the extension in your application: | ||
|
||
.. code-block:: terminal | ||
|
||
$ composer require twig/inky-extension | ||
|
||
Now, enable the extension (this is done automatically in Symfony applications):: | ||
|
||
// ... | ||
use Twig\Inky\InkyExtension; | ||
|
||
$templateLoader = new FilesystemLoader(__DIR__.'/templates'); | ||
$twig = new Environment($templateLoader); | ||
$twig->addExtension(new InkyExtension()); | ||
|
||
Finally, use the ``inky`` filter to convert parts or the entire email | ||
contents from Inky to HTML: | ||
|
||
.. code-block:: html+twig | ||
|
||
{% filter inky %} | ||
<container> | ||
<row class="header"> | ||
<columns> | ||
<spaccer size="16"></spacer> | ||
<h1 class="text-center">Welcome {{ username }}!</h1> | ||
</columns> | ||
|
||
{# ... #} | ||
</row> | ||
</container> | ||
{% endfilter %} | ||
|
||
You can combine all filters to create complex email messages: | ||
|
||
.. code-block:: html+twig | ||
|
||
{% filter inky|inline_css(source('@zurb/stylesheets/main.css')) %} | ||
{# ... #} | ||
{% endfilter %} | ||
|
||
.. _`MIME`: https://en.wikipedia.org/wiki/MIME | ||
.. _`Twig do tag`: https://twig.symfony.com/do | ||
.. _`{% filter %} Twig tag`: https://twig.symfony.com/doc/2.x/tags/filter.html | ||
.. _`Markdown syntax`: https://commonmark.org/ | ||
.. _`Inky`: https://foundation.zurb.com/emails.html |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.