Chytám štafetu od Lukáše
a honem s ní běžím k vám, abyste nepřišli o tak úžasný denní
program. On vlastně není úžasný, on je přímo příšerný a nejraději
bych se ho zbavil, ale když už tu jednou je, tak to tak asi má být, žeano.
Tedy k věci.
- Ráno: Můj krásný den začne 6.25, kdy mě vzbudí
budík. To ještě ale nic neznamená, z postele lezu až 6.50. Oblíct, věci
šup do batohu (rozuměj jeden deníček na všechno) a cestou ze schodů malé
zastavení v koupelně, což je vlastně i záchod, a od tam rovnou do
předsíně. Snídani raději posouvám do školy. Bus jede 7.12.
- Zbytek dne: Celý krásný den prosedím v té
příšerné budově jménem škola.
- Večer: Domů se vrátím většinou kolem šesté. Když
to jde lépe, tak i k sedmé.
Hamu papu, pak něco na počítači, něco možná do školy.
A spát. (Když to jde dobře, tak v 10, když špatně, tak k 12.)
Tak, a pro všechny ty, kteří by rádi věděli, co jinak na tom
počítači dělám, tak pro ně se nyní podělím. Nutno podotknout, že tu
sem snad čím dál tím míň. Ale!
Když už zrovna nepracuji (nevydělávám) tak
rozhodně koukám na How I Met, no, nebo taky na StarGate, a když zbude čas
a trocha chuti, tak taky makám na nové verzi frameworku. Už se na ní sám
moc moc těším.
No, a protože všichni mí osobně známí blogeři už štafetu dostali,
tak toto bude slepá ulička. Pokud by se našel případný zájemce, můžeme
to proprat v komentářích.
Všichni, kdo se trochu více zajímají o frameworky, jistě mají nějaké
ty zkušenosti s routingem. Ano, díky němu máme ty krásné adresy, to
krásné oddělení na controllery apod. Dnes bude řeč ale o něčem
specifičtějším, o reverzním routingu, neboli o zpětném sestavení URL
adres. Můj názor je zřejmě ovlivněn nepochopením, nezkušeností, snad
i mou neschopností, přesto myslím, že není ojedinělý. Snad. 
Reverzní routing, dále jako tvorba url, implementuje určitě více
frameworků. Co vím, tak něco má CakePHP a třeba takové Nette je na něm
celé postaveno. Já jsem s ním samozřejmě také kdysi experimentoval a
dnes mě můžete přesvědčit, abych se k tomu zase vrátil. Ale teď mám
slovo já.
Na úvod je ale důležité zmínit tento fakt. Frameworky používáme
proto, aby nám pomohly, ne proto, abychom s nimi jedno url napsali na
5 řádků. Tedy, zápis musí být jasný, jednoduchý a přitom dostatečně
univerzální.
Kupříkladu si vezměme routing mého blogu:
- první segment url je metoda controlleru (clanek, clanky) – to
jsou action
- nebo zde máme url pro administraci (/admin) – to je zase namespace
(jinde by to nazvaly spíše modulem)
V Háefku routing vypadá velmi zjednodušeně takhle:
Router::connect('/:action{clanek|clanky}/*', array('controller' => 'posts'));
Router::connect('/:namespace{admin}/:controller/:action/*');
Nyní si vypišme možnosti – typy – odkazů:
- z rootu na článek
- z rootu na seznam článků
- z článku na seznam článků
První problém na sebe nenechá dlouho čekat. Jsme na rootu, a chceme jíti
do článku. Podle jakého pravidla má framework url vytvořit???
Možné řešení: Defaultně podle aktuálního, jinak si routy pojmenujeme.
Stejný problém se opakuje při všech jiných přechodech na jinou routu.
Dobře, nutně si tedy musíme routy pojmenovat, a protože jsme na rootu, a
žádná routa není aktivní, musíme už zde nutně propašovat název routy
do metody, jenž url vytváří.
Další typ odkazů je přecházení na jiné view v rámci stejné routy.
Uvažujme, že se všechny parametry-proměnné v url automaticky dědí.
V našem příkladu je ovšem dědit nechceme. Musíme je tedy vynulovat, nebo
přidat volitelný parametr na dědění. A taky chceme nějakou tu proměnnou
přidat. Zde vyplývá další nutnost – mít pojmenované všechny
proměnné v routingu.
Tedy, kdybych chtěl jít z toho článku na seznam článků kategorie, ve
které je zařazen, musel bych napsat třeba něco takového:
<a href="<?= $this->url('jmeno-prvni-routy', 'posts', 'clanky',
array('kategorie' => $post->category->url), false) ?>">
Seznam článů kategorie</a>
Snad je jasné, co který argument představuje. Poslední je onen
povinný/nepovinný argument řešící otázku dědičnosti. Ano, tohoto
argumentu bychom se mohli zbavit. Ale ne jednoduše, museli bychom pak vypsat
„totální routing“ úplně pro každou „blbost“ a posléze kontrolovat
klíče/počty argumentů atp.
Závěrem
Nemíním si routy nijak pojmenovávat, nijak je identifikovat. Proč? No
protože bych si ony názvy musel pamatovat, a kdykoliv při psaní odkazů si
vzpomínat. Mimo to, zápis url by se prodloužil, a byl by z toho ještě
větší maglajs. Dále místo jednoduchého napsání url musím přemýšlet,
kde píšu jaký parametr… jestli chcu něco dědit, jak se jmenuje ta
proměnná, jestli to náhodou nedědím něco bokem a nějak tak podobně.
Je také ale jasné, že s klasickou ruční tvorbou odkaz se vystačit
nedá. Proto na závěr ukázka, jak řešíme podobný problém
v Háefku:
<a href="<?= $controller->url('clanky/' . $post->category->title) ?>">
Odkaz na kategorie</a>
Hm, to nic moc, že?
No jistě. Tady právě není co příliš řešit. Dědit
ale Háefko umí.
<a href="<?= $controller->url('clanek/{:post-name}/edit') ?>">
Editovat článek</a>
// respektive
<?= $this->link('clanek/{:post-name}/edit', 'Editovat článek') ?>
Jako výhoda reverzního routingu se stále hází větami
typu: „Stačí změnit jen routing, url se pak generují automaticky
nová“.
Tak mi prosím ukažte nějaký větší projekt, kde si jen tak změnili url.
He, ehm, ne, url se prostě tak často nemění. Jo, ano, možná jednou,
dvakrát. Ale aby došla tato feature naplnění, pak by to mělo být spíše
každý den. Cena je totiž vysoká. Nejvíc ji žene nahoru komplikovanost
zápisu. Vždy totiž musíme nějak něco více či méně specifikovat.
Přijde mi jednoduší psát rovnou url, s určitými pomocnými
vychytávkami, než url nějak „skládat“. Neodpustím si na
závěr malé porovnání. Je to jako zápis SQL, někteří ho prostě raději
napíšou ručně, jiní ho musí prostě skládat přes všemožné objekty,
recordy, fluent interfacy atp. Děkuji, můžete se posadit.
Až do teď jsem byl přesvědčen, že jsou si následující konstrukce
totožné:
$array = array('name' => 'Jan');
if (isset($array['name']))
echo $array['name'];
if (array_key_exists('name', $array))
echo $array['name'];
Pro funkci isset doteď
hovořila především rychlost a kratší zápis. Ohledně rychlosti už
proběhlo mnoho testů, viz. třeba google nebo test
Davida Grudla. Array_key_exists byla pro mě trapná prodlouženina, která je
ještě k tomu pomalejší. A hle, ono tomu tak není.
Hádejte, co se stane, když klíč budeme mít null hodnotu. Ano, pak se
nám už isset nechytí…
$array = array('name' => null);
if (isset($array['name']))
echo 'isset check';
if (array_key_exists('name', $array))
echo 'array_key_exists check';
Jak dlouho jsem ve svém frameworku hledal chybu někde jinde, než jsem
přišel, že jde o tuto funkci. A když se na to dívám s odstupem, je to
vlastně jasné. Funkce isset kontroluje, jestli proměnná/klíč má nějakou
nastavenou hodnotu, ne jestli proměnná/klíč existuje.
No, tak tak jsem
zase jednou pohořel 
Po večeru hledání se mi konečně podařilo zprovoznit poedit, aby
dokázal pořádně „vysosnout“ překlady. A co to má společného
s Háefkem?
Díky skvělému editoru Poedit můžete jednoduše
upravovat vlastní překlady. Komplikací je, že pokud něco přiděláte,
nebo odděláte, je nutné to upravit v překladu hned, než na to zapomenete.
Poedit nabízí velmi pěkné řešení, proskenuje váš php kód a všechny
výskyty volání funkce gettext zaeviduje a vytvoří vám normální seznam
klíčů pro překlad. Rád bych vám dnes ukázal řešení dvou problémů.
1) nastavit poedit, aby kód proskenoval 2) zprovoznit parsování i na
jiných voláních funkce pro překlad.
Po instalaci si otevřete „Soubor → Konfigurace …“ a přejděte na
záložku „Parsery“, zde editujte parser PHP. Upravte následující
vstupní pole:
- Seznam koncovek oddělených středníky:
*.php;*.phtml;
- Příkaz ke spuštění parseru: xgettext –force-po -o %o %C %K %F
-L php
V české překladu je u příkladu koncovek chyba!
V příkladu jsou koncovky odděleny čárkou, ale jednotlivé přípony
oddělujte středníkem! Než jsem na toto přišel, tak mi to trvalo asi
hodinu!
Číst dále…