A blog kezdőlapja
Most létrehozzuk a kezdőlapot, amely a legutóbbi bejegyzéseket jeleníti meg.
Mielőtt elkezdenénk, ismerni kell legalább a Model-View-Presenter tervezési minta alapjait (hasonlóan az MVC-hez ((Model-View-Controller))):
- Modell – az adatokkal dolgozó réteg. Teljesen elkülönül az alkalmazás többi részétől. Csak a presenterrel kommunikál.
- View – a front-end réteg. A kért adatokat sablonok segítségével jeleníti meg, és megjeleníti a felhasználónak.
- Presenter (vagy Controller) – az összekötő réteg. A Presenter összeköti a Modellt és a View-t. Feldolgozza a kéréseket, lekérdezi az adatokat a Modelltől, és visszaküldi azokat a View-nak.
Egyszerű alkalmazások esetén, mint a mi blogunk, az egész modell réteget csak adatbázis-lekérdezések alkotják – ehhez egyelőre nincs szükségünk extra kódra. Kezdetnek tehát csak presentereket és sablonokat hozunk létre. A Nette-ben minden presenternek saját sablonjai vannak, így ezeket egyszerre fogjuk létrehozni.
Adatbázis létrehozása az Adminer segítségével
Az adatok tárolására MySQL adatbázist fogunk használni, mivel ez a legelterjedtebb a webalkalmazás-fejlesztők körében. Ha azonban nem szeretné használni, nyugodtan válasszon saját belátása szerint adatbázist.
Most előkészítjük az adatbázis struktúráját, ahol a blogunk cikkei lesznek tárolva. Nagyon egyszerűen kezdünk – csak egy táblát hozunk létre a bejegyzésekhez.
Az adatbázis létrehozásához letölthetjük az Adminer-t, vagy bármely más kedvenc adatbázis-kezelő eszközünket.
Nyissuk meg az Adminert, és hozzunk létre egy új adatbázist quickstart
néven.
Hozzunk létre egy új posts
nevű táblát a következő oszlopokkal:
id
int, jelöljük be az autoincrement-et (AI)title
varchar, length 255content
textcreated_at
timestamp
Az eredményül kapott struktúrának így kell kinéznie:

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;
Nagyon fontos az InnoDB tároló használata. Hamarosan megmutatjuk, miért. Egyelőre egyszerűen válassza ki, és kattintson a mentésre.
Mielőtt létrehoznánk a cikkek adatbázisba való hozzáadásának lehetőségét az alkalmazáson keresztül, adjon hozzá néhány minta cikket a bloghoz manuálisan.
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);
Csatlakozás az adatbázishoz
Most, hogy az adatbázis már létre van hozva, és van benne néhány cikkünk, itt az ideje megjeleníteni őket a gyönyörű új oldalunkon.
Először meg kell mondanunk az alkalmazásnak, hogy melyik adatbázist használja. Az adatbázis-kapcsolatot a
config/common.neon
fájlban állítjuk be DSN ((Data Source Name)) és bejelentkezési adatok segítségével.
Valahogy így kell kinéznie:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *itt adja meg a felhasználónevet*
password: *itt adja meg az adatbázis jelszavát*
Ennek a fájlnak a szerkesztésekor ügyeljen a sorok behúzására. A NEON formátum elfogadja mind a szóközökkel, mind a tabulátorokkal történő behúzást, de nem mindkettőt egyszerre. A Web Project alapértelmezett konfigurációs fájlja tabulátorokat használ.
Adatbázis-kapcsolat átadása
A HomePresenter
presenternek, amely a cikkek listázásáért felel, szüksége van adatbázis-kapcsolatra. Ennek
megszerzéséhez a konstruktort használjuk, amely így fog kinézni:
<?php
namespace App\Presentation\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Bejegyzések betöltése az adatbázisból
Most betöltjük a bejegyzéseket az adatbázisból, és elküldjük őket a sablonnak, amely azután HTML kódként jeleníti meg őket. Erre szolgál az úgynevezett render metódus:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
A presenter most egy renderelő metódust tartalmaz, a renderDefault()
-t, amely adatokat ad át az adatbázisból
a sablonnak (View). A sablonok az app/Presentation/{PresenterName}/{viewName}.latte
helyen találhatók, tehát
ebben az esetben a sablon az app/Presentation/Home/default.latte
helyen van. A sablonban most elérhető lesz a
$posts
változó, amelyben az adatbázisból lekérdezett bejegyzések találhatók.
Sablon
Az egész weboldalhoz rendelkezésünkre áll egy fő sablon (amelyet layout-nak neveznek, tartalmazza a fejlécet, stílusokat, láblécet,…) és továbbá konkrét sablonok minden nézethez (View) (pl. a blogbejegyzések megjelenítéséhez), amelyek felülírhatják a fő sablon egyes részeit.
Alapértelmezés szerint a layout sablon az app/Presentation/@layout.latte
helyen található, és
tartalmazza:
...
{include content}
...
A {include content}
beilleszti a fő sablonba a content
nevű blokkot. Ezt az egyes nézetek (View)
sablonjaiban fogjuk definiálni. Esetünkben az Home/default.latte
fájlt a következőképpen módosítjuk:
{block content}
Hello World
{/block}
Ezzel definiáltuk a blokkot content, amely be lesz illesztve a
fő layoutba. Ha újra frissítjük a böngészőt, egy oldalt látunk a “Hello World” szöveggel (a forráskódban az
@layout.latte
-ban definiált HTML fejléccel és lábléccel együtt).
Jelenítsük meg a blogbejegyzéseket – a sablont a következőképpen módosítjuk:
{block content}
<h1>Blogom</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}
Ha frissítjük a böngészőt, látni fogjuk az összes bejegyzés listáját. A lista egyelőre nem túl szép, sem színes,
ezért a www/css/style.css
fájlba hozzáadhatunk néhány CSS stílusokat, és belinkelhetjük a
layoutban:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
A {foreach}
tag iterál az összes bejegyzésen, amelyeket a $posts
változóban adtunk át a
sablonnak, és mindegyikhez megjeleníti az adott HTML darabot. Pontosan úgy viselkedik, mint a PHP kód.
A |date:
írásmódot szűrőnek nevezzük. A szűrők a kimenet formázására szolgálnak. Ez a konkrét
szűrő átalakítja a dátumot (pl. 2013-04-12
) annak olvashatóbb formájára (April 12, 2013
). A
|truncate
szűrő levágja a stringet a megadott maximális hosszúságra, és ha a stringet lerövidíti, a végére
három pontot tesz. Mivel ez egy előnézet, nincs értelme a teljes cikk tartalmát megjeleníteni. További alapértelmezett
szűrőket megtalálhatók a dokumentációban, vagy létrehozhatunk sajátokat,
ha szükséges.
Még egy dolog. Az előző kódot lerövidíthetjük és egyszerűsíthetjük. Ezt a Latte tagek n:attribútumokra cserélésével érhetjük el:
{block content}
<h1>Blogom</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}
Az n:foreach
attribútum a div blokkot foreach-csel veszi körül (teljesen ugyanúgy működik,
mint az előző kód).
Összegzés
Most van egy nagyon egyszerű MySQL adatbázisunk néhány bejegyzéssel. Az alkalmazás csatlakozik ehhez az adatbázishoz, és egyszerű listát jelenít meg ezekről a bejegyzésekről a sablonban.