Reputation: 2711
I am successfully sending emails with this piece of code:
\App::setLocale('pl');
Mail::send('emails.new_'.$itemtype, ['object' => $object, 'email' => $email_recipee], function ($m) use ( $email_recipee, $object, $itemtype) {
$m->to($email_recipee, 'Title')->subject(' Subject of email');
//
});
But the emails are translated to en
, the default language of the app.
How make Laravel send email with a locale declared just for a particular email (each recipient has a different language set).
\App::setLocale('pl');
just before the Mail
commandsetting my working middleware in the controller globally in __construct()
:
$this->middleware('setLocale'); // sets the locale to the recipee locale
For now I just add a line inside the email view:
{{ \App::setLocale($lead->client->lang)}}
Any better way to do it? Thank you.
Upvotes: 10
Views: 13458
Reputation: 29059
Update: Since Laravel 5.7 you can use localize mailables:
Mail::to($request->user())->locale('es')->send(
new OrderShipped($order)
);
Before Laravel 5.7:
What you proposed should work. Just change the locale before sending the mail. However you should be sure to reset the locale:
$temp = \App::getLocale();
\App::setLocale($user->language);
\Mail::to($user)->send(new OrderShipped($order));
\App::setLocale($temp);
Since this is a bit bloated you could simplify that to
\App\Mail\SendMail::to($user, '\App\Mail\OrderShipped', [$order]);
if you create the following SendMail
class:
<?php
namespace App\Mail;
use App\User;
class SendMail
{
/**
* Send Mail to correct emailadress and set correct language
* @param User $user
* @param String $classname
* @param Array $data
* @return void
*/
public static function to(User $user, String $class, Array $params)
{
$temp = \App::getLocale();
\App::setLocale($user->lang);
$reflection_class = new \ReflectionClass($class);
$mailclass = $reflection_class->newInstanceArgs($params);
\Mail::to($user)->send($mailclass);
\App::setLocale($temp);
}
}
Maybe its also usefull to know that you can get your language content also without setLocale
. For instance __('birthday_parole', [], 'pl')
will try to give you the polish version, despite the settings of setLocale
.
Upvotes: 4
Reputation: 1042
TL;DR: Just set a $locale
field in an object of Mailable
class:
class ResetPassword extends Mailable
{
// ...
/**
* Create a new message instance.
*/
public function __construct(User $user, string $token)
{
$this->user = $user;
$this->token = $token;
/*
* Set locale of mail to User's locale
*/
$this->locale = $this->user->locale; // <-- of course adapt this line to YOUR User model :]
}
Long story:
There is a trait Localizable
. It declares a method withLocale
that calls a given function "enveloped" in a specified locale. By "enveloping" I mean: remember a current locale, set a new locale, call a function, restore the remembered locale.
An example of usage can be found in \Illuminate\Mail\Mailable::send
:
public function send(MailerContract $mailer)
{
return $this->withLocale($this->locale, function () use ($mailer) {
Container::getInstance()->call([$this, 'build']);
return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) {
$this->buildFrom($message)
->buildRecipients($message)
->buildSubject($message)
->runCallbacks($message)
->buildAttachments($message);
});
});
}
However, this method gives us a clue how to change a locale for a mail - in the first line there is $this->locale
. Indeed, Mailable
has this field defined:
class Mailable implements MailableContract, Renderable
{
// ...
/**
* The locale of the message.
*
* @var string
*/
public $locale;
Upvotes: 13
Reputation: 5168
For anyone using Laravel 6.* and viewing this post, it looks like things have changed more recently.
Now, you can define the locale within the controller itself, simply by adding ->locale()
to the Mail.
For example:
Mail::to($request->user())->locale('es')->send(
new OrderShipped($order)
);
For more information, please see the official documentation.
Happy coding!
Upvotes: 8
Reputation: 701
You can use the Mailable class
Docs
In the constructor __construct(User $user)
you can type hint the user, and set the locale from there:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
class Welcome extends Mailable
{
use Queueable, SerializesModels;
protected $user;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(User $lead)
{
\App::setLocale($lead->client->lang);
$this->user = $lead;
$this->subject = trans('welcome_title');
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('emails.welcome')->with('user', $this->user);
}
}
Upvotes: 1