I want to add a view helper path in an existing project. To do this I have added the following line to my application.ini:
resources.view[] =
And in my bootstrap file:
$this->bootstrap("view");
$view = $this->getResource("view");
$view->addHelperPath(APPLICATION_PATH . "/../library/MyPath", MyNamespace");
Now I am indeed able to add view helpers to my path, so no problem there.
However, variables that I have added to the view in my Action Helpers are suddenly no longer accessible inside my views. I can retreive them inside my layout as usual so I know they get assigned properly.
I assign a variable in my Action Helper in the postDispatch:
$view = $this->getActionController()->view;
$view->myVar = $this->var;
Then in my layout
Zend_Debug::dump( $this->myVar );
results in: (string) "myVar contents"
And in my view
Zend_Debug::dump( $this->myVar );
results in: null
Since this is an existing project I need a general solution that I can use in either my bootstrap or application.ini
You can add paths to your view from application.ini:
resources.view.helperPath.MyPrefix = "/path/to/helpers"
Hopefully this will fix the problem. I'm assuming that the way you do it, an existing view-instance is somehow overwritten, which destroy previous changes. You could try fetching the view from the frontcontroller, set the helper-path, and pass it back to the frontcontroller.
After some research this is what I found out.
Edit: Removed text concerning differences between view variables and layout variables - see comments by #pieter and #david weinraub
The postDispatch of the Action Helper fires AFTER the view is rendered, but BEFORE the layout is rendered. Therefore, any variables assigned to the view in the postDispatch of the action helper were unavailable in my views, they didn't exist yet.
I am very curious why this behaviour occurs ONLY when actively bootstrapping the view? I will leave the question unanswered, maybe someone can clarify this.
Related
I'm trying to pass a variable from the master layout to the view, but I'm having no luck.
layout.phtml
$this->hadMessages = true;
myview.phtml
var_dump($this->hadMessages);
The var_dump always comes back with NULL. From what I've read, the layout is a view too, so it should be in the same context, right?
I'm using Zend Framework 1.11.
The layout is rendered after the view, so that's why this doesn't work. Depending on what you are trying to do you might be able to achieve the desired effect with the help of a controller plugin.
There is no way to pass variable from layout to view, because according to MVC pattern you shouldn't have tasks like this. Wether layout contains some messages or not should be decided on controller or bootstrap level, not in layout itself.
It means in controller you should make all needed assignments like $this->view->layout_messages_shown = true and get this variable value both in layout and view like echo ( $this->layout_messages_shown ? "messages shown" : "messages hidden" )
I am playing with layout in Yii, and have one question need your help.
As I looked into layout view file: "column1.php" I see the beginContent() method:
<?php $this->beginContent('//layouts/main'); ?>
As I read a guiedbook "Agile web development with Yii", it said: [quote]The view being specified
here is our main layout page 'layouts/main'. If nothing is specified, it will use the default layout
specified either at the controller level, or if not specified at the controller level, at the
application level.[/quote]
As I understand that the layout specified at the controller level is "layout/column1" (as I have checked value $this->layout). so If I leave this layout empty in the beginContent() method, then it will render "layout/column1", am I right?
If so, the new loaded layout will reapeatly load the "layout/colum1" as there's no layout value pass to beginContent() method at this new loaded layout. and I iffer that this will return an error.
But, when I leave this layout value empty. the view file still load as normal. no error occured.
I am very supprised with it.
Could someone tell me what has happened?
Thank you.
I can't understand when to use Layout's variables and when to use View's variables to get page segments on the page. Here is the picture form their Layout package tutorial ($this means the View instance everywhere):
Why Navigation, Content and Sidebar segments are got as Layout variables?
$this->layout()->nav;
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
$this->headTitle(); // I know that this is a placeholder view helper.
// But this segment of the page logically belongs to Layout.
// and it has to be called smth like view->layout->placeholder
And why Header and Footer are from some partial method of the View but not Layout's properties?
$this->partial('header.phtml');
I've tried to change them and both ways work fine:
echo $this->nav; // I assigned navigation segment script to the View and it works;
I tried to assign Footer segment script to the Layout and it also works:
$layout->footer = $footer;
echo $this->layout()->footer; // it also works, it's displayed on the page
Any of the ways may be applied to any variable on the page. For example in Navigation segment I have a lot of variables to display and I can output them using both ways - one variable as Layout's property, another one sa View's property.
So what is the rule to use them right way? When should I use View's variables and when Layout's ones?
I agree that this isn't very clear from the documentation, and I don't think $this->layout()->nav is explained at all. A few points that might help:
$this->layout() is actually a call to the layout view helper, which returns the current instance of Zend_Layout.
Zend_Layout registers its own placeholder helper (with the key 'Zend_Layout'), and by default creates a 'content' variable in this.
the Zend_Layout class has a magic __get() method which proxies any member variable calls over to its registered placeholder container. So calling $this->layout()->content is another way of writing $this->placeholder('Zend_Layout')->content
the Zend_Layout class also has a magic __set() method that proxies stored data to the placeholder class. So $layout->footer = 'foo' is the same as calling $this->placeholder('Zend_Layout')->footer = 'foo' in the view
With that in mind:
Why Navigation, Content and Sidebar segments are got as Layout variables?
As these are accessing data stored in Zend_Layout's placeholder. You could also use $this->placeholder('Zend_Layout')->content
But HeadTitle, HeadScript, HeadStylesheet are got straightly from View?
These are view helpers.
And why Header and Footer are from some partial method of the View but not Layout's properties?
This is the standard way of accessing content from other templates.
In general, assume that using the view object is the correct way to access the data. Use the layout object/helper only if you know the data is in the layout placeholder.
The advantage of using placeholders over partials is that you can access and modify them in several different places, including in the view itself. For example say you had a sidebar which is stored in a partial. If you were to store this in the Zend_Layout placeholder instead (for example in a controller plugin), you can then override this for certain actions in the controller:
public function someAction()
{
$this->view->layout()->sidebar = 'Some other sidebar content';
}
or in the view script itself:
<?php $this->layout()->sidebar = 'Content for this page only'; ?>
I have this layout file called menuAdmin.
I wish to, each time a given controller and a given action is active, to show the "li" element with a specific class.
So, I have the following on my menuAdmin.php :
<li <?php echo ($this->controller == "d" && $this->action == "a") ? "class='selectedMenuItem'" : ''; ?>>Aaaa Dddd</li>
I get nothing with this, and if I dump:
var_dump($this->controller); and var_dump($this->action); I get NULL NULL
So I believe Zend don't trigger those at that point.
Question:
How can I accomplish such a task? Should I follow this path? If so, how will my menuAdmin layout know about what controller and action is in place?
Update:
menuAdmin.php is a layout file, inside Layouts folder on Zend structure.
This is a large application and the structure in place is already like this - using layout files as menus where this is just one of them.
So $this->controller and $this->action only work inside the controller, OR if I explicitly pass it to the view. On this case, however, I would like to call it on the layout. Why there? Because by doing so, I can make one change and allow that change to be replicated all over the views that use this layout.
Regarding the above clarifications, could your answers change ?
Update 2:
I don't know if this is relevant or not but, all this menuadmin layout is called from a main layout file "layouts/main.php" and there we have: <?php echo $this->render("menuadmin.php"); ?>
Thanks again
Depending on what menuAdmin.php is you can get the controller and action in a variety of ways.
If your file is a controller you can do one of the following, they all do the same thing
$controller = $this->getRequest()->controller;
$controller = $this->getRequest()->getParam("controller");
$controller = $this->getRequest()->getControllerName();
Ideally you should use Zend_Navigation to do this though.
You should instead use Zend_Navigation as this is a built-in feature.
Edit: To answer your question about the null "controller" and "action" values; unless you have set these as view parameters from a controller or something else at the controller level (helper, plugin, etc), of course they will be empty.
I call an action helper in one of my views using the following code
echo $this->action('foo', 'bar');
The fooAction in the barController does its thing and outputs a list of pages. However, the list has the layout in the output again, which is mightily irritating. If I disable the layout in the fooAction, this causes layout to be completely disabled on the live side, as well.
I'm vexed. I could just create a view helper, and there are many ways around this, but out of curiousity I was wondering if anyone had a solution to this.
From the ZF Reference Guide on Action ViewHelper
The API for the Action view helper follows that of most MVC components that invoke controller actions: action($action, $controller, $module = null, array $params = array()). $action and $controller are required; if no module is specified, the default module is assumed.
Modify your controller to accept a param that controls whether the action should disable the layout. When using the action helper, pass this control flag.
On a sidenote: using the Action ViewHelper is considered bad practise as it will go through the entire dispatch process again and this will slow down your app. If possible, try to access the model directly.