I am working on my first Laravel 5 project and desperately need a way to inline CSS from my email views. I am using Mailgun because of delivery issues with Mandrill (unfortunately, Mandrill has CSS inline capability baked in but Mailgun does not).
It appears that most packages out there for inlining CSS on emails for Laravel are out of date, most stopped working correctly on version 4.2. I have tried:
Inlining CSS when sending an email with Mailgun in Laravel - Antoine Augusti - does not seem to do anything, emails are not inlined. It appears that there are several fundamental differences in L5 that break this approach
fedeisas/laravel-mail-css-inliner - Does not work. Someone posted some code at the end of this Issue but I cannot figure out how to implement it (also do not know if it was intended for Laravel 5).
bweston92/laravel-inline-css-mailer - Looks promising but does not seem to do anything, CSS is not being inlined.
Does anyone have any recommendations? I would really like to be able to inline CSS for email, especially when I'm injecting HTML prior to sending (from WYSIWYG editor).
Inspired by bweston92/laravel-inline-css-mailer, which I could not get to work, I came up with this little class using the TijsVerkoyen\CssToInlineStyles package. Please feel free to offer suggestions or point me in a better direction, just needed something quickly.
<?php namespace App\Library;
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
/**
* Class inlineEmail
*
* Returns rendered Email view with inlined CSS
* @package App\Library
*/
class inlineEmail {
/**
* Filename of the view to render
* @var string
*/
private $view;
/**
* Data - passed to view
* @var array
*/
private $data;
/**
* @param string $view Filename/path of view to render
* @param array $data Data of email
*/
public function __construct($view, array $data)
{
// Render the email view
$emailView = view($view, $data)->render();
$this->view = $emailView;
$this->data = $data;
}
/**
* Convert to inlined CSS
*
* @return string
* @throws \TijsVerkoyen\CssToInlineStyles\Exception
*/
public function convert()
{
$converter = new CssToInlineStyles();
$converter->setUseInlineStylesBlock();
$converter->setCleanup();
$converter->setStripOriginalStyleTags();
$converter->setHTML($this->view);
$content = $converter->convert();
return $content;
}
}
Use:
$data = ['someVar' => 'someValue'];
$inlineEmail = new inlineEmail('emails.group-email', $data);
$content = $inlineEmail->convert();
Mail::queue('emails.raw', ['content' => $content], function($message) use ($data) {
$message->subject('Hello World')
->to('[email protected]')
->bcc($data['recipients']);
});
The converted, inlined HTML/CSS is then passed to emails.raw
, which contains only {!! $content !!}
.
Here is the template I use for the majority of my emails - it is essentially a minimal version of Bootstrap for email. I'd give credit to its author but having trouble tracking down exactly where I found it, if someone knows please leave a comment. There are many other templates out there, just search for Bootstrap Email Template or HTML Email Boilerplate.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Email Title</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
font-size: 100%;
line-height: 1.6;
}
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
width: 100%!important;
height: 100%;
}
a {
color: #348eda;
}
.btn-primary {
text-decoration: none;
color: #FFF;
background-color: #348eda;
border: solid #348eda;
border-width: 10px 20px;
line-height: 2;
font-weight: bold;
margin-right: 10px;
text-align: center;
cursor: pointer;
display: inline-block;
border-radius: 25px;
}
.btn-secondary {
text-decoration: none;
color: #FFF;
background-color: #aaa;
border: solid #aaa;
border-width: 10px 20px;
line-height: 2;
font-weight: bold;
margin-right: 10px;
text-align: center;
cursor: pointer;
display: inline-block;
border-radius: 25px;
}
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.padding {
padding: 10px 0;
}
table.body-wrap {
width: 100%;
padding: 20px;
}
table.body-wrap .container {
border: 1px solid #f0f0f0;
}
table.footer-wrap {
width: 100%;
clear: both!important;
}
.footer-wrap .container p {
font-size: 12px;
color: #666;
}
table.footer-wrap a {
color: #999;
}
h1, h2, h3 {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
line-height: 1.1;
margin-bottom: 15px;
color: #000;
margin: 40px 0 10px;
line-height: 1.2;
font-weight: 200;
}
h1 {
font-size: 36px;
}
h2 {
font-size: 28px;
}
h3 {
font-size: 22px;
}
p, ul, ol {
margin-bottom: 10px;
font-weight: normal;
font-size: 14px;
}
ul li, ol li {
margin-left: 5px;
list-style-position: inside;
}
.container {
display: block!important;
max-width: 600px!important;
margin: 0 auto!important; /* makes it centered */
clear: both!important;
}
.body-wrap .container {
padding: 20px;
}
.content {
max-width: 600px;
margin: 0 auto;
display: block;
}
.content table {
width: 100%;
}
</style>
</head>
<body bgcolor="#f6f6f6">
<!-- Main Body -->
<table class="body-wrap">
<tr>
<td></td>
<td class="container" bgcolor="#FFFFFF">
<div class="content">
<table>
<tr>
<td align="center">
<img src="https://example.com/images/logo.png" alt="Company Logo"/>
</td>
</tr>
<!-- Email content goes here .. -->
@yield('content')
</table>
</div>
</td>
<td></td>
</tr>
</table>
<!-- /Main Body -->
<!-- Footer -->
<table class="footer-wrap">
<tr>
<td></td>
<td class="container">
<div class="content">
<table>
<tr>
<td align="center">
<p>Footer goes here</p>
</td>
</tr>
</table>
</div>
</td>
<td></td>
</tr>
</table>
<!-- /Footer -->
</body>
</html>
A typical email that extends this view would look something like this:
@extends('emails.template')
@section('content')
<tr>
<td>
<h1>Example Email</h1>
<p>This is an example email. There are many like it but this one is mine.</p>
</td>
</tr>
<tr>
<td align="center">
<p>
<a href="http://example.com" class="btn-primary">This is a Button</a>
</p>
</td>
</tr>
@endsection
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With