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.