Symfony po krůčkách – oblékáme MicroKernel

V dnešním díle seriálu Symfony po krůčkách budeme pokračovat MicroKernelem. Oblékneme ho do Symfony struktury a zhotovíme si jednoduchý web o třech stránkách. Navíc si ukážeme i Twig – rychlý, jednoduchý a bezpečný šablonovací nástroj od tvůrců Symfony.
Seriál: Symfony po krůčkách (18 dílů)
- Symfony po krůčkách – Event Dispatcher 30. 11. 2015
- Symfony Console jako první rande se Symfony 7. 12. 2015
- Symfony po krůčkách – Filesystem a Finder 14. 12. 2015
- Symfony po krůčkách – Paralýza možností? OptionsResolver tě zachrání 21. 12. 2015
- Symfony po krůčkách – spouštíme procesy 4. 1. 2016
- Symfony po krůčkách – Translation – překlady jednoduše 11. 1. 2016
- Symfony po krůčkách – Validator (1) 18. 1. 2016
- Symfony po krůčkách – Validator (2) 25. 1. 2016
- Symfony po krůčkách – Routing 1. 2. 2016
- Symfony po krůčkách – MicroKernel 9. 2. 2016
- Konfigurujeme Symfony pomocí YAMLu 16. 2. 2016
- Symfony po krůčkách – oblékáme MicroKernel 23. 2. 2016
- Symfony po krůčkách – ClassLoader 29. 2. 2016
- Symfony po krůčkách – Twig 8. 3. 2016
- Symfony po krůčkách – Twig II. 15. 3. 2016
- Symfony po krůčkách – DomCrawler a CssSelector 23. 3. 2016
- Symfony po krůčkách – HTTP fundamentalista 12. 4. 2016
- Symfony po krůčkách – ušli jsme pořádný kus 19. 4. 2016
Nálepky:
Tento text je pokračováním článku Symfony po krůčkách – MicroKernel.
Připrav se na plné Symfony
Symfony MicroKernel můžeš používat skoro v libovolné adresářové struktuře. Chceš-li ale být připravený na to, že tvůj projekt může narůst tak, že budeš chtít přejít na klasické Symfony, měl bys rovnou používat doporučenou adresářovou strukturu:
- app/ – Konfigurace, šablony, překlady,
- bin/ – Spustitelné soubory (např. konzole),
- src/ – Kód naší aplikace (zejména “bundly”),
- tests/ – Testy,
- var/ – Dočasné soubory (cache, logy); pro účely dema používáme systémovou tmp složku (viz metody getCacheDir a getLogDir ve třídě MicroKernel),
- vendor/ – Knihovny třetích stran,
- web/ – Kořenová složka našeho webu (frontend).
Podívej se na zdrojáky na GitHubu.
Oproti minulému článku si do composer.json přidáme ještě FrameworExtraBundle.
composer require sensio/framework-extra-bundle
Konfigurace
Konfiguraci řešíme přes YAMLy, které máme dva – config_prod.yml pro produkci a config_dev.yml pro náš lokální vývoj. Co není v nich, to se načte z defaultního config.yml. Aby nám full stack fungoval, museli jsme do configu přidat secret, povolit assets a říct Symfony, že chceme používat Twig. To je minimum, abychom to celé rozhýbali.
framework:
secret: ThisTokenIsNotSoSecretChangeIt
assets: ~
templating:
engines: ['twig']
Mimochodem o YAMLu na Zdrojáku nedávno vyšel pěkný článek.
MicroKernel
Do našeho předešlého kernelu jsme přidali:
- SensioFrameworkExtraBundle – využijeme poporu anotací,
- TwigBundle – aby nám fungovaly šablony,
- AppBundle – náš výchozí bundle.
Frontend
Na frontendu máme klasicky dva endpointy, app.php pro produkci a app_dev.php, které funguje jen na localhostu (to lze samozřejmě upravit). Aby nám app.php fungovalo, přidali jsme .htaccess.
Pár tipů pro začátečníky v nesnázích
- Nastav oprávnění pro zápis do složky s cachí a logy (pokud nepoužíváš systémovou tmp složku, která je v tomto článku demonstrována).
- Nainstaluj balíčky composeru
composer install - Nainstaluj assets (tohle není důležité, ale pokud je nenainstaluješ, uvidíš škaredé chybové hlášky, protože obrázky a styly z bundlů, které instalujeme přes Composer, nebudou ve složce web/bundles)
php bin/console assets:install

Bez nainstalovaných assets.

S nainstalovanými assets.
Udělejme si web
Teď už máme vše potřebné k tomu, abychom si udělali nějaký užitečný web, třeba s úvodní stránkou, kontaktem a informací o východu a zapádu Slunce.
Ve složce src/AppBundle/Controller si vytvoříme soubor DefaultController.php, ten bude obsahovat všechny tři zmíněné stránky (akce) včetně jejich URL adresy.
Homepage, Kontakt
Homepage obslouží metoda indexAction, ve které máme dvě anotace:
@Route(path="/", name="homepage")
path – jakou cestu stránka má (můžeme vynechat a napsat jen “/” místo path=”/”)
name – název dané cesty (parametr není povinný, ale pro vykreslování menu se nám bude hodit)@Template("AppBundle:Default:index.html.twig")
Anotace říká, jaká šablona se má použít, v našem případě tedy index.html.twig. Pokud je název souboru (index) shodný s názvem akce (index), pak můžeme anotovat jen jako @Template()
Metoda indexAction vrací prázdné pole, protože šabloně nechceme předat žádné proměnné. Kdybychom parametr return vynechali, Symfony by vyvolalo výjimku.
Kontakt funguje obdobně.
Východ a západ Slunce
@Route("/vychod-a-zapad-slunce/{when}", name="sunrise_and_sunset", defaults={"when"="0"}, requirements={"when"="\d+"})
V definici vidíme, že přibyl parametr “when”, který má výchozí hodnotu 0 a může to být číslo (regulární výraz “\d+”). Možné URL jsou pak tyto:
- /vychod-a-zapad-slunce (when bude mít hodnotu 0),
- /vychod-a-zapad-slunce/1 (when bude mít hodnotu 1),
- /vychod-a-zapad-slunce/2 (when bude mít hodnotu 2) atd.
Cesta /vychod-a-zapad-slunce/mars by už neprošla, protože “mars” není číslo.
V akci počítáme, kdy v Praze vyjde a zapadne Slunce, což si zde vysvětlovat nebudeme. Nás bude ale zajímat return, ve kterém vidíme, že do šablony sunriseAndSunset.html.twig předáváme tři hodnoty, přičemž první dvě jsou textové a ta poslední je \DateTime objekt.
Twig
Když máme logiku kontrolerů hotovou, je čas podívat se na šablony. Layout jsme nadefinovali v souboru layout.html.twig, kde máme i menu. Odkazy jsme vygenerovali pomocí helperu “path”, který nám vrátí odkazy dle nastavených anotací.
Na stránce také používáme proměnnou “title”, ve které je název stránky a blok “content”, kde bude náš obsah.
{#src/AppBundle/Resources/views/Layout/layout.html.twig#}
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>MicroWeb</h1>
<p>Menu:</p>
<ul>
<li><a href="{{ path('homepage') }}">Homepage</a></li>
<li><a href="{{ path('sunrise_and_sunset') }}">Východ a západ Slunce</a></li>
<li><a href="{{ path('contact') }}">Kontakt</a></li>
</ul>
<h2>{{ title }}</h2>
{% block content %}
{% endblock %}
</body>
</html>
Renderování jednotlivých stránek probíhá nějak takto:
{#src/AppBundle/Resources/views/Default/sunriseAndSunset.html.twig#}
{% extends "AppBundle:Layout:layout.html.twig" %}
{% set title = "Východ a západ Slunce" %}
{% block content %}
<p>
Dne {{ date|date("d.m.Y") }} v Praze Slunce vychází v {{ sunrise }} a zapadá v {{ sunset }}.
</p>
<ul>
<li><a href="{{ path('sunrise_and_sunset', {'when': '0'}) }}">dnes</a></li>
<li><a href="{{ path('sunrise_and_sunset', {'when': '1'}) }}">zítra</a></li>
<li><a href="{{ path('sunrise_and_sunset', {'when': '2'}) }}">pozítří</a></li>
</ul>
{% endblock content %}

A jsi zase o krok dál
Teď už víš, jak jednoduše to může fungovat, a to je jen kousek toho, co Symfony nabízí. Navíc jsou ochutnal(a) i Twig, což je báječný pomocník.
Neboj se udělat git clone https://github.com/Symfonisti/micro-kernel.git a hrát si. Symfony tě bude bavit jako mě :)