Sdružení rodičů a přátel Nette
Frameworku vás srdečně zve na tradiční členskou schůzi vývojářů
webových aplikací. Program bude zahájen volbou nástěnkáře, bude
následovat recitace básní oslavujících Nette Framework, poplácávání se,
kritizování a posmívání se ostatním frameworkům a konzumace
alkoholických nápojů dle vlastního výběru.
Účast nutná!
termín: pátek 18. července od 16 hodin
místo konání: Brno, Schnitzel House na Běhounské 15 (mapka)
Pokud máte chuť probrat věci týkající se vývoje webových aplikací
v Nette Frameworku, ale také vývoje frameworku samotného, budu rád, když
dorazíte. Jde čistě o neformální setkání. Abych mohl vybrat a zamluvit
nějaký prostor (salonek v restauraci blízko centra – máte tip?),
potřeboval bych vědět, kolik lidí asi tak dorazí, takže prosím svou
účast potvrďte v komentářích. Jestli pojedete autem a můžete někoho
vzít, napište svůj kontakt a odkud jedete.
Pro objektový návrh presenterů by se měla dodržovat stejná pravidla,
která platí pro OOP jako takové. Konkrétně mám na mysli tezi, že objekt
by měl plnit pouze jeden úkol.
Presentery s více pohledy (views) nebo akcemi (actions) svádějí tento
princip porušovat. Svým způsobem i sebesložitější aplikaci mohu narvat
do jednoho presenteru s obrovským počtem pohledů. A každý z nich bude
používat jen svůj okruh komponent a parametrů. Asi cítíte, že to je
špatný přístup.
Druhým extrémem je pro každý pohled vytvořit vlastní presenter. Ano,
jde také o extrém, ale z hlediska návrhu poměrně čistý (dokonce
předchozí verze Nette tak byly koncipované a třída Presenter se
jmenovala Page).
Jakou zvolit cestu mezi oběma mantinely? Doporučuji řídit se tímto
pravidlem:
V jednom presenteru sdružujte jen ty pohledy, které používají
společné komponenty a persistentní parametry.
V tu chvíli začne presenter plnit jen jeden úkol – obhospodařovat
své komponenty a persistentní parametry. Pravidlo má navíc příjemný
důsledek – automatické předávání persistentních parametrů v Nette
bude pracovat velmi efektivně a pouze ve váš prospěch.
Vytvořte hierarchii
presenterů
Všechny presentery ve vaší aplikaci by měly tvořit hierarchii.
Přinejmenším vytvořte jednoho společného předka. Díky tomu se vyhnete
opakování stejného kódu na více místech aplikace. Společný předek
může v metodě startup() zajistit připojení k modelu nebo
zkontrolovat uživatelská oprávnění.
S hierarchií úzce souvisí automatické předávání persistentních
parametrů. Pokud potřebujete, aby se určitý parametr automaticky přenášel
mezi skupinou presenterů, tak ho deklarujte na úrovni jejich předka.
Buď final, nebo abstract
Pokuste se hierarchii presenterů navrhnout tak, aby každý z nich
představoval buď list, nebo větev. Listem je myšlen presenter, od kterého
už nelze odvozovat nové třídy (je deklarovaný pomocí klíčového slova
final, na obrázku označen jako leaf). Větev je naopak presenter, který lze
použít pouze k odvozování (je deklarovaný jako abstract). Nette nedovolí
abstraktní presentery vůbec adresovat.
Tato technika zajistí, že každá akce presenteru bude v celé struktuře
jedinečná.
Každý ladič je dobrým kamarádem s funkcí var_dump, která podrobně vypíše obsah
proměnné. Bohužel v prostředí HTML výpis pozbude formátování a slije
se do jednoho řádku, o sanitizaci HTML kódu ani nemluvě. V praxi je
nezbytné var_dump nahradit šikovnější funkcí. Tou je
právě Debug::dump()
$arr = array(10, 20.2, true, null, 'hello');
Debug::dump($arr);
// včetně jmenného prostoru Nette\Debug::dump($arr);
Tohle všechno jsou sice užitečné drobnosti, skutečným killerem je však
jiná Laděnčina vlastnost.
Zpráva o nezachycené výjimce nebo chybě poskytuje vývojáři důležité
informace o tom, kde a proč k ní došlo. Standardní výstup v PHP vypadá
asi takto:
Standardní podoba nezachycené výjimky
Pusťme však ke slovu Laděnku. Po aktivaci příkazem
Debug::enable() nám předvede svou nejvíce sexy polohu:
Nezachycená výjimka v provedení NDebug
Takto vypadá výjimka, takto
vypadá vygenerovaná chyba. To je pak jiné
ladění, co?
Snad nemusím dodávat, že vypisování chyb se nesmí nikdy dostat na
produkční server. Je to výborná společnice na pracovišti, ale nikdy ji
nesmíme brát sebou ven. Je totiž děsně ukecaná a vyzradí na vás úplně
všechno (nicméně kdyby k tomu náhodou došlo, má integrovaný systém pro
skrytí citlivých políček, např. hesel). Na produkčním serveru je však
možné nechat výpisy ukládat do adresáře nebo odesílat administrátorovi
emailem.
Je známo, že objekty se do jazyka PHP dostaly spíš jako nezvaní hosté.
Docela příznačným rozdílem mezi jazykem, který byl jako objektový již
navrhován, a jazykem, který se jím stal k velkému překvapení samotných
tvůrců, je v absenci resp. přítomnosti společného předka všech tříd.
Object Pascal deklaruje TObject, DOT.NET má
System.Object a v Javě nebo Ruby stojí v hierarchii nejvýše
Object (je delikátní, že nejzákladnější třída
bývá pojmenována objekt). V PHP nic takového neexistuje.
Základní třída obvykle deklaruje metody pro sebereflexi. Například
metodu vracející název třídy. Je to sice detail, ale vždycky mi připadalo
tuze ošklivé mixovat hezký objektový kód s voláním pro-objektové
funkce get_class:
Titulky obsahující slovo „aneb“ mi vždycky připadaly
divné. A tento je ze všech úplně nejdivnější. Že jo?
Téměř každý den dostávám dotaz, kdy bude Nette. Už jsem si říkal,
že si připravím automatickou odpověď, nebo si napíšu do messengera
plugin, který to za mě bude vyřizovat sám. Ale nakonec jsem šáhl po blogu.
Takže, slyšte…
Rozpaky programátora
Svatopluka
Je krásný vlahý den, tři hodiny ráno, a vy si zlehka programujete novou
báječnou webovou aplikaci. Důležitou roli v ní hraje vaše šikovná
knihovna Manipulator. Když tu si najednou všimnete, že volání
metody $manipulator->appendFor(true, $objA) má jednu
kosmetickou vadu. Teda vlastně dvě. Jednak samotný název metody je
nešťastný, vhodnější by bylo appendTo nebo pouhé
append. A za druhé – to pořadí argumentů by mělo být
opačné. No jistě, kolikrát už jste se sám spletl. Je to jasné,
$manipulator->append($objA, true) vypadá mnohem lépe. Navíc
druhý parametr bývá v 99 % případů true, takže ho můžeme dát jako
volitelný, s touto výchozí hodnotou.
Motivace na drobný refactoring jako vyšitá.
Co zatím nevíte…
Něco vám musím prozradit. Knihovna Manipulator je velmi
populárním open-source projektem. Používají ho tisíce vývojářů. A vy
jste jeho autorem.
Jo, kdybyste byl samotář, co si kód píše a používá sám,
přejmenování metody a prohození parametrů by byla brnkačka. No,
uvažujete, na to by se dal napsat regulární výraz. Prográmkem (samozřejmě
opět vlastní výroby) Search & Replace si projedete všechny své
zdrojáky a jednotlivé záměny budete ručně potvrzovat. To pro sichr.
Odhadem – bajvoko – za čtvrt hodinky je to hotové.
Ale jak jsem zmínil, Manipulator je big fasa project.
Takže přemýšlíte, jestli vážně tu změnu udělat:
Neváhal bych, jenže co ty tisíce uživatelů? Způsobím jim komplikace,
práci navíc. A přitom jde vlastně o hloupost.
Jenže, mně se prostě appendFor nelíbí, mně to tam vadí.
Chci to změnit. Manipulator používá stále víc programátorů
a čím později změnu udělám, tím víc jich to postihne.
Nebo raději počkám na větší update, až se změní velké
číslo verze.
Ale kurnik žádné závazky přece nemám, prostě to změním a hotovo.
Napíšu to do changelogu, programátoři si to přečtou a svůj kód si holt
budou muset změnit.
Ach jo, víš, jak to dopadne, budeš odpovídat na tisíce dotazů „hele,
updatnul jsem si Manipulator a píše mi Fatal error: Call to undefined method
appendFor, co stím?“
Doprkýnka, pošlu je do patřičných míst v changelogu.
Ale nepošleš. Jen si vzpomeň, kolikrát jsi sám aktualizoval software a
nikdy jsi nestudoval changelog. Sám to neděláš a po ostatních
to chceš?
Dobře, ale co já z těch „ostatních“ mám? Dávám jim svůj těžce
vydřený software zdarma – a co je zdarma, to nikdo neocení. Píšu
dokumentaci, odpovídám na stovky dotazů a výsledek je, že se nervuju, když
chci přejmenovat jednu blbou funkci.
Nebo vznesu návrh, uvidíme, co na to řeknou uživatelé.
No co asi. Zrovna minulý týden jsi přejmenoval dvě klíčové třídy. To
bude zase radosti… Vykašli se na to.
Stop!
A tady příběh zastavíme. Jako na videu. Od této chvíle je to na vás!
Jak se má programátor Svatopluk Kuřátko rozhodnout?
změnit název metody a prohodit pořadí parametrů
na úpravu se vykašlat
Posílejte SMS ve tvaru HLA DGX A nebo B. Jste to
vy, kdo ovlivní další děj!
Málem bych zapomněl. Vy vlastně chcete vědět, kdy bude Nette, že?
Já se tak rozepsal, že mi to skoro vypadlo. Uff, to bylo o fous.
Upozornění: Knihovna Nette\Utils\Html se neustále
vyvíjí. Aktuální informace najdete na webu Nette
Framework. Popis v tomto článku postupně aktualizuji, takže některé
komentáře pod ním mohou být již nesouvisející.
Způsobů, jak v PHP vygenerovat kód stránky, je celá řada. Od
obyčejného volání příkazu echo, přes použití šablon, až po funkce
DOM. Hledání nejlepší metody vede k paradoxu. Čím je programátor
zkušenější, tím více tíhne k čistějším řešením, ideálně na
bázi XML DOM. Tím však začne narážet na nové překážky a omezení a
více času tráví jejich řešením a obcházením. Díky čemuž více tíhne
k pragmatickým řešením, jako je třeba volání echo.
Ale posuzování vhodnosti jednotlivých způsobů není předmětem
článku.
Seznamte se
s Nette\Utils\Html (dříve NHtml)
Generování HTML značek „na koleně“ vede k nepřehlednému kódu a
tím i k větší náchylnosti k chybám. Vezměme si jednoduchý
příklad:
Programový kód zpřehledníme rozdělením do více souborů. V případě
OOP se nabízí ukládání každé třídy/interface (resp. několika úzce
souvisejících tříd) do samostatného souboru. Tyto soubory je vhodné
pojmenovávat podle nějaké své konvence. Následně je vkládáme do skriptů
konstrukcí require_once. Opět, kvůli přehlednosti, bývá
zvykem všechna vkládání umísťovat na začátky skriptů.
Odbočka: pokud použijete relativní cestu k souboru,
require_once jej dohledá možná trošku nečekaným způsobem. Na include_path
se také nerad spoléhám, proto se kloním k používání absolutních cest
tímto způsobem:
require_once dirname(__FILE__).'/soubor.php';
Slabá místa
Tohle všechno sice přispívá ke zpřehlednění kódu, ale má to
i slabé stránky:
vkládáme soubory, které třeba nebudeme potřebovat
ke každé třídě si musíme pamatovat název souboru
Obzvláště ta dualita třída ↔ soubor mi hodně vadí. Hledal jsem tedy
nějaké flexibilní řešení, které by jednak odstranilo obě slabá místa,
zároveň co nejvíce zjednodušilo programátorovi život a hlavně nekladlo
nová omezení či pravidla.
Minule jsem ukazoval, jak lze s Nette stavět statické stránky. Ne náhodou jsem
začal právě tímto tématem. Statické stránky a technika „dědění“
jsou totiž základním pilířem budování webového sídla. Je na webovém
architektovi, aby připravil návrh website, grafik společně s HTML kodérem
mohou pilovat vizuální podobu stránek a programátor je oživuje. Nette plně
podporuje tuto pokrokovou filozofii skupinového vývoje.
Upozornění: Článek se týká velmi staré alpha
verze Nette Framework, současná syntaxe je jiná.
Troška terminologie nikoho
nezabije
Začínáme se věnovat oživování stránek, opusťme tedy pojem
„statické stránky“. Jen by nás mátl.
Nette podporuje stránky zapsané nejen v jazyce XHTML, ale i HTML a XML (např. RSS kanály). Místo neobratného
„HTML-XHTML-XML stránky“ budu dále používat termín
dokumenty.
Dokument je tvořen stromem elementů. Program může s touto
hierarchií dále pracovat prostřednictvím tzv. DOM.
Základní jednotkou oživování dokumentů je komponenta. Jde
o třídu (resp. objekt, podle kontextu), která je potomkem
Component. Speciálním druhem komponenty je stránka (třída
Presenter). Komponenty tvoří stromovou strukturu a jejím
kořenem je vždy nějaký následník třídy Presenter. Tuto
strukturu budu označovat jako COM. Nemá
to nic společného s technologií COM od Microsoftu.
Ačkoliv obě aplikace Nette i Texy! jsou zcela samostatné jednotky, je
možné je přimět k úzké spolupráci. Webdesignéry – příznivce Texy!
by mohla potěšit tato ukázka:
Samozřejmě konečná syntaxe je ještě věcí bádání, a to nejen
v tomto příkladě. Vzhledem k charakteru textu zvažuji i něco
takového:
<pre nette:type="texy">
I **love** it!
</pre>
S obsahem vkládaným i v podobě Texy! syntaxe bude možné dále
dynamicky pracovat. A tím je asi jasné, že další (a tak dlouho slibovaná)
verze Texy! přijde společně s Nette.
Žádný komplexní framework se nehodí pro jednoduché weby.
Výhody se totiž projeví až od určité míry složitosti webové aplikace.
V opačném případě práci spíš komplikuje.
Nette je framework, který se výborně hodí i pro tvorbu statických
stránek. Ano, čtete dobře! Obyčejných statických stránek. Pojďme se
na to podívat.
Upozornění: Článek se týká velmi staré alpha
verze Nette Framework, současná syntaxe je jiná.
Jednotlivé stránky v rámci jednoho serveru se hodně podobají. Liší se
sice v textu titulku, hlavním obsahu, ale mají stejné (či podobné)
hlavičky, patičky atd. Jak jsem zmiňoval dříve, primární zásada Nette
zní Nic nepsat dvakrát. Tak si ukažme v praxi, jak bez dvojího
psaní vytvoříme stránku „kontakty“: