Easy and Fast Emails with Laravel 5.3 Mailables

Introduction
Laravel 5.3 has just been released and there are a ton of great new features. One of the major improvements is in how you send mail in your applications.
Let’s take a look at sending emails. Before Laravel 5.3, sending emails in Laravel looked a lot like this.
Mail::send(’emails.send’, [‘title’ => $title, ‘message’ => $message], function ($message) { $message->from(‘no-reply@example.com’, ‘Bat Signal’); $message->to(‘batman@example.com’); });
This method worked for a while, but after sending a couple of emails, the codebase got messy. Since I didn’t really like this method, I found myself using event listeners to build emails.
At the time of this article, installing Laravel 5.3 with Laravel installer is as simple as.
- laravel new project
Mailables in Laravel abstracts building emails with a mailable class. Basically, mailables are responsible for collating data and passing them to views. Meanwhile, the API for sending emails got really simple.
To send emails in Laravel, all we have to do now is.
Mail::to(‘batman@example.com’)->send(new KryptoniteFound);
Don’t get me wrong, the previous API will work just fine (and it will still work in your applications) — it’s just that the Mail API got a whole lot simpler.
With artisan our super handy Laravel CLI-tool, we can simply create a mailable like this.
- php artisan make:mail
Since our mailable’s name is KryptoniteFound, we can create our mailable using this command.
- php artisan make:mail KryptoniteFound
After we’ve created our mailable, in app/mail, we can see our newly created mailable class.
namespace AppMail; use IlluminateBusQueueable; use IlluminateMailMailable; use IlluminateQueueSerializesModels; use IlluminateContractsQueueShouldQueue; class KryptoniteFound extends Mailable { use Queueable, SerializesModels; public function __construct() { } public function build() { return $this->view(‘view.name’); } }
The created class should look like the snippet above (comments stripped).
As we can see, the build method builds the message. For our case, we can replace the view.name with the path to our email view email.kryptonite-found.
In resources/views create a new blade template in an email folder called kryptonite-found.blade.php.
Any public property on your mailable class is automatically made available to your view file. So passing data to your views is as simple as making the data public on the mailable class.
Say for example I wanted to pass the weight of Kryptonite found, all I need to do is expose the total on the mailable like this.
public $total = 30;
While in our view template, we access the data like a normal variable.
Woot Woot!!
Alfred just found {{ $total }}lbs of kryptonite
We can also explicitly set data using the with method.
public function build() { return $this->view(’emails.kryptonite-found’) ->with($key, $value); }
To send emails, we will use mailtrap. For other service configurations like Amazon SES, Chris wrote an article on the topic.
Next, we move to our .env file and configure our mail credentials.
MAIL_DRIVER=”smtp” MAIL_HOST=”mailtrap.io” MAIL_PORT=2525 MAIL_USERNAME=MAIL_USERNAME MAIL_PASSWORD=MAIL_PASSWORD MAIL_ENCRYPTION=null
You replace MAIL_USERNAME and MAIL_PASSWORD with your mailtrap details. Using the credentials above won’t work.
Still, on the issue of configuring mail, we also need to configure the mailers from details. In config/mail.php, look for an array from key and configure the address and name. If you are satisfied with the defaults, you can just leave it. But, under no condition can it be null.
Adding bcc, cc and the rest can be called on $this in the build method.
public function build() { $address = ‘ignore@example.com’; $name = ‘Ignore Me’; $subject = ‘Krytonite Found’; return $this->view(’emails.kryptonite-found’) ->from($address, $name) ->cc($address, $name) ->bcc($address, $name) ->replyTo($address, $name) ->subject($subject); }
Previously, our routes were located in app/Http/routes.php, but with this release, routes are now in app/routes. Now we can use routes based on the interface (web, API, or console). For this tutorial, we only need the web.php routes file.
use AppMailKryptoniteFound; Route::get(‘/’, function () { Mail::to(‘batman@batcave.io’)->send(new KryptoniteFound); return view(‘welcome’); });
Now, we can start our Laravel server by running the following artisan command.
- php artisan serve
We can trigger an email by visiting http://localhost:8080.
To queue emails, instead of calling send on the Mail::to, just call the queue method and pass it the mailable.
Mail::to(‘batman@example.com’)->queue(new KryptoniteFound);
Delay Message Queueing
To delay a queued email, we use the later method. This method takes in two parameters. The first is a DateTime object that represents the time to wait. The second parameter is mailable.
$when = CarbonCarbon::now()->addMinutes(10); Mail::to(‘batman@example.com’)->later($when, new KryptoniteFound);
Laravel 5.3 offers a lot of promising features like notifications, OAuth, search, etc. Watch out for them.