Skip to content

Commit 9a66cca

Browse files
authored
chore(docs): move documentation to main repository (#1476)
1 parent 24e7470 commit 9a66cca

37 files changed

+8423
-8
lines changed

.github/workflows/deploy-docs.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Deploy documentation
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- 2.x
7+
8+
jobs:
9+
trigger:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Trigger documentation deployment
13+
uses: octokit/[email protected]
14+
with:
15+
route: POST /repos/:owner/:repo/dispatches
16+
owner: tempestphp
17+
repo: tempest-docs
18+
event_type: deploy
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

bun.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
"workspaces": {
44
"": {
55
"devDependencies": {
6-
"@types/bun": "1.2.19",
7-
"bumpp": "10.2.1",
8-
"dprint": "0.50.1",
9-
"typescript": "5.8.3",
6+
"@types/bun": "latest",
7+
"bumpp": "^10.0.1",
8+
"dprint": "^0.50.0",
9+
"typescript": "^5.7.3",
1010
"unbuild": "^3.3.1",
1111
"vite-plugin-tempest": "workspace:*",
12-
"vitest": "3.2.4",
12+
"vitest": "^3.2.3",
1313
},
1414
},
1515
"packages/vite-plugin-tempest": {
1616
"name": "vite-plugin-tempest",
17-
"version": "1.5.0",
17+
"version": "1.6.0",
1818
"dependencies": {
1919
"@innocenzi/utils": "^0.3.0",
2020
"picocolors": "^1.1.1",
@@ -192,7 +192,7 @@
192192

193193
"@trysound/sax": ["@trysound/[email protected]", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
194194

195-
"@types/bun": ["@types/[email protected].19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
195+
"@types/bun": ["@types/[email protected].20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
196196

197197
"@types/chai": ["@types/[email protected]", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="],
198198

@@ -236,7 +236,7 @@
236236

237237
"bumpp": ["[email protected]", "", { "dependencies": { "ansis": "^4.1.0", "args-tokenizer": "^0.3.0", "c12": "^3.1.0", "cac": "^6.7.14", "escalade": "^3.2.0", "jsonc-parser": "^3.3.1", "package-manager-detector": "^1.3.0", "semver": "^7.7.2", "tinyexec": "^1.0.1", "tinyglobby": "^0.2.14", "yaml": "^2.8.0" }, "bin": { "bumpp": "bin/bumpp.mjs" } }, "sha512-Dhgao1WhrcMg+1R3GU+57e6grUNNIGORN53YllDFurNEVGWmkD/z63R3xX4Sl9IqEw//1/UxbrvmK8V1pcJDHw=="],
238238

239-
"bun-types": ["[email protected].19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
239+
"bun-types": ["[email protected].20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
240240

241241
"c12": ["[email protected]", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="],
242242

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
title: Introduction
3+
description: "Tempest is a framework for PHP development, designed to get out of your way. Its core philosophy is to help you focus on your application code, without being bothered hand-holding the framework."
4+
---
5+
6+
Tempest's goal is to make you more productive when building web and console apps in PHP. It handles all the boilerplate parts of such projects for you, so that you can focus on what matters the most: writing application code.
7+
8+
People using 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. On this page, you'll read what sets Tempest apart as a framework for modern PHP development. If you're already convinced, you can head over to the [installation page](../0-getting-started/02-installation.md) and get started with Tempest.
9+
10+
## Vision
11+
12+
Tempest's vision can be summarized like this: **it's a community-driven, modern PHP framework that gets out of your way and dares to think outside the box**. Let's dissect that vision in depth.
13+
14+
### Community driven
15+
16+
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 something real.
17+
18+
Currently, there are three core members dedicating a lot of their 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.
19+
20+
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.
21+
22+
### Embracing modern PHP
23+
24+
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).
25+
26+
Just to name a couple of examples, Tempest uses property hooks:
27+
28+
```php
29+
interface DatabaseMigration
30+
{
31+
public string $name {
32+
get;
33+
}
34+
35+
public function up(): ?QueryStatement;
36+
37+
public function down(): ?QueryStatement;
38+
}
39+
```
40+
41+
Attributes:
42+
43+
```php
44+
final class BookController
45+
{
46+
#[Get('/books/{book}')]
47+
public function show(Book $book): Response { /* … */ }
48+
}
49+
```
50+
51+
Proxy objects:
52+
53+
```php
54+
use Tempest\Container\Proxy;
55+
56+
final readonly class BookController
57+
{
58+
public function __construct(
59+
#[Proxy] private SlowDependency $slowDependency,
60+
) { /* … */ }
61+
}
62+
```
63+
64+
And a lot more.
65+
66+
### Getting out of your way
67+
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.
69+
70+
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.
71+
72+
```php
73+
final class ConsoleCommandDiscovery implements Discovery
74+
{
75+
use IsDiscovery;
76+
77+
public function __construct(
78+
private readonly ConsoleConfig $consoleConfig,
79+
) {}
80+
81+
public function discover(DiscoveryLocation $location, ClassReflector $class): void
82+
{
83+
foreach ($class->getPublicMethods() as $method) {
84+
if ($consoleCommand = $method->getAttribute(ConsoleCommand::class)) {
85+
$this->discoveryItems->add($location, [$method, $consoleCommand]);
86+
}
87+
}
88+
}
89+
90+
public function apply(): void
91+
{
92+
foreach ($this->discoveryItems as [$method, $consoleCommand]) {
93+
$this->consoleConfig->addCommand($method, $consoleCommand);
94+
}
95+
}
96+
}
97+
```
98+
99+
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.
100+
101+
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.
102+
103+
```php
104+
use Tempest\View\ViewRenderer;
105+
106+
$container->singleton(ViewRenderer::class, $myCustomViewRenderer);
107+
```
108+
109+
### Thinking outside the box
110+
111+
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:
112+
113+
```php
114+
final readonly class BooksCommand
115+
{
116+
use HasConsole;
117+
118+
public function __construct(
119+
private BookRepository $repository,
120+
) {}
121+
122+
#[ConsoleCommand]
123+
public function find(?string $initial = null): void
124+
{
125+
$book = $this->search(
126+
'Find your book',
127+
$this->repository->find(...),
128+
);
129+
}
130+
131+
#[ConsoleCommand(middleware: [CautionMiddleware::class])]
132+
public function delete(string $title, bool $verbose = false): void
133+
{ /* … */ }
134+
}
135+
```
136+
137+
Or what about [Tempest's ORM](../1-essentials/03-database), which aims to have truly decoupled models:
138+
139+
```php
140+
use Tempest\Validation\Rules\Length;
141+
use App\Author;
142+
143+
final class Book
144+
{
145+
#[Length(min: 1, max: 120)]
146+
public string $title;
147+
148+
public ?Author $author = null;
149+
150+
/** @var \App\Chapter[] */
151+
public array $chapters = [];
152+
}
153+
```
154+
155+
```php
156+
final class BookRepository
157+
{
158+
public function findById(int $id): Book
159+
{
160+
return query(Book::class)
161+
->select()
162+
->with('chapters', 'author')
163+
->where('id = ?', $id)
164+
->first();
165+
}
166+
}
167+
```
168+
169+
Then there's our view engine, which embraces the most original template engine of all time: HTML;
170+
171+
```html
172+
<x-base :title="$this->seo->title">
173+
<ul>
174+
<li :foreach="$this->books as $book">
175+
{{ $book->title }}
176+
177+
<span :if="$this->showDate($book)">
178+
<x-tag>
179+
{{ $book->publishedAt }}
180+
</x-tag>
181+
</span>
182+
</li>
183+
</ul>
184+
</x-base>
185+
```
186+
187+
## Getting started
188+
189+
Are you intrigued? Want to give Tempest a try? Head over to [the next chapter](../0-getting-started/02-installation.md) to learn about how to get started with Tempest.
190+
191+
If you want to become part of our community, you're more than welcome to [join our Discord server](/discord), and to check out [Tempest on GitHub](https://github.com/tempestphp/tempest-framework).
192+
193+
Enjoy!
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
title: Installation
3+
description: Tempest can be installed as a standalone PHP project, as well as a package within existing projects. The framework modules can also be installed individually, including in projects built on other frameworks.
4+
---
5+
6+
## Prerequisites
7+
8+
Tempest requires PHP [8.4+](https://www.php.net/downloads.php) and [Composer](https://getcomposer.org/) to be installed. Optionally, you may install either [Bun](https://bun.sh) or [Node](https://nodejs.org) if you chose to bundle front-end assets.
9+
10+
For a better experience, it is recommended to have a complete development environment, such as [ServBay](https://www.servbay.com), [Herd](https://herd.laravel.com/docs), or [Valet](https://laravel.com/docs/valet). However, Tempest can serve applications using PHP's built-in server just fine.
11+
12+
Once the prerequisites are installed, you can chose your installation method. Tempest can be a [standalone application](#creating-a-tempest-application), or be added [in an existing project](#tempest-as-a-package)—even one built on top of another framework.
13+
14+
## Creating a Tempest application
15+
16+
To get started with a new Tempest project, you may use {`tempest/app`} as the starting point. The `composer create-project` command will scaffold it for you:
17+
18+
```sh
19+
{:hl-keyword:composer:} create-project tempest/app {:hl-type:my-app:}
20+
{:hl-keyword:cd:} {:hl-type:my-app:}
21+
```
22+
23+
If you have a dedicated development environment, you may then access your application by opening `{txt}https://my-app.test` in your browser. Otherwise, you may use PHP's built-in server:
24+
25+
```sh
26+
{:hl-keyword:php:} tempest serve
27+
{:hl-comment:PHP 8.4.5 Development Server (http://localhost:8000) started:}
28+
```
29+
30+
### Scaffolding front-end assets
31+
32+
Optionally, you may install a basic front-end scaffolding that includes [Vite](https://vite.dev/) and [Tailwind CSS](https://tailwindcss.com/). To do so, run the Vite installer and follow through the wizard:
33+
34+
```sh
35+
{:hl-keyword:php:} tempest install vite --tailwind
36+
```
37+
38+
The assets created by this wizard, `main.entrypoint.ts` and `main.entrypoint.css`, are automatically discovered by Tempest. You can serve them using the [`<x-vite-tags />`](../1-essentials/03-views#x-vite-tags) component in your templates.
39+
40+
You may then [run the front-end development server](../1-essentials/04-asset-bundling#running-the-development-server), which will serve your assets on-the-fly:
41+
42+
```bash
43+
{:hl-keyword:npm:} run dev
44+
```
45+
46+
## Tempest as a package
47+
48+
If you already have a project, you can opt to install {`tempest/framework`} as a standalone package. You could do this in any project; it could already contain code, or it could be an empty project.
49+
50+
```sh
51+
{:hl-keyword:composer:} require tempest/framework
52+
```
53+
54+
Installing Tempest this way will give you access to the Tempest console, `./vendor/bin/tempest`. Optionally, you can choose to install Tempest's entry points in your project. To do so, you may run the framework installer:
55+
56+
```txt
57+
{:hl-keyword:./vendor/bin/tempest:} install framework
58+
```
59+
60+
This installer will prompt you to install the following files into your project:
61+
62+
- `public/index.php` — the web application entry point
63+
- `tempest` – the console application entry point
64+
- `.env.example` – a clean example of a `.env` file
65+
- `.env` – the real environment file for your local installation
66+
67+
You can choose which files you want to install, and you can always rerun the `install` command at a later point in time.
68+
69+
## Project structure
70+
71+
Tempest won't impose any file structure on you: one of its core features is that it will scan all project and package code for you, and will automatically discover any files the framework needs to know about.
72+
73+
For instance, Tempest is able to differentiate between a controller method and a console command by looking at the code, instead of relying on naming conventions or configuration files.
74+
75+
:::info
76+
This concept is called [discovery](../4-internals/02-discovery), and is one of Tempest's most powerful features.
77+
:::
78+
79+
The following project structures work the same way in Tempest, without requiring any specific configuration:
80+
81+
```txt
82+
. .
83+
└── src └── src
84+
├── Authors ├── Controllers
85+
│ ├── Author.php │ ├── AuthorController.php
86+
│ ├── AuthorController.php │ └── BookController.php
87+
│ └── authors.view.php ├── Models
88+
├── Books │ ├── Author.php
89+
│ ├── Book.php │ ├── Book.php
90+
│ ├── BookController.php │ └── Chapter.php
91+
│ ├── Chapter.php ├── Services
92+
│ └── books.view.php │ └── PublisherGateway.php
93+
├── Publishers └── Views
94+
│ └── PublisherGateway.php ├── authors.view.php
95+
└── Support ├── books.view.php
96+
└── x-base.view.php └── x-base.view.php
97+
```
98+
99+
## About discovery
100+
101+
Discovery works by scanning your project code, and looking at each file and method individually to determine what that code does. In production environments, [Tempest will cache the discovery process](../4-internals/02-discovery#discovery-in-production), avoiding any performance overhead.
102+
103+
As an example, Tempest is able to determine which methods are controller methods based on their route attributes, such as `#[Get]` or `#[Post]`:
104+
105+
```php app/BlogPostController.php
106+
use Tempest\Router\Get;
107+
use Tempest\Http\Response;
108+
use Tempest\View\View;
109+
110+
final readonly class BlogPostController
111+
{
112+
#[Get('/blog')]
113+
public function index(): View
114+
{ /* … */ }
115+
116+
#[Get('/blog/{post}')]
117+
public function show(Post $post): Response
118+
{ /* … */ }
119+
}
120+
```
121+
122+
Likewise, it is able to detect console commands based on the `#[ConsoleCommand]` attribute:
123+
124+
```php app/RssSyncCommand.php
125+
use Tempest\Console\HasConsole;
126+
use Tempest\Console\ConsoleCommand;
127+
128+
final readonly class RssSyncCommand
129+
{
130+
use HasConsole;
131+
132+
#[ConsoleCommand('rss:sync')]
133+
public function __invoke(bool $force = false): void
134+
{ /* … */ }
135+
}
136+
```

0 commit comments

Comments
 (0)