Zend Framework: Использование Smarty как шаблонного движка

Posted by Dmytro Shteflyuk on under PHP · English (151,178 views)

Класс View, который входит в Zend Framework, имеет очень плохие способности к расширению. Он содержит шаблонные переменные, но не дает доступа к ним, он включает массив различных путей (к шаблонам, фильтрам), но не позволяет добавлять другие типы или использовать их. Таким образом, единственным вариантом использования Smarty с Zend Framework является отказ от Zend_View и управление объектом Smarty напрямую.

Для начала необходимо создать объект Smarty. Я сделал это в index.php сразу после подключения Zend.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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');

Я не люблю глобальные переменные, потому решил добавить объект Smarty в реестр Zend Framework:

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

Использование крайне просто. Достаточно проинициализировать переменные Smarty в классе Controller и отобразить шаблон:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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');
  }
}

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

Zend_View содержит возможность использовать Ваши собственные фильтры и вспомогательные функции, но при использовании Smarty они вам не нужны, потому что он содержит свои собственные плагины, фильтры и модификаторы. Просто забудьте о Zend_View и используйте лучший шаблонный движок для PHP в мире!

Рекомендуемые книги

54 Responses to this entry

Subscribe to comments with RSS

st0ne_c0ld (Ru)
said on Июль 18, 2007 at 17:57 · Permalink

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

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.

krypin
said on Июль 19, 2007 at 19:49 · Permalink

You can turn rendering off with:

1
$frontController->setParam('noViewRenderer', true);
st0ne_c0ld (Ru)
said on Июль 20, 2007 at 09:58 · Permalink

It helped. Thanks krypin!

said on Июль 27, 2007 at 18:21 · Permalink

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

said on Август 18, 2007 at 00:57 · Permalink

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

said on Август 29, 2007 at 07:41 · Permalink

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

said on Сентябрь 11, 2007 at 16:07 · Permalink

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?

said on Октябрь 5, 2007 at 20:12 · Permalink

[...] 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 [...]

said on Февраль 5, 2008 at 23:06 · Permalink

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

Евгений @
said on Февраль 15, 2008 at 16:27 · Permalink

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

Lance
said on Апрель 17, 2008 at 20:03 · Permalink

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.

guai @
said on Апрель 28, 2008 at 22:18 · Permalink

Всем привет.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
    }
}

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

1
2
3
4
5
6
7
8
9
10
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');

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

guai @
said on Апрель 29, 2008 at 01:13 · Permalink

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

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

view.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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:

1
2
3
4
5
6
7
//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:

1
2
3
4
5
6
$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:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>

Матёро, не?

said on Июль 4, 2008 at 13:15 · Permalink

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$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.

1
<?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

arbol @
said on Август 18, 2008 at 22:19 · Permalink

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

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

and then use it on .tpl file like this

1
{foobar->method}

Bye

clockworkbird @
said on Октябрь 1, 2008 at 16:36 · Permalink

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

said on Октябрь 1, 2008 at 19:49 · Permalink

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…

zendrej @
said on Март 10, 2009 at 12:56 · Permalink

I could not find ‘zend.php’ and failed to include this. I would be thankful if anyone can help me

The below index.phtml is not rendering values too

1
<?=$this->val?>

Regards,
rej

said on Март 17, 2009 at 19:29 · Permalink

This is a little outdated…

It works… but instead of using Zend::register(‘smarty’, $smarty) you should use Zend_Registry::set(‘smarty’, $smarty) and instead of using Zend::registry(‘smarty’) you should use Zend_Register::get(‘smarty’). And ofcourse you must: require_once ‘Zend/Registry.php’ in the bootstrap.

said on Март 17, 2009 at 19:33 · Permalink

I’m against this method of incorporating smarty into ZF. This method assumes you will be rendering a smarty view with each action.

Also… this will produce an error with current versions on ZF that automatically render a view at the end of an action. With this method you must call $this->_helper->viewRenderer->setNoRender(true) in every action to disable zend from attempting to render a default view after the smarty display.

More comments: 1 2

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.