Pagina de pornire a blogului
Acum vom crea pagina de pornire care afișează cele mai recente postări.
Înainte de a începe, este necesar să cunoașteți cel puțin elementele de bază ale pattern-ului de design Model-View-Presenter (similar cu MVC):
- Model – stratul care lucrează cu datele. Este complet separat de restul aplicației. Comunică doar cu presenterul.
- View – stratul front-end. Redă datele solicitate folosind șabloane și le afișează utilizatorului.
- Presenter (sau Controller) – stratul de legătură. Presenterul leagă Modelul și View-ul. Procesează cererile, interoghează Modelul pentru date și le returnează înapoi View-ului.
În cazul aplicațiilor simple, cum va fi blogul nostru, întregul strat de model va consta doar din interogări în baza de date – pentru asta nu avem nevoie de cod suplimentar deocamdată. Pentru început, vom crea doar presenterele și șabloanele. În Nette, fiecare presenter are propriile sale șabloane, așa că le vom crea simultan.
Crearea bazei de date folosind Adminer
Pentru stocarea datelor vom folosi o bază de date MySQL, deoarece este cea mai răspândită printre programatorii de aplicații web. Totuși, dacă nu doriți să o utilizați, puteți alege o bază de date la alegerea dumneavoastră.
Acum vom pregăti structura bazei de date unde vor fi stocate articolele blogului nostru. Vom începe foarte simplu – vom crea doar un singur tabel pentru postări.
Pentru crearea bazei de date, putem descărca Adminer sau alt instrument preferat pentru administrarea bazelor de date.
Deschidem Adminer și creăm o nouă bază de date cu numele quickstart
.
Creăm un nou tabel cu numele posts
și cu următoarele coloane:
id
int, bifăm autoincrement (AI)title
varchar, length 255content
textcreated_at
timestamp
Structura rezultată ar trebui să arate astfel:

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;
Este foarte important să folosiți stocarea InnoDB. Vom arăta în curând de ce. Deocamdată, pur și simplu selectați-o și faceți clic pe salvare.
Înainte de a crea posibilitatea de a adăuga articole în baza de date prin intermediul aplicației, adăugați manual câteva articole exemplu pe blog.
INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
(1, 'Article One', 'Lorem ipusm dolor one', CURRENT_TIMESTAMP),
(2, 'Article Two', 'Lorem ipsum dolor two', CURRENT_TIMESTAMP),
(3, 'Article Three', 'Lorem ipsum dolor three', CURRENT_TIMESTAMP);
Conectarea la baza de date
Acum că baza de date este creată și avem câteva articole stocate în ea, este momentul potrivit să le afișăm pe noua noastră pagină frumoasă.
În primul rând, trebuie să spunem aplicației ce bază de date să folosească. Conexiunea la baza de date o setăm în
fișierul config/common.neon
folosind DSN și datele de
autentificare. Ar trebui să arate cam așa:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *introduceți aici numele de utilizator*
password: *introduceți aici parola bazei de date*
La editarea acestui fișier, aveți grijă la indentarea liniilor. Formatul NEON acceptă atât indentarea cu spații, cât și indentarea cu tabulatori, dar nu ambele simultan. Fișierul de configurare implicit din Web Project utilizează tabulatori.
Transmiterea conexiunii la baza de date
Presenterul HomePresenter
, care se va ocupa de afișarea articolelor, are nevoie de conexiunea la baza de date.
Pentru a o obține, vom folosi un constructor, care va arăta astfel:
<?php
namespace App\Presentation\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Încărcarea postărilor din baza de date
Acum vom încărca postările din baza de date și le vom trimite șablonului, care le va reda ulterior ca și cod HTML. Pentru aceasta este destinată așa-numita metodă render:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
Presenterul conține acum o metodă de redare renderDefault()
, care transmite datele din baza de date către
șablon (View). Șabloanele sunt localizate în app/Presentation/{PresenterName}/{viewName}.latte
, deci în acest caz
șablonul este localizat în app/Presentation/Home/default.latte
. În șablon va fi acum disponibilă variabila
$posts
, în care se află postările obținute din baza de date.
Șablonul
Pentru întreaga pagină web avem la dispoziție un șablon principal (care se numește layout, conține antet, stiluri, subsol,…) și, în plus, șabloane specifice pentru fiecare vizualizare (View) (de exemplu, pentru afișarea postărilor pe blog), care pot suprascrie unele părți ale șablonului principal.
În mod implicit, șablonul layout este localizat în app/Presentation/@layout.latte
și conține:
...
{include content}
...
Notația {include content}
inserează în șablonul principal blocul cu numele content
. Acesta îl
vom defini în șabloanele vizualizărilor individuale (View). În cazul nostru, vom modifica fișierul
Home/default.latte
astfel:
{block content}
Hello World
{/block}
Prin aceasta am definit blocul content, care va fi inserat în
layout-ul principal. Dacă reîmprospătăm din nou browserul, vom vedea pagina cu textul “Hello World” (în codul sursă și
cu antetul și subsolul HTML definite în @layout.latte
).
Să afișăm postările de pe blog – vom modifica șablonul astfel:
{block content}
<h1>Blogul meu</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}
Dacă reîmprospătăm browserul, vom vedea lista tuturor postărilor. Lista nu este deocamdată foarte frumoasă, nici
colorată, de aceea putem adăuga în fișierul www/css/style.css
câteva stiluri CSS și să-l legăm în layout:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
Tag-ul {foreach}
iterează prin toate postările pe care le-am transmis șablonului în variabila
$posts
și pentru fiecare redă bucata respectivă de HTML. Se comportă exact ca și codul PHP.
Notației |date:
îi spunem filtru. Filtrele sunt destinate formatării ieșirii. Acest filtru specific
convertește data (de ex. 2013-04-12
) în forma sa mai lizibilă (April 12, 2013
). Filtrul
|truncate
trunchiază șirul la lungimea maximă specificată și, în cazul în care șirul este scurtat, adaugă
puncte de suspensie la sfârșit. Deoarece este vorba de o previzualizare, nu are sens să afișăm întregul conținut al
articolului. Alte filtre implicite le găsiți în documentație sau putem crea
propriile noastre filtre, atunci când este necesar.
Încă un lucru. Putem scurta și simplifica codul anterior. Realizăm acest lucru înlocuind tag-urile Latte cu n:atribute:
{block content}
<h1>Blogul meu</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}
Atributul n:foreach
învelește blocul div cu un foreach (funcționează absolut la fel ca și codul
anterior).
Rezumat
Acum avem o bază de date MySQL foarte simplă cu câteva postări. Aplicația se conectează la această bază de date și afișează o listă simplă a acestor postări în șablon.