Σελίδα μονής δημοσίευσης
Ας προσθέσουμε μια άλλη σελίδα στο ιστολόγιό μας, η οποία θα εμφανίζει το περιεχόμενο μιας συγκεκριμένης ανάρτησης ιστολογίου.
Πρέπει να δημιουργήσουμε μια νέα μέθοδο render, η οποία θα αντλεί μια
συγκεκριμένη ανάρτηση του ιστολογίου και θα την περνάει στο πρότυπο.
Το να έχουμε αυτή την προβολή στη διεύθυνση HomePresenter
δεν είναι
ωραίο, επειδή πρόκειται για μια ανάρτηση ιστολογίου και όχι για την
αρχική σελίδα. Έτσι, ας δημιουργήσουμε μια νέα κλάση PostPresenter
και
ας την τοποθετήσουμε στο app/UI/Post/
. Θα χρειαστεί μια σύνδεση με τη
βάση δεδομένων, οπότε βάλτε και πάλι εκεί τον κώδικα database injection.
Το PostPresenter
θα πρέπει να μοιάζει με αυτό:
<?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);
}
}
Πρέπει να ορίσουμε ένα σωστό namespaces App\UI\Post
για τον παρουσιαστή
μας. Εξαρτάται από την αντιστοίχιση του
παρουσιαστή.
Η μέθοδος renderShow
απαιτεί ένα όρισμα – το ID της δημοσίευσης που
θα εμφανιστεί. Στη συνέχεια, φορτώνει τη δημοσίευση από τη βάση
δεδομένων και περνάει το αποτέλεσμα στο πρότυπο.
Στο πρότυπο Home/default.latte
προσθέτουμε έναν σύνδεσμο προς την
ενέργεια Post:show
:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
Η ετικέτα {link}
δημιουργεί διεύθυνση URL που παραπέμπει στη δράση
Post:show
. Αυτή η ετικέτα προωθεί επίσης το αναγνωριστικό της
δημοσίευσης ως όρισμα.
Το ίδιο μπορούμε να γράψουμε σύντομα χρησιμοποιώντας το n:attribute:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
Το χαρακτηριστικό n:href
είναι παρόμοιο με την ετικέτα
{link}
.
Το πρότυπο για τη δράση Post:show
δεν υπάρχει ακόμη. Μπορούμε να
ανοίξουμε έναν σύνδεσμο προς αυτή τη θέση. Η Tracy
θα εμφανίσει ένα σφάλμα, γιατί το Post/show.latte
δεν υπάρχει. Αν δείτε
κάποια άλλη αναφορά σφάλματος, πιθανόν να πρέπει να ενεργοποιήσετε το
mod_rewrite στον webserver σας.
Έτσι θα δημιουργήσουμε το Post/show.latte
με αυτό το περιεχόμενο:
{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>
Ας ρίξουμε μια ματιά στα επιμέρους μέρη.
Η πρώτη γραμμή ξεκινά τον ορισμό ενός ονομαζόμενου μπλοκ που
ονομάζεται “content” και το οποίο είδαμε νωρίτερα. Θα εμφανιστεί σε ένα
πρότυπο διάταξης. Όπως μπορείτε να δείτε, λείπει η ετικέτα τέλους
{/block}
. Είναι προαιρετική.
Η δεύτερη γραμμή παρέχει έναν σύνδεσμο προς τη λίστα των αναρτήσεων
του ιστολογίου, ώστε ο χρήστης να μπορεί να πλοηγείται ομαλά μπρος-πίσω
στο ιστολόγιό μας. Χρησιμοποιούμε και πάλι το χαρακτηριστικό
n:href
, επομένως η Nette θα φροντίσει να δημιουργήσει τη διεύθυνση URL
για εμάς. Ο σύνδεσμος δείχνει στην ενέργεια default
του παρουσιαστή
Home
(θα μπορούσατε επίσης να γράψετε n:href="Home:"
, καθώς η
ενέργεια default
μπορεί να παραλειφθεί).
Η τρίτη γραμμή μορφοποιεί τη χρονοσφραγίδα δημοσίευσης με ένα φίλτρο, όπως ήδη γνωρίζουμε.
Η τέταρτη γραμμή εμφανίζει τον τίτλο της δημοσίευσης στο
ιστολόγιο ως <h1>
επικεφαλίδα. Υπάρχει ένα μέρος που ίσως δεν
γνωρίζετε, και αυτό είναι το n:block="title"
. Μπορείτε να μαντέψετε τι
κάνει; Αν έχετε διαβάσει προσεκτικά τα προηγούμενα μέρη, έχουμε
αναφέρει το n: attributes
. Αυτό είναι ένα άλλο παράδειγμα. Είναι
ισοδύναμο με:
{block title}<h1>{$post->title}</h1>{/block}
Με απλά λόγια, * επαναπροσδιορίζει* ένα μπλοκ που ονομάζεται
title
. Το μπλοκ ορίζεται στο πρότυπο διάταξης
(/app/UI/@layout.latte:11
) και όπως συμβαίνει με την παράκαμψη OOP,
παρακάμπτεται εδώ. Επομένως, το αρχείο της σελίδας <title>
θα
περιέχει τον τίτλο της εμφανιζόμενης ανάρτησης. Έχουμε παρακάμψει τον
τίτλο της σελίδας και το μόνο που χρειαζόμασταν ήταν το
n:block="title"
. Υπέροχα, ε;
Η πέμπτη και τελευταία γραμμή του προτύπου εμφανίζει το πλήρες περιεχόμενο της ανάρτησής σας.
Έλεγχος του αναγνωριστικού της δημοσίευσης
Τι συμβαίνει αν κάποιος αλλάξει το URL και εισάγει το id
που δεν
υπάρχει? Θα πρέπει να παρέχουμε στο χρήστη ένα ωραίο σφάλμα “η σελίδα
δεν βρέθηκε”. Ας ενημερώσουμε τη μέθοδο render στο 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;
}
Εάν η δημοσίευση δεν μπορεί να βρεθεί, η κλήση του $this->error(...)
θα εμφανίζει μια σελίδα 404 με ένα ωραίο και κατανοητό μήνυμα.
Σημειώστε, ότι στο περιβάλλον ανάπτυξης (στον φορητό σας υπολογιστή),
δεν θα δείτε τη σελίδα σφάλματος. Αντ' αυτού, το Tracy θα εμφανίσει την
εξαίρεση με πλήρεις λεπτομέρειες, κάτι που είναι αρκετά βολικό για την
ανάπτυξη. Μπορείτε να ελέγξετε και τις δύο λειτουργίες, απλά αλλάξτε
την τιμή που περνάτε στο setDebugMode
στο Bootstrap.php
.
Περίληψη
Έχουμε μια βάση δεδομένων με αναρτήσεις ιστολογίου και μια εφαρμογή ιστού με δύο προβολές – η πρώτη εμφανίζει τη σύνοψη όλων των πρόσφατων αναρτήσεων και η δεύτερη εμφανίζει μια συγκεκριμένη ανάρτηση.