-
-
Notifications
You must be signed in to change notification settings - Fork 282
/
home-page.texy
202 lines (135 loc) · 8.02 KB
/
home-page.texy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
Úvodní stránka blogu
********************
.[perex]
Nyní si vytvoříme úvodní stránku zobrazující poslední příspěvky.
Než začneme, je zapotřebí znát alespoň základy návrhového vzoru Model-View-Presenter (podobné jako MVC((Model-View-Controller))):
- **Model** - vrstva pracující s daty. Je kompletně oddělena od zbytku aplikace. Komunikuje pouze s presenterem.
- **View** - front-end vrstva. Vykresluje požadovaná data pomocí šablon a zobrazuje je uživateli.
- **Presenter** (nebo Controller) - propojovací vrstva. Presenter propojuje Model a View. Zpracovává požadavky, dotazuje se Modelu na data a vrací je zpět do View.
V případě jednoduchých aplikací, jako bude náš blog, budou celou modelovou vrstvu tvořit jenom dotazy do databáze - na to zatím žádný extra kód nepotřebujeme. Pro začátek si tedy vytvoříme jenom presentery a šablony. V Nette má každý presenter své vlastní šablony, takže je budeme vytvářet zároveň.
Vytvoření databáze pomocí Admineru
==================================
Pro ukládání dat použijeme MySQL databázi, protože je nejvíce rozšířená mezi programátory webových aplikací. Pokud ji však použít nechcete, klidně si zvolte databázi dle vlastního uvážení.
Nyní si připravíme databázovou strukturu, kde budou uloženy články našeho blogu. Začneme velmi jednoduše - vytvoříme si pouze jednu tabulku pro příspěvky.
Pro vytvoření databáze si můžeme stáhnout [Adminer |https://www.adminer.org], nebo jiný váš oblíbený nástroj pro správu databází.
Otevřeme si Adminer a vytvoříme novou databázi s názvem `quickstart`.
Vytvoříme novou tabulku s názvem `posts` a s těmito sloupci:
- `id` int, zaškrtneme na autoincrement (AI)
- `title` varchar, length 255
- `content` text
- `created_at` timestamp
Výsledná struktura by měla vypadat takto:
[* adminer-posts.webp *]
```sql
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;
```
.[caution]
Je opravdu důležité použít úložiště **InnoDB**. Za chvilku si ukážeme proč. Prozatím ji jednoduše vyberte a klikněte na uložit.
Než vytvoříme možnost přidávat články do databáze pomocí aplikace, přidejte několik vzorových článků na blogu ručně.
```sql
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);
```
Připojení k databázi
====================
Nyní, když je již databáze vytvořena a máme v ní uloženo pár článků, je ten správný čas zobrazit je na naší krásné nové stránce.
Prvně musíme aplikaci říct, jakou databázi má použít. Připojení k databázi nastavíme v souboru `config/common.neon` pomocí DSN((Data Source Name)) a přihlašovacích údajů. Mělo by to vypadat nějak takto:
```neon .{file:config/common.neon}
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *zde vložte jméno uživatele*
password: *zde vložte heslo k databázi*
```
.[note]
Při editování tohoto souboru dávejte pozor na odsazení řádků. Formát [NEON |neon:format] akceptuje jak odsazení pomocí mezer, tak odsazení pomocí tabulátorů, ale ne obojí zároveň. Výchozí konfigurační soubor ve Web Projectu využívá tabulátory.
Předání databázového spojení
============================
Presenter `HomePresenter`, který se bude starat o výpis článků, potřebuje připojení k databázi. Pro jeho získání využijeme konstruktor, který bude vypadat takto:
```php .{file:app/UI/Home/HomePresenter.php}
<?php
namespace App\UI\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
```
Načítání příspěvků z databáze
=============================
Nyní načteme příspěvky z databáze a pošleme je do šablony, která je následně vykreslí jako HTML kód. Pro tohle je určena takzvaná *render* metoda:
```php .{file:app/UI/Home/HomePresenter.php}
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
```
Presenter nyní obsahuje jednu renderovací metodu `renderDefault()`, která předává data z databáze do šablony (View). Šablony jsou umístěny v `app/UI/{PresenterName}/{viewName}.latte`, takže v tomto případě je šablona umístěna v `app/UI/Home/default.latte`. V šabloně nyní bude k dispozici proměnná `$posts`, ve které jsou příspěvky získané z databáze.
Šablona
=======
Pro celou webovou stránku máme k dispozici hlavní šablonu (která se jmenuje *layout*, obsahuje hlavičku, styly, patičku,...) a dále konkrétní šablony pro každý pohled (View) (např. pro zobrazení příspěvků na blogu), které mohou přepsat některé části hlavní šablony.
Ve výchozím stavu je layout šablona umístěna v `app/UI/@layout.latte` a obsahuje:
```latte .{file:app/UI/@layout.latte}
...
{include content}
...
```
Zápis `{include content}` vkládá do hlavní šablony blok s názvem `content`. Ten budeme definovat v šablonách jednotlivých pohledů (View). V našem případě soubor `Home/default.latte` upravíme následovně:
```latte .{file:app/UI/Home/default.latte}
{block content}
Hello World
{/block}
```
Tímto jsme nadefinovali [blok |latte:tags#block] *content*, který bude vložen do hlavního layoutu. Pokud opět obnovíme prohlížeč, uvidíme stránku s textem "Hello World" (ve zdrojovém kódu i s HTML hlavičkou a patičkou definovanou v `@layout.latte`).
Pojďme zobrazit příspěvky z blogu - šablonu upravíme následovně:
```latte .{file:app/UI/Home/default.latte}
{block content}
<h1>Můj 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}
```
Pokud obnovíme prohlížeč, uvidíme výpis všech příspěvků. Výpis zatím není moc hezký, ani barevný, proto můžeme do souboru `www/css/style.css` přidat pár [CSS stylů |https://github.com/nette-examples/quickstart/blob/v4.0/www/css/style.css] a zalinkovat jej v layoutu:
```latte .{file:app/UI/@layout.latte}
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
```
Značka `{foreach}` iteruje přes všechny příspěvky, které jsme předali šabloně v proměnné `$posts`, a pro každý vykreslí daný kus HTML. Chová se přesně jako PHP kód.
Zápisu `|date:` říkáme filtr. Filtry jsou určeny k formátování výstupu. Tento konkrétní filtr převádí datum (např. `2013-04-12`) na jeho čitelnější podobu (`April 12, 2013`). Filtr `|truncate` ořízne řetězec na uvedenou maximální délku a v případě, že řetězec zkrátí, přidá na konec trojtečku. Jelikož se jedná o náhled, nemá smysl zobrazovat celý obsah článku. Další výchozí filtry [najdeme v dokumentaci |latte:filters] a nebo si můžeme vytvořit vlastní, když je to potřeba.
Ještě jedna věc. Předchozí kód můžeme zkrátit a zjednodušit. Toho docílíme záměnou *Latte tagů* za *n:atributy*:
```latte .{file:app/UI/Home/default.latte}
{block content}
<h1>Můj 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` obaluje *div* blokem *foreach* (funguje naprosto stejně jako předchozí kód).
Shrnutí
=======
Nyní máme velmi jednoduchou MySQL databázi s pár příspěvky. Aplikace se připojuje k této databázi a vypisuje jednoduchý seznam těchto příspěvků do šablony.
{{priority: -1}}
{{sitename: Nette Quickstart}}