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" )
Related
I'm using laravel with controllers layout. But there are some parts of my app where I don't want to use a layout (for example, when returning data to the payment gateway request, for wich I send XML data). I just want to pass data to my view and render it alone, with no need for a layout.
How can I do that? I've been trying some approaches but none worked for this. I can successfuly change what layout to render, but I can't set to render the view without a layout.
Thanks!
Edit: Let me explain it better
My default layout is set in Base_Controller. Then all my controllers extends it but in one of them I need no layout, as I told above. Maybe I need to unset the default layout or something like that, I'm not sure.
You can simply return something from your controller action to bypass the layout.
function get_xml($id) {
$user = User::find($id);
return View::make('user.xml', $user);
}
On your controller functions, you can simply return a string, which will be thrown back to the browser as-is. Alternatively, you can craft a Laravel\Response object, which will allow you to fine-tune your site's output a lot more than just returning a string.
The Response class has a few tricks up its sleeve that are not mentioned on the docs: default return, JSON, forced download.
You're more interested in the first one, which will allow you to correctly set the content-type of the response to application/xml. In addition to this, you can still use views for XML! Generate the view as you would with View::make, but instead of directly returning it, store it in a variable. To render it, call render() on it - it will return the output.
A simple way....
suppose there is a main layout
<body>
#yield('content')
</body>
This content will be where the view will be inserted.
Now,
if you want to use layout, Make the view page like this:
#layout('main')
#section('content')
blah blah your content
#endsection
If you don't want to use layout, omit the codes above.
In controller, the code will be same for both the files.
return View::make('index');
I am just getting started with Laravel and working on porting a mess of a site to the framework.
One feature of the site is a dynamically added image in the header. I am using a common Blade template and was wondering if there is any way to inject a random variable (an integer between 1 and 4 would do) into every View that uses that layout.
What I would like to do is to be able to add something like so in the the common template-
<img src="img/cutouts/cutout-<?= $randomInt;?>.jpg" alt=""/>
with $randomInt sent to every View
You could look into View composers
So you would have something like:
View::composer('your.view', function($view)
{
$view->with('randomInt', rand(1,4));
}
That will pass the $randomInt variable in everytime you use the 'your.view' (or whatever) View.
It's also possible to add a variable to all views through View::share().
For example, you could modify the __construct method in Base_Controller with:
View::share('randomInt', rand(1,4));
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 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.
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.