Startseite des Blogs
Jetzt erstellen wir eine Startseite, die die neuesten Beiträge anzeigt.
Bevor wir beginnen, ist es notwendig, zumindest die Grundlagen des Model-View-Presenter (ähnlich wie MVC) Entwurfsmusters zu kennen:
- Model – Schicht, die mit Daten arbeitet. Ist komplett vom Rest der Anwendung getrennt. Kommuniziert nur mit dem Presenter.
- View – Front-End-Schicht. Rendert die angeforderten Daten mithilfe von Templates und zeigt sie dem Benutzer an.
- Presenter (oder Controller) – Verbindungsschicht. Der Presenter verbindet Model und View. Er verarbeitet Anfragen, fragt Daten vom Model ab und gibt sie an die View zurück.
Im Falle einfacher Anwendungen, wie unser Blog eine sein wird, besteht die gesamte Modellschicht nur aus Datenbankabfragen – dafür benötigen wir vorerst keinen zusätzlichen Code. Für den Anfang erstellen wir also nur Presenter und Templates. In Nette hat jeder Presenter seine eigenen Templates, daher werden wir sie gleichzeitig erstellen.
Erstellung der Datenbank mit Adminer
Zur Datenspeicherung verwenden wir eine MySQL-Datenbank, da sie unter Webentwicklern am weitesten verbreitet ist. Wenn Sie sie jedoch nicht verwenden möchten, können Sie gerne eine Datenbank Ihrer Wahl wählen.
Nun bereiten wir die Datenbankstruktur vor, in der die Artikel unseres Blogs gespeichert werden. Wir beginnen sehr einfach – wir erstellen nur eine Tabelle für Beiträge.
Zur Erstellung der Datenbank können wir Adminer herunterladen oder ein anderes bevorzugtes Werkzeug zur Datenbankverwaltung verwenden.
Öffnen wir Adminer und erstellen eine neue Datenbank mit dem Namen quickstart
.
Wir erstellen eine neue Tabelle mit dem Namen posts
und diesen Spalten:
id
int, Autoincrement (AI) ankreuzentitle
varchar, Länge 255content
textcreated_at
timestamp
Die resultierende Struktur sollte so aussehen:

CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARSET=utf8;
Es ist wirklich wichtig, den InnoDB-Speicher zu verwenden. Wir werden gleich sehen, warum. Vorerst wählen Sie ihn einfach aus und klicken Sie auf Speichern.
Bevor wir die Möglichkeit schaffen, Artikel über die Anwendung zur Datenbank hinzuzufügen, fügen Sie einige Beispielartikel manuell zum Blog hinzu.
INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
(1, 'Artikel Eins', 'Lorem ipusm dolor eins', CURRENT_TIMESTAMP),
(2, 'Artikel Zwei', 'Lorem ipsum dolor zwei', CURRENT_TIMESTAMP),
(3, 'Artikel Drei', 'Lorem ipsum dolor drei', CURRENT_TIMESTAMP);
Verbindung zur Datenbank herstellen
Nun, da die Datenbank erstellt ist und wir einige Artikel darin gespeichert haben, ist es der richtige Zeitpunkt, sie auf unserer schönen neuen Seite anzuzeigen.
Zuerst müssen wir der Anwendung mitteilen, welche Datenbank sie verwenden soll. Die Verbindung zur Datenbank konfigurieren wir
in der Datei config/common.neon
mithilfe von DSN und
Anmeldedaten. Es sollte ungefähr so aussehen:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *hier Benutzernamen einfügen*
password: *hier Datenbankpasswort einfügen*
Achten Sie beim Bearbeiten dieser Datei auf die Einrückung der Zeilen. Das NEON-Format akzeptiert sowohl Einrückungen mit Leerzeichen als auch mit Tabulatoren, aber nicht beides gleichzeitig. Die Standard-Konfigurationsdatei im Web Project verwendet Tabulatoren.
Datenbankverbindung übergeben
Der Presenter HomePresenter
, der für die Anzeige der Artikel zuständig ist, benötigt eine Verbindung zur
Datenbank. Um diese zu erhalten, verwenden wir einen Konstruktor, der wie folgt aussieht:
<?php
namespace App\Presentation\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Laden von Beiträgen aus der Datenbank
Nun laden wir die Beiträge aus der Datenbank und übergeben sie an das Template, das sie anschließend als HTML-Code rendert. Dafür ist die sogenannte render-Methode vorgesehen:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
Der Presenter enthält nun eine Rendering-Methode renderDefault()
, die Daten aus der Datenbank an das Template
(View) übergibt. Templates befinden sich in app/Presentation/{PresenterName}/{viewName}.latte
, daher befindet sich
das Template in diesem Fall in app/Presentation/Home/default.latte
. Im Template steht nun die Variable
$posts
zur Verfügung, die die aus der Datenbank abgerufenen Beiträge enthält.
Template
Für die gesamte Website steht uns ein Haupt-Template zur Verfügung (das layout heißt, Header, Stile, Footer usw. enthält) sowie spezifische Templates für jede Ansicht (View) (z. B. zur Anzeige von Blogbeiträgen), die einige Teile des Haupt-Templates überschreiben können.
Standardmäßig befindet sich das Layout-Template in app/Presentation/@layout.latte
und enthält:
...
{include content}
...
Die Anweisung {include content}
fügt den Block namens content
in das Haupt-Template ein. Diesen
definieren wir in den Templates der einzelnen Ansichten (View). In unserem Fall passen wir die Datei
Home/default.latte
wie folgt an:
{block content}
Hallo Welt
{/block}
Damit haben wir den Block content definiert, der in das
Hauptlayout eingefügt wird. Wenn wir den Browser erneut aktualisieren, sehen wir eine Seite mit dem Text “Hallo Welt” (im
Quellcode auch mit dem HTML-Header und -Footer, die in @layout.latte
definiert sind).
Lassen Sie uns die Blogbeiträge anzeigen – wir passen das Template wie folgt an:
{block content}
<h1>Mein Blog</h1>
{foreach $posts as $post}
<div class="post">
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h2>{$post->title}</h2>
<div>{$post->content|truncate:256}</div>
</div>
{/foreach}
{/block}
Wenn wir den Browser aktualisieren, sehen wir eine Auflistung aller Beiträge. Die Auflistung ist noch nicht sehr schön oder
farbenfroh, daher können wir der Datei www/css/style.css
einige CSS-Stile hinzufügen und sie im Layout
verlinken:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
Das Tag {foreach}
iteriert über alle Beiträge, die wir dem Template in der Variablen $posts
übergeben haben, und rendert für jeden das entsprechende HTML-Stück. Es verhält sich genau wie PHP-Code.
Die Schreibweise |date:
nennen wir Filter. Filter dienen zur Formatierung der Ausgabe. Dieser spezielle Filter
konvertiert ein Datum (z. B. 2013-04-12
) in seine lesbarere Form (April 12, 2013
). Der Filter
|truncate
kürzt eine Zeichenkette auf die angegebene maximale Länge und fügt am Ende drei Punkte hinzu, wenn die
Zeichenkette gekürzt wird. Da es sich um eine Vorschau handelt, macht es keinen Sinn, den gesamten Inhalt des Artikels
anzuzeigen. Weitere Standardfilter finden Sie in der Dokumentation, oder wir
können bei Bedarf eigene erstellen.
Noch eine Sache. Den vorherigen Code können wir kürzen und vereinfachen. Dies erreichen wir, indem wir Latte-Tags durch n:Attribute ersetzen:
{block content}
<h1>Mein Blog</h1>
<div n:foreach="$posts as $post" class="post">
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h2>{$post->title}</h2>
<div>{$post->content|truncate:256}</div>
</div>
{/block}
Das Attribut n:foreach
umschließt den div-Block mit einem foreach (funktioniert absolut genauso wie
der vorherige Code).
Zusammenfassung
Wir haben jetzt eine sehr einfache MySQL-Datenbank mit einigen Beiträgen. Die Anwendung verbindet sich mit dieser Datenbank und gibt eine einfache Liste dieser Beiträge im Template aus.