Page de l'article
Créons maintenant une autre page du blog, qui affichera un article spécifique.
Nous devons créer une nouvelle méthode render, qui obtiendra un article spécifique et le transmettra au template. Avoir
cette méthode dans HomePresenter
n'est pas très propre, car nous parlons d'un article et non de la page d'accueil.
Créons donc PostPresenter
dans app/Presentation/Post/
. Ce presenter a également besoin de se connecter
à la base de données, nous écrirons donc à nouveau un constructeur qui nécessitera une connexion à la base de données.
PostPresenter
pourrait donc ressembler à ceci :
<?php
namespace App\Presentation\Post;
use Nette;
use Nette\Application\UI\Form;
final class PostPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
public function renderShow(int $id): void
{
$this->template->post = $this->database
->table('posts')
->get($id);
}
}
Nous ne devons pas oublier d'indiquer le namespace correct App\Presentation\Post
, qui est soumis aux paramètres
de mappage des presenters.
La méthode renderShow
nécessite un argument – l'ID d'un article spécifique qui doit être affiché. Ensuite,
elle charge cet article depuis la base de données et le transmet au template.
Dans le template Home/default.latte
, insérons un lien vers l'action Post:show
.
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
La balise {link}
génère une adresse URL qui pointe vers l'action Post:show
. Elle transmet
également l'ID de l'article comme argument.
Nous pouvons écrire la même chose de manière abrégée en utilisant un n:attribut :
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
L'attribut n:href
est analogue à la balise {link}
.
Cependant, il n'existe pas encore de template pour l'action Post:show
. Nous pouvons essayer d'ouvrir le lien vers
cet article. Tracy affichera une erreur, car le template Post/show.latte
n'existe pas encore. Si vous voyez un autre message d'erreur, vous devrez probablement activer mod_rewrite
sur le
serveur web.
Créons donc le template Post/show.latte
avec ce contenu :
{block content}
<p><a n:href="Home:default">← retour à la liste des articles</a></p>
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h1 n:block="title">{$post->title}</h1>
<div class="post">{$post->content}</div>
Passons maintenant en revue les différentes parties du template.
La première ligne commence la définition d'un bloc nommé “content”, comme c'était le cas sur la page d'accueil. Ce bloc
sera à nouveau affiché dans le template principal. Comme vous pouvez le voir, la balise de fin {/block}
est
manquante. Elle est en effet facultative.
Sur la ligne suivante se trouve un lien de retour vers la liste des articles du blog, afin que l'utilisateur puisse facilement
naviguer entre la liste des articles et un article spécifique. Comme nous utilisons l'attribut n:href
, Nette
s'occupe lui-même de la génération des liens. Le lien pointe vers l'action default
du presenter Home
(nous pouvons également écrire n:href="Home:"
, car l'action nommée default
peut être omise, elle est
complétée automatiquement).
La troisième ligne formate l'affichage de la date à l'aide du filtre que nous connaissons déjà.
La quatrième ligne affiche le titre du blog dans la balise HTML <h1>
. Cette balise contient un
attribut que vous ne connaissez peut-être pas (n:block="title"
). Devinez-vous ce qu'il fait ? Si vous avez lu
attentivement la partie précédente, vous savez déjà qu'il s'agit d'un n:attribut
. C'est un autre exemple de
ceux-ci, qui est équivalent à :
{block title}<h1>{$post->title}</h1>{/block}
En termes simples, ce bloc redéfinit le bloc nommé title
. Ce bloc est déjà défini dans le template
layout principal (/app/Presentation/@layout.latte:11
) et, tout comme pour le remplacement de méthodes en POO,
ce bloc dans le template principal est complètement remplacé. Ainsi, le <title>
de la page contient
maintenant le titre de l'article affiché, et il nous a suffi d'utiliser un simple attribut n:block="title"
. Génial,
n'est-ce pas ?
La cinquième et dernière ligne du template affiche l'intégralité du contenu d'un article spécifique.
Vérification de l'ID de l'article
Que se passe-t-il si quelqu'un modifie l'ID dans l'URL et insère un id
inexistant ? Nous devrions proposer à
l'utilisateur une belle erreur de type “page non trouvée”. Modifions donc un peu la méthode render dans
PostPresenter
:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Page non trouvée');
}
$this->template->post = $post;
}
Si l'article ne peut pas être trouvé, en appelant $this->error(...)
, nous affichons une page d'erreur
404 avec un message compréhensible. Attention, en mode développeur (localhost), vous ne verrez pas cette page d'erreur. À la
place, Tracy s'affichera avec les détails de l'exception, ce qui est assez pratique pour le développement. Si nous voulons
afficher les deux modes, il suffit de changer l'argument de la méthode setDebugMode
dans le fichier
Bootstrap.php
.
Résumé
Nous avons une base de données avec des articles et une application web qui a deux vues – la première affiche un aperçu de tous les articles et la seconde affiche un article spécifique.