Startseite des Blogs
Erstellen wir die Startseite, die Ihre neuesten Beiträge anzeigt.
Bevor wir beginnen, sollten Sie zumindest die Grundlagen des Entwurfsmusters Model-View-Presenter kennen (ähnlich MVC):
- Model – die Schicht, die mit den Daten arbeitet. Sie ist vom Rest der Anwendung vollständig getrennt. Sie kommuniziert nur mit dem Presenter.
- View – die Frontend-Schicht. Sie rendert die angeforderten Daten mithilfe von Templates und zeigt sie dem Benutzer.
- Presenter (oder Controller) – die verbindende Schicht. Der Presenter verbindet das Model und den View. Er verarbeitet Requests, fordert vom Model Daten an und übergibt sie dann an den View.
Bei einer einfachen Anwendung wie unserem Blog besteht die gesamte Modellschicht nur aus Datenbankabfragen – dafür brauchen wir noch keinen zusätzlichen PHP-Code. Für den Anfang erstellen wir also nur Presenter und Templates. In Nette hat jeder Presenter seine eigenen Templates, deshalb erstellen wir sie gleichzeitig.
Erstellung der Datenbank mit Adminer
Zum Speichern der Daten verwenden wir eine MySQL-Datenbank, weil das die häufigste Wahl unter Webentwicklern ist. Wenn Sie sie nicht verwenden wollen, wählen Sie ruhig eine Datenbank Ihrer Wahl.
Bereiten wir die Struktur der Datenbank vor, in der unsere Blogbeiträge gespeichert werden. Wir können ganz einfach beginnen – mit einer einzigen Tabelle für die Beiträge.
Zum Anlegen der Datenbank können wir Adminer herunterladen oder ein anderes Werkzeug zur Datenbankverwaltung verwenden, das Sie bevorzugen.
Öffnen wir Adminer und legen wir eine neue Datenbank namens quickstart an.
Legen Sie eine neue Tabelle namens posts an und ergänzen Sie diese Spalten:
idint, autoincrement (AI) ankreuzentitlevarchar, Länge 255contenttextcreated_attimestamp
Das 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 sehr wichtig, die Storage Engine InnoDB zu verwenden. Den Grund sehen Sie später. Wählen Sie sie vorerst einfach aus und klicken Sie auf Speichern.
Versuchen Sie, ein paar Beispielbeiträge von Hand hinzuzufügen, bevor wir das Hinzufügen neuer Beiträge direkt aus unserer Anwendung umsetzen.
INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
(1, 'Article One', 'Lorem ipsum dolor one', CURRENT_TIMESTAMP),
(2, 'Article Two', 'Lorem ipsum dolor two', CURRENT_TIMESTAMP),
(3, 'Article Three', 'Lorem ipsum dolor three', CURRENT_TIMESTAMP);
Verbindung zur Datenbank herstellen
Jetzt, da die Datenbank angelegt ist und wir ein paar Beiträge darin haben, ist es der richtige Zeitpunkt, sie auf unserer brandneuen Seite anzuzeigen.
Zuerst müssen wir unserer Anwendung mitteilen, welche Datenbank sie verwenden soll. Die Konfiguration der Datenbankverbindung
wird in der Datei config/common.neon über DSN und die
Zugangsdaten gesetzt. Das sollte ungefähr so aussehen:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *hier Ihren Benutzernamen eintragen*
password: *hier Ihr Datenbankpasswort eintragen*
Achten Sie beim Bearbeiten dieser Datei auf die Einrückung. Das Format NEON akzeptiert sowohl Leerzeichen als auch Tabs, aber nicht beides gemeinsam. Die Standardkonfigurationsdatei im Web Project verwendet Tabs.
Datenbankverbindung injizieren
Der Presenter HomePresenter, der die Beiträge auflisten wird, braucht eine Datenbankverbindung. Um sie zu
bekommen, verwenden wir den Konstruktor so:
<?php
namespace App\Presentation\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Beiträge aus der Datenbank laden
Holen wir nun die Beiträge aus der Datenbank und übergeben wir sie an das Template, das daraus den HTML-Code rendert. Dafür ist die sogenannte render-Methode da:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
Der Presenter hat nun eine Render-Methode renderDefault(), die die Daten aus der Datenbank an das Template (den
View) übergibt. Templates liegen in app/Presentation/{PresenterName}/{viewName}.latte, in diesem Fall also in
app/Presentation/Home/default.latte. Im Template steht nun eine Variable $posts zur Verfügung, die die
aus der Datenbank geholten Beiträge enthält.
Template
Für die gesamte Website haben wir ein Haupt-Template (das sogenannte Layout, das Kopf, Styles, Fuß usw. enthält) und eigene Templates für jeden View (etwa für die Anzeige der Blogbeiträge), die Teile des Haupt-Templates überschreiben können.
Standardmäßig liegt das Layout-Template in app/Presentation/@layout.latte und enthält:
...
{include content}
...
Der Tag {include content} fügt einen Block namens content in das Haupt-Template ein. Diesen Block
definieren wir in den Templates der einzelnen Views. In unserem Fall ändern wir die Datei Home/default.latte
folgendermaßen:
{block content}
Hello World
{/block}
Damit haben wir den Block content definiert, der in das
Haupt-Layout eingefügt wird. Wenn Sie den Browser erneut aktualisieren, sehen Sie eine Seite mit dem Text “Hello World” (im
Quelltext samt HTML-Kopf und -Fuß, die in @layout.latte definiert sind).
Zeigen wir die Blogbeiträge an – wir ändern das Template folgendermaßen:
{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 Sie den Browser aktualisieren, sehen Sie die Liste Ihrer Blogbeiträge. Die Liste ist noch nicht besonders schick oder
farbenfroh, ergänzen Sie also ruhig ein paar schöne CSS-Styles in der Datei
www/css/style.css und binden Sie sie im Layout ein:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
Der Tag {foreach} iteriert über alle Beiträge, die dem Template in der Variablen $posts übergeben
wurden, und gibt für jeden Beitrag ein Stück HTML-Code aus. Er verhält sich genauso wie PHP-Code.
Die Schreibweise |date: nennt man Filter. Filter dienen dazu, die Ausgabe zu formatieren. Dieser Filter wandelt
ein Datum (z. B. 2013-04-12) in eine besser lesbare Form um (April 12, 2013). Der Filter
|truncate kürzt den String auf die angegebene Höchstlänge und ergänzt am Ende Auslassungspunkte (…), wenn der
String gekürzt wurde. Da es sich um eine Vorschau handelt, hat es keinen Sinn, den vollständigen Inhalt des Beitrags anzuzeigen.
Weitere Standardfilter finden Sie in der Dokumentation, oder Sie erstellen bei
Bedarf eigene.
Noch eines. Wir können den bisherigen Code kürzer und einfacher machen. Das erreichen wir, indem wir die 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 einer foreach-Schleife (es funktioniert genauso
wie der vorherige Code).
Zusammenfassung
Wir haben nun eine sehr einfache MySQL-Datenbank mit ein paar Beiträgen. Die Anwendung verbindet sich mit dieser Datenbank und gibt eine einfache Liste dieser Beiträge in einem Template aus.