7. diel - Jednoduchý redakčný systém v Nette - Administrácia
V minulej lekcii, Jednoduchý redakčný systém v Nette - Výpis článku , sme už vytvorili základnú štruktúru pre výpis článkov okrem šablón, ktoré dnes pridáme. Tým výpis sprevádzkujeme a budeme pokračovať s tvorbou ich administrácie.
Šablóny
Teraz je teda čas pozrieť sa na zúbok šablónam (templates). Opäť tu
môžeme zmazať celú zložku app/templates/Homepage/, pretože
rovnako ako triedu HomepagePresenter ju už nebudeme ďalej
potrebovať.
App/templates/@layout.latte
Samozrejme nezačneme ničím iným ako úpravou celkového vzhľadu našej
aplikácie, ktorý v tomto prípade zaisťuje Latte šablóna @layout.latte,
opäť predpripravená v sandboxe, z ktorého vychádzame.
{**
* @param string $basePath web base path
* @param array $flashes flash messages
*}
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{include description|striptags}">
<title>{include title|striptags}</title>
{block css}
<link rel="stylesheet" href="{$basePath}/css/style.css">
{/block}
{block head}{/block}
</head>
<body>
<header>
<h1>Jednoduchý redakční systém v Nette</h1>
</header>
{* Výpis flash zpráv. *}
<p n:foreach="$flashes as $flash" class="message">{$flash->message}</p>
<nav>
<ul>
<li><a n:href=:Core:Article:>Úvod</a></li>
<li><a href="#">Seznam článků</a></li>
<li><a href="#">Kontakt</a></li>
</ul>
</nav>
<br clear="both">
<article>
<header>
<h1>{include title}</h1>
</header>
<section>
{include content} {* Vložení obsahu do šablony. *}
</section>
</article>
<footer>
<p>
Ukázkový tutoriál pro jednoduchý redakční systém v Nette z programátorské sociální sítě
<a href="http://www.itnetwork.cz" target="_blank">itnetwork.cz</a>
</p>
</footer>
{block scripts}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
</body>
</html>
App / CoreModule / templates / Article / default.latte
Nakoniec vytvoríme zložku Article/ pre šablóny nášho
ArticlePresenter v CoreModule a do nej pridáme súbor
default.latte ako šablónou pre jeho predvolenú akciu
renderDefault(). Samotná šablóna je relatívne jednoduchá:
{block title}{$article->title}{/block}
{block description}{$article->description}{/block}
{block content}
{$article->content|noescape}
Teraz si už môžete skúsiť web spustiť a mali by ste vidieť úvodnú
stránku. Je to určite príjemný pocit po tom, čo sme zmenili toľko kódu,
že? 

Úplný základ máme sprevádzkovaný, teraz sa pozrieme hlbšie do
CoreModule a to konkrétne na administráciu článkov 
Presenter
Model máme už nachystaný z minula, takže začneme rovno od Presenter.
App / CoreModule / presenters / ArticlePresenter.php
Keďže v Nette môžeme mať viac podujatí v jednom prezentačného, budeme
pokračovať v rozširovaní našej triedy ArticlePresenter a
pridáme do nej nasledujúce metódy ďalších akcií:
<?php namespace App\CoreModule\Presenters; use App\CoreModule\Model\ArticleManager; use App\Presenters\BasePresenter; use Nette\Application\AbortException; use Nette\Application\BadRequestException; use Nette\Application\UI\Form; use Nette\Database\UniqueConstraintViolationException; use Nette\Utils\ArrayHash; /** * Presenter pro akce s články. * @package App\CoreModule\Presenters */ class ArticlePresenter extends BasePresenter { /** @var string URL výchozího článku. */ private $defaultArticleUrl; /** @var ArticleManager Model pro správu s článků. */ private $articleManager; /** * Konstruktor s nastavením URL výchozího článku a injektovaným modelem pro správu článků. * @param string $defaultArticleUrl URL výchozího článku * @param ArticleManager $articleManager automaticky injektovaný model pro správu článků */ public function __construct($defaultArticleUrl, ArticleManager $articleManager) { parent::__construct(); $this->defaultArticleUrl = $defaultArticleUrl; $this->articleManager = $articleManager; } /** * Načte a předá článek do šablony podle jeho URL. * @param string|null $url URL článku * @throws BadRequestException Jestliže článek s danou URL nebyl nalezen. */ public function renderDefault($url = null) { if (!$url) $url = $this->defaultArticleUrl; // Pokud není zadaná URL, vezme se URL výchozího článku. // Pokusí se načíst článek s danou URL a pokud nebude nalezen vyhodí chybu 404. if (!($article = $this->articleManager->getArticle($url))) $this->error(); // Vyhazuje výjimku BadRequestException. $this->template->article = $article; // Předá článek do šablony. } /** Načte a předá seznam článků do šablony. */ public function renderList() { $this->template->articles = $this->articleManager->getArticles(); } /** * Odstraní článek. * @param string|null $url URL článku * @throws AbortException */ public function actionRemove($url = null) { $this->articleManager->removeArticle($url); $this->flashMessage('Článek byl úspěšně odstraněn.'); $this->redirect('Article:list'); } /** * Vykresluje formulář pro editaci článku podle zadané URL. * Pokud URL není zadána, nebo článek s danou URL neexistuje, vytvoří se nový. * @param string|null $url URL adresa článku */ public function actionEditor($url = null) { if ($url) { if (!($article = $this->articleManager->getArticle($url))) $this->flashMessage('Článek nebyl nalezen.'); // Výpis chybové hlášky. else $this['editorForm']->setDefaults($article); // Předání hodnot článku do editačního formuláře. } } /** * Vytváří a vrací formulář pro editaci článků. * @return Form formulář pro editaci článků */ protected function createComponentEditorForm() { // Vytvoření formuláře a definice jeho polí. $form = new Form; $form->addHidden('article_id'); $form->addText('title', 'Titulek')->setRequired(); $form->addText('url', 'URL')->setRequired(); $form->addText('description', 'Popisek')->setRequired(); $form->addTextArea('content', 'Obsah'); $form->addSubmit('save', 'Uložit článek'); // Funkce se vykonaná při úspěšném odeslání formuláře a zpracuje zadané hodnoty. $form->onSuccess[] = function (Form $form, ArrayHash $values) { try { $this->articleManager->saveArticle($values); $this->flashMessage('Článek byl úspěšně uložen.'); $this->redirect('Article:', $values->url); } catch (UniqueConstraintViolationException $e) { $this->flashMessage('Článek s touto URL adresou již existuje.'); } }; return $form; } }
Tu by som upozornil predovšetkým na spôsob odovzdávania východiskových
hodnôt do editačného formulára a hlavne na to, že sa úkon vykonáva v
metóde actionEditor(), nie v renderEditor(). Vyplýva
to z životného cyklu akcie Nette prezentačného.
Ďalej si všimnite použitie Nette knižnice pre vytvorenie editačného
formulára, čo nám, mimo napr. Bezpečnosti, v šablóne následne ušetrí
veľa kódu pri jeho vykresľovanie 
App / CoreModule / presenters / AdministrationPresenter.php
Ešte ako dnes skončíme s Presenter, vytvoríme si jeden prázdny pre administračné sekciu. Prázdny bude preto, že v tejto chvíli v podstate nepotrebujeme do jeho šablóny nič odovzdávať:
<?php namespace App\CoreModule\Presenters; use App\Presenters\BasePresenter; /** * Presenter pro vykreslování administrační sekce. * @package App\CoreModule\Presenters */ class AdministrationPresenter extends BasePresenter { }
Nabudúce, v lekcii Jednoduchý redakčný systém v Nette - Dokončenie administrácia , si pridáme ešte presenter pre kontaktný
formulár a potom tiež všetky chýbajúce šablóny. Tými administráciu
článkov v našom redakčnom systéme dokončíme 
