Szablony w Zend Frameworku

Jak zapewne wszyscy wiedzą sam PHP jest już swego rodzaju systemem szablonów, dlatego w założeniach ZF w części widoku nie ma niczego przypominającego Smarty czy OPT. Zamiast tego operujemy na czystym PHP z minimalna ilością kodu. Niestety, nie zawsze się to sprawdza. Kod który musimy wklepać w szablonie jest zazwyczaj o wiele dłuższy, niż taki sam napisany w Smarty. Na korzyść tego pierwszego na pewno można zaliczyć szybkość działania, ponieważ kod nie musi być dodatkowo parsowany.

Tych którym jednak nie podoba się defaultowa forma Zend_Viem, mogą w potencjalnie prosty sposób zastosować inny system. Są na to dwa sposoby. Pierwszy to po prostu stworzenie w bootstrapie odpowiedniego obiektu (np Smarty) i trzymanie go w rejestrze. Niestety w poniższy sposób ograniczamy znacząco funkcjonalność jaką daje nam sam ZF. O wiele lepszym sposobem jest rozszerzenie klasy Zend_View. Możemy tego dokonać w np poniższy sposób.



require_once 'Zend/View.php';
require_once 'Smarty/Smarty.class.php';

class Naneau_View_Smarty extends Zend_View_Abstract
{

protected $_smarty;


public function __construct($config)
{
$this->_smarty = new Smarty();

$this->_smarty->compile_dir = $config['compileDir'];

parent::__construct($config);
}

public function getEngine()
{
return $this->_smarty;
}

protected function _run()
{

$vars = get_object_vars($this);
foreach ($vars as $key => $value) {
if ('_' != substr($key, 0, 1)) {
$this->_smarty->assign($key, $value);
}
}

$this->_smarty->assign_by_ref('this', $this);
$path = $this->getScriptPaths();
$file = substr(func_get_arg(0), strlen($path[0]));
$this->_smarty->template_dir = $path[0];
echo $this->_smarty->fetch($file);
}
}


To co wydawać się miało błogosławieństwem - $this->_smarty->assign_by_ref('this', $this); - w teorii dając nam dostęp do wszystkich możliwości ZF (helperów itp), w praktyce już nie okazuje się takie kolorowe. Wszystko przez same Smarty i parsowanie szablonów. W niektórych przypadkach gdy probujemy sie odwołać do jakiegoś helpera Zend_View, Smarty zwraca nam error podobny do poniższego. np:

{$this->placeholder('Zend_Layout')->content}


Wywoła błąd:

Fatal error: Smarty error: [in default.tpl line 41]: syntax error: unrecognized tag:


Niestety nie ma na to prostego rozwiązania, aczkolwiek można na to częściowo zaradzić. W niektórych przypadkach pomoże zdefiniowanie pośredniej zmiennej:

{assign var="layout" value=$this->placeholder('Zend_Layout')}
{$layout->content}


Rozwiązanie częściowo poprawne, jednak lekko kłopotliwe. Na szczęście takich sytuacji nie ma za wiele. Można też uciec się do bezpośredniego wstawienia bloku PHP w szablonie (rozwiązanie mniej eleganckie):

{php}
echo $this->get_template_vars('this')->placeholder('Zend_Layout')->content;
{/php}


Dodatkowy kłopot pojawia się również przy przekazywaniu tablic jako argumenty helperów (co jest związane znowu z parserem Smarty):

{$this->url(array("action" => "logout", "controller" => "account"))}


Da to podobny wynik w postaci błędu, ale na to również można poradzić tworząc dodatkowa funkcje Smarty:

function smarty_function_helper($params, &$smarty)
{
$c = 1;
while(isset($params['param'.$c])) {
if (preg_match('/^array\(/', $params['param'.$c])) {
eval('$param[] = '.$params['param'.$c].';');
} else {
$param[] = $params['param'.$c];
}
$c++;
}
return call_user_func_array(array($smarty->_tpl_vars['this'], $params['helper']), $param);
}


Dzięki temu dostajemy możliwość odwoływania się poprzez:
{helper helper="url" param1='array("action" => "logout", "controller" => "account")'}


Jak dla mnie, trochę za dużo zabawy jak na tak błahe sprawy. Dlatego pora przemyśleć całą sprawę szablonów od początku. Chyba że ktoś dysponuje jakimiś lepszymi rozwiązaniami, powyższych problemów. Z drugiej strony dzięki Smarty oraz przedstawionym metodom uzyskujemy stosunkowo przyjazny system szablonów z masa dodatków, ogromnym supportem oraz społecznoscia.

108 Responses to “Szablony w Zend Frameworku”

  1. Odnośnie szablonów polecam jeszcze http://weierophinney.net/matthew/archives/152-Zend_Layout-and-Zend_View-Enhanced-components-now-in-core.html
    PS. Jakaś literówka się wkradła: "Zend_Viem".

  2. Skoro już umieszczasz czyjść kod oraz pomysł, wypadało by podać źródło : http://naneau.nl/

  3. Tak, jest to z źródła jakie podałeś jak sama nazwa klasy wskazuje z lekkimi przeróbkami.

    Pozdrawiam.

  4. Jak robiłem projekt w Zend Frameworku, w ogóle się nie bawiłem w pisanie jakichś nakładek na system szablonów. Jednak z drugiej strony miałem też znacznie fajniejsze zabawki, niż zendowe helpery, tak więc ten problem odpadał.

    Zauważ, że system szablonów będziesz konfigurować raz. Jak już będzie wszystko gotowe, możesz używać kodu ponownie. Osobiście wolę raz się trochę więcej pomęczyć, a później mieć 10 razy łatwiej, niż na odwrót.

  5. "Kod który musimy wklepać w szablonie jest zazwyczaj o wiele dłuższy" to akurat jest kiepski argument...

  6. Re: Up


    Jak bys mial w szablonie 80% kodu PHP (same echo $this->costam->costam) i 20% HTMLa to bys tak nie mowil, a powiedzmy sobie szczerze - w masie przykladow tak jest.

    Smarty sa dobre w przypadku, kiedy np. przekazuje sie do szablonu zapytanie z baz danych, po czym przechodzi sie w petli po wszystkich elementach - problem pojawia sie wowczas, kiedy nalezy w szablonie cos z tymi danymi zrobic, wtedy mnoza sie Smartowe {ify} i tym podobne w sytuacjach, gdzie linijka czystego kodu PHP zalatwilaby sprawe bardzo szybko. Niestety - jak wyglada umieszczanie kodu PHP w Smartach kazdy wie.

  7. przecież możesz sprowadzić swój kod do postaci gdzie nie będą potrzebne żadne ify w smartych, zaś co się tyczy wyższości smarty to tak przygotowany szablon jest znacznie czytelniejszy w wysiwyg'ach

  8. Jakis czas temu zaproponowalem temat na forum php.pl niestety pozostal bez odzewu.

    http://forum.php.pl/index.php?showtopic=85777&p=434213

    Zapraszam do dyskusji chetnie poczytam o zaletach i wadach korzystania ze Smarty czy Zend_View.

Leave a Reply