Uvodna stran bloga

Zdaj bomo ustvarili uvodno stran, ki prikazuje zadnje prispevke.

Preden začnemo, je potrebno poznati vsaj osnove načrtovalskega vzorca Model-View-Presenter (podobno kot MVC):

  • Model – plast, ki dela s podatki. Je popolnoma ločena od preostanka aplikacije. Komunicira samo s presenterjem.
  • View – front-end plast. Izrisuje zahtevane podatke s pomočjo predlog in jih prikazuje uporabniku.
  • Presenter (ali Controller) – povezovalna plast. Presenter povezuje Model in View. Obdeluje zahteve, sprašuje Model za podatke in jih vrača nazaj v View.

V primeru preprostih aplikacij, kot bo naš blog, bodo celotno modelno plast tvorile samo poizvedbe v podatkovno bazo – za to zaenkrat ne potrebujemo nobene dodatne kode. Za začetek si torej ustvarimo samo presenterje in predloge. V Nette ima vsak presenter svoje lastne predloge, zato jih bomo ustvarjali hkrati.

Ustvarjanje podatkovne baze z Adminerjem

Za shranjevanje podatkov bomo uporabili MySQL podatkovno bazo, ker je najbolj razširjena med programerji spletnih aplikacij. Če pa je ne želite uporabiti, si mirno izberite podatkovno bazo po lastni presoji.

Zdaj si pripravimo podatkovno strukturo, kjer bodo shranjeni članki našega bloga. Začeli bomo zelo preprosto – ustvarili si bomo samo eno tabelo za prispevke.

Za ustvarjanje podatkovne baze si lahko prenesemo Adminer ali drugo vaše priljubljeno orodje za upravljanje podatkovnih baz.

Odprimo Adminer in ustvarimo novo podatkovno bazo z imenom quickstart.

Ustvarimo novo tabelo z imenom posts in z naslednjimi stolpci:

  • id int, označimo autoincrement (AI)
  • title varchar, length 255
  • content text
  • created_at timestamp

Končna struktura bi morala izgledati takole:

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;

Res je pomembno uporabiti shrambo InnoDB. Čez trenutek si bomo pokazali zakaj. Zaenkrat jo preprosto izberite in kliknite na shrani.

Preden ustvarimo možnost dodajanja člankov v podatkovno bazo s pomočjo aplikacije, dodajte nekaj vzorčnih člankov na blogu ročno.

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);

Povezava s podatkovno bazo

Zdaj, ko je podatkovna baza že ustvarjena in imamo v njej shranjenih nekaj člankov, je pravi čas, da jih prikažemo na naši lepi novi strani.

Najprej moramo aplikaciji povedati, katero podatkovno bazo naj uporabi. Povezavo s podatkovno bazo nastavimo v datoteki config/common.neon s pomočjo DSN in prijavnih podatkov. Moralo bi izgledati nekako takole:

database:
	dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
	user: *tukaj vnesite uporabniško ime*
	password: *tukaj vnesite geslo za podatkovno bazo*

Pri urejanju te datoteke bodite pozorni na zamik vrstic. Format NEON sprejema tako zamik s presledki kot zamik s tabulatorji, vendar ne obojega hkrati. Privzeta konfiguracijska datoteka v Web Projectu uporablja tabulatorje.

Predaja podatkovne povezave

Presenter HomePresenter, ki bo skrbel za izpis člankov, potrebuje povezavo s podatkovno bazo. Za njeno pridobitev bomo uporabili konstruktor, ki bo izgledal takole:

<?php
namespace App\Presentation\Home;

use Nette;

final class HomePresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}

	// ...
}

Nalaganje prispevkov iz podatkovne baze

Zdaj bomo naložili prispevke iz podatkovne baze in jih poslali predlogi, ki jih bo nato izrisala kot HTML kodo. Za to je namenjena tako imenovana render metoda:

public function renderDefault(): void
{
	$this->template->posts = $this->database
		->table('posts')
		->order('created_at DESC')
		->limit(5);
}

Presenter zdaj vsebuje eno render metodo renderDefault(), ki predaja podatke iz podatkovne baze predlogi (View). Predloge so nameščene v app/Presentation/{PresenterName}/{viewName}.latte, torej je v tem primeru predloga nameščena v app/Presentation/Home/default.latte. V predlogi bo zdaj na voljo spremenljivka $posts, v kateri so prispevki, pridobljeni iz podatkovne baze.

Predloga

Za celotno spletno stran imamo na voljo glavno predlogo (ki se imenuje layout, vsebuje glavo, stile, nogo,…) in nadalje specifične predloge za vsak pogled (View) (npr. za prikaz prispevkov na blogu), ki lahko prepišejo nekatere dele glavne predloge.

V privzetem stanju je layout predloga nameščena v app/Presentation/@layout.latte in vsebuje:

...
{include content}
...

Zapis {include content} vstavlja v glavno predlogo blok z imenom content. Tega bomo definirali v predlogah posameznih pogledov (View). V našem primeru datoteko Home/default.latte uredimo na naslednji način:

{block content}
	Hello World
{/block}

S tem smo definirali blok content, ki bo vstavljen v glavni layout. Če ponovno osvežimo brskalnik, bomo videli stran z besedilom “Hello World” (v izvorni kodi tudi s HTML glavo in nogo, definirano v @layout.latte).

Prikažimo prispevke iz bloga – predlogo uredimo na naslednji način:

{block content}
	<h1>Moj 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}

Če osvežimo brskalnik, bomo videli izpis vseh prispevkov. Izpis zaenkrat ni zelo lep, niti barvit, zato lahko v datoteko www/css/style.css dodamo nekaj CSS stilov in jo povežemo v layoutu:

	...
	<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...

Oznaka {foreach} iterira skozi vse prispevke, ki smo jih predali predlogi v spremenljivki $posts, in za vsakega izriše dani kos HTML. Obnaša se natanko tako kot PHP koda.

Zapisu |date: pravimo filter. Filtri so namenjeni formatiranju izpisa. Ta konkreten filter pretvori datum (npr. 2013-04-12) v njegovo bolj berljivo obliko (April 12, 2013). Filter |truncate odreže niz na navedeno maksimalno dolžino in v primeru, da niz skrajša, na konec doda tri pike. Ker gre za predogled, nima smisla prikazovati celotne vsebine članka. Druge privzete filtre najdemo v dokumentaciji ali pa si lahko ustvarimo lastne, ko je to potrebno.

Še ena stvar. Prejšnjo kodo lahko skrajšamo in poenostavimo. To dosežemo z zamenjavo Latte oznakn:atributi:

{block content}
	<h1>Moj 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}

Atribut n:foreach ovije div z blokom foreach (deluje popolnoma enako kot prejšnja koda).

Povzetek

Zdaj imamo zelo preprosto MySQL podatkovno bazo z nekaj prispevki. Aplikacija se povezuje s to podatkovno bazo in izpisuje preprost seznam teh prispevkov v predlogi.