"Nejbohatší život má ten, kdo žije s minimem nároků." --Platón

Zend_Layout

15.3.2008 | koubel | Zend Framework

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.

  • Currently 99/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
aktuální hodnocení 3.30/5 (hlasovalo: 40)
viewpic 4146x
0 trackbacků - url pro trackback
4 komentáře - Přidej komentář
1.   Tomáš Fejfar - 21.4.2008 18:08
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...
2.   Tomáš Fejfar - 21.4.2008 18:39
Ha, tak se omlouvám, nevšim jsem si, že syntaxe je ActionStack(action,controller,modul) - myslel sem, že to jsou jen další actions ^^
3.   DarkStar - 8.7.2008 14:42
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
4.   koubel - 13.7.2008 11:24
[3] - Dotazy prosím směruj třeba na zend framework fórum, jinak v dokumentaci se píše něco ve smyslu
public function bazAction()
    {
        // use different layout script with this action:
        $this->_helper->layout->setLayout('foobaz');
    }
Přidej komentář