Skip to content

Commit 46b98b3

Browse files
committed
wip
1 parent 1785010 commit 46b98b3

File tree

7 files changed

+244
-26
lines changed

7 files changed

+244
-26
lines changed

composer.lock

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Web/Blog/BlogController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function index(BlogRepository $repository): View
2424
{
2525
$posts = $repository->all();
2626

27-
return view('./index.view.php', posts: $posts, meta: MetaType::BLOG);
27+
return view('./index.view.php', posts: $posts, metaType: MetaType::BLOG);
2828
}
2929

3030
#[Get('/blog/{slug}')]

src/Web/Blog/BlogPost.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ final class BlogPost
1616
public ?string $tag = null;
1717
public ?string $description = null;
1818
public bool $published = true;
19+
public array $meta = [];
1920
public string $uri {
2021
get {
2122
return uri([BlogController::class, 'show'], slug: $this->slug);
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
title: Tempest's Vision
3+
description: What sets Tempest apart as a framework for modern PHP development.
4+
author: brent
5+
tag: Thoughts
6+
meta:
7+
canonical: https://tempestphp.com/main/getting-started/introduction
8+
---
9+
10+
Today I want to share a bit of Tempest's vision. People often ask about the "why" of building a new framework, and so I wanted to take some time to properly think and write down my thoughts.
11+
12+
I tried to summarize Tempest's vision in one sentence, and came up with this: **Tempest is a community-driven, modern PHP framework that gets out of your way and dares to think outside the box**.
13+
14+
There's a lot packed in one sentence though, so let's go through it in depth.
15+
16+
## Community driven
17+
18+
Tempest started out as an educational project, without the intention for it to be something real. People picked up on it, though, and it was only after a strong community had formed that we considered making it anything else but a thought exercise.
19+
20+
Currently, there are three core members dedicating time to Tempest, as well as over [50 additional contributors](https://github.com/tempestphp/tempest-framework). We have an active [Discord server](/discord) with close to 400 members.
21+
22+
Tempest isn't a solo project and never has been. It is a new framework and has a way to go compared to Symfony or Laravel, but there already is significant momentum and will only keep growing.
23+
24+
## Embracing modern PHP
25+
26+
The benefit of starting from scratch like Tempest did is having a clean slate. Tempest embraced modern PHP features from the start, and its goal is to keep doing this in the future by shipping built-in upgraders whenever breaking changes happen (think of it as Laravel Shift, but built into the framework).
27+
28+
Just to name a couple of examples, Tempest uses property hooks:
29+
30+
```php
31+
interface DatabaseMigration
32+
{
33+
public string $name {
34+
get;
35+
}
36+
37+
public function up(): ?QueryStatement;
38+
39+
public function down(): ?QueryStatement;
40+
}
41+
```
42+
43+
Attributes:
44+
45+
```php
46+
final class BookController
47+
{
48+
#[Get('/books/{book}')]
49+
public function show(Book $book): Response { /* … */ }
50+
}
51+
```
52+
53+
Proxy objects:
54+
55+
```php
56+
use Tempest\Container\Proxy;
57+
58+
final readonly class BookController
59+
{
60+
public function __construct(
61+
#[Proxy] private SlowDependency $slowDependency,
62+
) { /* … */ }
63+
}
64+
```
65+
66+
And a lot more.
67+
68+
## Getting out of your way
69+
70+
A core part of Tempest's philosophy is that it wants to "get out of your way" as best as possible. For starters, Tempest is designed to structure project code however you want, without making any assumptions or forcing conventions on you. You can prefer a classic MVC application, DDD or hexagonal design, microservices, or something else; Tempest works with any project structure out of the box without any configuration.
71+
72+
Behind Tempest's flexibility is one of its most powerful features: [discovery](../internals/discovery). Discovery gives Tempest a great number of insights into your codebase, without any handholding. Discovery handles routing, console commands, view components, event listeners, command handlers, middleware, schedules, migrations, and more.
73+
74+
```php
75+
final class ConsoleCommandDiscovery implements Discovery
76+
{
77+
use IsDiscovery;
78+
79+
public function __construct(
80+
private readonly ConsoleConfig $consoleConfig,
81+
) {}
82+
83+
public function discover(DiscoveryLocation $location, ClassReflector $class): void
84+
{
85+
foreach ($class->getPublicMethods() as $method) {
86+
if ($consoleCommand = $method->getAttribute(ConsoleCommand::class)) {
87+
$this->discoveryItems->add($location, [$method, $consoleCommand]);
88+
}
89+
}
90+
}
91+
92+
public function apply(): void
93+
{
94+
foreach ($this->discoveryItems as [$method, $consoleCommand]) {
95+
$this->consoleConfig->addCommand($method, $consoleCommand);
96+
}
97+
}
98+
}
99+
```
100+
101+
Discovery makes Tempest truly understand your codebase so that you don't have to explain the framework how to use it. Of course, discovery is heavily optimized for local development and entirely cached in production, so there's no performance overhead. Even better: discovery isn't just a core framework feature, you're encouraged to write your own project-specific discovery classes wherever they make sense. That's the Tempest way.
102+
103+
Besides Discovery, Tempest is designed to be extensible. You'll find that any part of the framework can be replaced and hooked into by implementing an interface and plugging it into the container. No fighting the framework, Tempest gets out of your way.
104+
105+
```php
106+
use Tempest\View\ViewRenderer;
107+
108+
$container->singleton(ViewRenderer::class, $myCustomViewRenderer);
109+
```
110+
111+
## Thinking outside the box
112+
113+
Finally, since Tempest originated as an educational project, many Tempest features dare to rethink the things we've gotten used to. For example, [console commands](../1-essentials/04-console-commands), which in Tempest are designed to be very similar to controller actions:
114+
115+
```php
116+
final readonly class BooksCommand
117+
{
118+
use HasConsole;
119+
120+
public function __construct(
121+
private BookRepository $repository,
122+
) {}
123+
124+
#[ConsoleCommand]
125+
public function find(?string $initial = null): void
126+
{
127+
$book = $this->search(
128+
'Find your book',
129+
$this->repository->find(...),
130+
);
131+
}
132+
133+
#[ConsoleCommand(middleware: [CautionMiddleware::class])]
134+
public function delete(string $title, bool $verbose = false): void
135+
{ /* … */ }
136+
}
137+
```
138+
139+
Or what about [Tempest's ORM](../1-essentials/03-database), which aims to have truly decoupled models:
140+
141+
```php
142+
use Tempest\Validation\Rules\Length;
143+
use App\Author;
144+
145+
final class Book
146+
{
147+
#[Length(min: 1, max: 120)]
148+
public string $title;
149+
150+
public ?Author $author = null;
151+
152+
/** @var \App\Chapter[] */
153+
public array $chapters = [];
154+
}
155+
```
156+
157+
```php
158+
final class BookRepository
159+
{
160+
public function findById(int $id): Book
161+
{
162+
return query(Book::class)
163+
->select()
164+
->with('chapters', 'author')
165+
->where('id = ?', $id)
166+
->first();
167+
}
168+
}
169+
```
170+
171+
Then there's our view engine, which embraces the most original template engine of all time: HTML;
172+
173+
```html
174+
<x-base :title="$this->seo->title">
175+
<ul>
176+
<li :foreach="$this->books as $book">
177+
{{ $book->title }}
178+
179+
<span :if="$this->showDate($book)">
180+
<x-tag>
181+
{{ $book->publishedAt }}
182+
</x-tag>
183+
</span>
184+
</li>
185+
</ul>
186+
</x-base>
187+
```
188+
189+
---
190+
191+
So, those are the four main pillars of Tempest's vision:
192+
193+
- Community-driven
194+
- Modern PHP
195+
- Getting out of your way
196+
- Thinking outside the box
197+
198+
People who use Tempest say it's the sweet spot between the robustness of Symfony and the eloquence of Laravel. It feels lightweight and close to vanilla PHP; and yet powerful and feature-rich.
199+
200+
But, you shouldn't take my word for it. I'd encourage you to [give Tempest a try](/main/getting-started/installation).

src/Web/Blog/show.view.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66

77
?>
88

9-
<x-base :meta-image-uri="uri([MetaImageController::class, 'blog'], slug: $post->slug)" :title="$post->title" :description="$post->description" :copy-code-blocks="true">
9+
<x-base
10+
:meta-image-uri="uri([MetaImageController::class, 'blog'], slug: $post->slug)"
11+
:title="$post->title"
12+
:description="$post->description"
13+
:copy-code-blocks="true"
14+
:meta="$post->meta"
15+
>
1016
<!-- Main container -->
1117
<main class="container px-4 mx-auto xl:px-8 flex flex-col grow isolate items-center relative">
1218
<!-- Main content -->

src/Web/Documentation/content/main/0-getting-started/01-introduction.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ And a lot more.
6565

6666
### Getting out of your way
6767

68-
A core part of Tempest's philosophy is that it wants to "get out of your way" as best as possible. For starters, Tempest is designed to structure your project code however you want, without making any assumptions or forcing conventions on you. You can prefer a classic MVC applications, DDD or hexagonal design, microservices, or something else; Tempest works with any project structure out of the box without any configuration.
68+
A core part of Tempest's philosophy is that it wants to "get out of your way" as best as possible. For starters, Tempest is designed to structure your project code however you want, without making any assumptions or forcing conventions on you. You can prefer a classic MVC application, DDD or hexagonal design, microservices, or something else; Tempest works with any project structure out of the box without any configuration.
6969

7070
Behind Tempest's flexibility is one of its most powerful features: [discovery](../internals/discovery). Discovery gives Tempest a great number of insights into your codebase, without any handholding. Discovery handles routing, console commands, view components, event listeners, command handlers, middleware, schedules, migrations, and more.
7171

@@ -100,6 +100,12 @@ Discovery makes Tempest truly understand your codebase so that you don't have to
100100

101101
Besides Discovery, Tempest is designed to be extensible. You'll find that any part of the framework can be replaced and hooked into by implementing an interface and plugging it into the container. No fighting the framework, Tempest gets out of your way.
102102

103+
```php
104+
use Tempest\View\ViewRenderer;
105+
106+
$container->singleton(ViewRenderer::class, $myCustomViewRenderer);
107+
```
108+
103109
### Thinking outside the box
104110

105111
Finally, since Tempest originated as an educational project, many Tempest features dare to rethink the things we've gotten used to. For example, [console commands](../1-essentials/04-console-commands), which in Tempest are designed to be very similar to controller actions:

0 commit comments

Comments
 (0)