Most web applications use email to communicate with users. Common use cases are to confirm registration for a webapp, to inform customers about the status of an order, to send an invoice etc.
Of course you can send a plain text email, but it’s much nicer to send the emails in the style of the corresponding website, using your own email template. Email templates are very useful for this purpose and fortunately, they are easy to use in Laravel.
One of things that is a bit more tricky, is the customization of the ‘password reset email’ of a default Laravel installation. The default Laravel authentication contains features like user registration, login and password reset functionality. They saved us lots of time, but it took us a bit more effort to customize the password reset email.
Mailables
In this blog, we describe the process of creating mailables, apply them to your own emails and finally customizing the ‘password reset emails’ that are included in the authentication scaffolding of Laravel.
We start with an email to inform customers about the status of their order. Laravel uses markdown mail components by default to create emails. Before you start customizing them, you have to publish the components to the views directory of your project. Use the following command:
php artisan vendor:publish –tag=laravel-mail
As a result, a new directory ‘vendor/mail’ is created in the resources/views directory of your project, which contains a html and a markdown folder. Those contain the components to build up the emails.
Create a mail template
Create a file called ‘your-mail-template’ and save it to the html folder. Make sure to include at least the following parts:
- The html of your template, including a,,and all other fixed parts that should occur in every email you’re sending, e.g. logo, contact information etc.
- At the location where you want to put the main content of your mail, add a $slot variable.
- Named slots can be added to the template, for example, a $title variable.
- For elements that occur in many emails, you can create components or customize the components that ship with Laravel (for example the button component).
- Save a copy to the markdown folder. This is the plain text version of the email, so you have to strip all html from this version.
Create a mailable
Use the following command to create a mailable and the corresponding view for this specific email:
php artisan make:mail OrderStatus –markdown=emails.order-status
This creates a file OrderStatus in the App/Mail directory, and a corresponding view in the resources/views/emails folder called ‘order-status’.
The view
Start with editing the order-status view. Make sure the view has the following components:
@component(‘mail::your-mail-template’) the content that should be placed at the position of the $slot variable in your template, for example: We send this email to inform you that your order has been send @slot(‘title’) Orderstatus @endslot @endcomponent
The mailable
Open the App/Mail/OrderStatus mailable. In the build method, you define the properties of your email, for example:
return $this->markdown('emails.order-status') ->subject(‘The status of your order at my webshop') ->from('info@my-webshop.com', 'Customer service');
This code indicates which email is going to be sent (‘order-status’), what the subject is and who is the sender.
Now, your email is ready and all you have to do is send the email.
Sending your email
Before you are able to send any email, you have to configure a mail server. This is easy in Laravel, but beyond the scope of this blog, so have a look at the official documentation
Let’s assume that you want to send your email from within a controller. All you have to do is add the following code to your controller:
\Mail::to(‘customer@email.com’,’Customer name’)->send(new \App\Mail\OrderStatus);
Customizing the password reset email
Laravel has authentication scaffolding which saves you a lot of time when setting up a new webapp. It sets up functionality for users to register, login and reset their password with a single command.
One of the things you usually want to customize is the reset password email. You can do this, by creating the following mailable:
php artisan make:mail CustomPasswordReset –markdown=emails.password-reset
The view
Build up the email view as described above, but at least include the following component:
@component('mail::button',['url'=>url('password/reset/'. $token.'?email='.$email)]) Reset your password @endcomponent
This will include a button with a link to the page where a user can choose a new password. Of course, it’s the link itself that is important, you can choose a different styling.
The mailable
Make sure the mailable has at least the following methods:
public function __construct($token,$email) { $this->token = $token; $this->email = $email; }
In the constructor method, we accept the email address of the user and some token which is used by the Laravel framework. In the build method of the mailable, we pass these variables to the view.
The build method is similar to the one described above, but we add an additional line to pass variables:
return $this->markdown('emails.password-reset') ->subject(‘Reset your password') ->from('info@my-webshop.com', 'Customer service') ->with([‘token’ => $this->token, ‘email’ => $this->email]);
Notification
We will use Laravel’s notification service to actually send the email. First, we create a notification using the following command:
php artisan make:notification CustomPasswordResetNotification
Notifications allow you to send the same message via several channels, like email, slack or nexmo, but in this case we only use the mail channel. We end up with the following notification:
class CustomPasswordResetEmail extends Notification { use Queueable; public $token, $email; public function __construct($token,$email) { $this->token = $token; $this->email = $email; } public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { return new (\App\Mail\CustomPasswordReset($this->token,$this->email))->to($this->email); } }
In the constructor we accept the token and email variable. Next, in the via method, we define the channel we want to use (email) and finally, we send the email in the toMail method.
Adjusting your user model
The last step in customizing the password reset email for your webapp, is to overwrite the SendPasswordResetNotification of your User model. Add the following code to the User model of your app:
public function sendPasswordResetNotification($token) { $this->notify(new \App\Notification\CustomPasswordReset($token,$this->email)); }
Now you’re done and users will receive a customized password reset email.