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:
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'); |
I don’t like global variables therefor I’ve added Smarty object into Zend Framework’s registry:
1 | Zend::register('smarty', $smarty); |
Using is pretty simple. Just initialize Smarty variables in your Controller class and display template:
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'); } } |
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!
Nice Dmytro :)
Wouldn’t it be just
$smarty->display('index.tpl')
? orecho $smarty->fetch('index.tpl')
?Best regards
holo
Thanks, you are right :-) I’ll fix it now.
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:2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
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')
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.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.
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 :-)
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:
2
3
$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:
In the layout template placeholder variables for content and modules are set:
2
3
$this->content
$this->modules_navigation
How would do this with Smarty?
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.
2
3
4
5
6
7
// 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
2
3
<div id="news">{include file="modules/news.tpl"}</div>
<div id="content">{include file=$content_template}</div>
5) Render main layout
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.
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…)
[…] un piccolo articolo su come integrare smarty con lo zend framework […]
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.
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.
[…] 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. […]
Идея не нова, но многим будет это полезно. Автору респект
Very nice, Dmytri! Thanks for useful introduction into smarty+ZFW!
BTW: will recommend this blog to my friends.
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
Спасибо Дмитро, просто и понятно!
>Как можно заметить, интеграция Smarty с Zend Framework – довольно >простая задача.
Після циєї статті ц дійсно просто. Дякую!
just admit that Zend sucks and use PhpED instead?
This one manages Smarty right.
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 …
Gigel its all about how the code looks in smarty templates :)
[…] Zend Framework: Using Smarty as template engine […]
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.
[…] 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). […]
Note that it is possible to use Zend_View helpers in Smarty too. All you need to do is this:
And then you can use it in your templates:
Добрый день. Меня заинтересовала ваша публикация,в ближайшее время на моем сайте откроется большое количество разделов, в одном из которых я хотел бы разместить данную публикацию. Можно ли это сделать и на каких условиях? Если можно – то на [email protected], с уважением Максим.
Можно разместить со ссылкой на оригинал :-)
Должен сказать спасибо, подобная задача стояла, решение нашел у вас :)
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.
Единственная адекватная статья, из которой(правда только после второго прочтения) ставноится понятно, как их вместе готовить. Респект.
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.
You can turn rendering off with:
It helped. Thanks krypin!
Три раза подряд прочел… Интересное решение
Good article and start point.
I successfully run with the latest Zend Framework 1.0.1 and latest Smarty 2.6.18.
Сегодня прикрутил Smarty к ZF, решил посмотреть другие решения. Автор молодец. Smarty рулит.
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?
[…] 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 […]
[…] 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 […]
[…] Втория вариант е относително елементарен, което и ме накара да се спра на него. На мен лично нещо не ми проработи идеята със Zend::registry, затова предпочетох да коментирам реда и да си дефинирам променливата като глобална. От там нататък всичко беше 6+ и нямаше никакви проблеми. Ето как трябва да изглежда един примерен IndexController: PHP: […]
Спасибо автору!
Именно этот подход я использую уже несколько месяцев, однако все это время меня не оставляет в покое тот факт, что было бы все-таки удобнее реализовать что-то вроде smarty-авторендеринга, что бы по умолчанию происходила обработка конкретного шаблона, как это делается с phtml. Нет ли у кого подобных наработок?
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.
Всем привет.
Напэашпил файлик, думаю будет полезен собравшимся.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}
}
Так подрубается:
2
3
4
5
6
7
8
9
10
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');
Так отрубается:
2
3
4
5
6
7
8
9
10
11
12
13
class IndexController extends Zend_Controller_Action
{
public function init()
{
$this->view->_useSmarty=false;
}
public function indexAction()
{
}
}
Думаю понятно, что к чему.
Зендовский код не загажен ничем, специфичным для Смарти, шаблоны лежат где и были по дефолту, тока на смарти.
Кстати, мона без палева довернуть определение движка шаблонов по расширению файла. Тока не знаю нафига.
А кэширование имхо лучше юзать зэндовское, оно матёрее.
ЗЫЖ это под 1.5.1
Исчо раз фсем привет.
Кой-чего переправил по сравнению с предыдущем постом:
view.php:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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:
2
3
4
5
6
7
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:
2
3
4
5
6
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:
2
3
4
{
return "\$THIS=\$this->_tpl_vars['THIS'];$tag_attrs;";
}
И вот для чего это фсё делалось:
файл \app\views\scripts\layout.phtml:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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>
Матёро, не?
[…] 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 […]
[…] Using Smarty as template engine […]
How could I pass form element with server side validation functions through smarty?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$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.
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
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
2
$smarty->register_object('foobar',$myobj);
and then use it on .tpl file like this
Bye
Использование Smarty целесообразно только в случае переноса готового проекта, использующего Smarty на ZF. Если говорить о новом проекте, то используйте Zend_Layout и Zend_View и забудьте о “лучшем шаблонном движке для PHP в мире”. Безусловно Смарти таковым и является, но при использовании ZF необходимость в нем просто отпадает.
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…