Chapters
31 Chapters
|
3:19:40
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
11.
Ink: Automatic CSS Email Framework
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial is built on Symfony 4.3, but will work well with Symfony 4.4 or 5.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.110.11
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.1
"doctrine/doctrine-bundle": "^1.6.10", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-snappy-bundle": "^1.6", // v1.6.0
"knplabs/knp-time-bundle": "^1.8", // v1.9.1
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.23
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"league/html-to-markdown": "^4.8", // 4.8.2
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.1,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.1.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.1
"sensio/framework-extra-bundle": "^5.1", // v5.4.1
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.3.4
"symfony/console": "^4.0", // v4.3.4
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "^4.0", // v4.3.4
"symfony/framework-bundle": "^4.0", // v4.3.4
"symfony/mailer": "4.3.*", // v4.3.4
"symfony/messenger": "4.3.*", // v4.3.4
"symfony/property-access": "4.3.*", // v4.3.4
"symfony/property-info": "4.3.*", // v4.3.4
"symfony/security-bundle": "^4.0", // v4.3.4
"symfony/sendgrid-mailer": "4.3.*", // v4.3.4
"symfony/serializer": "4.3.*", // v4.3.4
"symfony/twig-bundle": "^4.0", // v4.3.4
"symfony/validator": "^4.0", // v4.3.4
"symfony/web-server-bundle": "^4.0", // v4.3.4
"symfony/webpack-encore-bundle": "^1.4", // v1.6.2
"symfony/yaml": "^4.0", // v4.3.4
"twig/cssinliner-extra": "^2.12", // v2.12.0
"twig/extensions": "^1.5", // v1.5.4
"twig/extra-bundle": "^2.12|^3.0", // v2.12.1
"twig/inky-extra": "^2.12", // v2.12.0
"twig/twig": "^2.12|^3.0" // v2.13.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.2.2
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/browser-kit": "4.3.*", // v4.3.5
"symfony/debug-bundle": "^3.3|^4.0", // v4.3.4
"symfony/dotenv": "^4.0", // v4.3.4
"symfony/maker-bundle": "^1.0", // v1.13.0
"symfony/monolog-bundle": "^3.0", // v3.4.0
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.3.4
"symfony/stopwatch": "4.3.*", // v4.3.4
"symfony/var-dumper": "^3.3|^4.0", // v4.3.4
"symfony/web-profiler-bundle": "4.3.*" // v4.3.4
}
}
30 Comments
Hi
Excellent course! I have learned lots of new things!
Isn't it better to use '*.inky.twig' instead of '*.html.twig'? Personally I think it's pretty straight forward to understand it's not the regular standard html. Anyway not an issue though!
Thank you!
Hey Mohamed!
Ah, cool idea! Honestly, it never occurred to me. But yes, I think that's a perfectly appropriate idea - I like it!
Cheers!
It took some time to get this to work with my php7.4 running on linux alpine. Turns out the xsl extension needed to be installed.
I made a docker image if anyone has the same problem codebuds/php:prod-1.0.1
Hey DennisdeBest
Thanks for sharing it with others. Cheers!
What would be a best practice to render the inky templates locally? Right now I have to resend the mails every time I change something. While creating the mere template this is a bit complicated. Thanks!
Hi @Eric,
Probably the most complicated thing here is dummy data for email, because rendering is simple, just create a controller which will receive template name and return you a rendered page. You can embed this page with iframe on some admin page, and with little JS help change templates you need to watch =)
Of course you will need some dummy data manager to populate email vars, we created an YAML config file for every email, with predefined data.
Cheers and happy coding!
My first try was indeed a simple Controller rendering the template. But I make use of the email variable in the template. Is there a way to create this variable in a Controller? I tried passing a new TemplatedEmail but that didn't help much... :)
It's not very complex solution, you need some place to predefine this variables, for example yaml
and so on...then you need a service which will read this vars as array and pass it to twig on template rendering
cheers!
Does it have to be external predefined variables? Or is there a way to create all necessary vars in the controller and pass them via the render-function? That way one could keep everything close together.
It feels like there is some basic concept involved I am currently missing.
I prefer an external file with variables, but the solution may be complex here, because it depends on what data you need to pass to emails, is it simple vars (strings, arrays) or it's some complex models. In both ways you create a service for example
DummyEmailDataManagerin that service you read your variables data from file or any other place you like and in controller you should call something like$this->render('emails/'.$emailTemplate.'.html.twig', $dummnyEmailDataMenager->loadVariablesFor($emailTemplate));and that's all sorry can't provide you exact implementation of variables loader, but it's doable and it's not very hard
cheers
Hey @Eric!
I think you just asked one of those "nobody does this well" questions, lol. We created a system internally to handle this in our admin - an area where you can select from an email, and see it rendered. It's SUPER convenient, but it did take a bit of time to setup. Let me bing Vladimir who worked on it - he can add some extra details about how our system looks :).
Cheers!
Hi guys! I really like this tutorial about Mailer because I was having a lot of mess coding emails. However, I have the same issue of other student in the comments, my emails are not responsive using Ink and Mailtrap. I had to fix manually the style labels. Do you have another recommendation of tool or framework for this? Thanks in advance.
Hey Cesar,
Hm, the Inky description here is saying:
> Inky is an HTML-based templating language that converts simple HTML into complex, responsive email-ready HTML
So as you see it should be "responsive email-ready HTML". I'd recommend you to double-check with their docs first to make sure you
re not missing anything. Then, if it does not help, try to upgrade to the latest version of it. If you still have this problem, probably try to open an issue in the original repository, maybe someone from maintainers would have an idea what's wrong in your case.
I can suggest you to look at this blog post from Mailtrap if you're looking for alternatives: https://mailtrap.io/blog/be... - but alternatives do not have such a smooth integration with Twig unfortunately.
I hope this helps!
Cheers!
Hello, I just noticed that in reality, the email is not responsive. On mailTrap, when I click on the "mobile phone" icon to see the mobile view, the rendering is not responsive, look:
On Desktop :
<img src="https://image.noelshack.com/minis/2020/44/7/1604229049-mailer-desktop.png" border="0" alt="1604229049-mailer-desktop.png - envoi d'image avec NoelShack" title="1604229049-mailer-desktop.png"/>
On mobile :
<img src="https://image.noelshack.com/minis/2020/44/7/1604229049-mailer-mobile.png" border="0" alt="1604229049-mailer-mobile.png - envoi d'image avec NoelShack" title="1604229049-mailer-mobile.png"/>
Hey Kiuega!
Hmm. To be honest, I'm not sure what's going on there :/. This IS one of the things that Foundation/Inky is supposed to take care of, but to be honest, I don't know much about how it works behind the scenes (and I'm not the person here at SymfonyCasts that works on the email portion). What happens if you try to send and check on a real mobile email client? I'm a bit dubious about how Mailtrap is showing it... I would normally think that a mail client would reduce the size show the entire email in the frame. \
Cheers!
Hello and sorry for the delay in response, I had completely forgotten! So I just checked, and indeed, if I send to a real email address, it works as it should! On the other hand, the email is sent in the "spam" folder, it's a shame
Hey @kieuga!
Ah, thanks for following-up - I was wondering about this!
> On the other hand, the email is sent in the "spam" folder, it's a shame
That is a shame :). "Deliverability" (the science of not getting your emails sent to SPAM) is a totally different topic, but one that we cover in good detail a bit later in the tutorial - https://symfonycasts.com/sc...
Cheers!
wassup, guys!
pls add a note of requirement to install (activate) XSL extension in local env to make inky work
I've spent a half-hour to understand what's wrong when got an err
Hey Bagar,
Thanks for reporting it! Hm, wasn't error message clear enough? Did you get that error on executing?
$ composer require twig/inky-extra
Because in package dependencies it clearly shows that you need to have XSL extension, otherwise I suppose this package won't be even installed. Just want to clarify things here.
Cheers!
Hy Victor!
I not sure that the XSL-ext is required
https://github.com/twigphp/...
I installed the package without any err but then I tried to get a result on the page I got an unobvious error message. Then I've been looking for it in SO and understood I need to install XSL
Hey Bagar,
Hm, interesting. OK, thanks for additional clarification on it, I think note would help here.
Cheers!
👍🏻
Hey Roman P.
Thanks for letting us know about it. We'll add a note to the tutorial
Cheers!
You should also note that you may need to enable the .xsl extension in PHP .ini when you are running the composer require inky command
Hey Nick F.!
Ah, that's true! A package downstream requires it - so you would get a Composer error if you're missing it. Is that what you saw? Or did it (somehow) allow you to download the package and you got an error later?
Cheers!
Hi team,
Isn't going to be resource consuming to transform inky to html and inline css on every email send?
What are the benefits except for keeping the inky files within the same version control?
I mean, wouldn't it be better to use production exports of the email templates instead?
Greets!
Hey Donchev,
Hm, good question! But what exactly do you mean about "to use production exports of the email templates instead"? Yes, you can always make it faster by doing some kind of optimization (sometimes probably crazy complex optimization?), but does it worth it? And probably it depends! It depends on *your* project and on how many and how often you send your emails. If you really send a lot, probably it would be better for you. But if you send rare, or send not so many emails at once - probably that level of complexity would be worse for you, because you would need to maintain that complexity in the future. Anyway, you can always profile and measure things, and see if you need some optimization in this spot or you just don't care.
As always, using simple "if-else" router is always faster than using Symfony Router, dispute the fact that Symfony Router is probably the fastest router written in PHP. But does it mean that you need to rewrite all your routes with simple "if-else" router?.. ;)
I hope this helps!
Cheers!
Thank You for the reply!
<blockquote>But what exactly do you mean about "to use production exports of the email templates instead"</blockquote>
Currently i am developing my email templates as a separate "foundation for emails" project.
With
npm run buildI get the production ready files (with css inlined), then I move these file to my Symfony project.On my current project I send roughly 50-60k emails per month (transactional + newsletters). If I move the inky files to symfony, this will mean that the inky template will be converted and css inlined by twig 50-60k times per month, right?
Hey mr_d!
Ah, yes I understand! We also have used the separate "foundation for emails" project - so I understand what you mean by doing all the transforming and inlining at "compile" time. The short answer is that: if you use the Twig functions, then yes - you will be going through the inlining & inky transformation for *every* email. The benefit of course is simplicity in your code. But there is that performance cost - and I haven't profiled it to know exactly how high it is. Some ability to cache the inlining or inky transformation could be added to the Twig extensions - but it doesn't exist currently. So, my best advice is to: (A) profile to see how big of an issue this is and (if it is) (B) either stick with your current setup or (most performant) send your emails async anyways with Messenger. If you're really worried about performance... the last option is the "best" because even if you aren't doing this processing for every email, sending emails still involves a network request. If you can make it async, obviously, that will have the best page speed result.
Anyways, great question! Let me know if it makes sense.
Cheers!
Thanks for the reply!
I will implement messenger into my project regardless of the email template - because it's nice ferature. But probably will keep the email templates as a separate project and use only the HTML files in Symfony.
:)
"Houston: no signs of life"
Start the conversation!