Page d'affichage unique
Ajoutons une autre page à notre blog, qui affichera le contenu d'un article particulier.
Nous devons créer une nouvelle méthode de rendu, qui récupérera un article de blog spécifique et le transmettra au
modèle. Avoir cette vue dans HomePresenter
n'est pas agréable car il s'agit d'un article de blog, pas de la page
d'accueil. Donc, créons une nouvelle classe PostPresenter
et plaçons-la dans app/UI/Post/
. Elle aura
besoin d'une connexion à la base de données, donc remettez le code database injection.
Le PostPresenter
devrait ressembler à ceci :
<?php
namespace App\UI\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 devons définir un espace de noms correct App\UI\Post
pour notre présentateur. Cela dépend du mappage du présentateur.
La méthode renderShow
requiert un argument – l'ID de l'article à afficher. Ensuite, elle charge l'article
depuis la base de données et transmet le résultat au modèle.
Dans le modèle Home/default.latte
, nous ajoutons 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
. Cette balise transmet
également l'ID du message en tant qu'argument.
On peut écrire la même chose en utilisant n:attribute :
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
L'attribut n:href
est similaire à la balise {link}
.
Le modèle pour l'action Post:show
n'existe pas encore. Nous pouvons ouvrir un lien vers ce poste. Tracy montrera une erreur, pourquoi Post/show.latte
n'existe pas. Si vous
voyez un autre rapport d'erreur, vous devez probablement activer le mod_rewrite dans votre serveur Web.
Nous allons donc créer Post/show.latte
avec ce contenu :
{block content}
<p><a n:href="Home:default">← back to posts list</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>
Regardons les différentes parties.
La première ligne commence la définition d'un bloc nommé appelé “contenu” que nous avons vu précédemment. Il
sera affiché dans un modèle de mise en page. Comme vous pouvez le constater, la balise de fin {/block}
est
absente. Elle est facultative.
La deuxième ligne fournit un lien retour vers la liste des articles du blog, de sorte que l'utilisateur puisse naviguer en
douceur d'avant en arrière sur notre blog. Nous utilisons à nouveau l'attribut n:href
, donc Nette se chargera de
générer l'URL pour nous. Le lien pointe vers l'action default
du présentateur Home
(vous pouvez
également écrire n:href="Home:"
car l'action default
peut être omise).
La troisième ligne formate l'horodatage de la publication avec un filtre, comme nous le savons déjà.
La quatrième ligne affiche le titre de l'article de blog comme un <h1>
titre. Il y a une partie que
vous ne connaissez peut-être pas, c'est n:block="title"
. Pouvez-vous deviner ce qu'elle fait ? Si vous avez lu
attentivement les parties précédentes, nous avons mentionné n: attributes
. Voici un autre exemple. Il est
équivalent à :
{block title}<h1>{$post->title}</h1>{/block}
En termes simples, il re-définit un bloc appelé title
. Le bloc est défini dans le modèle de mise en
page (/app/UI/@layout.latte:11
) et, comme dans le cas de la surcharge de la POO, il est surchargé ici. Par
conséquent, la page <title>
de la page contiendra le titre de l'article affiché. Nous avons remplacé le
titre de la page et tout ce dont nous avions besoin était n:block="title"
. Super, non ?
La cinquième et dernière ligne du modèle affiche le contenu complet de votre article.
Vérification de l'ID du message
Que se passe-t-il si quelqu'un modifie l'URL et insère id
qui n'existe pas ? Nous devrions fournir à
l'utilisateur une belle erreur “page non trouvée”. Mettons à jour la méthode de rendu dans PostPresenter
:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Post not found');
}
$this->template->post = $post;
}
Si le message est introuvable, l'appel à $this->error(...)
affichera une page 404 avec un message agréable
et compréhensible. Notez que dans votre environnement de développement (sur votre ordinateur portable), vous ne verrez pas la
page d'erreur. Au lieu de cela, Tracy affichera l'exception avec tous les détails, ce qui est assez pratique pour le
développement. Vous pouvez vérifier les deux modes, il suffit de changer la valeur passée à setDebugMode
dans
Bootstrap.php
.
Résumé
Nous avons une base de données avec des articles de blog et une application web avec deux vues – la première affiche le résumé de tous les articles récents et la seconde affiche un article spécifique.