Mediovski Technology

Smarty 3 + Zend Framework

Data: 20 Listopad 2009 13:21 Autor: Michał Szkodziński | Kategoria: PHP,Smarty,Zend Framework

Opis uruchomienia Smarty 3 we współpracy z Zend Framework oraz przykłady użycia helperów.

Update is available for this entry for: / Dostępna jest aktualizacja tego wpisu dla:
Smarty 3.0 RC3 & Zend Framework 1.10.4
http://technology.mediovski.pl/2010/08/08/smarty-3-0-rc3-zend-framework-1-10-4

Przygotowany na podstawie aplikacji działającej z:

  • Apache 2.2.11
  • PHP 5.3
  • MySQL 5.1.33
  • Zend Framework 1.9.5
  • Smarty 3.0 Beta 4

Więcej na temat Smarty 3 można przeczytać tutaj.

Smarty 3 beta 4 można pobrać z

Część struktury aplikacji (* oznaczono pliki, których kod źródłowy jest przedstawiony w dalszej części wpisu):

structure
Widok inicjalizujemy w Bootstrapie w metodzie _initView():

class Bootstrap
{
 
	(...)
 
	/**
	* Inicjalizacja widoku
	*/
	protected function _initView()
	{
		// Połączenie Zend View - Smarty
		$view = new My_View_Smarty(array(
			'scriptPath' => 'application/',
			'params' => array(
				'plugins_dir' => 'plugins',
				'compile_dir' => 'tmp/templates_c'
			),
			'helperDirs' => array(
				'My/View/Helper' => 'My_View_Helper_',
				'Zend/View/Helper' => 'Zend_View_Helper_'
			)
		));
 
		// View Renderer
		Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer')
		->setViewScriptPathSpec(':module/view/:controller/:action.:suffix')
		->setViewSuffix('tpl')
		->setView($view);
 
		// Zend Layout
		$view->layout = Zend_Layout::startMvc(array(
			'inflectorTarget' => 'layout/:script.:suffix',
			'layout' => 'default',
			'viewSuffix' => 'tpl'
		))->setView($view);
	}
 
	(...)
 
}

Rozszerzamy klasę Zend_View_Abstract o obsługę Smarty. Klasa wygląda bardzo podobnie do klas używanych podczas łączenia Smarty 2 z ZF.

class My_View_Smarty extends Zend_View_Abstract
{
	/**
	* Obiekt Smarty
	*
	* @var My_Smarty
	*/
	protected $_smarty = null;
 
	/**
	* Konstruktor
	*
	* @param array $config dane konfiguracyjne
	*/
	public function __construct($config = array())
	{
		$this->_smarty = new My_Smarty();
		$this->_smarty->setZendView($this);
 
		foreach ($config['params'] as $key => $value) {
			$this->_smarty->$key = $value;
		}
 
		$this->setScriptPath($config['scriptPath']);
 
		// Ścieżki do helperów
		foreach ($config['helperDirs'] as $path => $prefix) {
			$this->addHelperPath($path, $prefix);
		}
	}
 
	/**
	 * Zwraca obiekt Smarty
	 *
	 * @return My_Smarty
	 */
	public function getEngine()
	{
		return $this->_smarty;
	}
 
	/**
	* Ustawia ścieżkę do szablonów
	*
	* @param string $path ścieżka
	*/
	public function setScriptPath($path)
	{
		if (null === $path) {
			return;
		}
 
		$this->_smarty->template_dir = $path;
	}
 
	/**
	* Pobiera ścieżki do szablonów
	*
	* @return array tablica ścieżek
	*/
	public function getScriptPaths() {
		return array($this->getScriptPath(null));
	}
 
	/**
	* Zwraca ściezkę do plików tpl
	*
	* @return string ścieżka
	*/
	public function getScriptPath($name) {
		return $this->_smarty->template_dir;
	}
 
	/**
	* Ustawienie parametru
	*
	* @param string $key klucz
	* @param mixed $value wartość
	*/
	public function setParam($key, $value)
	{
		$this->_smarty->$key = $value;
	}
 
	/**
	* Ustawia zmienną w widoku
	*
	* @param string $key nazwa zmiennej
	* @param mixed $value wartość zmiennej
	*/
	public function __set($key, $value)
	{
		$this->_smarty->assign($key, $value);
	}
 
	/**
	* Pobiera zmienną z widoku
	*
	* @param string $key nazwa zmiennej
	* @return mixed wartość zmiennej
	*/
	public function __get($key)
	{
		return $this->_smarty->get_template_vars($key);
	}
 
	/**
	* Sprawdzenie czy zmienna jest ustawiona w widoku
	*
	* @param string $key nazwa zmiennej
	* @return boolean czy zmienna jest ustawiona
	*/
	public function __isset($key)
	{
		return null === $this->_smarty->get_template_vars($key);
	}
 
	/**
	* Usunięcie zmiennej z widoku
	*
	* @param string $key nazwa zmiennej
	*/
	public function __unset($key)
	{
		$this->_smarty->clear_assign($key);
	}
 
	/**
	* Przypisywanie zmiennych do widoku
	*
	* @param string|array $var nazwa zmiennej lucz tablica par (klucz => wartość)
	* @param mixed $value wartość zmiennej
	*/
	public function assign($var, $value = null)
	{
		if (is_array($var)) {
			$this->_smarty->assign($var);
			return;
		}
 
		$this->_smarty->assign($var, $value);
	}
 
	/**
	* Usunięcie wszystkich przypisanych do widoku zmiennych
	*/
	public function clearVars()
	{
		$this->_smarty->clear_all_assign();
	}
 
	/**
	* Renderowanie szablonu
	*
	* @param string $name nazwa szablonu
	* @return string wyrenderowany szablon
	*/
	public function render($name)
	{
		if (file_exists($this->getScriptPath($name) . $name)) {
			return $this->_smarty->fetch($name);
		}
		return null;
	}
 
	/**
	* Rozszerzenie abstrakcyjnej metody klasy nadrzędnej
	*/
	protected function _run()
	{
	}
}

Rozszerzamy klasę Smarty o obsługę helperów widoku Zend Framework:

class My_Smarty extends Smarty
{
	/**
	* Obiekt widoku
	*
	* @var Zend_View_Abstract
	*/
	protected $_zendView = null;
 
	/**
	* Konstruktor
	*
	*/
	public function __construct()
	{
		parent::__construct();
 
		$this->plugin_handler = new My_Smarty_Plugin_Handler($this);
		$this->default_plugin_handler_func = 'My_Smarty_Plugin_Handler::loadZendPlugin';
	}
 
	/**
	* Ustawienie widoku
	*
	* @param Zend_View_Abstract $view obiekt widoku
	*/
	public function setZendView(Zend_View_Abstract $view)
	{
		$this->_zendView = $view;
	}
 
	/**
	* Pobranie widoku
	*
	* @param Zend_View_Abstract obiekt widoku
	*/
	public function getZendView()
	{
		return $this->_zendView;
	}
}

Dodatkowa klasa do ładowania oraz uruchamiania helperów Zend Framework:

class My_Smarty_Plugin_Handler extends Smarty_Internal_Plugin_Handler
{
	/**
	* Wywołanie pluginu
	*
	* @param string $name nazwa pluginu
	* @param array $args $args[0] = tablica atrybutów
	* @return bool czy udało się wywołać plugin
	*/
	public function __call($name, $args)
	{
		if ($this->loadSmartyPlugin($name, $args[1])) {
			$plugin = $this->smarty->registered_plugins[$name][1];
			$pluginClass = get_class($plugin[0]);
	    		if (strncmp($pluginClass, 'My_', 3) || strncmp($pluginClass, 'Zend_', 5)) {
	    			try {
					if (isset($args[0][0]['_method'])) {
						$plugin[1] = $args[0][0]['_method'];
						unset($args[0][0]['_method']);
					}
		    			return call_user_func_array($plugin, $args[0][0]);
		    		} catch (Exception $e) {
	    				return false;
		    		}
			}
		}
		return parent::__call($name, $args);
	}
 
	/**
	* Ładowanie helperów Zend Framework
	*
	* @param string $name nazwa helpera
	* @param array $plugin_type typ pluginu
	* @param Smarty_Internal_Plugin_Handler $smarty_plugin_handler
	* @return bool czy ładowanie przebiegło pomyślnie
	*/
	public static function loadZendPlugin($name, $plugin_type, $smarty_plugin_handler)
	{
		try {
			$smarty_plugin_handler->smarty->registered_plugins[$name] = array(
				'function',
				array(
					$smarty_plugin_handler->smarty->getZendView()->getHelper($name),
					$name
				),
				true
			);
		} catch (Zend_Loader_PluginLoader_Exception $e) {
			// Nie znaleziono helpera
			return false;
		}
		return true;
	}
}

Przykłady użycia helperów ZF w szablonach, aby wywołać inną metodę niż domyślną należy jej nazwę podać jako wartość parametru _method.

{baseUrl}
{url urlOptions=['module' => 'Default', 'controller' => 'index', 'action' => 'index'] name='default' reset=true}
{myHelper _method='myMethod' options=['key1' => 'value1', 'key2' => 'value2'] limit=20}
RSS
Get Adobe Flash player