I have problem with email template encoding:
This is my template:
mail/user-created.blade.php
#component('mail::message')
# Invoice Paid
Your invoice has been paid!
#component('mail::button', ['url' => '#'])
View Invoice
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent
For example in web.php:
Route::get('/test', function () {
$message = (new \App\Notifications\UserCreated(\App\User::first()))->toMail('test#email.com');
$markdown = new \Illuminate\Mail\Markdown(view(), config('mail.markdown'));
return $markdown->render('mail.user-created', $message->toArray());
});
And I get:
Preview in browser
Preview in browser 2
What is wrong?
--
I moved code to the left:
Code left
Code left 2
Your email template has to be left-aligned. Just move everything over to the left.
#component('mail::message')
# Invoice Paid
Your invoice has been paid!
#component('mail::button', ['url' => '#'])
View Invoice
#endcomponent
Thanks,<br>
{{ config('app.name') }}
#endcomponent
I just found solution:
vendor/tijsverkoyen/css-to-inline-styles/src/CssToInlineStyles.php
Line 129:
Replace:
$html = $document->saveHTML($htmlElement);
To:
$html = $document->saveHTML();
But why?
Related
I am currently trying to translate a string in Symfony/Twig inside an include Statement for a twig Template.
This is the non-translated Code is use for it currenty:
{{ include('#BluelineUser/user/_form.html.twig', {
'back_link': path('user_index'),
'title' : 'Edit User: ' ~ user.username,
'button_caption': 'Save'
}) }}
And in my form I output it like this:
{{ form_start(form) }}
<h1>{{ title|trans }}</h1>
{{ form_end(form) }}
Now if I use the include with a diffrent title (without a variable in it) it works fine.
Adding this to my translation file just doesn't pick up the 'Edit User: '
<trans-unit id="edit.name2">
<source>Edit User: </source>
<target>Benutzer bearbeiten: </target>
</trans-unit>
Any idea on how to get they 'Edit User: ' in the title translated? I think it's breaking because of the variable.
So far couldn't find any example on how to get this working in an include statement.
Try to translate it before like this:
{{ include('#BluelineUser/user/_form.html.twig', {
'back_link': path('user_index'),
'title' : ('Edit User: '|trans) ~ user.username,
'button_caption': 'Save'
}) }}
I'm attempting to modify the template for e-mails on an older website I did, running Laravel 5.4
I do eventually plan to update to at least Laravel 5.5, and possibly Laravel 5.7 - but I don't want to do that right now unless strictly necessary (it would involve some significant re-writes to some of my controllers and a lot of extra testing)
I ran:
php artisan vendor:publish --tag=laravel-mail
This created files in resources/views/vendor/mail
I then edited these files and tried sending a message. No change.
I then edited the files in vendor/laravel/framework/src/Illuminate/Mail/resources/views/ and sent a message - the new template showed up.
So despite the existence of the resources/views/vendor/mail folder, Laravel is still reading from the vendor/ folder after running php artisan vendor:publish. How do I fix this? What am I doing wrong?
Update
Some additional info, in case it helps. Here's my mail template (resources/views/mail/email-a-friend.blade.php):
#component('mail::message')
Your friend, {{ $senderName }}, has sent you information about a property they feel you might be interested in.
This property is listed by {{ config('app.name') }}. To view this property and more like it, please click the link below.
#if($agent->id !== $property->agent->id)
[{{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }}]({{ url($property->url()) }}?agent={{ $agent->first_name }}-{{ $agent->last_name }})
#else
[{{ url($property->url()) }}]({{ url($property->url()) }})
#endif
#if($text != "")
They also sent this message:
#component('mail::panel')
{{ $text }}
#endcomponent
#endif
#endcomponent
Here's the controller that queues up the e-mail (app/http/Controllers/AjaxController.php - just the relevant function):
public function emailAFriend(Request $request)
{
$property = \App\Models\Property\Property::find($request->input('property-id'));
$agent = $property->agent;
if ($request->input('agent-id') !== $agent->id) {
$agent = \App\User::find($request->input('agent-id'));
}
Mail::to($request->input('send-to'))
->queue(new \App\Mail\EmailAFriend($property, $agent, $request->input('name'), $request->input('reply-to'), $request->input('text')));
return Response::json("success", 200);
}
Here's the Mailable (app/Mail/EmailAFriend.php):
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Property\Property;
use App\User;
class EmailAFriend extends Mailable
{
use Queueable, SerializesModels;
public $subject = "Someone sent you a property!";
public $property;
public $agent;
public $senderName;
public $senderEmail;
public $text;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(Property $property, User $agent, $name, $email, $text)
{
$this->subject = "$name sent you information about a property";
$this->property = $property;
$this->agent = $agent;
$this->senderName = $name;
$this->senderEmail = $email;
$this->text = $text;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->markdown('emails.email-a-friend')
->replyTo($this->senderEmail, $this->senderName)
->attachData(
$this->property->generatePdf(['agent' => $this->agent])->inline(),
"{$this->property->details->lot_size} acres in {$this->property->location->county} county.pdf",
[
'mime' => 'application/pdf'
]
);
}
}
For testing purposes I'm using the sync QueueDriver, so this sends immediately upon the AJAX request being made. In production I use the database QueueDriver.
Update 2
The components:
resources/views/vendor/mail/html/message.blade.php:
#component('mail::layout')
{{-- Header --}}
#slot('header')
#component('mail::header', ['url' => config('app.url')])
<img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />
#endcomponent
#endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
#if (isset($subcopy))
#slot('subcopy')
#component('mail::subcopy')
{{ $subcopy }}
#endcomponent
#endslot
#endif
{{-- Footer --}}
#slot('footer')
#component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
#endcomponent
#endslot
#endcomponent
resources/views/vendor/mail/markdown/message.blade.php:
#component('mail::layout')
{{-- Header --}}
#slot('header')
#component('mail::header', ['url' => config('app.url')])
![{{ config('app.name') }}]({{ url('/img/layout/logo.png') }})
#endcomponent
#endslot
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
#if (isset($subcopy))
#slot('subcopy')
#component('mail::subcopy')
{{ $subcopy }}
#endcomponent
#endslot
#endif
{{-- Footer --}}
#slot('footer')
#component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
#endcomponent
#endslot
#endcomponent
The difference between these two and the default components (vendor/laravel/framework/src/Illuminate/Mail/resources/views/html/message.blade.php and the markdown equivalent) is in the header:
{{ config('app.name') }}
replaced with:
<img src="{{ url('/img/layout/logo.png') }}" alt="{{ config('app.name') }}" />
I was attempting to replace the company name with their logo. When I go into vendor/laravel/framework/src/Illuminate/Mail/resources/views/markdown/message.blade.php and edit this file directly, I do see the logo in the resulting e-mail. So despite the existence of the published component, it's still reading from the vendor/ directory (and editing the vendor/ directory is no good, because then the change won't persist in production)
So after digging through the Laravel source for over an hour, I finally figured this out.
The Markdown renderer loads components from its componentPaths variable
The componentPaths variable gets set by loadComponentFrom()
loadComponentsFrom is called in the constructor of the Markdown renderer and passed $options['paths']
Knowing this I started looking into "Laravel markdown options paths" and found the following: https://stackoverflow.com/a/44264874/436976
I updated config/mail.php and added the recommended lines and it worked perfectly! I feel like vendor:publish should have done this for me, or there should have at least been some mention of this step in the official Laravel documentation, but fortunately I figured this out in under a day - so that's always nice
Note (Further Research)
It turns out this was mentioned in the official Laravel documentation, just not where I expected.
My website was originally a Laravel 5.1 site that was upgraded to 5.2, then to 5.3, and then ultimately to 5.4 before it went live (I never updated to 5.5 because once the site was live I wanted to minimize changes to the underlying framework)
With each Laravel upgrade I kept rolling forward the old files from the config/ directory and I apparently did a poor job of following the upgrade guides, because they are pretty clear:
https://laravel.com/docs/5.4/upgrade
New Configuration Options
In order to provide support for Laravel 5.4's new Markdown mail components, you should add the following block of configuration to the bottom of your mail configuration file:
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
Had I updated my configuration file as directed, I would never have had these issues.
working with Symfony 2.7 I would like to include HTML in a flash message:
class MyController extends Controller {
public function someAction(Request $request) {
...
$this->addFlash('success', $tranlator->trans('some.success.msg', array(), 'app'));
...
}
}
// app.yml
some:
success:
msg: Text with some <strong>HTML</strong>
This creates a Flash Message
Text with some <strong>HTML</strong>
instead of
Text with some HTML
Within my own Twig template I would use the raw filter, to display the HTML code directly instead of the escaped version. But how can I achive the same within addFlash(...)?
Not sure i really understand your question. If this is not what you're asking just say it and I will remove this answer.
As said in documentation you use
app.session.flashbag.get('success')
to retrieve your flash message.
Example :
{% for flash_message in app.session.flashbag.get('success') %}
{{ flash_message|raw }}
{% endfor %}
I think this cannot be done directly. But you can tweak where you are showing the message using some html and css.
Like:
In setting the flash message:
$this->get('session')->getFlashBag()->add('notice', array('type' => 'success', 'title' => 'Done!', 'message' => 'OK! It is done!'));
And in twig file:
{% for msg in app.session.flashbag.get('notice') %}
<div class="alert alert-{{ msg.type }}">
<strong>{{ msg.title }}</strong><br/>{{ msg.message }}
</div>
{% endfor %}
In their new documentation there isn't anything for flash messages.
I installed the flash extension from their github repository (slimphp/Slim-Flash). Everything works fine, I can add messages and can also get these messages.
// Adding a message
$this->flash->addMessage('test', 'This is a message');
// Getting a message
$this->flash->getMessage('test')[0];
But this only works inside routes. Of course I want to have these messages displayed on my view.
But I just don't know how to get this message on the twig view.
I have already tried:
{{ container.flash.message('test')[0] }}
{{ container.flash.getMessage('test')[0] }}
{{ this.flash.message('test')[0] }}
{{ this.flash.getMessage('test')[0] }}
{{ flash.message('test')[0] }}
{{ flash.getMessage('test')[0] }}
{{ app.flash.message('test')[0] }}
{{ app.flash.getMessage('test')[0] }}
{{ container.flash.test }}
Thanks for help!
You can add the flash message inside the data attribute from the render method:
$this->view->render($res, 'path/to/template.twig', [
'flash' => $this->flash
]);
Or you could add a middleware and add your flash instance to the twig parameters
$app->add(function ($request, $response, $next) {
$this->view->offsetSet("flash", $this->flash);
return $next($request, $response);
});
then it should be possible to access the messages inside the twig template with
{{ flash.getMessage('test') }}
My Laravel app allows users to modify email templates, then save them to database.
Sample:
Customer {{ $customer_name }} has accepted your proposed timing {{ $timing }} for PO {{ $po_no }}
(User can change 'customer' to 'client' etc.. but leave the {{ }} intact )
The app then loads dynamic data below into above template.
$data = array('customer_email'=> "email#mail.com",
'timing'=> "2pm",'po_no' => "PO001"
);
Then email those rendered text to some emails.
How can I do that?
Rephrase:
load text from db
make it a Blade template
render that template with data
I get stuck at #2
add email view to your views/emails folder
ex: mail_template.blade.php
Customer {{ $customer_name }} has accepted your proposed
timing {{ $timing }} for PO {{ $po_no }}
send method
Mail::send('emails.mail_template', array('customer_email'=> "email#mail.com", 'timing'=> "2pm",'po_no' => "PO001" ), function($message)
{
$message->to('sendto#gmail.com')->subject('your email subject');
});
further read Official Doc