Einzelner Beitrag Seite
Fügen wir unserem Blog eine weitere Seite hinzu, die den Inhalt eines bestimmten Blogbeitrags anzeigt.
Wir müssen eine neue Render-Methode erstellen, die einen bestimmten Blogeintrag abruft und ihn an die Vorlage weitergibt.
Diese Ansicht in HomePresenter
zu haben, ist nicht schön, da es sich um einen Blogeintrag und nicht um die Homepage
handelt. Also erstellen wir eine neue Klasse PostPresenter
und platzieren sie in app/UI/Post/
. Sie
benötigt eine Datenbankverbindung, also fügen wir den Datenbankinjektions-Code dort wieder ein.
Die PostPresenter
sollte so aussehen:
<?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);
}
}
Wir müssen einen korrekten Namespace App\UI\Post
für unseren Präsentator festlegen. Dies hängt von der Zuordnung der Präsentatoren ab.
Die Methode renderShow
benötigt ein Argument – die ID des Beitrags, der angezeigt werden soll. Dann lädt sie
den Beitrag aus der Datenbank und übergibt das Ergebnis an die Vorlage.
In der Vorlage Home/default.latte
fügen wir einen Link zur Aktion Post:show
hinzu:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
Das Tag {link}
erzeugt eine URL-Adresse, die auf die Aktion Post:show
verweist. Dieser Tag leitet
auch die ID des Beitrags als Argument weiter.
Das Gleiche können wir kurz mit n:attribute schreiben:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
Das Attribut n:href
ist dem Tag {link}
ähnlich.
Die Vorlage für die Aktion Post:show
existiert noch nicht. Wir können einen Link zu diesem Beitrag öffnen. Tracy wird eine Fehlermeldung anzeigen, warum Post/show.latte
nicht existiert.
Wenn Sie eine andere Fehlermeldung sehen, müssen Sie wahrscheinlich mod_rewrite in Ihrem Webserver einschalten.
Wir werden also Post/show.latte
mit diesem Inhalt erstellen:
{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>
Schauen wir uns die einzelnen Teile an.
Die erste Zeile beginnt mit der Definition eines benannten Blocks namens “content”, den wir bereits gesehen haben.
Er wird in einer Layoutvorlage angezeigt. Wie Sie sehen können, fehlt der Endtag {/block}
. Er ist
optional.
Die zweite Zeile enthält einen Rückverweis auf die Liste der Blog-Einträge, so dass der Benutzer problemlos in unserem Blog
hin und her navigieren kann. Wir verwenden wieder das Attribut n:href
, so dass Nette die URL für uns generiert. Der
Link verweist auf die Aktion default
des Presenters Home
(Sie könnten auch n:href="Home:"
schreiben, da die Aktion default
weggelassen werden kann).
In der dritten Zeile wird der Zeitstempel der Veröffentlichung mit einem Filter formatiert, wie wir bereits wissen.
Die vierte Zeile zeigt den Titel des Blogbeitrags als <h1>
Überschrift. Es gibt einen Teil, mit dem
Sie vielleicht nicht vertraut sind, und das ist n:block="title"
. Können Sie erraten, was er bewirkt? Wenn Sie die
vorherigen Teile aufmerksam gelesen haben, haben wir n: attributes
erwähnt. Dies ist ein weiteres Beispiel. Es ist
gleichbedeutend mit:
{block title}<h1>{$post->title}</h1>{/block}
In einfachen Worten: Es definiert einen Block namens title
neu. Der Block ist in der Layout-Vorlage
(/app/UI/@layout.latte:11
) definiert und wird hier, wie bei OOP-Überschreibungen, überschrieben. Daher wird die
Seite <title>
den Titel des angezeigten Beitrags enthalten. Wir haben den Titel der Seite überschrieben, und
alles, was wir brauchten, war n:block="title"
. Großartig, nicht wahr?
In der fünften und letzten Zeile der Vorlage wird der gesamte Inhalt Ihres Beitrags angezeigt.
Überprüfen der Post-ID
Was passiert, wenn jemand die URL ändert und id
einfügt, die nicht existiert? Wir sollten dem Benutzer eine
schöne Fehlermeldung “Seite nicht gefunden” geben. Aktualisieren wir die Render-Methode in 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;
}
Wenn der Beitrag nicht gefunden werden kann, wird durch den Aufruf von $this->error(...)
eine 404-Seite mit
einer schönen und verständlichen Meldung angezeigt. Beachten Sie, dass Sie in Ihrer Entwicklungsumgebung (auf Ihrem Laptop) die
Fehlerseite nicht sehen werden. Stattdessen zeigt Tracy die Ausnahme mit allen Details an, was für die Entwicklung sehr praktisch
ist. Sie können beide Modi prüfen, indem Sie den an setDebugMode
übergebenen Wert in Bootstrap.php
ändern.
Zusammenfassung
Wir haben eine Datenbank mit Blog-Beiträgen und eine Web-Applikation mit zwei Ansichten – die erste zeigt die Zusammenfassung aller aktuellen Beiträge, die zweite einen bestimmten Beitrag an.