rap-2-h
rap-2-h

Reputation: 31978

Laravel: HTML in notification

I'm using the default notification system (Laravel 5.3) to send an email. I want to add HTML tags in message. This does not work (it displays the strong tags in plain text):

public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('Info')
                ->line("Hello <strong>World</strong>")
                ->action('Voir le reporting', config('app.url'));
}

I know it's normal because text is displayed in {{ $text }} in the mail notification template. I tried to use the same system as in csrf_field() helper:

->line( new \Illuminate\Support\HtmlString('Hello <strong>World</strong>') )

But it does not work: it displays strong as plain text.

Can I send HTML tags without changing the view? (I don't want to change the view: protecting text is OK for all other cases). Hope it's clear enough, sorry if not.

Upvotes: 13

Views: 16331

Answers (5)

Koushik Das
Koushik Das

Reputation: 10793

The HtmlString class works perfectly fine. I've done this with Laravel 7, 8 and 9.

Try this and it should work

->line(new HtmlString("<b>This is bold HTML text</b>"))

Make sure to import this at the top

use Illuminate\Support\HtmlString;

Upvotes: 37

AndyDunn
AndyDunn

Reputation: 1084

If you just want to add a bit of basic style to the template, you can use Markdown within the line() method without having to modify any other code.

Upvotes: 5

thtg88
thtg88

Reputation: 54

For anybody following @eric-lagarda's approach as I did, remember not to tab the content in the custom email.blade.php view as you would normally do in your views, as it will be interpreted by Laravel's markdown parser as code, wrapping the whole content HTML in <code> HTML tags. This caused me headaches but thanks to this answer I managed to figure out what the issue was. Your resulting bit of code to append to the email.blade.php view, will therefore be this (please note the missing spaces/tabulation before the curly brackets):

@if (isset($content))
<hr>
{!! $content !!}
<hr>
@endif

Upvotes: 3

Eric Lagarda
Eric Lagarda

Reputation: 302

Well, you can also create a new MailClass extending the MailMessage Class.

For example you can create this class in app\Notifications

<?php

namespace App\Notifications;

use Illuminate\Notifications\Messages\MailMessage;

class MailExtended extends MailMessage
{
    /**
     * The notification's data.
     *
     * @var string|null
     */
    public $viewData;

    /**
     * Set the content of the notification.
     *
     * @param string $greeting
     *
     * @return $this
     */
    public function content($content)
    {
        $this->viewData['content'] = $content;

        return $this;
    }

    /**
     * Get the data array for the mail message.
     *
     * @return array
     */
    public function data()
    {
        return array_merge($this->toArray(), $this->viewData);
    }
}

And then use in your notification:

Instead:

return (new MailMessage())

Change it to:

return (new MailExtended())

And then you can use content var in your notification views. For example if you publish the notification views (php artisan vendor:publish), you can edit email.blade.php in resources/views/vendor/notifications and append this:

@if (isset($content))
<hr>
    {!! $content !!}
<hr>
@endif

We do it like this and works like a charm :D

Upvotes: 10

Alexey Mezenin
Alexey Mezenin

Reputation: 163788

Run php artisan vendor:publish command which will copy email.blade.php to resources/views/vendor/notifications from vendor directory.

Open this view and change {{ $line }} to {!! $line !!} in two places. In Laravel 5.3 these are 101 and 137 lines in the view.

This will display unescaped line strings which will allow you to use HTML tags in notification emails.

Upvotes: 16

Related Questions