bernhard Posted February 6 Share Posted February 6 Ever felt like your ProcessWire emails look like they're stuck in 1999? You know the drill - sending emails is super easy with WireMail: $m = new WireMail(); $m->from('foo@bar.com'); $m->to('xxx@yyy.com'); $m->subject('Hello there!'); $m->bodyHTML('<h1>This is great!</h1><p>I am an ugly mail...</p>'); $m->send(); But let's be honest - they look about as pretty as a website built with Microsoft FrontPage! π πͺ Enter the Mail Pimp Hook! Drop this magical hook into your /site/ready.php (or even better Site.module.php), and watch your emails transform from ugly ducklings into beautiful swans: <?php $wire->addHookBefore('WireMail::send', function(HookEvent $event) { // double check that we got a wiremail instance // this also tells the IDE what $mail is (to get IntelliSense) $mail = $event->object; if (!$mail instanceof WireMail) return; // get current mail body $html = $mail->get('bodyHTML'); if (!$html) return; // get email layout markup $layoutFile = wire()->config->paths->templates . 'mails/default.html'; if (!is_file($layoutFile)) return; // replace ##content## with actual mail content $html = str_replace( '##content##', $html, wire()->files->render($layoutFile) ); // write new body to mail $mail->bodyHTML($html); }); The HTML Just create a beautiful MJML template at /site/templates/mails/default.mjml, put ##content## where your email content should go, convert it to HTML and BOOM! π₯ Every email gets automatically wrapped in your gorgeous template. No more CSS wrestling matches, no more "Why does this look different in Outlook?" headaches. Just pure email beauty, automagically! β¨ Now your clients will think you spent days crafting those emails, when in reality, you're sipping coffee while your hook does all the heavy lifting. Work smarter, not harder! π #ProcessWire #EmailMagic #NoMoreUglyEmails PS: This is the MJML template that I used: <mjml> <mj-head> <mj-attributes> <mj-all font-family="Tahoma" /> <mj-text line-height="140%" /> </mj-attributes> </mj-head> <mj-body background-color="#efefef"> <mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="30px" padding-top="30px" text-align="center" > <mj-column> <mj-image align="center" padding="25px" src="xxx" target="_blank" width="200px" alt="Logo" ></mj-image> <mj-text>##content##</mj-text> </mj-column> </mj-section> <mj-section> <mj-column> <mj-text font-size="10px" color="#a0a0a0" align="center" > powered by <a href="https://www.baumrock.com/" style="color: #158f66" >baumrock.com</a > </mj-text> </mj-column> </mj-section> </mj-body> </mjml> VSCode has an extension to get a live preview and export MJML to HTML: And here are some other free templates: https://mjml.io/templates I use https://www.base64-image.de/ to add the logo to my mail template as src="data:image/jpeg;base64,/9j/4QAWRXhpZgAATU0AKgAAAA..." to avoid headaches with image paths, remote assets blocking etc. 13 6 Link to comment Share on other sites More sharing options...
Jonathan Lahijani Posted February 6 Share Posted February 6 Nice. Just wanted to mention Cerberus as an alternative to MJML if you want to use email-friendly HTML templates directly. 10 1 Link to comment Share on other sites More sharing options...
Laksone Posted February 21 Share Posted February 21 That's really cool! Thanks! π 1 Link to comment Share on other sites More sharing options...
Ellyot_Chase Posted February 25 Share Posted February 25 Wow, really helpfull @bernhard! Thanks. Up until now i had an output buffer and included a template file, or rendered a page before my wiremail call to get an instance. But this will make things way cleaner. 1 Link to comment Share on other sites More sharing options...
bernhard Posted February 25 Author Share Posted February 25 Glad it was helpful π 1 Link to comment Share on other sites More sharing options...
Cybermano Posted 21 hours ago Share Posted 21 hours ago Thanks @bernhard in past I have used Cerberus as mentioned by @Jonathan Lahijani, but MJML is very awesome; expecially for the VScode extension with the html compiler. and preview. I think the template could be used directly in the wire mail construct, (without the ready hook): // ... $m->bodyHTML(wire()->files->render($layoutFile)); // ... Or do you think this is not a good practice? Now I'm testing it dynamically with "placeholders" : // get template $bodyHTML = wire()->files->render($layoutFile); // let's say we have 2 placeholders into the html template: one for user name as [[userName]] and one page body content as [[pageBody]] $bodyHTML = str_replace( ["[[userName]]","[[pageBody]]"], [ucfirst(wire('user')->name),$page->body], $bodyHTML, ); // ... $m->bodyHTML($bodyHTML); // ... This works for me: it has great potential. Many thanks again for sharing this solution. Link to comment Share on other sites More sharing options...
bernhard Posted 17 hours ago Author Share Posted 17 hours ago Hey @Cybermano glad it was helpful! 21 hours ago, Cybermano said: // ... $m->bodyHTML(wire()->files->render($layoutFile)); // ... Or do you think this is not a good practice? Expand That's what I've been using before I had the idea of hooking into WireMail::send. Everything in life has pro's and con's... So I'd not say it's a bad practise. But what I like about the solution is that it fits my credo "simple things should be simple". Sending a beautiful thing should be simple. And what you show might look QUITE simple it's not as simple as my version. If you only have one mail it won't matter or your version would even be easier (because you see everything that is going on). But if you are sending mails from different places in different occasions (eg on registration, on a new post, on a schedule, etc...) then my version keeps your code DRY (don't repeat yourself) whereas your version either tempts the dev to copy and paste those lines of code or be too lazy and just send out an ugly 90s style email. Both is not ideal in my opinion and investing a little more time to setup the hook will be beneficial in the long run. Also, while it's just a few lines of code, when your codebase grows every line of code that is not instantly and easily understandable matters. Your brain has to read the code, understand it, interpret it and remember it. With your str_replace that might be QUITE easy, but things add up and suddenly it might make the difference between easy to read code and a bloat of spaghetti code. It's about building a habit. Another problem with your solution is that if you copy&paste this to 3 spots, for example, and later you add another replacement tag, you have to do a search&replace and you might miss one spot and you introduce a bug. If you have it on a central place this can not happen. On the other hand if you want to render different files or you want different tags for different emails your approach might be the better one. And for someone not familiar with your codebase it might be easier to understand your version vs. the hook, because only seeing the $mail->send() somewhat hides how the mail gets sent with nice HTML and your version makes that obvious. 1 Link to comment Share on other sites More sharing options...
Cybermano Posted 17 hours ago Share Posted 17 hours ago Hi @bernhard, thanks for your explanations. I will made my best trying to follow those suggestions. 1 Link to comment Share on other sites More sharing options...
monollonom Posted 7 hours ago Share Posted 7 hours ago @Cybermano you could also use this module I made https://processwire.com/modules/page-mjml-to-html/, though you lose the ability to see your changes live in VSCode. Pros and cons like @bernhard says π 1 1 Link to comment Share on other sites More sharing options...
Cybermano Posted 4 hours ago Share Posted 4 hours ago Thanks @monollonom, it looks very interesting. I will surely give a look and try. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now