laravel 5.4 embed image in mail - laravel

I have just upgraded my 5.2 install of laravel to 5.3 and then to 5.4 following the official upgrading methods.
I am now trying to use one of the new features, to create a markdown formated email.
According to the documentation found at: https://laravel.com/docs/5.4/mail#view-data
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 manually:
However, this:
<img src="{{ $message->embed(public_path().'/img/official_logo.png') }}">
will produce the following error:
Undefined variable: message
Am I missing something? Or is there something undocumented in the upgrading guides?
Later edit:
I am calling the email function with:
\Mail::to($user)->send(new WelcomeCandidate($user, $request->input('password')));
And WelcomeCandidate looks like:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\User;
class WelcomeCandidate extends Mailable
{
use Queueable, SerializesModels;
public $user;
public $password;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user, $password)
{
//
$this->user = $user;
$this->password = $password;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this->subject('Welcome!');
return $this->markdown('emails.welcome-candidate');
}
}

It seems that the older $message->embed doesn't work nicely with Markdown emails. Like you mentioned in the comments it seems broken since 5.4
But you could just try it like this inside your markdown email:
This is your logo
![Some option text][logo]
[logo]: {{asset('/img/official_logo.png')}} "Logo"
Like shown here:
https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#images
Asset function reference: https://laravel.com/docs/5.4/helpers#method-asset

Try this:
<img src="data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}}" alt="">
or
![](data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}})

You can also use this useful package
https://github.com/eduardokum/laravel-mail-auto-embed
Taken from the readme
Its use is very simple, you write your markdown normally:
#component('mail::message')
# Order Shipped
Your order has been shipped!
#component('mail::button', ['url' => $url])
View Order
#endcomponent
Purchased product:
![product](https://example.com/products/product-1.png)
Thanks,<br>
{{ config('app.name') }}
#endcomponent
When sending, it will replace the link that would normally be generated:
<img src="https://example.com/products/product-1.png">
by an embedded inline attachment of the image:
<img src="cid:3991f143cf1a86257f8671883736613c#Swift.generated">

Solved my issue!
<img src="{{ $message->embed(base_path() . '/img/logo.png') }}" />
Controller:
\Mail::send(['html' =>'mail'],
array(
'name' => $r->name,
'email' => $r->email,
'user_message' => $r->message,
// 'telephone'=>$r->telephone,
// 'subject'=>$r->subject
), function($message) use ($r) {
$message->to('abc#gmail.com')->subject('Contact Form || abc.com');
$message->from($r->email);
// ->setBody($r->user_message); // assuming text/plain
});
If you are in localhost , you can use public_path instead of base_path function

I just encountered the same issue and found a solution.
Before rendering images you have to create a symbolic link from "public/storage" to "storage/app/public" using this command:
php artisan storage:link
In "storage/app/public" you should have a folder "images"
Now you can render this code in your markdown.blade.php:
!['alt_tag']({{Storage::url('/images/your_image.png')}})
Second option is similar:
!['alt_text']({{Storage::url($comment->user->image->path)}})
Both work fine

You could try the following:
class WelcomeCandidate extends Mailable
{
use Queueable, SerializesModels;
public $message;
public function __construct(User $user)
{
$this->user = $user;
$this->message = (object) array('image' => '/path/to/file');
}
}

The below solution works for me.
<img src="{{ $message->embed(asset('img/logo.png')) }}"/>
In .env file.
For local: APP_URL=http://localhost/project_name
For Production: APP_URL=https://www.example.com
Reference: https://laravel.com/docs/7.x/mail#inline-attachments

In backend i created endpoint for showing images. And put image that i need in resource/img. Laravel code looks like:
public function getImage($name)
{
return response()->file(base_path() . '/resources/img/' . $name . '.png');
}
Then in my html email template i created div with background-image.
<div style='background: url("https://mysite1.com/api/v1/get_image/logo")'></div>
And it's works for me.

Related

How to retrieve converted image in Spatie laravel-medialibrary?

I'm uploading images using the spatie media library and the images get uploaded and converted successfully. When accessing an uploaded image as below it works:
#foreach ($articles as $article)
<h1>{{ $article->title }}</h1>
<img src="{{ $article->getFirstMediaUrl() }}" alt="">
#endforeach
How can I access the converted images? I think I'm missing something from the documentation to make it work.
My model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class Article extends Model implements HasMedia
{
use HasFactory, InteractsWithMedia;
protected $fillable = ['title'];
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(250)
->height(90);
}
}
My store function
public function store(Request $request)
{
$file = $request->file('image');
$article = Article::create(['title' => 'First title']);
$article->addMedia($file)->toMediaCollection();
return back();
}
you should use getUrl() method to access the media url, so change your template like this.
<img src="{{ $article->getFirstMediaUrl()->getUrl() }}" alt="">
you will get the converted file perhaps if you want to access other object you can use other library function though from the document
https://spatie.be/docs/laravel-medialibrary/v10/introduction

Why html tags are not rendered in laravel sent email?

Sending email with
\Mail::to(
method in laravel 8 app
I have html tags in im my email template
#component('mail::message')
<h3 >
You registered at {{ $site_mame }}
</h3>
Best regards, <br>
...
#endcomponent
and code in my app/Mail/UserRegistered.php :
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class UserRegistered extends Mailable
{
use Queueable, SerializesModels;
public $site_mame;
public $user;
public $confirmation_code;
public function __construct( $site_mame, $user, $confirmation_code )
{
$this->site_mame = $site_mame;
$this->user = $user;
$this->confirmation_code = $confirmation_code;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('email.UserRegisteredEmail')
->with('site_mame', $this->site_mame)
->with('user', $this->user)
->with('confirmation_code', $this->confirmation_code);
}
}
With sendgrid options in my .env file I got valid emaul at my google account, but html tags are not rendered.
If there is a way to render all html tags? Does it depend on laravel app/emailing options
or setting in my google(or some other account).
What can I do from my side?
UPDATED :
Modified :
$this->view(
I got error :
No hint path defined for [mail]. (View: project/resources/views/email/UserRegisteredEmail.blade.php)
Pointing to my blade file.
Searching in net I found as possible decision :
php artisan vendor:publish --tag=laravel-mail
and clearing all cache
But I still got the same error.
Did I miss some options ?
Thanks in advance!
You are using the markdown() method, which is a method to utilize the pre-built templates and components of mail notifications in your mailables.
This offers a multitude of advantages:
instead of wrapping headings in h1, h2, etc. tags, you can just put a #, ##, etc. at the beginning of the line
no need to wrap lists in <ul>, and list items in <li> tags. In markdown, you can just use a dash (-) for listing elements
italic/bold font can be achieved by putting */** around the text you want to emphasize
You can read more about this on the official Laravel documentation.
https://laravel.com/docs/8.x/mail#markdown-mailables
If you want to use HTML, you can just render a view:
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('email.UserRegisteredEmail')
->with('site_mame', $this->site_mame)
->with('user', $this->user)
->with('confirmation_code', $this->confirmation_code);
}

Laravel: Set mail subject from mail blade template

When using the Laravel 6 mail functionality, I would like to set the message subject in the email's blade template. This seems more natural to me than doing it in the Mail class itself, because whoever is maintaining the mail templates should also be able to customize the subject and use the template variables.
Example of what I am trying to accomplish:
#component('mail::subject')
Sample Message to {{ $user }}
#endcomponent
#component('mail::message')
# Sample Message
This is a sample message
#endcomponent
How could this be done?
I struggled with this as well. It took me a while to find a decent solution but here it is:
The mailable class:
class Mailing extends Mailable {
use Queueable;
use SerializesModels;
...
public function build() {
return $this
->markdown('emails.somemailing')
->with('setSubject', function($subject) { // Use to be able to set the subject from within the markdown blade
$this->subject($subject);
});
}
}
Then in the markdown blade you can call the setSubject like this:
#php
$setSubject('Hooray, it works!');
#endphp
#component('mail::message')
...
#endcomponent
PS You can also set $this->subject directly as a closure:
->with('setSubject', Closure::fromCallable([$this, 'subject']));
In APP - Mail
add this
public function build()
{
return $this->markdown('emails.user')->subject('here subject');
}

show module value in template laravel

I am new to Laravel I have install laravel 5.2 and running laraadmin.
I have added a 'header' module with field phone and want to show it in my blade template on my site.
Please help me.
my controller name headercontroller have the code
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
/**
* Class HomeController
* #package App\Http\Controllers
*/
class headerController extends Controller
{
public function index()
{
$header = headers::all();
return view('layout.aap')->with('headers', $header);
}
}
my view file name is "app.blade.php" inside a folder name "layout" have the following code
{{ $header -> phone }}
I cannot show the phone number on site please help me.
I didn't worked on laraadmin. But you can try this -
In your controller -
public function example(){
$data = Phone::all(); //Phone is model name. You make change according to your's
return view('xyz', compact('data'));
}
Now in your view you can access variable data.
#foreach($data as $d)
<span>$d->phone</span>
#endforeach

Laravel 5: HTML with variables from DB for Mailable class

So I need to store my blade email templates in database.
And now I am having problem to use db content with view, because dynamic informations are not rendered.
Here is the code to elaborate a bit more problem which I am facing:
Mailable class:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
class activateUser extends Mailable
{
public $html;
public $user;
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user)
{
//this actually is much longer text coming from the DB - basicly coopied blade email template into the db
$this->html = 'Hi {{ $user->first_name }},<br /><br /> Your profile on our site has been activated.<br /><br />';
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('emails.activateUser')->subject('Your account is activated');
}
}
Then the view emails.activateUser.blade.php looks like this:
{{ $html }}
And Inside of my controller I am calling this:
Mail::to($user->email)->send(new activateUser($user));
Problem is that actual username of the user will not be printed in the email and {{ }} will stay as well in email content.
Any ideas how to solve this, since my email template content needs to come from DB
You can use the Blade template compiler to compile a string:
public function compileBladeString(string $template, $data = []): string
{
$bladeCompiler = app('blade.compiler');
ob_start() && extract($data, EXTR_SKIP);
eval('?>' . $bladeCompiler->compileString($template));
$compiled = ob_get_contents();
ob_end_clean();
return $compiled;
}
You can then simply invoke this method with a string containing your template from the database.

Resources