Translate queued mails (localization)
I have been struggling to get this done in a more efficient way. Currently I have it set up like this. Hopefully this helps someone in the future with this issue:
// Fetch the locale of the receiver.
$user = Auth::user();
$locale = $user->locale;
Mail::queue('emails.welcome.template', ['user' => $user, 'locale' => $locale], function($mail) use ($user, $locale) {
$mail->to($user->email);
$mail->subject(
trans(
'mails.subject_welcome',
[], null, $locale
)
);
});
And use the following in your template:
{{ trans('mails.welcome', ['name' => ucfirst($user['first_name'])], null, $locale) }}
Note: do not forget to restart your queue
If your emails inherits the built-in Illuminate\Mail\Mailable
class you can build your own Mailable class that will take care of translations.
Create your own SendQueuedMailable
class that inherits from Illuminate\Mail\SendQueuedMailable
.
Class constructor will take current app.location from config and remember it in a property (because laravel queues serializes it).
In queue worker it will take the property back from config and set the setting to the current environment.
<?php
namespace App\Mail;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
use Illuminate\Mail\SendQueuedMailable as IlluminateSendQueuedMailable;
class SendQueuedMailable extends IlluminateSendQueuedMailable
{
protected $locale;
public function __construct(MailableContract $mailable)
{
parent::__construct($mailable);
$this->locale = config('app.locale');
}
public function handle(MailerContract $mailer)
{
config(['app.locale' => $this->locale]);
app('translator')->setLocale($this->locale);
parent::handle($mailer);
}
}
Then, create your own Mail
class that inherits from Illuminate\Mail\Mailable
<?php
namespace App\Mail;
use Illuminate\Contracts\Queue\Factory as Queue;
use Illuminate\Mail\Mailable as IlluminateMailable;
class Mailable extends IlluminateMailable
{
public function queue(Queue $queue)
{
$connection = property_exists($this, 'connection') ? $this->connection : null;
$queueName = property_exists($this, 'queue') ? $this->queue : null;
return $queue->connection($connection)->pushOn(
$queueName ?: null, new SendQueuedMailable($this)
);
}
}
And, voila, all your queued mailables inherited from App\Mailable
class automatically will take care of current locale.
In Laravel 5.6 is a locale function added to Mailable: $infoMail->locale('jp'); Mail::queue($infoMail);