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
I have a string returned to one of my views, like this:
$text = '<p><strong>Lorem</strong> ipsum dolor <img src="images/test.jpg"></p>'
I'm trying to display it with Blade:
{{$text}}
However, the output is a raw string instead of rendered HTML. How do I display HTML with Blade in Laravel?
PS. PHP echo() displays the HTML correctly.
You need to use
{!! $text !!}
The string will auto escape when using {{ $text }}.
For laravel 5
{!!html_entity_decode($text)!!}
Figured out through this link, see RachidLaasri answer
You can try this:
{!! $text !!}
You should have a look at: http://laravel.com/docs/5.0/upgrade#upgrade-5.0
Please use
{!! $test !!}
Only in case of HTML while if you want to render data, sting etc. use
{{ $test }}
This is because when your blade file is compiled
{{ $test }} is converted to <?php echo e($test) ?>
while
{!! $test !!} is converted to <?php echo $test ?>
There is another way. If object purpose is to render html you can implement \Illuminate\Contracts\Support\Htmlable contract that has toHtml() method.
Then you can render that object from blade like this: {{ $someObject }} (note, no need for {!! !!} syntax).
Also if you want to return html property and you know it will be html, use \Illuminate\Support\HtmlString class like this:
public function getProductDescription()
{
return new HtmlString($this->description);
}
and then use it like {{ $product->getProductDescription() }}.
Of course be responsible when directly rendering raw html on page.
When your data contains HTML tags then use
{!! $text !!}
When your data doesn't contain HTML tags then use
{{ $text }}
Try this. It worked for me.
{{ html_entity_decode($text) }}
In Laravel Blade template, {{ }} wil escape html. If you want to display html from controller in view, decode html from string.
You can do that using three ways first use if condition like below
{!! $text !!}
The is Second way
<td class="nowrap">
#if( $order->status == '0' )
<button class="btn btn-danger">Inactive</button>
#else
<button class="btn btn-success">Active</button>
#endif
</td>
The third and proper way for use ternary operator on blade
<td class="nowrap">
{!! $order->status=='0' ?
'<button class="btn btn-danger">Inactive</button> :
'<button class="btn btn-success">Active</button> !!}
</td>
I hope the third way is perfect for used ternary operator on blade.
you can do with many ways in laravel 5..
{!! $text !!}
{!! html_entity_decode($text) !!}
Use {!! $text !!}to display data without escaping it. Just be sure that you don’t do this with data that came from the user and has not been cleaned.
To add further explanation, code inside Blade {{ }} statements are automatically passed through the htmlspecialchars() function that php provides. This function takes in a string and will find all reserved characters that HTML uses. Reserved characters are & < > and ". It will then replace these reserved characters with their HTML entity variant. Which are the following:
|---------------------|------------------|
| Character | Entity |
|---------------------|------------------|
| & | & |
|---------------------|------------------|
| < | < |
|---------------------|------------------|
| > | > |
|---------------------|------------------|
| " | " |
|---------------------|------------------|
For example, assume we have the following php statement:
$hello = "<b>Hello</b>";
Passed into blade as {{ $hello }} would yield the literal string you passed:
<b>Hello</b>
Under the hood, it would actually echo as <b>Hello<b>
If we wanted to bypass this and actually render it as a bold tag, we escape the htmlspecialchars() function by adding the escape syntax blade provides:
{!! $hello !!}
Note that we only use one curly brace.
The output of the above would yield:
Hello
We could also utilise another handy function that php provides, which is the html_entity_decode() function. This will convert HTML entities to their respected HTML characters. Think of it as the reverse of htmlspecialchars()
For example say we have the following php statement:
$hello = "<b> Hello <b>";
We could now add this function to our escaped blade statement:
{!! html_entity_decode($hello) !!}
This will take the HTML entity < and parse it as HTML code <, not just a string.
The same will apply with the greater than entity >
which would yield
Hello
The whole point of escaping in the first place is to avoid XSS attacks. So be very careful when using escape syntax, especially if users in your application are providing the HTML themselves, they could inject their own code as they please.
This works fine for Laravel 5.6
<?php echo "$text"; ?>
In a different way
{!! $text !!}
It will not render HTML code and print as a string.
For more details open link:- Display HTML with Blade
By default, Blade {{ }} statements are automatically sent through PHP's htmlspecialchars function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:
According to the doc, you must do the following to render your html in your Blade files:
{!! $text !!}
Be very careful when echoing content that is supplied by users of your application. You should typically use the escaped, double curly brace syntax to prevent XSS attacks when displaying user supplied data.
If you want to escape the data use
{{ $html }}
If don't want to escape the data use
{!! $html !!}
But till Laravel-4 you can use
{{ HTML::link('/auth/logout', 'Sign Out', array('class' => 'btn btn-default btn-flat')) }}
When comes to Laravel-5
{!! HTML::link('/auth/logout', 'Sign Out', array('class' => 'btn btn-default btn-flat')) !!}
You can also do this with the PHP function
{{ html_entity_decode($data) }}
go through the PHP document for the parameters of this function
html_entity_decode - php.net
Try this, It's worked:
#php
echo $text;
#endphp
For who using tinymce and markup within textarea:
{{ htmlspecialchars($text) }}
On controller.
$your_variable = '';
$your_variable .= '<p>Hello world</p>';
return view('viewname')->with('your_variable', $your_variable)
If you do not want your data to be escaped, you may use the following syntax:
{!! $your_variable !!}
Output
Hello world
{!! !!} is not safe.
Read here: https://laravel.com/docs/5.6/blade#displaying-data
You can try:
#php
echo $variable;
#endphp
If you use the Bootstrap Collapse class sometimes {!! $text !!}
is not worked for me but {{ html_entity_decode($text) }} is worked for me.
I have been there and it was my fault. And very stupid one.
if you forget .blade extension in the file name, that file doesn't understand blade but runs php code. You should use
/resources/views/filename.blade.php
instead of
/resources/views/filename.php
hope this helps some one
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
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>
I have a page who contains children blocs.
Each blocs need to have a specific render (with specific template).
For this i had to use #php in my blade template.
This is my code :
PageController.php
public function edit(Page $page)
{
return view('pages.edit', compact('page'));
}
View page/edit.blade.php
<section id="contents" class="contents ui-sortable">
#foreach ($page->blocs as $bloc)
#php
echo $bloc->id;
echo App\Http\Controllers\BlocController::renderBloc($bloc);
#endphp
#endforeach
</section>
BlocController.php
public static function renderBloc(Bloc $bloc) {
echo $bloc->id;
return view('blocs.show.' . $bloc->bloc_type, [
'bloc' => $bloc,
'data' => json_decode($bloc->data)
]);
}
And then an exemple of bloc
resources/views/blocs/show/text.blade.php
#extends('blocs.show')
#section('bloc')
{{ $bloc->id }}
#endsection
resources/views/blocs/show.blade.php
<section class="bloc bloc_{{ $bloc->bloc_type }}" data-bid="{{ $bloc->id }}">
{{$bloc->id}}
#yield('bloc')
</section>
I have 2 problems with this :
I think it's not really a good way to do ? I don't like to use #php in template. I would love to have an opinion about this ? Maybe i need to use a Service Provider ?
The $bloc->id inside the template (resources/views/blocs/show/text.blade.php) is wrong (it shows the id of the first child bloc in the foreach, even if all my echo $bloc->id before display the good id (page/edit/blade.php, BlocController.php, resources/view/blocs/show.blade.php). This is an other proof i'm doing something wrong i guess ?
Thanks
If you have to use controller in your views, it means only that you have not so good architecture. Laravel's Blade easily can do what you try to solve via controller.
You can use #include with parameters and get rid of #php:
resources/views/pages/edit.blade.php
#foreach ($page->blocs as $bloc)
#include('blocs.show', ['bloc' => $bloc])
#endforeach
resources/views/blocs/show.blade.php
<section class="bloc bloc_{{ $bloc->bloc_type }}" data-bid="{{ $bloc->id }}">
{{$bloc->id}}
#include('blocs.show.' . $bloc->bloc_type, [
'bloc' => $bloc,
'data' => json_decode($bloc->data)
])
</section>
resources/views/blocs/show/text.blade.php
Bloc ID = {{ $bloc->id }}
Bloc Text = {{ $data->text }}