Passing variables to email footer in Laravel - laravel

I would like to show a disclaimer in the footer saying
This email was sent to {recipients email address}.
but i can't figure out how i can get the email address into the standard footer blade.
Here is what I have:
In my notification component I make the following call with $rcp_email having the email address of the recipient:
return (new MailMessage)
->subject('Contact Form Submitted')
->markdown('emails.generic.contactform', [
'first_name' => $this->first_name,
'message' => $this->message,
'rcp_email' => $this->rcp_email,
'url_security_issue' => $url_security_issue,
]);
The emails.generic.contactform looks like this
#extends('emails.main')
#section('content')
(body of email)
#endsection
emails.main looks like this
#component('mail::message')
#yield('content')
#if (isset($unsubscribe_url))
(html code for unsubscribe)
#endif
#endcomponent
the standard vendor\mail\html\message blade looks like this:
#component('mail::layout')
{{-- Header --}}
#slot('header')
#component('mail::header', ['url' => config('app.front_end_url'), 'logo' => asset('logo-image-white-circular-background.png')])
{{ config('app.name') }}
#endcomponent
#endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
#isset($subcopy)
#slot('subcopy')
#component('mail::subcopy')
{{ $subcopy }}
#endcomponent
#endslot
#endisset
{{-- Footer --}}
#slot('footer')
#component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. #lang('All rights reserved.')
#endcomponent
#endslot
#endcomponent
I traced each level of blade and $rcp_email is first of all not availble in the message blade. I tried to pass it on by changing the first line of emails.main to
#component('mail::message', ['rcp_email' => $rcp_email])
but in either case when i try to use the variable in the message blade, i get the error Undefined variable: rcp_email
In an ideal case, I would want to add the html code and make use of the variable in the actual footer blade, but I don't know if that's possible.
I would much appreciate if there is any hints/any docus or articles you can share that describes in depth how this works?
Thanks,
Goppi

hopefully this helps for others with issue
From what I did, when you use #component('mail::message', ['rcp_email' => $rcp_email]) it will pass the variable $rcp_email to the message blade.
Here change your message blade #component('mail::footer') to #component('mail::footer', ['rcp_email' => $rcp_email]) to pass it again to your footer blade.
In footer blade access the variable like {{$rcp_email}}
so example would be <p>sent to {{$rcp_email}}</p>
Also as a note, when passing the variable like ['name' => $variable] it uses the name as the variable in the next blade. so here you would access it like $name

Thanks #Jack C - your solution didn't work for me back then as you can see from my original post. I tried to pass rcp_email on to the message blade using
#component('mail::message', ['rcp_email' => $rcp_email])
and when I tested $rcp_email within the message blade, it came back with undefined variable. That said, I didn't figure out why it wasn't working, but I used #component with variables for other blades without issues. Perhaps it didn't work due to caching issue.
The solution that I came up with back then opened itself up once I decided not to use the standard email template, but design my own.
The emails.generic.contactform changed as follows:
#extends('emails.layout.layout')
#section('content')
{{-- body of email --}}
#endsection
The emails.layout.layout blade looks like this:
#component('mail::layout')
{{-- Content --}}
{{-- Footer --}}
#slot('footer')
#component('mail::footer')
{{ $recipient ?? '' }}
#endcomponent
#endslot
to summarize, my understanding on how to pass variables between blades is as follows:
extend - extends allows the layout blade to use all variables with the same names as the extended blade.
#extends('layout')
components have no access to the variables of the parent blade. Instead they need to be passed on. There are two ways to pass them on: as one or more variables or as a slot. In the example below $name is available within the component footer.
#component('footer', ['name' => $rcp_email])
#endcomponent
component - the second way is as a slot. In the example below the variable $slot would contain the email address.
#component('footer')
{{ $rcp_email }}
#endcomponent

Related

How to customize the emails sent by Laravel Breeze?

I wanted to customize the emails sent by Breeze from the default styles. Looks like the installation of Breeze does not publish the files for that but I found online that using php artisan vendor:publish --tag=laravel-notifications will publish the email files, and it did, although looks like it did not publish all the necessary files (it only published one file)
It only published /vendor/notifications/email.blade.php, with the following code, but looks like other things are missing like the components themselves such as the x-mail::button?
<x-mail::message>
{{-- Greeting --}}
#if (! empty($greeting))
# {{ $greeting }}
#else
#if ($level === 'error')
# #lang('Whoops!')
#else
# #lang('Hello!')
#endif
#endif
{{-- Intro Lines --}}
#foreach ($introLines as $line)
{{ $line }}
#endforeach
{{-- Action Button --}}
#isset($actionText)
<?php
$color = match ($level) {
'success', 'error' => $level,
default => 'primary',
};
?>
<x-mail::button :url="$actionUrl" :color="$color">
{{ $actionText }}
</x-mail::button>
#endisset
{{-- Outro Lines --}}
#foreach ($outroLines as $line)
{{ $line }}
#endforeach
{{-- Salutation --}}
#if (! empty($salutation))
{{ $salutation }}
#else
#lang('Regards'),<br>
{{ config('app.name') }}
#endif
{{-- Subcopy --}}
#isset($actionText)
<x-slot:subcopy>
#lang(
"If you're having trouble clicking the \":actionText\" button, copy and paste the URL below\n".
'into your web browser:',
[
'actionText' => $actionText,
]
) <span class="break-all">[{{ $displayableActionUrl }}]({{ $actionUrl }})</span>
</x-slot:subcopy>
#endisset
</x-mail::message>
How can I customize that? The buttons for example? Because looks like this template is working for all the types of emails (welcome, verification, password-reset), so I can't just replace the contents with my code but I somehow need only to change the styles

Laravel Components: default content in {{ slots }}

In old-style Laravel blade templated we used to use #section('section-name') in the following way:
{{-- h1para.blade.php --}}
<h1>
#section('heading')
Heading from Template
#endsection
</h1>
<p>
#yield('details')
</p>
And then extend that template with:
{{-- content.blade.php --}}
#extends('h1para')
#section('details')
Content from content page
#endsection
In the above, my rendered HTML output would look like the following, because the "missing" 'heading' section in the extending file means that we default back to the content in the template:
<h1>Heading from Template</h1>
<p>Content from content page</p>
But in the new components way of doing things, I do:
{{-- .../components/h1para.blade.php --}}
<h1>{{ $heading }}</h1>
<p>{{ $slot }}</p>
In case you haven't gathered, the question is: how do I set a default value for a slot's contents, such that if it isn't supplied in the extending component/template, it falls back to that default?
(I've done my searches, but haven't been able to find the same question asked before)
EDIT:
I should add that I've seen the solution (in the Laravel documentation):
<h1>{{ $heading ?? 'Default Heading Here' }}</h1>
But this seems only to be appropriate if the default value is a short easy to manage string. If the default is a long stream of HTML, then it wouldn't work for my needs.
EDIT 2:
Just to reiterate: the whole point of the question is that the default content could be a long stream of HTML. Solving the problem by passing in a string (be that formatted as HTML or not) wouldn't work for my real-world needs.
I think the solution is this:
{{-- .../component/template.blade.php --}}
<div>
#if (isset($heading))
{{ $heading }}
#else
<h1>Default Heading<span class="subhead">default subheadin and lots of other html content</span></h1>
#endif
<p>{{ $slot }}</p>
</div>
It's not super elegant, but I think it's the only solution. Anyone else have a better answer, I'd love to hear it.
If you pass data like:
<x-h1para header="<span>Header content</span>">
<div>Default slot content here</div>
</x-h1para>
You can display in your component like:
<div>
<h1>{!! $heading ?? 'Default Heading Here' !!}</h1>
{{ $slot }}
</div>

Parse content from function as were it Blade contents

I've got a blade view in which I load another string via a function called retrieveSomeContent()
retrieveSomeContent() returns a string, which could hold 'references' like {{ $action->url }}. The data itself is available in the view.
// myView.blade.php
// simplified
...
{{-- doesn't work
displays {{ $action->url }}
--}}
{!! retrieveSomeContent('section1B') !!}
{{-- works --}}
{{ $action->url }}
...
Off course the view right now will just displays {{ ... }} as text instead of parsing it to http://......
How would I be able to parse the string generated via retrieveContent()?

How can I solve "No hint path defined for [mail]." (customize email layout) on laravel?

From here : Laravel 5.4 - How to customize notification email layout?
I try customize notification email layout
My code to send email like this :
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Test')
->view('vendor.mail.markdown.message',['data'=>$this->data]);
}
The view like this :
#component('mail::layout')
{{-- Header --}}
#slot('header')
#component('mail::header', ['url' => config('app.url')])
{{ config('app.name') }}
#endcomponent
#endslot
{{-- Body --}}
{{ $slot }} test
{{-- Subcopy --}}
#isset($subcopy)
#slot('subcopy')
#component('mail::subcopy')
{{ $subcopy }}
#endcomponent
#endslot
#endisset
{{-- Footer --}}
#slot('footer')
#component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
#endcomponent
#endslot
#endcomponent
If the code executed, there exist error like this :
(2/2) ErrorException No hint path defined for [mail]. (View:
C:\xampp\htdocs\myshop\resources\views\vendor\mail\markdown\message.blade.php)
How can I solve the error?
If you are using markdown in your template, you need to use the ->markdown() method rather than the ->view() method on your MailMessage
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Test')
->markdown('vendor.mail.markdown.message', ['data' => $this->data]);
}
In an application migrated through different Laravel versions (and now at 5.6) I had to modify the file config/mail.php, changing the parameter markdown/paths from resource_path('views/vendor/mail') to resource_path('views/vendor/mail/markdown'), so it found the base templates for my Markdown mails.

What is the use of .blade in the Laravel framework?

I encountered the file welcome.blade.php in the views folder.
What is the purpose of .blade in the file's name?
Laravel uses Blade Template as its template engine (e.g. smarty was quite popular in past ) and .blade.php is extension used for it. Can find more details here
As mentioned by Abbasi Blade is a templating engine. I just wanted to share a good resource for blade and Laravel in general which provides some nice examples like:
#extends('layout.name')
// Begin a section
#section('name')
// End a section
#stop
// End a section and yield
#show
#parent
// Show a section in a template
#yield('name')
#include('view.name')
#include('view.name', array('key' => 'value'));
#lang('messages.name')
#choice('messages.name', 1);
#if
#else
#elseif
#endif
#unless
#endunless
#for
#endfor
#foreach
#endforeach
#while
#endwhile
//forelse 4.2 feature
#forelse($users as $user)
#empty
#endforelse
// Echo content
{{ $var }}
// Echo escaped content
{{{ $var }}}
{{-- Blade Comment --}}
// Echoing Data After Checking For Existence
{{{ $name or 'Default' }}}
// Displaying Raw Text With Curly Braces
#{{ This will not be processed by Blade }}
check out this site for other Laravel syntax helpers

Resources