Skip to content

Commit cd2bc1f

Browse files
authored
Merge pull request #626 from filamentphp/feat/absolute-image-urls
feat: convert relative image urls to absolute
2 parents 8dc889e + e1981e7 commit cd2bc1f

File tree

4 files changed

+105
-44
lines changed

4 files changed

+105
-44
lines changed

app/Models/Plugin.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,31 +67,34 @@ public function stars(): MorphMany
6767
return $this->morphMany(Star::class, 'starrable');
6868
}
6969

70-
public function getDocs(string $version = null): ?string
70+
public function getDocUrl(string $version = null): ?string
7171
{
72-
if (filled($this->content)) {
73-
return $this->content;
72+
if (filled($this->docs_url)) {
73+
return $this->docs_url;
7474
}
7575

76-
$docs_url = $this->docs_url;
77-
7876
if (filled($this->docs_urls)) {
79-
if ($version !== null) {
80-
$docs_url = $this->docs_urls[$version];
81-
} else {
82-
$docs_url = $this->docs_urls[key($this->docs_urls)];
83-
}
77+
return $this->docs_urls[$version ?? key($this->docs_urls)] ?? null;
78+
}
79+
80+
return null;
81+
}
82+
83+
public function getDocs(string $version = null): ?string
84+
{
85+
if (filled($this->content)) {
86+
return $this->content;
8487
}
8588

86-
if (blank($docs_url)) {
89+
if (blank($url = $this->getDocUrl($version))) {
8790
return null;
8891
}
8992

9093
try {
9194
return cache()->remember(
9295
"plugin:{$this->slug}:docs:{$version}",
9396
now()->addHour(),
94-
fn (): string => file_get_contents($docs_url),
97+
fn (): string => file_get_contents($url),
9598
);
9699
} catch (\Throwable) {
97100
return null;

app/Support/Markdown.php

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
namespace App\Support;
44

5+
use Illuminate\Contracts\Support\Htmlable;
56
use Illuminate\Support\HtmlString;
67
use League\CommonMark\Environment\Environment;
78
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
89
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
910
use League\CommonMark\Extension\Table\TableExtension;
1011
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
1112
use League\CommonMark\MarkdownConverter;
13+
use Stringable;
1214
use Torchlight\Commonmark\V2\TorchlightExtension;
1315

14-
class Markdown
16+
class Markdown implements Htmlable, Stringable
1517
{
16-
public static function parse(string $text): HtmlString
17-
{
18-
$text = self::convertSpecialBlockQuotes($text);
18+
protected Environment $environment;
1919

20-
$environment = new Environment([
20+
public function __construct(protected string $content)
21+
{
22+
$this->environment = new Environment([
2123
'allow_unsafe_links' => false,
2224
'heading_permalink' => [
2325
'html_class' => 'heading-anchor',
@@ -37,35 +39,85 @@ public static function parse(string $text): HtmlString
3739
],
3840
]);
3941

40-
$environment->addExtension(new CommonMarkCoreExtension);
41-
$environment->addExtension(new TableExtension);
42-
$environment->addExtension(new HeadingPermalinkExtension);
43-
$environment->addExtension(new TorchlightExtension);
44-
$environment->addExtension(new TableOfContentsExtension);
42+
$this->environment->addExtension(new CommonMarkCoreExtension);
43+
$this->environment->addExtension(new TableExtension);
44+
$this->environment->addExtension(new HeadingPermalinkExtension);
45+
$this->environment->addExtension(new TorchlightExtension);
46+
$this->environment->addExtension(new TableOfContentsExtension);
47+
}
48+
49+
public static function parse(string $text): static
50+
{
51+
$static = app(static::class, ['content' => $text]);
52+
53+
$static->convert();
54+
$static->removeH1Tags();
55+
$static->convertSpecialBlockQuotes();
56+
57+
return $static;
58+
}
59+
60+
protected function convert(): static
61+
{
62+
$this->content = (new MarkdownConverter($this->environment))
63+
->convert($this->content)
64+
->getContent();
65+
66+
return $this;
67+
}
68+
69+
protected function removeH1Tags(): static
70+
{
71+
$this->content = preg_replace(
72+
pattern: '/\<h1(.*)\>(.*)\<\/h1\>/',
73+
replacement: '',
74+
subject: $this->content
75+
);
4576

46-
$converter = new MarkdownConverter($environment);
77+
return $this;
78+
}
4779

48-
return new HtmlString($converter->convert($text)->getContent());
80+
protected function convertSpecialBlockQuotes(): static
81+
{
82+
$this->content = preg_replace(
83+
pattern: [
84+
'/> \[\!NOTE\]\s*\n> /',
85+
'/> \[\!TIP\]\s*\n> /',
86+
'/> \[\!IMPORTANT\]\s*\n> /',
87+
'/> \[\!WARNING\]\s*\n> /',
88+
'/> \[\!CAUTION\]\s*\n> /',
89+
],
90+
replacement: [
91+
'> 📝 **Note:** ',
92+
'> 💡 **Tip:** ',
93+
'> ❗ **Important:** ',
94+
'> ⚠️ **Warning:** ',
95+
'> ⚠️ **Caution:** ',
96+
],
97+
subject: $this->content
98+
);
99+
100+
return $this;
101+
}
102+
103+
public function absoluteImageUrls(string $baseUrl): static
104+
{
105+
$this->content = preg_replace(
106+
pattern: '/src=["\'](?!https?:\/\/)([^"\']+)["\'][^>]/i',
107+
replacement: 'src="' . $baseUrl . '$1" ',
108+
subject: $this->content
109+
);
110+
111+
return $this;
112+
}
113+
114+
public function __toString(): string
115+
{
116+
return str($this->content)->sanitizeHtml();
49117
}
50118

51-
protected static function convertSpecialBlockQuotes(string $text): string
119+
public function toHtml()
52120
{
53-
$searchPatterns = [
54-
'/> \[\!NOTE\]\s*\n> /',
55-
'/> \[\!TIP\]\s*\n> /',
56-
'/> \[\!IMPORTANT\]\s*\n> /',
57-
'/> \[\!WARNING\]\s*\n> /',
58-
'/> \[\!CAUTION\]\s*\n> /',
59-
];
60-
$replacePatterns = [
61-
'> 📝 **Note:** ',
62-
'> 💡 **Tip:** ',
63-
'> ❗ **Important:** ',
64-
'> ⚠️ **Warning:** ',
65-
'> ⚠️ **Caution:** ',
66-
];
67-
68-
// Perform the replacement
69-
return preg_replace($searchPatterns, $replacePatterns, $text);
121+
return new HtmlString($this->content);
70122
}
71123
}

resources/views/articles/view-article.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class="select-none rounded-full bg-stone-200/50 px-5 py-2.5 text-sm"
160160
<div
161161
class="prose selection:bg-stone-500/30 prose-a:break-words prose-blockquote:not-italic prose-code:break-words prose-code:rounded prose-code:bg-merino prose-code:px-1.5 prose-code:py-0.5 prose-code:font-normal prose-code:before:hidden prose-code:after:hidden [&_p]:before:hidden [&_p]:after:hidden"
162162
>
163-
{!! preg_replace('/\<h1(.*)\>(.*)\<\/h1\>/', '', str(\App\Support\Markdown::parse($article->content))->sanitizeHtml()) !!}
163+
{!! \App\Support\Markdown::parse($article->content) !!}
164164
</div>
165165
</div>
166166
</div>

resources/views/plugins/view-plugin.blade.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,13 @@ class="block w-32 rounded-lg border border-gray-300 bg-gray-50 p-2 text-sm text-
343343
<div
344344
class="prose selection:bg-stone-500/30 prose-a:break-words prose-blockquote:not-italic prose-code:break-words prose-code:rounded prose-code:bg-merino prose-code:px-1.5 prose-code:py-0.5 prose-code:font-normal prose-code:before:hidden prose-code:after:hidden [&_p]:before:hidden [&_p]:after:hidden"
345345
>
346-
{!! preg_replace('/\<h1(.*)\>(.*)\<\/h1\>/', '', str(\App\Support\Markdown::parse($docs))->sanitizeHtml()) !!}
346+
{!!
347+
\App\Support\Markdown::parse($docs)->absoluteImageUrls(
348+
baseUrl: str($plugin->getDocUrl(request()->query('v')))
349+
->lower()
350+
->before('readme.md'),
351+
)
352+
!!}
347353
</div>
348354
</div>
349355
@endif

0 commit comments

Comments
 (0)