S verzí 1.5 Zend Frameworku, přichází i podpora layoutu. Jedná se o jednu s velmi žádaných věcí, která ve verzi 1.0 chyběla. Ačkoli i dříve se layout dal implementovat pomocí front controller pluginu, je jeho podpora přímo vývojáři určitě dobrým krokem a do frameworku určitě patří. Implementace layoutu je zároveň integrována s novými view helpery. Pokusím se popsat základní principy, jak layout v Zend Frameworku funguje. Pro další čtení je potřeba mít základní tušení, jak funguje MVC v Zend Frameworku.
Layout, (často se zmiňuje také označení Two Step View), umožňuje obalit celý obsah aplikace do kabátku - layoutu, který obvykle představuje view šablona. Implementace layoutu ve frameworku se skládá z několika tříd, které jsou součástí balíčku Zend_Layout. Jedná se zejména o samotnou třídu Zend_Layout a třídy, které napomáhají integraci layoutu do MVC implementace, která je v Zend Frameworku. Implementace je poměrně flexibilní, takže je možné layout měnit, zakazovat a povolovat pro jednotlivé actions, měnit nastavení adresářů a view šablon pro layout atd. Jak jsem řekl, je implementace provázána na MVC infrastrukturu frameworku, nicméně layout lze používat i bez ní, samostatně. Já jsem jí samozřejmě na tomto blogu použil s MVC, proto se možností použití bez MVC zabývat nebudu.
Jak jsem se již zmínil, již dříve se dal princip layoutu implementovat front controller pluginem, podobně je použit i Zend_Layout, který využívá jak pluginu, tak action helperů a integraci s viewRendererem. Implementace také využívá nových view helperů a placeholderů, což je nový typ view helperu. Základní použití je asi následující. Máme šablonu layout.phtml
v adresáři /path/to/layouts/
- náš kabátek.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>My Site</title> </head> <body> <?php // fetch 'content' key using layout helper: echo $this->layout()->content; // fetch 'rightBlock' key using placeholder helper: echo $this->placeholder('Zend_Layout')->rightBlock; // fetch layout object and retrieve various keys from it: $layout = $this->layout(); echo $layout->bar; echo $layout->baz; ?> </body> </html>
Inicializace layoutu je velmi jednoduchá, v bootstrapu zavoláme statickou metodu
Zend_Layout::startMvc('/path/to/layouts/')
která vytvoří instanci Zend_Layout. Jako parametr dostává cestu k adresáři s layout view skripty. Jako parametr můžeme použít i pole s konfigurací layotu nebo Zend_Config, více o konfiguraci v manuálu.
Tak a teď to nejdůležitější, jak do layoutu dostat obsah. Ve výše zmíněném layout view skriptu je demonstrováno použití layout view helperu
$this->layout()->content
a layout placeholderu
$this->placeholder('Zend_Layout')->rightBlock
jsou to dvě rovnocenné možnosti jak se dostat k proměnným layoutu. Je totiž důležité si uvědomit, že layout šablona je použita skrz view objekt, který si drží viewRenderer. Jakékoli proměnné, které tedy do tohoto view objektu nastavíte, můžete klidně v layout šabloně použít - to je první možnost, jak vytvořit obsah layotu. Lepší je to ale udělat jinak.
Response segmenty a obsah layoutu
Response objekt v MVC Zend frameworku podporuje takzvané response segmenty, v podstatě tak lze výsledný zobrazovaný celek rozdělit na určité samostatné části a manipulovat s nimi. Response segmenty se dají pojmenovat. Implicitně viewRenderer používá segment jménem default pro výstup controller akcí. Jak jsem se již zmínil, layout funguje jako front controller plugin a právě pomocí tohoto pluginu se dosahuje toho, že jednotlivé segmenty se převádějí na view proměnné v layout šabloně, přičemž právě default
segment se převede na proměnnou content
. Takže pokud v našem příkladu budeme mít třeba controller
class FooController extends Zend_Controller_Action { public function barAction() { $this->rightBlock(); } public function righBlock() { $category=new Category(); $this->view->categories=$category->getAll(); //Renders rightblock into 'rightBlock' segment $response = $this->getResponse(); $response->insert('rightBlock', $this->view->render('rightBlock.phtml')); unset($this->view->categories); } }
a šablonu scriptsPath/foo/bar.phtml
<span style="color:red">this is main content</span>
pak v naší layout šabloně layout.html
dojde k tomu, že v místě
$this->layout()->content
se dostaneme k obsahu naší bar.phtml
šablony - použil se layout view helper a v místě
$this->placeholder('Zend_Layout')->rightBlock
budeme mít obsah našeho pravého bloku - použil se layout placeholder view helper.
V této souvislosti je dobré zmínit i nový ActionStack front controller plugin a a stejnojmenný action helper, pomocí něhož si můžeme nadefinovat posloupnost akcí. Řekl bych, že to bude i doporučovanější metoda, než výše uvedený postup s volaní public metody. Nezkoušel jsem to, ale mohlo by to vypadat asi nějak takto.
class FooController extends Zend_Controller_Action { public function barAction() { $this->_helper->actionStack('right-block', 'Foo','default'); } public function righBlockAction() { $category=new Category(); $this->view->categories=$category->getAll(); //Renders right block into 'rightBlock' segment $this->_helper->viewRenderer->setResponseSegment('rightBlock'); unset($this->view->categories); } }
To je tak asi k základům použití a funkce layoutu všechno. Samozřejmě, že layout má spoustu dalších možností namátkou třeba přepínání view šablony, vypínání layoutu, nastavování konfigurace, jak na to se lze dovědět v Zend framework manuálu.
Komentáře (4)
Mam k tomuhle drobný dotaz :) Co když potřebuju zavolat akci z jiného kontrolleru?! Třeba konkrétně u vytváření widgetů přece nebudu widgety cpát pokaždé do jednotlivých controllerů, ale hoim si jeden controller ve kterém budou zapouzdřené jednou pro vždy...
Ha, tak se omlouvám, nevšim jsem si, že syntaxe je ActionStack(action,controller,modul) - myslel sem, že to jsou jen další actions ^^
Ahoj,
Ked uz tu mas ten tutorial k layoutom,
chcel by som sa ta spytat ze ked na nejakej stranke
chcem pouzit iny layout, ako to spravim?
Dik za odpoved
[3] - Dotazy prosím směruj třeba na zend framework fórum, jinak v dokumentaci se píše něco ve smyslu
Komentáře jsou uzavřeny.