Zend Framework: Using Smarty as template engine

Mar 08
2006 16:41 (Development, PHP) · Русский (92,896 views)

Zend Framework’s View class has very bad capability for extending. It contains template variables but does not allow to access them, it has array with different pathes (templates, filters), but does not allow to add another type or access them. Therefor only way to use Smarty with Zend Framework is to abandon Zend_View and manipulate Smarty object directly.

First we need to create Smarty object. I do it in index.php after including Zend.php:

require('Zend.php');

include 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->debugging = false;
$smarty->force_compile = true;
$smarty->caching = false;
$smarty->compile_check = true;
$smarty->cache_lifetime = -1;
$smarty->template_dir = 'resources/templates';
$smarty->compile_dir = 'resources/templates_c';
$smarty->plugins_dir = array(
  SMARTY_DIR . 'plugins',
  'resources/plugins');

I don’t like global variables therefor I’ve added Smarty object into Zend Framework’s registry:

Zend::register('smarty', $smarty);

Using is pretty simple. Just initialize Smarty variables in your Controller class and display template:

class IndexController extends Zend_Controller_Action
{
  function index()
  {
    $smarty = Zend::registry('smarty');
    $smarty->assign('title', 'Test');
    $smarty->display('index.tpl');
  }

  function noRoute()
  {
    $smarty = Zend::registry('smarty');
    $smarty->display('error404.tpl');
  }
}

As you can see Smarty integration with Zend Framework is very simple task. Zend_View has ability to use your own filters and helper functions, but with Smarty you don’t need them because Smarty has its own plugins, filters, modifiers. Just forget about Zend_View and use best template engine for PHP in the world!

Books recommended

50 Responses to 'Zend Framework: Using Smarty as template engine'

Subscribe to comments with RSS or TrackBack to 'Zend Framework: Using Smarty as template engine'.

1
Holografix
said on 2006-03-10 at 6.45 pm

Nice Dmytro :)

echo $smarty->display('index.tpl');

Wouldn’t it be just $smarty->display(’index.tpl’) ? or echo $smarty->fetch(’index.tpl’) ?

Best regards
holo

2
said on 2006-03-10 at 6.47 pm

Thanks, you are right :-) I’ll fix it now.

3
Gregory Szorc
said on 2006-03-16 at 5.58 am

I already did something like this for a project I am working on. My solution was to create a class that extended Zend_View_Abstract. That way, you can still use all the methods with the Zend View API. My basic implementation is as follows:

class My_Smarty_View extends Zend_View_Abstract
{
  private $_smarty;
 
  public function __construct($config = array()) {
    parent::__construct($config);
   
    $this->_smarty = new Smarty();
   
    //i have a config object for my application
    $root = Zend::registry('config')->get('root', 'project');
   
    $this->_smarty->template_dir  = $root.'application/views/';
    $this->_smarty->compile_dir = $root.'tmp/templates_c/';
    $this->_smarty->config_dir = $root.'tmp/configs/';
    $this->_smarty->cache_dir = $root.'tmp/cache/';
   
  }
  public function assign($spec) {
    $args = func_get_args();
    call_user_func(array('parent', 'assign'), $args);
   
    if (is_string($spec)) {
      $arg = func_get_arg(1);
      $this->_smarty->assign($spec, $arg);
    } elseif (is_array($spec)) {
      foreach ($spec as $k=>$v) {
      $this->_smarty->assign($k, $v);
      }
    }
    else {
      throw new Zend_View_Exception('assign() expects a string or array');
    }
  }
}

Then in my controllers, I can just do a Zend::registry(’view’), $view->assign(’foo’, ‘bar’) and $view->render(’foo’)

4
said on 2006-03-16 at 7.53 am

Thanks for comment, Gregory

I tried to create something similar but I don’t see advantages of this approach. For different projects I need to setup different directories with plugins (for example if I use my own plugins), templates (if I use themes-based architecture). You’ve extended Zend_View_Abstract but you don’t use almost all its functionality. I don’t think this is a good object-oriented practice - to extend but not to use methods of base class.

5
said on 2006-03-17 at 5.31 am

I’ve been playing with this too, but it seems a wee bit wasteful to create a Smarty object if you don’t know if you’ll be needing it or not (for example, the index controller may process a form, or output a file without ever needing to have the Smarty class instantiated).

I take your point that it also not very clean to extend a class that is not truly a descendant, but it may be more prudent to create a factory class for View that can select a backend on-the-fly (e.g. a Zend_View or a Smarty_View). Then that class can create the backend object only when a render() method is called to save resources.

6
said on 2006-03-17 at 3.28 pm

Simon, you are right with inefficiency of creating Smarty object without knowing is it neccessary to generate responce. There is possible solution is to create factory object which will construct Smarty object on demand. But both methods has their own pros and cons and I don’t know which method is more preferable. I’ll think over your idea on weekend :-)

7
said on 2006-03-20 at 11.51 am

Hi,

I have been reading through your proposal and made up my mind. In a web application, I would like to use some layouts containing elements like navigation, news..,and of course the content of the actual request.

How would you implement layouts in the Zend Framework?

Without using Smarty I used the following method:

in Controller:

1) check request variables, authentication..

2) get required data from DB

3) use Zend_View to render the modules and the content for the actual request, save them as variables in the $view - Object:

$view->module_news = $view->render('modules/news'); // news
$view->module_navigation = $view->render('modules/navigation')// navigation
$view->content = $view->render('action.php')// content

4) render and output the desired layout for the action:

echo $view->render('layouts/default.php');

In the layout template placeholder variables for content and modules are set:

$this->modules_news
$this->content
$this->modules_navigation

How would do this with Smarty?

8
said on 2006-03-20 at 12.04 pm

Hello, fjonzo

With Smarty you can use layouts in following way:

1) check request variables, authentication..

2) get required data from DB

3) Assign all required variables to Smarty object.

// Common variables for all pages.
// Their can be setted up in the index.php file.
$smarty->assign('news', $newsData);
$smarty->assign('navigation', $navigationData);
// content_template means name of the content template file.
// Usually I've assigned this variable in the controller file.
$smarty->assign('content_template', 'about.tpl');

4) In main layout (layouts/default.tpl) you can use {include file=”"} construction

<div id="navigation">{include file="modules/navigation.tpl"}</div>
<div id="news">{include file="modules/news.tpl"}</div>
<div id="content">{include file=$content_template}</div>

5) Render main layout

$smarty->display('layouts/default.tpl');
9
said on 2006-03-21 at 2.41 pm

Thanks a lot,

I played around with Smarty and ZF and Smarty seems to be many times superior to Zend_View. But one thing that worries me is stepping out of the framework.

10
Norm 2782
said on 2006-03-22 at 4.10 pm

I wonder why the Zend Framework would bother writing a new template engine, instead of:
1) using Smarty 2.x
2) helping develop Smarty 3.x (if there’s gonna be a 3.x…)

11
said on 2006-03-28 at 1.37 am

[...] un piccolo articolo su come integrare smarty con lo zend framework [...]

12
Shammai Ellman
said on 2006-03-28 at 8.44 pm

I have the same question as Norm2782.
Why isn’t Zend integrating Smarty into their framework.
I have developed my own database driven framework that works just like the Zend Framework even before ZF came out. I use Smarty as the template engine because it is fast and stable. I am glad to see that others are interested in incorporating Smarty into a standard framework and I hope Zend takes the hint.
Perhaps we can start our own extension group for the Zend Framework and try to get Zend to incorporate it.

13
said on 2006-03-29 at 11.43 am

Norm2782, Shammai, thanks for comments

As I understood, Zend Framework team does not want to relay on third-party components. They are providing a simplest solution (but very powerfull and efficient) and everyone can extend or replace any part of system with his own parts.

14
said on 2006-04-09 at 7.38 pm

[...] Why use a template engine like Smarty or Template_Lite? When using the MVC pattern is seems to fit well. This article here provides a good example using Smarty with the Zend Framework. [...]

15
said on 2006-04-26 at 10.15 am

Идея не нова, но многим будет это полезно. Автору респект

16
said on 2006-04-26 at 11.00 am

Very nice, Dmytri! Thanks for useful introduction into smarty+ZFW!

BTW: will recommend this blog to my friends.

17
OpenMacNews
said on 2006-05-02 at 2.48 am

hi Dmytri,

i’m returning to Smarty after a disappointing foray through some CMSs — and having been trying to get my head around ZF. thx! for a great intro to Smarty+ZF!

i’ve also just read Ralf Egger’ts post:

INTEGRATING SMARTY WITH THE ZEND FRAMEWORK
http://devzone.zend.com/node/view/id/120

which he claims as being ‘inspired’ by *this* …

i’m hoping that you might be able to close-the-loop and comment on some of his effort there in light of your own thinking.

thx!

richard

18
said on 2006-05-25 at 6.20 am

Спасибо Дмитро, просто и понятно!

19
said on 2006-05-27 at 11.56 am

>Как можно заметить, интеграция Smarty с Zend Framework - довольно >простая задача.

Після циєї статті ц дійсно просто. Дякую!

20
Why don't you
said on 2006-06-07 at 1.56 pm

just admit that Zend sucks and use PhpED instead?
This one manages Smarty right.

21
said on 2006-07-04 at 7.51 am

what does smarty do with the zend framework ?
zend framework is a mvc framework, it has a viewer and a controller … is enough to separate bussines logic from presentation logic, smarty is useles, unles you want users to submit their templates, also in this case you have alternatives… using apache htaccess to limit some of php functions.
Smarty the interpreted language inside an interpred language (PHP), usless piece of code … one question bothers me … why are so many people use this useles thing anyway ? ….oh right … mediocre programmers …. a lot of php programmers are beginers …. but they must evolve as programmers … or maybe just learn how to program … not to write code … this means that you need to know more than a programming language …
Anyway, evolve … smarty people …

22
kabom!
said on 2006-07-17 at 2.59 am

Gigel its all about how the code looks in smarty templates :)

23
said on 2006-09-21 at 3.42 pm

[...] Zend Framework: Using Smarty as template engine [...]

24
Gerrit
said on 2007-02-04 at 11.46 pm

Gigel,
its not about mediocre programmers is about separating concerns.
Designers work on layout, programmers work on code. I know many programmers who cannot do a descent looking layout to save themselves and a number of web designers who cannot program.
When you work on a project that involves more than one person you may understand.

25
said on 2007-03-23 at 5.47 pm

[...] Smarty & ZendFramework Posted Marzo 12, 2007 In attesa che il ZendFramework arrivi alla versione stabile 1.0 ecco un ottimo e semplice modo per integrare il template engine Smarty nel modello MVC proposto da Zend (ho preso spunto da questo articolo). [...]

26
said on 2007-03-24 at 11.42 am

Note that it is possible to use Zend_View helpers in Smarty too. All you need to do is this:

$smarty->assign("helpers", new Zend_View);

And then you can use it in your templates:

{$helpers->formText("field1")}
27
Max
said on 2007-03-24 at 7.09 pm

Добрый день. Меня заинтересовала ваша публикация,в ближайшее время на моем сайте откроется большое количество разделов, в одном из которых я хотел бы разместить данную публикацию. Можно ли это сделать и на каких условиях? Если можно - то на max@asax.info, с уважением Максим.

28
said on 2007-03-25 at 12.53 am

Можно разместить со ссылкой на оригинал :-)

29
said on 2007-06-06 at 10.14 am

Должен сказать спасибо, подобная задача стояла, решение нашел у вас :)

30
said on 2007-07-10 at 1.30 pm

hi,
I am a novice when it comes to Zend Framework along with smarty. The question that i’m posing now may seem very silly.But the thing that confuses me is:

require(’Zend.php’);

what is the content of this file?
why is it required?

One more question is, since i am a novice in this, which website other than http://www.zend.com can i visit to understand both zend and smarty, or books i can purchase to learn more on this topic.
Thanks.

31
st0ne_c0ld (Ru)
said on 2007-07-18 at 5.57 pm

Единственная адекватная статья, из которой(правда только после второго прочтения) ставноится понятно, как их вместе готовить. Респект.

The one disadvantage I found is I still have to create files like:
/views/scripts/blabla1/blabla1.phtml
Because the Zend_Controller_Front throws exceptions when file like this don’t exists.

32
krypin
said on 2007-07-19 at 7.49 pm

You can turn rendering off with:

$frontController->setParam('noViewRenderer', true);
33
st0ne_c0ld (Ru)
said on 2007-07-20 at 9.58 am

It helped. Thanks krypin!

34
said on 2007-07-27 at 6.21 pm

Три раза подряд прочел… Интересное решение

35
said on 2007-08-18 at 12.57 am

Good article and start point.
I successfully run with the latest Zend Framework 1.0.1 and latest Smarty 2.6.18.

36
said on 2007-08-29 at 7.41 am

Сегодня прикрутил Smarty к ZF, решил посмотреть другие решения. Автор молодец. Smarty рулит.

37
said on 2007-09-11 at 4.07 pm

Hi fellows,
it is interesting to see the discussion.
I thing it’s more clean to use smarty on his own. So you are also better prepared to upcomming ZF’s.
BTW. Where would images and CSS be stored best? in template/xxx oder in a folder by itsself?

38
said on 2007-10-05 at 8.12 pm

[...] conclusión que acaba pareciendo código spaghetti. Eso sí,parece que se puede utilizar Smarty como motor de plantillas, con el que en su día no estuve demasiado cómodo trabajando y no me [...]

39
said on 2007-12-18 at 11.38 am

[...] updated version for it is based on version 1+ campared to the other previous integrations like Zend Framework: Using Smarty as template engine and Integrating Smarty with the Zend [...]

40
said on 2008-02-05 at 11.06 pm

[...] Втория вариант е относително елементарен, което и ме накара да се спра на него. На мен лично нещо не ми проработи идеята със Zend::registry, затова предпочетох да коментирам реда и да си дефинирам променливата като глобална. От там нататък всичко беше 6+ и нямаше никакви проблеми. Ето как трябва да изглежда един примерен IndexController: PHP: [...]

41
Евгений
said on 2008-02-15 at 4.27 pm

Спасибо автору!
Именно этот подход я использую уже несколько месяцев, однако все это время меня не оставляет в покое тот факт, что было бы все-таки удобнее реализовать что-то вроде smarty-авторендеринга, что бы по умолчанию происходила обработка конкретного шаблона, как это делается с phtml. Нет ли у кого подобных наработок?

42
Lance
said on 2008-04-17 at 8.03 pm

Repeating Mel’s post becauase-I don’t understand this line either:

Require ‘Zend.php’;

I can’t find any Zend.php in the Zend framework libraries so I’m trying to figure out what was meant by this line also.

43
guai
said on 2008-04-28 at 10.18 pm

Всем привет.

Напэашпил файлик, думаю будет полезен собравшимся.

require_once 'Zend/View.php';

class View extends Zend_View
{
    protected $_smarty;
    public $_useSmarty=true;

    protected function _run()
    {
        if($this->_useSmarty):
            if(!isset($this->_smarty))
            {
                require_once SMARTY_DIR.'Smarty.class.php';
                $this->_smarty=new Smarty();
                include MY_SMARTY_CFG_FILE;
            }
            $this->_smarty->assign($this->getVars());
            $this->_smarty->display(ROOT_DIR.func_get_arg(0));
        else:
            $args=func_get_args();
            call_user_method_array ('_run',$parent=parent,$args);
        endif;
    }
}

Так подрубается:

chdir('..');
require_once 'config.php';
require_once 'view.php';

require_once 'Zend/Controller/Front.php';
require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';

Zend_Controller_Action_HelperBroker::addHelper(new Zend_Controller_Action_Helper_ViewRenderer(new View()));

Zend_Controller_Front::run('app/ctrls');

Так отрубается:

require_once 'Zend/Controller/Action.php';

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
    $this->view->_useSmarty=false;
    }

    public function indexAction()
    {
    }
}

Думаю понятно, что к чему.
Зендовский код не загажен ничем, специфичным для Смарти, шаблоны лежат где и были по дефолту, тока на смарти.
Кстати, мона без палева довернуть определение движка шаблонов по расширению файла. Тока не знаю нафига.
А кэширование имхо лучше юзать зэндовское, оно матёрее.

ЗЫЖ это под 1.5.1

44
guai
said on 2008-04-29 at 1.13 am

Исчо раз фсем привет.

Кой-чего переправил по сравнению с предыдущем постом:

view.php:

require_once 'Zend/View.php';

class View extends Zend_View
{
    protected $_smarty;
    public $_useSmarty=true;

    protected function _run()
    {
        if($this->_useSmarty):
            if(!isset($this->_smarty)) {
                require_once SMARTY_DIR.'Smarty.class.php';
                $this->_smarty=new Smarty();
                include MY_SMARTY_CFG_FILE;
            }
            $this->_smarty->clear_all_assign();
            $this->_smarty->assign($this->getVars());
            $this->_smarty->assign_by_ref('THIS',$this);
            $this->_smarty->display(ROOT_DIR.func_get_arg(0));
        else:
            $args=func_get_args();
            call_user_method_array ('_run',$parent=parent,$args);
        endif;
    }
}

config.php:

//set_include_path(realpath('..'));
define('DS',DIRECTORY_SEPARATOR);

// SMARTY
define('ROOT_DIR',realpath('.').DS);
define('SMARTY_DIR',ROOT_DIR.'smarty'.DS);
define('MY_SMARTY_CFG_FILE',ROOT_DIR.'smarty.cfg.php');

smarty.cfg.php:

$this->_smarty->plugins_dir=array(
    SMARTY_DIR.'plugins',
    ROOT_DIR.'my_smarty_plugins');
$this->_smarty->template_dir=__(ROOT_DIR.$this->getScriptPath(''));
$this->_smarty->compile_dir=ROOT_DIR.'tmp';
$this->_smarty->force_compile=true;

Самое интересное:
наколбасил свой плугин для смарти:
файл my_smarty_plugins/compiler.zf:

function smarty_compiler_zf($tag_attrs, &$compiler)
{
    return "\$THIS=\$this->_tpl_vars['THIS'];$tag_attrs;";
}

И вот для чего это фсё делалось:
файл \app\views\scripts\layout.phtml:

<!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=windows-1251" />
    {zf echo $THIS->headTitle() }
    {zf echo $THIS->headScript() }
    {zf echo $THIS->headStyle() }
</head>
<body>
    {include file='footer.phtml'}

    <div id="nav">{zf echo $THIS->placeholder('nav') }</div>

    <div id="content">{zf echo $THIS->layout()->content }</div>

    {include file='header.phtml'}
</body>
</html>

Матёро, не?

45
said on 2008-06-18 at 8.25 pm

[...] in Zend Framework and i search through the web to find proper resolution for my problem. I found this article and another one inspired by the first. I tested both approaches but they were not what i [...]

46
said on 2008-06-26 at 10.36 am

[...] Using Smarty as template engine [...]

47
said on 2008-07-04 at 1.15 pm

How could I pass form element with server side validation functions through smarty?

$this->setName('frmDrawing');
$this->setName('frmDrawing');
$this->setView(new Zend_View());
        $this->getView()->headScript()->appendFile('/zenddemo/public/js/Zend/Form.js');
       
$id = new Zend_Form_Element_Hidden('id');
$name = new Zend_Form_Element_Text('name');
$drawing_name->setLabel('Drawing Name')
           ->setRequired(true)
           ->addFilter('StripTags')
           ->addFilter('StringTrim')
           ->addValidator('NotEmpty');
          
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', 'submitbutton');
        $this->addElements(array($id, $name, $submit));

With default template we can create form element in model and we can pass to template.

<?php echo $this->form ;?>

Through above code we can show compete form and on submit method we can also check server validation which we provide in model declaration.

Is any similar way available through smarty? from where we can directly assign server validation function in model and on submit it will execute that function and return appropriate value.

Thanks

48
said on 2008-08-18 at 10.19 pm

Hi Amit Shah, I found this solution at Advanced Features/Objects, may be it will be useful for you.

I register the php object with an smarty method

// registering the object (will be by reference)
$smarty->register_object('foobar',$myobj);

and then use it on .tpl file like this

{foobar->method}

Bye

49
clockworkbird
said on 2008-10-01 at 4.36 pm

Использование Smarty целесообразно только в случае переноса готового проекта, использующего Smarty на ZF. Если говорить о новом проекте, то используйте Zend_Layout и Zend_View и забудьте о “лучшем шаблонном движке для PHP в мире”. Безусловно Смарти таковым и является, но при использовании ZF необходимость в нем просто отпадает.

50
said on 2008-10-01 at 7.49 pm

Integrating Smarty with the Zend Framework…

Ralf Eggert wrote:

” Inspired by this article I started to play around a bit to integrate the Smarty template engine into the Zend Framework. My ambition was to minimize the required code in the controller actions but stay close to the given Zend_V…

Post a comment

You can use simple HTML-formatting tags (like <a>, <ul> and others). To format your code sample use <code lang="php">$a = "hello";</code> (allowed languages are ruby, php, yaml, html, csharp, javascript). Also you could use <code>$a = "hello";</code> and its syntax would not be highlighted. If you are not using <code> tag, replace < sign with &lt;.

Submit Comment

 
Copyright © 2005 - 2008, Dmytro Shteflyuk