I'm attempting to modify the template for e-mails on an older website I did, running Laravel 5.4
I do eventually plan to update to at least Laravel 5.5, and possibly Laravel 5.7 - but I don't want to do that right now unless strictly necessary (it would involve some significant re-writes to some of my controllers and a lot of extra testing)
I ran:
php artisan vendor:publish --tag=laravel-mail
This created files in resources/views/vendor/mail
I then edited these files and tried sending a message. No change.
I then edited the files in vendor/laravel/framework/src/Illuminate/Mail/resources/views/
and sent a message - the new template showed up.
So despite the existence of the resources/views/vendor/mail
folder, Laravel is still reading from the vendor/
folder after running php artisan vendor:publish
. How do I fix this? What am I doing wrong?
Update
Some additional info, in case it helps. Here's my mail template (resources/views/mail/email-a-friend.blade.php
):
@component('mail::message')
Your friend, {{ $senderName }}, has sent you information about a property they feel you might be interested in.
This property is listed by {{ config('app.name') }}. To view this property and more like it, please click the link below.
@if($agent->id !== $property->agent->id)
[{{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }}]({{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }})
@else
[{{ url($property->url()) }}]({{ url($property->url()) }})
@endif
@if($text != "")
They also sent this message:
@component('mail::panel')
{{ $text }}
@endcomponent
@endif
@endcomponent
Here's the controller that queues up the e-mail (app/http/Controllers/AjaxController.php
- just the relevant function):
public function emailAFriend(Request $request)
{
$property = \App\Models\Property\Property::find($request->input('property-id'));
$agent = $property->agent;
if ($request->input('agent-id') !== $agent->id) {
$agent = \App\User::find($request->input('agent-id'));
}
Mail::to($request->input('send-to'))
->queue(new \App\Mail\EmailAFriend($property, $agent, $request->input('name'), $request->input('reply-to'), $request->input('text')));
return Response::json("success", 200);
}
Here's the Mailable (app/Mail/EmailAFriend.php
):
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Property\Property;
use App\User;
class EmailAFriend extends Mailable
{
use Queueable, SerializesModels;
public $subject = "Someone sent you a property!";
public $property;
public $agent;
public $senderName;
public $senderEmail;
public $text;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(Property $property, User $agent, $name, $email, $text)
{
$this->subject = "$name sent you information about a property";
$this->property = $property;
$this->agent = $agent;
$this->senderName = $name;
$this->senderEmail = $email;
$this->text = $text;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.email-a-friend')
->replyTo($this->senderEmail, $this->senderName)
->attachData(
$this->property->generatePdf(['agent' => $this->agent])->inline(),
"{$this->property->details->lot_size} acres in {$this->property->location->county} county.pdf",
[
'mime' => 'application/pdf'
]
);
}
}
For testing purposes I'm using the sync
QueueDriver, so this sends immediately upon the AJAX request being made. In production I use the database
QueueDriver.
Update 2
The components:
resources/views/vendor/mail/html/message.blade.php
:
@component('mail::layout')
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
<img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />
@endcomponent
@endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
@if (isset($subcopy))
@slot('subcopy')
@component('mail::subcopy')
{{ $subcopy }}
@endcomponent
@endslot
@endif
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
@endcomponent
@endslot
@endcomponent
resources/views/vendor/mail/markdown/message.blade.php
:
@component('mail::layout')
{{-- Header --}}
@slot('header')
@component('mail::header', ['url' => config('app.url')])
 }})
@endcomponent
@endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
@if (isset($subcopy))
@slot('subcopy')
@component('mail::subcopy')
{{ $subcopy }}
@endcomponent
@endslot
@endif
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
@endcomponent
@endslot
@endcomponent
The difference between these two and the default components (vendor/laravel/framework/src/Illuminate/Mail/resources/views/html/message.blade.php
and the markdown equivalent) is in the header:
{{ config('app.name') }}
replaced with:
<img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />
I was attempting to replace the company name with their logo. When I go into vendor/laravel/framework/src/Illuminate/Mail/resources/views/markdown/message.blade.php
and edit this file directly, I do see the logo in the resulting e-mail. So despite the existence of the published component, it's still reading from the vendor/
directory (and editing the vendor/
directory is no good, because then the change won't persist in production)
php artisan view:clear
? – Mihir Bhendevendor
directory instead of theresources/views/vendor
directory. And yes, I did customize both the HTML and markdown components. I'll append those to my post. – stevendesuconfig/mail.php
? – Mihir Bhendeconfig/mail.php
. In fact, most ofconfig/mail.php
is ignored as I'm using.env
to overwriteMAIL_DRIVER
,MAIL_HOST
,MAIL_PORT
,MAIL_USERNAME
,MAIL_PASSWORD
,MAIL_ENCRYPTION
,MAIL_FROM_ADDRESS
, andMAIL_FROM_NAME
. – stevendesu