8. diel - Jednoduchý redakčný systém v Symfony - Administrácia
V minulej lekcii, Jednoduchý redakčný systém v Symfony - Výpis článku , sme už vytvorili základnú štruktúru pre výpis článkov. Dnes budeme pokračovať s tvorbou ich administrácie v redakčnom systéme postavenom na PHP frameworku Symfony.
Kontrolér
Keďže modelovú vrstvu v podobe entity a repozitára máme už nachystanú z minula, začneme rovno od kontroleru.
Src / Controller / ArticleController.php
Pretože v Symfony môžeme mať viac podujatí v jednom kontroleru, budeme
pokračovať v rozširovaní našej triedy ArticleController
a
pridáme do nej nasledujúce metódy ďalších akcií:
<?php namespace App\Controller; use App\Entity\Article; use App\Repository\ArticleRepository; use Doctrine\ORM\ORMException; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; /** * Kontroler pro práci s články. * @package App\Controller */ class ArticleController extends AbstractController { /** @var ArticleRepository Repositář pro správu článků. */ private $articleRepository; /** * Konstruktor kontroleru pro práci s články. * @param ArticleRepository $articleRepository automaticky injektovaný repositář pro správu článků */ public function __construct(ArticleRepository $articleRepository) { $this->articleRepository = $articleRepository; } /** * Načte a předá seznam všech článků do šablony. * @return Response HTTP odpověď * @Route("/seznam-clanku", name="article_list") */ public function list(): Response { return $this->render('article/list.html.twig', ['articles' => $this->articleRepository->findAll()]); } /** * Odstraní článek podle jeho URL. * @param string|null $url URL článku * @return Response HTTP odpověď * @Route("/odstranit/{url}", name="remove_article") * @throws ORMException Jestliže nastane chyba při mazání článku. */ public function remove(string $url = null): Response { $this->articleRepository->removeByUrl($url); $this->addFlash('notice', 'Článek byl úspěšně odstraněn.'); return $this->redirectToRoute('article_list'); } /** * Vytváří a zpracovává formulář pro editaci článku podle jeho URL. * @param string|null $url URL článku * @param Request $request HTTP požadavek * @return Response HTTP odpověď * @Route("/editor/{url}", name="article_editor") * @throws ORMException Jestliže nastane chyba při ukládání článku. */ public function editor(string $url = null, Request $request): Response { if ($url) { // Pokud byla zadána URL, pokusí se načíst článek podle ní. if (!($article = $this->articleRepository->findOneByUrl($url))) { // Pokud se článek s danou URL nepodaří najít, vypíše chybovou hlášku a vytvoří nový s danou URL. $this->addFlash('warning', 'Článek se zadanou URL nebyl nalezen!'); $article = (new Article())->setUrl($url); } } else $article = new Article(); // Jinak se nejedná o editaci článku a vytváří se nový článek. // Vytváření editačního formuláře podle entity článku. $editorForm = $this->createFormBuilder($article) ->add('title', null, ['label' => 'Titulek']) ->add('url', null, ['label' => 'URL']) ->add('description', null, ['label' => 'Popisek']) ->add('content', null, ['label' => 'Obsah', 'required' => false]) ->add('submit', SubmitType::class, ['label' => 'Uložit článek']) ->getForm(); // Zpracování editačního formuláře. $editorForm->handleRequest($request); if ($editorForm->isSubmitted() && $editorForm->isValid()) { $this->articleRepository->save($article); $this->addFlash('notice', 'Článek byl úspěšně uložen.'); return $this->redirectToRoute('article', ['url' => $article->getUrl()]); } // Předání editačního formuláře do šablony. return $this->render('article/editor.html.twig', ['editorForm' => $editorForm->createView()]); } /** * Načte článek podle jeho URL a předá jej do šablony. * Pokud není zadaná URL, nastaví se jí hodnota pro výchozí článek. * @param Article $article článek * @return Response HTTP odpověď * @throws NotFoundHttpException Jestliže článek s danou URL nebyl nalezen. * @Route("/{url?%default_article_url%}", name="article") * @Entity("article", expr="repository.findOneByUrl(url)") */ public function index(Article $article): Response { return $this->render('article/index.html.twig', ['article' => $article]); } }
Teraz by asi bolo dobré si kód trochu popísať. V prvom rade sme pridali nasledujúce akcie is pravidlami pre routovanie, ktoré využívajú nášho repozitára článkov:
listAction()
- Vypisuje zoznam všetkých článkov.removeAction()
- Odstráni vybraný článok.editorAction()
- Umožňuje vytvárať nové aj editovať existujúce články.
Ďalej sme zjednotili získanie repozitára pre správu článkov pomocou DI naprieč všetkými týmito metódami a to pomocou princípov OOP, konkrétne privátneho atribútu a konstruktoru.
Nakoniec stojí asi za povšimnutie formulár pre vytváranie a editáciu
článkov, ktorý sme postavili na našej entite Article
, takže
využíva jej validačných pravidiel a automaticky nám tak dovolí uložiť
iba článok s validnými dátami.
Konfigurácia
Ešte než sa presunieme k samotným šablónam, pridáme jednu drobnú vychytávku do konfigurácie.
Config / packages / twig.yaml
Naučíme totiž všetky formuláre v našej aplikácii používať predvolenú Twig šablónu pre ich vykresľovanie:
twig: paths: ['%kernel.project_dir%/templates'] debug: '%kernel.debug%' strict_variables: '%kernel.debug%' # Nastaví všem formulářům v aplikaci tuto šablonu pro vykreslování. form_themes: - 'form/fields.html.twig'
Šablóny
Teraz sa pozrieme na šablóny k jednotlivým akciám.
Templates / form / fields.html.twig
Začneme definíciou onej šablóny pre vykreslenie jedného všeobecného formulárového elementu:
{# Vlastní definice vzhledu jednoho řádku formuláře. #} {% block form_row %} <div> {{ form_errors(form) }}<br> {{ form_label(form) }}<br> {{ form_widget(form) }} </div> {% endblock form_row %}
Šablónu si samozrejme môžete upraviť podľa ľubovôle na dosiahnutie vášho obľúbeného vzhľadu.
Templates / article / editor.html.twig
Teraz nasleduje šablóna pre editor článkov. Tu si všimnite ako jednoducho sme zariadili vykreslenie formulára aj s našou vlastnou šablónou a ďalej spôsobu pridávanie ďalších JavaScript knižníc:
{% extends 'base.html.twig' %} {% block title %}Editor{% endblock %} {% block description %}Editor článků.{% endblock %} {% block body %} {# Formulář pro editaci článku. #} {{ form(editorForm) }} {% endblock %} {% block javascripts %} {{ parent() }} <script type="text/javascript" src="//cdn.tinymce.com/4/tinymce.min.js"></script> <script type="text/javascript"> tinymce.init({ selector: '#form_content', plugins: [ 'advlist autolink lists link image charmap print preview anchor', 'searchreplace visualblocks code fullscreen', 'insertdatetime media table contextmenu paste' ], toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image', entities: '160,nbsp', entity_encoding: 'raw' }); </script> {% endblock %}
Templates / article / list.html.twig
Ďalej pridáme šablónu pre výpis článkov:
{% extends 'base.html.twig' %} {% block title %}Výpis článků{% endblock %} {% block description %}Výpis všech článků.{% endblock %} {% block body %} <table> {% for article in articles %} <tr> <td> <h2><a href="{{ path('article', {'url': article.url}) }}">{{ article.title }}</a></h2> {{ article.description }} <br/> <a href="{{ path('article_editor', {'url': article.url}) }}">Editovat</a> <a href="{{ path('remove_article', {'url': article.url}) }}">Odstranit</a> </td> </tr> {% endfor %} </table> {% endblock %}
Templates / base.html.twig
Na záver pridáme ešte odkazy do východiskovej šablóny. Nebudem ju sem už vypisovať znovu celú, iba zmeny:
... <nav> <ul> <li><a href="{{ path('article') }}">Úvod</a></li> <li><a href="{{ path('article_list') }}">Seznam článků</a></li> <li><a href="#">Kontakt</a></li> </ul> </nav> ...
Teraz sa už môžete pozrieť na výsledok, skúsiť si vypísať zoznam článkov a pokojne ich aj nejako editovať.
Nabudúce si v lekcii Jednoduchý redakčný systém v Symfony - Kontaktný formulár pridáme ešte ContactControler
a
príslušné šablóny, čím administráciu článkov v našom redakčnom
systéme v Symfony dokončíme.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 73x (55.8 kB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP