I want to generate a dynamic site using Zend_Layout.
My layout (/application/layouts/scripts/layout.phtml) contains the following lines:
...
<body>
<?php echo $this->render('header.phtml') ?>
<div id="content"><?php echo $this->layout()->content ?></div>
<?php echo $this->render('footer.phtml') ?>
</body>
...
If i browse to my index controller index action - Zend renders the index view (application/views/scripts/index/index.phtml) inside of $this->layout()->content automatically.
Now i want to render the views of to different controller actions in the layout.
So i generate a new controller auth with an action login that shows a login form.
I change my layout to:
...
<body>
<?php echo $this->render('header.phtml') ?>
<div id="content"><?php echo $this->layout()->content ?></div>
<div id="login"><?php echo $this->layout()->login ?></div>
<?php echo $this->render('footer.phtml') ?>
</body>
...
When i browse to index/index, i want to define in this action that zend should render auth/login view inside $this->layout()->login and for example news/list inside of $this->layout()->content.
index/index is than a kind of a page layout -
and auth/login and news/list a kind of widget
How to do this?
First advice is to avoid the Action view helper at all costs, it will probably be removed in ZF 2.0 anyway. (ZF-5840) (Why the actionstack is evil)
This is related to a question I asked - and bittarman's answer is pretty useful. The best way to implement something like that is to have a view helper that can generate your "login" area. My_View_Helper_Login
for instance. Then your layout can call $this->login()
, and so can the view script for user/login
. As far as having index/index
render the content from news/list
just forward the request to the other controller/action from the controller. $this->_forward('list', 'news');
I would also advise against using the action view helper
. Unless you have a bunch of logic in your controller, you probably don't need to dispatch another request to another controller just to render a view partial.
I would recommend simply using a view partial just like you have done with your header.phtml
and footer.phtml
:
<body>
<?php echo $this->render('header.phtml') ?>
<div id="content"><?php echo $this->layout()->content ?></div>
<div id="login"><?php echo $this->render('auth/login.phtml') ?></div>
<?php echo $this->render('footer.phtml') ?>
</body>
And maybe your auth/login.phtml
view script looks like this:
<div id="login_box">
<?php if (empty($this->user)): ?>
Please log in
<?php else: ?>
Hello <?php echo $this->user->name ?>
<?php endif; ?>
</div>
As long as you set your view variables at some point in your controller, you can call the render view helper
from within a view (or even a controller if you wanted to).
#index controller
public function indexAction()
{
$this->view->user = Model_User::getUserFromSession();
}
You can use the not so speed performant
$this->action()
or you try it with
$this->partial()
(see http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.partial )
I got to this page when looking for an answer to my own problem, which was that my layout got called multiple times. This happened because of multiple reasons:
1) I made a bad ajax call, had /help instead of /module/help
2) I called an action, exampleAction(), I had to put a
$this->_helper->layout->disableLayout();
To prevent the layout from being rendered again.
3) I did a redirect, try using a forward or route.