Articles
Now let's create the page for our articles. Here is the steps we'll follow:
- Create the route with a basic controller (
/articles/{id}
) - Add a directory with some articles
- Render them with Twig
Let's go!
Create the route and the controller
First, let's create a basic empty controller
# src/Controller/ArticlesController.php
<?php
declare(strict_types=1);
namespace Archict\Archict\Controller;
use Archict\Router\RequestHandler;
use Psr\Http\Message\ServerRequestInterface;
final class ArticlesController implements RequestHandler
{
public function handle(ServerRequestInterface $request): string
{
return 'Article ' . $request->getAttribute('id');
}
}
And then declare our route in Application
with
$collector->addRoute(Method::GET, '/article/{id:\d+}', new ArticlesController());
/article/{id:\d+}
matches all uri beginning with /article/
followed by a number, we call this number id
so we can get it back in the controller via the attributes of the request.
If you go to http://localhost:8080/article/42, you should see a white page with just Article 42
writed.
Add some articles
In a real blog, we should implement a database and store our existing articles inside, but it's not the matter of this tutorial so we'll go to a shorter path: filesystem. We will store our articles inside public/articles
and name them with their ids. For example, article 42 will have path public/articles/42.html.twig
. I let you create some Twig templates corresponding to our system and then we can tune the controller to get them.
Twig rendering
The controller need to:
- get the seeked article id
- check if it exists
- render it
# src/Controller/ArticlesController.php
<?php
declare(strict_types=1);
namespace Archict\Archict\Controller;
use Archict\Archict\Services\Twig;
use Archict\Router\HTTPExceptionFactory;
use Archict\Router\RequestHandler;
use Psr\Http\Message\ServerRequestInterface;
final readonly class ArticlesController implements RequestHandler
{
public function __construct(private Twig $twig)
{
}
public function handle(ServerRequestInterface $request): string
{
// Get article id
$article_id = $request->getAttribute('id');
// Check it exists
$filename = __DIR__ . '/../../public/articles/' . $article_id . '.html.twig';
if (! file_exists($filename)) {
throw HTTPExceptionFactory::NotFound("Article $article_id not found");
}
// Render it
return $this->twig->render($filename);
}
}
Don't forget to add the argument to the controller constructor in Application
$collector->addRoute(Method::GET, '/article/{id:\d+}', new ArticlesController($this->twig));
Now if you go to http://localhost:8080/article/42, you should see you article. You can replace 42 by any number, if the article doesn't exists you'll get the message that the page doesn't exist.