Skip to content

Commit 2629ea2

Browse files
authored
Merge branch 'filamentphp:main' into main
2 parents 696ada0 + 08df595 commit 2629ea2

File tree

986 files changed

+6102
-2046
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

986 files changed

+6102
-2046
lines changed

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
**/dist
33
**/package-lock.json
44
**/vendor
5+
build
56
composer.lock
67
docs/dist
78
docs/filament
89
docs/node_modules
10+
docs/preserved-dist
911
docs/src/navigation.json
1012
docs/src/pages
1113
docs/torchlight-cache

app/Enums/Version.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace App\Enums;
4+
5+
enum Version: string
6+
{
7+
case Four = '4.x';
8+
case Three = '3.x';
9+
case Two = '2.x';
10+
case One = '1.x';
11+
12+
public static function getLatest(): self
13+
{
14+
return self::Four;
15+
}
16+
}

app/Models/Article.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function isCompatibleWithLatestVersion(): ?bool
7474
return null;
7575
}
7676

77-
return in_array(3, $this->versions);
77+
return in_array(4, $this->versions);
7878
}
7979

8080
public function getAuthor(): Author

app/Models/Plugin.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ public function getDocUrl(string $version = null): ?string
8585
}
8686

8787
if (filled($this->docs_urls)) {
88-
return $this->docs_urls[$version ?? key($this->docs_urls)] ?? null;
88+
$docsUrls = $this->docs_urls;
89+
krsort($docsUrls);
90+
91+
return $docsUrls[$version ?? array_key_first($docsUrls)] ?? null;
8992
}
9093

9194
return null;
@@ -174,7 +177,7 @@ public function getCategories(): Collection
174177

175178
public function isCompatibleWithLatestVersion(): bool
176179
{
177-
return in_array(3, $this->versions);
180+
return in_array(4, $this->versions);
178181
}
179182

180183
public function getAuthor(): Author

app/Providers/AppServiceProvider.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ public function boot(): void
4949
'plugin' => Plugin::class,
5050
]);
5151

52-
URL::forceScheme('https');
52+
if ($this->app->environment('production')) {
53+
URL::forceScheme('https');
54+
}
5355

5456
RateLimiter::for('vpn_api', function (CheckIfIpIsVpn $job): Limit {
5557
if (

app/Support/Markdown.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Illuminate\Support\HtmlString;
77
use League\CommonMark\Environment\Environment;
88
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
9+
use League\CommonMark\Extension\Embed\Bridge\OscaroteroEmbedAdapter;
10+
use League\CommonMark\Extension\Embed\EmbedExtension;
911
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
1012
use League\CommonMark\Extension\Table\TableExtension;
1113
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
@@ -17,38 +19,47 @@ class Markdown implements Htmlable, Stringable
1719
{
1820
protected Environment $environment;
1921

20-
public function __construct(protected string $content)
22+
public function __construct(protected string $content, bool $hasTableOfContents = true, protected bool $shouldSanitize = true)
2123
{
2224
$this->environment = new Environment([
2325
'allow_unsafe_links' => false,
26+
'embed' => [
27+
'adapter' => new OscaroteroEmbedAdapter,
28+
'allowed_domains' => ['youtube.com', 'youtube-nocookie.com'],
29+
'fallback' => 'link',
30+
],
2431
'heading_permalink' => [
2532
'html_class' => 'heading-anchor',
2633
'id_prefix' => '',
2734
'fragment_prefix' => '',
2835
'symbol' => '#',
2936
'title' => 'Permalink',
3037
],
31-
'table_of_contents' => [
38+
...$hasTableOfContents ? ['table_of_contents' => [
3239
'html_class' => 'table-of-contents',
3340
'position' => 'top',
3441
'style' => 'bullet',
3542
'min_heading_level' => 2,
3643
'max_heading_level' => 6,
3744
'normalize' => 'relative',
3845
'placeholder' => null,
39-
],
46+
]] : [],
4047
]);
4148

4249
$this->environment->addExtension(new CommonMarkCoreExtension);
50+
$this->environment->addExtension(new EmbedExtension);
4351
$this->environment->addExtension(new TableExtension);
4452
$this->environment->addExtension(new HeadingPermalinkExtension);
4553
$this->environment->addExtension(new TorchlightExtension);
46-
$this->environment->addExtension(new TableOfContentsExtension);
54+
55+
if ($hasTableOfContents) {
56+
$this->environment->addExtension(new TableOfContentsExtension);
57+
}
4758
}
4859

49-
public static function parse(string $text): static
60+
public static function parse(string $text, bool $hasTableOfContents = true, bool $shouldSanitize = true): static
5061
{
51-
$static = app(static::class, ['content' => $text]);
62+
$static = app(static::class, ['content' => $text, 'hasTableOfContents' => $hasTableOfContents, 'shouldSanitize' => $shouldSanitize]);
5263

5364
$static->convert();
5465
$static->removeH1Tags();
@@ -103,8 +114,8 @@ protected function convertSpecialBlockquotes(): static
103114
public function absoluteImageUrls(string $baseUrl): static
104115
{
105116
$this->content = preg_replace(
106-
pattern: '/src=["\'](?!https?:\/\/)([^"\']+)["\'][^>]/i',
107-
replacement: 'src="' . $baseUrl . '$1" ',
117+
pattern: '/\b(src|srcset)\s*=\s*(["\'])(?!https?:\/\/|data:|\/\/)([^"\']+)\2/i',
118+
replacement: '$1=$2' . $baseUrl . '$3$2',
108119
subject: $this->content
109120
);
110121

@@ -140,6 +151,10 @@ public function convertVideoToHtml(): static
140151

141152
public function __toString(): string
142153
{
154+
if (! $this->shouldSanitize) {
155+
return $this->content;
156+
}
157+
143158
return str($this->content)->sanitizeHtml();
144159
}
145160

build/doctum/.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
/vendor
1+
/build
2+
/cache
3+
/filament
4+
/vendor

build/doctum/doctum.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
'default_opened_level' => 2,
2727
'remote_repository' => new GitHubRemoteRepository('filamentphp/filament', dirname($dir)),
2828
'base_url' => 'https://filamentphp.com/api/%version%/',
29-
]);
29+
]);

content/articles/alexandersix-filament-v3-2.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ title: Introducing Filament v3.2
33
slug: alexandersix-filament-v3-2
44
author_slug: alexandersix
55
publish_date: 2024-01-16
6-
categories:
7-
- general
6+
categories: [general]
87
type_slug: news
98
---
109

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
---
2+
title: "Filament v4 is Stable!"
3+
slug: alexandersix-filament-v4-is-stable
4+
author_slug: alexandersix
5+
publish_date: 2025-08-12
6+
categories: [general]
7+
type_slug: news
8+
---
9+
10+
![Filament v4 is Stable!](/images/content/articles/alexandersix-filament-v4-is-stable/v4-stable.webp)
11+
12+
It's official! As of today, August 12, 2025, Filament v4 is officially stable!
13+
And in large part, that is thanks to our incredible community and all the help
14+
with testing, bug fixing, and overall recommendations. We don't take for granted
15+
all of you and the work you've put in to help us get to where we are today.
16+
17+
If you haven't been keeping up with the news regarding the v4 beta, or if you're
18+
new to Filament as of version 4, you'll be very happy to know that we have
19+
added in some incredible updates, new features, and overall performance enhancements
20+
to help you build even more incredible applications with Filament. There are
21+
WAY too many to list out here, but for a full rundown of the major updates present
22+
in v4, you can check out this incredible article written by the Filament Core Team's
23+
very own Leandro: ["What's new in Filament v4?"](https://filamentphp.com/content/leandrocfe-whats-new-in-filament-v4)
24+
25+
## What to expect from our favorite updates
26+
27+
We're very excited about the v4 release, so to celebrate, we wanted to share a
28+
few of our favorite features and what you can expect from them when using the
29+
new v4 release!
30+
31+
### Performance Enhancements
32+
33+
You know we couldn't make a list of our favorite updates without touching
34+
on the performance enhancements in v4. Whether you're building a brand-new,
35+
greenfield application on v4 or updating an older version of Filament to v4,
36+
you'll immediately notice some nice speed boosts across your application.
37+
38+
Out of the box, without any adjustments or code changes, you'll immediately
39+
receive a noticeable performance improvement when using Filament's tables!
40+
We have done a lot of work optimizing how the rendering code runs,
41+
and during our internal testing, we see improvements of around 3x for large
42+
datasets!
43+
44+
In addition, we've also added in a custom partial rendering solution that
45+
will allow you to skip expensive component re-renders when they are not needed.
46+
These improvements don't come for free, but they are opt-in with the use of
47+
methods like `partiallyRenderComponentsAfterStateUpdated()` and
48+
`skipRenderAfterStateUpdated()`. There's more to dig into here, so take a
49+
look at the [documentation for partial rendering](https://filamentphp.com/docs/4.x/forms/overview#field-partial-rendering)
50+
for more information on what each of these methods do, specifically.
51+
52+
If video content is more your speed (ha!), take a look at
53+
[this video from Nuno](https://www.youtube.com/watch?v=uJfFURplMQg) where
54+
he and Dan dive more deeply into the performance improvements found in v4!
55+
56+
### Schemas
57+
58+
Ever wanted to easily combine Filament's form fields, infolist entries,
59+
layout components, and prime components (the basic building blocks of
60+
most applications)? Previously, this was a bit of a pain to handle, but
61+
in v4, we've squished all of these together into what we're calling "Schemas"
62+
to more easily allow you to mix and match these different components
63+
together to create truly custom, ergonomic server-driven UIs. You can
64+
consider this a familiar and easy-to-understand re-imagining of how to
65+
combine the building blocks that Filament provides into something that
66+
works exactly as you (and your users) would expect in your app.
67+
68+
For a full list of the available Schema components and more information
69+
about how they're used in general, [check out the documentation](https://filamentphp.com/docs/4.x/schemas/overview#introduction)!
70+
71+
For those of you who prefer to glance at some code, here's an example
72+
schema direct from the documentation! You can see that, within the
73+
same schema (`form`, in this example), we're using components that were
74+
previously located in the Layout, Infolist, and Form namespaces!
75+
76+
```php
77+
use Filament\Forms\Components\Checkbox;
78+
use Filament\Forms\Components\Select;
79+
use Filament\Forms\Components\TextInput;
80+
use Filament\Infolists\Components\TextEntry;
81+
use Filament\Schemas\Components\Section;
82+
83+
$schema
84+
->components([
85+
Grid::make(2)
86+
->schema([
87+
Section::make('Details')
88+
->schema([
89+
TextInput::make('name'),
90+
Select::make('position')
91+
->options([
92+
'developer' => 'Developer',
93+
'designer' => 'Designer',
94+
]),
95+
Checkbox::make('is_admin'),
96+
]),
97+
Section::make('Auditing')
98+
->schema([
99+
TextEntry::make('created_at')
100+
->dateTime(),
101+
TextEntry::make('updated_at')
102+
->dateTime(),
103+
]),
104+
]),
105+
])
106+
```
107+
108+
Hopefully this starts the gears turning in your brain! We're
109+
so excited to see what people are capable of with this new, simple
110+
to use system in place in v4.
111+
112+
### Custom Data Tables
113+
114+
I mean, it's about time, right?
115+
116+
In all seriousness, we're so excited about our new table implementation
117+
and the fact that it now allows arbitrary, non-Model-backed data to be
118+
displayed! Now it's just as simple as giving your Filament Table an array
119+
of data to be shown, and we handle the rest for you. No more wrestling with
120+
the underlying Filament components or deferring to Sushi (a great package
121+
in its own right, though) to add custom data to your tables!
122+
123+
The best part is that in this new implementation, custom data, whether
124+
hard-coded, retrieved from an external API, or gleaned from anywhere else,
125+
receives all the same niceties that typical Model-backed data gets. This
126+
means your custom data can be paginated, searched, sorted, and it can
127+
even have Actions attached to it!
128+
129+
For more information, check our our [custom data documentation](https://filamentphp.com/docs/4.x/tables/custom-data)!
130+
131+
### Actions, Actions, Actions
132+
133+
This one is a short one, but a very, very sweet one.
134+
135+
Admit it, we've all done it before: we've wanted to add an Action
136+
somewhere in our Filament application, but we imported the _wrong_
137+
Action type from the _wrong_ namespace. It's not a hard error to
138+
fix, but it's incredibly irritating when it happens.
139+
140+
In v4, this is an issue (mostly) of the past!
141+
142+
We have now unified all of the action classes, so instead of needing
143+
to specifically use the `Action` class that corresponds to your
144+
given context, all actions now use a single `Filament\Actions`
145+
namespace. And, in addition to Action imports being much easier now,
146+
this also means that you can more easily create portable Actions
147+
which can be reused across different contexts (Forms, Infolists, Tables, etc.).
148+
149+
## There's more where that came from
150+
151+
These are just a small handful of the incredible updates that have
152+
been packed into the v4 release.
153+
154+
We're probably a bit biased in saying it, but we think this is easily
155+
one of the greatest Filament releases to date! You can read all about
156+
the update in the documentation or in Leandro's v4 overview post,
157+
but in my opinion, the best way to see what's available is to give it
158+
a try for yourself! Installation is as easy as ever, and the upgrade
159+
path from v3 -> v4 is simple and almost entirely automated thanks to
160+
our custom upgrade scripts (think Laravel Shift, but for Filament).
161+
162+
Once again, we have to give a huge thank you to the entire community
163+
for their constant encouragement and support, as well as for their
164+
contributions to this release. Filament wouldn't be half the project
165+
it is today without all of you, and we're eternally grateful to have
166+
you along for the ride.
167+
168+
Give v4 a whirl, and let us know what you think! We'd love to hear from
169+
you in the Filament Discord server, especially if you're building
170+
something that you're proud of using Filament!

0 commit comments

Comments
 (0)