diff --git a/src/Illuminate/Mail/Markdown.php b/src/Illuminate/Mail/Markdown.php
index e8ec2defc4c4..54c9c2ece372 100644
--- a/src/Illuminate/Mail/Markdown.php
+++ b/src/Illuminate/Mail/Markdown.php
@@ -69,9 +69,25 @@ public function render($view, array $data = [], $inliner = null)
$contents = $bladeCompiler->usingEchoFormat(
'new \Illuminate\Support\EncodedHtmlString(%s)',
function () use ($view, $data) {
- return $this->view->replaceNamespace(
- 'mail', $this->htmlComponentPaths()
- )->make($view, $data)->render();
+ EncodedHtmlString::encodeUsing(function ($value) {
+ $replacements = [
+ '[' => '\[',
+ '<' => '<',
+ '>' => '>',
+ ];
+
+ return str_replace(array_keys($replacements), array_values($replacements), $value);
+ });
+
+ try {
+ $contents = $this->view->replaceNamespace(
+ 'mail', $this->htmlComponentPaths()
+ )->make($view, $data)->render();
+ } finally {
+ EncodedHtmlString::flushState();
+ }
+
+ return $contents;
}
);
@@ -84,7 +100,7 @@ function () use ($view, $data) {
}
return new HtmlString(($inliner ?: new CssToInlineStyles)->convert(
- $contents, $this->view->make($theme, $data)->render()
+ str_replace('\[', '[', $contents), $this->view->make($theme, $data)->render()
));
}
@@ -112,10 +128,15 @@ public function renderText($view, array $data = [])
* Parse the given Markdown text into HTML.
*
* @param string $text
+ * @param bool $encoded
* @return \Illuminate\Support\HtmlString
*/
- public static function parse($text)
+ public static function parse($text, bool $encoded = false)
{
+ if ($encoded === false) {
+ return new HtmlString(static::converter()->convert($text)->getContent());
+ }
+
EncodedHtmlString::encodeUsing(function ($value) {
$replacements = [
'[' => '\[',
diff --git a/src/Illuminate/Mail/resources/views/html/button.blade.php b/src/Illuminate/Mail/resources/views/html/button.blade.php
index 4a9bf7d00495..050e969d2130 100644
--- a/src/Illuminate/Mail/resources/views/html/button.blade.php
+++ b/src/Illuminate/Mail/resources/views/html/button.blade.php
@@ -12,7 +12,7 @@
diff --git a/src/Illuminate/Mail/resources/views/html/header.blade.php b/src/Illuminate/Mail/resources/views/html/header.blade.php
index 56197f8d23f3..c47a260c56b2 100644
--- a/src/Illuminate/Mail/resources/views/html/header.blade.php
+++ b/src/Illuminate/Mail/resources/views/html/header.blade.php
@@ -5,7 +5,7 @@
@if (trim($slot) === 'Laravel')
@else
-{{ $slot }}
+{!! $slot !!}
@endif
diff --git a/src/Illuminate/Mail/resources/views/html/layout.blade.php b/src/Illuminate/Mail/resources/views/html/layout.blade.php
index d31a01de8630..0fa6b82f72b2 100644
--- a/src/Illuminate/Mail/resources/views/html/layout.blade.php
+++ b/src/Illuminate/Mail/resources/views/html/layout.blade.php
@@ -23,7 +23,7 @@
}
}
-{{ $head ?? '' }}
+{!! $head ?? '' !!}
@@ -31,7 +31,7 @@
-{{ $header ?? '' }}
+{!! $header ?? '' !!}
@@ -40,16 +40,16 @@
-{{ Illuminate\Mail\Markdown::parse($slot) }}
+{!! Illuminate\Mail\Markdown::parse($slot) !!}
-{{ $subcopy ?? '' }}
+{!! $subcopy ?? '' !!}
|
|
-{{ $footer ?? '' }}
+{!! $footer ?? '' !!}
diff --git a/src/Illuminate/Mail/resources/views/html/message.blade.php b/src/Illuminate/Mail/resources/views/html/message.blade.php
index 1a874fc26de5..f1e815f32a41 100644
--- a/src/Illuminate/Mail/resources/views/html/message.blade.php
+++ b/src/Illuminate/Mail/resources/views/html/message.blade.php
@@ -7,13 +7,13 @@
{{-- Body --}}
-{{ $slot }}
+{!! $slot !!}
{{-- Subcopy --}}
@isset($subcopy)
-{{ $subcopy }}
+{!! $subcopy !!}}
@endisset
diff --git a/src/Illuminate/Mail/resources/views/html/panel.blade.php b/src/Illuminate/Mail/resources/views/html/panel.blade.php
index 2975a60a021e..812db7c08e77 100644
--- a/src/Illuminate/Mail/resources/views/html/panel.blade.php
+++ b/src/Illuminate/Mail/resources/views/html/panel.blade.php
@@ -4,7 +4,7 @@
-{{ Illuminate\Mail\Markdown::parse($slot) }}
+{!! Illuminate\Mail\Markdown::parse($slot) !!}
|
diff --git a/tests/Integration/Mail/Fixtures/message-with-template.blade.php b/tests/Integration/Mail/Fixtures/message-with-template.blade.php
new file mode 100644
index 000000000000..9c53cef7e1bb
--- /dev/null
+++ b/tests/Integration/Mail/Fixtures/message-with-template.blade.php
@@ -0,0 +1,4 @@
+@component('mail::message')
+*Hi* {{ $user->name }}
+
+@endcomponent
diff --git a/tests/Integration/Mail/MailableTest.php b/tests/Integration/Mail/MailableTest.php
index 339ebb2422d7..4ff0f539b6ad 100644
--- a/tests/Integration/Mail/MailableTest.php
+++ b/tests/Integration/Mail/MailableTest.php
@@ -2,14 +2,20 @@
namespace Illuminate\Tests\Integration\Mail;
+use Illuminate\Foundation\Auth\User;
+use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
+use Orchestra\Testbench\Attributes\WithMigration;
+use Orchestra\Testbench\Factories\UserFactory;
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
class MailableTest extends TestCase
{
+ use LazilyRefreshDatabase;
+
/** {@inheritdoc} */
#[\Override]
protected function defineEnvironment($app)
@@ -69,4 +75,55 @@ public static function markdownEncodedDataProvider()
'My message is: Visit <span>https://laravel.com/docs</span> to browse the documentation',
];
}
+
+ #[WithMigration]
+ #[DataProvider('markdownEncodedTemplateDataProvider')]
+ public function testItCanAssertMarkdownEncodedStringUsingTemplate($given, $expected)
+ {
+ $user = UserFactory::new()->create([
+ 'name' => $given,
+ ]);
+
+ $mailable = new class($user) extends Mailable
+ {
+ public $theme = 'taylor';
+
+ public function __construct(public User $user)
+ {
+ //
+ }
+
+ public function build()
+ {
+ return $this->markdown('message-with-template');
+ }
+ };
+
+ $mailable->assertSeeInHtml($expected, false);
+ }
+
+ public static function markdownEncodedTemplateDataProvider()
+ {
+ yield ['[Laravel](https://laravel.com)', 'Hi [Laravel](https://laravel.com)'];
+
+ yield [
+ '',
+ 'Hi ',
+ ];
+
+ yield [
+ 'Visit https://laravel.com/docs to browse the documentation',
+ 'Hi Visit https://laravel.com/docs to browse the documentation',
+ ];
+
+ yield [
+ 'Visit to browse the documentation',
+ 'Hi Visit <https://laravel.com/docs> to browse the documentation',
+ ];
+
+ yield [
+ 'Visit https://laravel.com/docs to browse the documentation',
+ 'Hi Visit <span>https://laravel.com/docs</span> to browse the documentation',
+ ];
+ }
}
diff --git a/tests/Integration/Mail/MarkdownParserTest.php b/tests/Integration/Mail/MarkdownParserTest.php
index d21602c9ad00..6669fe038ba3 100644
--- a/tests/Integration/Mail/MarkdownParserTest.php
+++ b/tests/Integration/Mail/MarkdownParserTest.php
@@ -24,7 +24,7 @@ public function testItCanParseMarkdownString($given, $expected)
#[DataProvider('markdownEncodedDataProvider')]
public function testItCanParseMarkdownEncodedString($given, $expected)
{
- tap(Markdown::parse($given), function ($html) use ($expected) {
+ tap(Markdown::parse($given, encoded: true), function ($html) use ($expected) {
$this->assertInstanceOf(HtmlString::class, $html);
$this->assertStringEqualsStringIgnoringLineEndings($expected.PHP_EOL, (string) $html);