Créer et éditer des articles

C'est formidable ! Nous avons un tout nouveau blog génial, les gens discutent activement dans les commentaires et nous avons enfin du temps pour programmer davantage. Adminer est certes un excellent outil, mais il n'est pas très confortable pour écrire de nouveaux articles. C'est peut-être le bon moment pour créer un formulaire simple permettant d'ajouter de nouveaux articles directement depuis l'application. Allons-y.

Commençons par concevoir l'interface utilisateur :

  1. Sur la page d'accueil, ajoutons un lien “Écrire un nouvel article”.
  2. Ce lien affichera un formulaire avec un champ pour le titre et une zone de texte pour le contenu de l'article.
  3. Quand nous cliquerons sur le bouton Enregistrer, l'article sera sauvegardé dans la base de données.

Plus tard, nous ajouterons aussi l'authentification et n'autoriserons que les utilisateurs connectés à ajouter de nouveaux articles. Mais faisons cela plus tard. Quel code devons-nous écrire maintenant pour que tout fonctionne ?

  1. Créer un nouveau presenter avec un formulaire d'ajout d'articles.
  2. Définir un callback qui sera déclenché après l'envoi réussi du formulaire et enregistrera le nouvel article dans la base.
  3. Créer un nouveau template pour le formulaire.
  4. Ajouter un lien vers le formulaire dans le template de la page principale.

Nouveau presenter

Nommons le nouveau presenter EditPresenter et enregistrons-le dans app/Presentation/Edit/EditPresenter.php. Il a lui aussi besoin de se connecter à la base, nous écrivons donc là encore un constructeur qui exige une connexion :

<?php
namespace App\Presentation\Edit;

use Nette;
use Nette\Application\UI\Form;

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}

Formulaire d'enregistrement des articles

Nous avons déjà abordé les formulaires et les composants en ajoutant la prise en charge des commentaires. Si ce n'est toujours pas clair, allez revoir comment fonctionnent les formulaires et les composants, nous vous attendons ici ;)

Ajoutez maintenant cette méthode à EditPresenter :

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Titre :')
		->setRequired();
	$form->addTextArea('content', 'Contenu :')
		->setRequired();

	$form->addSubmit('send', 'Enregistrer et publier');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Enregistrer un nouvel article depuis le formulaire

Poursuivons en ajoutant la méthode gestionnaire :

private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage('L\'article a été publié avec succès.', 'success');
	$this->redirect('Post:show', $post->id);
}

Une explication rapide : elle récupère les valeurs du formulaire, les insère dans la base, crée un message indiquant à l'utilisateur que l'article a bien été enregistré et redirige vers la page où cet article est publié, afin que vous puissiez voir à quoi il ressemble.

Page de création d'un nouvel article

Créons maintenant le template Edit/create.latte :

{block content}
<h1>Nouvel article</h1>

{control postForm}

Tout devrait être clair à ce stade. La dernière ligne rend le formulaire que nous venons de créer.

Nous pourrions aussi créer une méthode renderCreate() correspondante, mais ce n'est pas nécessaire. Nous n'avons besoin de récupérer aucune donnée de la base ni de la passer au template, la méthode serait donc vide. Dans ce cas, elle n'a pas besoin d'exister du tout.

Lien de création d'articles

Vous savez probablement déjà comment ajouter un lien vers EditPresenter et son action create. Essayez.

Ajoutez simplement ceci au fichier app/Presentation/Home/default.latte :

<a n:href="Edit:create">Écrire un nouvel article</a>

Éditer les articles

Ajoutons maintenant la possibilité de modifier les articles existants. Ce sera très simple. Nous avons déjà le formulaire postForm et nous pouvons l'utiliser aussi pour l'édition.

Nous ajouterons une nouvelle page edit à EditPresenter :

public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Article non trouvé');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}

Et créons le template correspondant Edit/edit.latte :

{block content}
<h1>Éditer l'article</h1>

{control postForm}

Et mettons à jour la méthode postFormSucceeded, qui saura soit ajouter un nouvel article (comme elle le fait maintenant), soit modifier un article existant :

private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('L\'article a été publié avec succès.', 'success');
	$this->redirect('Post:show', $post->id);
}

Quand le paramètre id est fourni, cela signifie qu'un article est en cours d'édition. Dans ce cas, nous vérifions que l'article existe vraiment et, si oui, nous le mettons à jour dans la base. Si l'id n'est pas fourni, cela signifie qu'un nouvel article doit être ajouté.

Mais d'où vient l'id ? C'est le paramètre passé à la méthode renderEdit.

Vous pouvez maintenant ajouter un lien au template app/Presentation/Post/show.latte :

<a n:href="Edit:edit $post->id">Éditer cet article</a>

Résumé

Le blog fonctionne, les gens commentent à toute vitesse et nous ne dépendons plus d'Adminer pour ajouter de nouveaux articles. Il est totalement autonome et même des gens ordinaires peuvent y publier. Mais attendez : ce n'est probablement pas normal que n'importe qui, et je veux dire vraiment n'importe qui sur internet, puisse publier sur notre blog. Une forme d'authentification s'impose, pour que seuls les utilisateurs connectés puissent publier. Nous l'ajouterons au chapitre suivant.