Framework: Tried to use $message->embed() in the email template for the notification-email channel

Created on 28 Jan 2017  路  25Comments  路  Source: laravel/framework

  • Laravel Version: v5.4.6
  • PHP Version: 5.6.15
  • Database Driver & Version: mysqlnd 5.0.11-dev - 20120503

Description:

Can't send a notification with an image in the email template:
Undefined variable: message (View: ...\resources\views\vendor\notifications\email.blade.php)
You say in the docs that "To embed an inline image, use the embed method on the $message variable within your email template. Laravel automatically makes the $message variable available to all of your email templates, so you don't need to worry about passing it in manuall" but it seems not to work. If this isn't a bug, how can I add an embeded image in the mail template?

Steps To Reproduce:

Send an email via the email notification channel and try to use in the mail template the $message->embed() method.

Most helpful comment

I wrote a package that at the time of sending, it does the automatic embed
See if that helps.

laravel-mail-auto-embed

All 25 comments

+1 same issue after upgrade to 5.4

+1, also after upgrading to 5.4 (v5.4.6, PHP 7.1.1, MySQL 5.7.16)

+1, the same issue after updgade to 5.4.9

+1, the same issue after updgade to 5.4.9

+1, the same issue in 5.4.10

Started tracing the reason this does not work and the problem is even more deeply nested than just the notification emails. It is actually an issue with the way the markdown parser works.
Lets start by summing up my understanding of the notification-messages

  1. The MailChannel's send method is called
  2. It does some checking and then calls the buildView method to render the (markdown) views
  3. The MailChannel's buildView method calls the render method on the markdown parser (found in Illuminate\Mail\Markdown)
  4. The markdown parser renders both the html and text message into an HtmlString
  5. The resulting data is then passed onto the mailer
  6. The mailer sees the data is an HtmlString and appends it to the message
  7. The mailer completes the message (calling the callback defined in the send method, etc)

The same actually goes for Mailables that use markdown, when the send method is called they also run a variation of step 4 - 7.

Since the markdown parser never sees the $message in both cases, as soon as markdown is used for emails (Mailables or Notifications), they will never be able to use $message->embed or any related functionality.

The way I expect the markdown option to work is that (similar to regular blade-templates) the message is made available to the markdown parser through the data attribute instead of the message being pre-rendered to an HtmlString. This would mean a rewrite of the way the markdown functionality works to be handled inside the addContent section of the Illuminate\Mail\Mailer instead of rendering it inside the Mailable/Notification and sending the HtmlString. Maybe the easiest way is to "enhance" the views array with an additional "markdown" attribute (next to the html/text/raw attributes). As an added bonus this will make markdown based messages also available when not using Mailables/Notifications...

Just bumped into this as well. Going to revert to normal templates for now.

FYI, you can sidestep the issue until it's fixed by passing an email layout as a view.

public function toMail($notifiable)
{
    return (new MailMessage)
        ->greeting('Hello!')
        ->view('layouts.email');
}

@aaronlord I still get Undefined variable: message after adding view
:(

Having the same issue still in 5.4.13, I think its to do with the Markdown parser.

Have this problem as well.

The $message here is a Illuminate\Mail\Message , which is rendered by https://github.com/laravel/framework/blob/5.4/src/Illuminate/Mail/Mailer.php

However, the notification emails such as password reset emails are Illuminate\Notifications\Messages\MailMessage, which are rendered by https://github.com/laravel/framework/blob/5.4/src/Illuminate/Notifications/Channels/MailChannel.php

I tried to add $message->viewData['message'] = $message; to the send() method of MailChannel but \Notifications\Messages\MailMessage do not have embed.

I think it is not a good idea to point to the same set of views for two incompatible classes.

I wrote a package that at the time of sending, it does the automatic embed
See if that helps.

laravel-mail-auto-embed

+1 same issue in 5.4.15

@eduardokum thank you, your package save my life!

@eduardokum Thank you

Having the same issue still in 5.4.21

Same issue in 5.4.22

Guys a $message value doesn't exist in the notification email template, that is by design.

@themsaid Can you elaborate how to make it available in custom markdown mailables?

@eduardokum you rock buddy. Thank you man :)

@eduardokum When I do ({{ asset("storage/$news->image") }}) all I am getting is a link to that image.

@eduardokum problem solved :smile: Just didn't realize the importance of this thing ![product] before ({{ asset("storage/$news->image") }}). Perfect :+1:

@roshimon Please edit your message instead, getting lots of emails from this.

On topic: really wish there was less of a difference between mailables/views and markdown emails. You'd expect so anyway. Had to copy and tweak ALL Laravel markdown emails and layouts to my core app files to get the same, simple emails, but with support for the $message variable.

For anyone who following the doc to implement the following code in their email blade template

<div>
    Content: {{ $message->content }}
</div>

try to change the variable name $message to anything else (e.g $clientMessage)

Using @eduardokum package, to embed images not accessible by a public URL, I used file://<full/path/to/the/file/in/the/filesystem> and it worked all right.

Was this page helpful?
0 / 5 - 0 ratings