Is there any way to set variables for the partial in the controller level?
Because everytime I need variables inside a partial I always have to pass them:
<?php
echo $this->partial('travels/_steps.phtml',
array('searchHotel' => $this->searchHotel,
'actionName' => $this->actionName))
?>
I would really just like actionName to be available on all partials - for instance.
You could extend the Zend_View_Helper_Partial class to a class that keeps that variable in scope. You would need to override the cloneView() function:
public function cloneView()
{
$view = parent::cloneView();
$view->actionName = $this->view->actionName
return $view;
}
You could use $this->render() instead. With it, you wouldn't need to pass the view variables every time.
Hope that helps,
You could also just sent the current view as a parameter to the partial:
<?php
echo $this->partial('travels/_steps.phtml', array('parentView' => $this));
Then, in the partial:
<?php
$view = $this->parentView;
echo $view->searchHotel, $view->actionName;
In my humble opinion, you're doing exactly what you're supposed to do - passing just those variables you'll need in the partial.
If this causes you pain, perhaps you might consider that you're using partials unnecessarily.
Or, put another way, if you want to have some variable available in all partials then perhaps the partial is not where you should be using those variables.
Maybe have a look at Placeholders and rethink how you go about rendering your views.
Related
I do not have full ZF2 stack but I rigged my mostly-non-ZF2 code to accept $this->partial() and ViewModel() methods.
I often find a situation where I have a tree of View Helper Partials, to where some distant-from-root child needs a variable someVar.
I manage that variable passing it through each partial from root to the child, even when the in-route partials have no need for it.
Is there a way to not have to manage the var?
Example
//controller.php
echo $this->partial('root.phtml', array('someVar' => $someVar));
//root.phtml
<?
//this variable-pass-through-only step is one I would like to eliminate.
//aka. here someVar is not itself used in root.phtml
//it is only passed onto the child view partial
//I want to eliminate this pass-through-only code.
echo $this->partial('child.phtml', array('someVar' => $this->someVar)):
?>
//child.phtml - leaf child
<?
//variable is actually used for display purpose
echo $this->someVar;
?>
I am open to answers that use non-partial construct, i.e. ViewModel, etc.
Note: when I remove the pass-through code, hoping there is some kind of global scope for vars, it is not the case - the variable does not pass onto the child leaf view partial. I am hoping there is some kind of a better approach in ZF2 for what I want to do.
Goal / Spirit of the Question
To be clear I am seeking a way to make some vars to be a "global" var that extends itself from root of partial/view to the leaf .phtml without pass-through code, or perhaps a different approach altogether to where I do not need to do this, and yet not clutter my code with pass-through vars
You can use nested ViewModel instances to replicate the functionality of the partial view helper. By having the objects independently created there is no need to pass all variables to each of them.
A simple example.
$main = new ViewModel(['var1' => 'xyz', 'var2' => 'xyz']);
$main->setTemplate('main.phtml');
$foo = new ViewModel(['baz' => 'bob']);
$foo->setTemplate('foo.phtml');
$bar = new ViewModel(['test' => 123]);
$bar->setTemplate('bar.phtml');
// foo.phtml should echo $this->barResultHtml
$foo->addChild($bar, 'barResultHtml');
// main.phtml should echo $this->fooResultHtml
$main->addChild($foo, 'fooResultHtml');
// You will need to set this up to render the view model.
$view = new Zend\View\View();
$view->setRenderer(...);
echo $view->render($main);
I have been trying to pass an array that is generated in view to controller.
Say, $abc=array(); How do I sent this array to controller, then process it and sent this array to another view?
Is it even feasible? Not getting any answer after googling! Please help.
I see no point to generate array from inside the view.
It depends how your framework passes the data between the layers.
For example the controller do pass the data to the View object.
I.e.
public function someMethodInController() {
$this->view->varName['arr_key'] = 'something';
}
But talking about view, it might not have a certain controller already instantiated (usually it's against the MVC paradigm)
So I see two major ways:
Instantiate a controller (I would not prefer this)
$controller = MyController();
$controller->abc = $abc;
Or use sessions. This way to transmit data is universal inbetween your domain, and does not care if you are using a certain pattern, or how do you transmit between layers.
$_SESSION['abc'] = $abc;
Once assigned, you can use it in the same session from each of your files.
I'm repeatedly having to include one variable when I display my views:
$this->load->view('login', array('logged_in' => $this->auth->is_logged_in()));
$this->load->view('somepage', array('logged_in' => $this->auth->is_logged_in()));
$this->load->view('anotherpage', array('logged_in' => $this->auth->is_logged_in()));
How can I include this one variable across all of my view outputs? Is there a simpler method than extending the templating class?
One simpler way would be to make the array into a variable, so you dont have to type it out all the time, e.g.
$params = array('logged_in' => $this->auth->is_logged_in());
$this->load->view('login', $params);
$this->load->view('somepage', $params);
$this->load->view('anotherpage', $params);
An alternative would be to create a Helper that returns whether a user is logged in. Helpers are globally available in your controllers and views. See http://codeigniter.com/user_guide/general/helpers.html and also
CodeIgniter: Create new helper?
how about using sessions?
$this->session->userdata($var);
or cookies
$this->input->cookie($var, TRUE);
thanks.
Great solution, Gordon! But, depending on the case, it's also possible to use the Most Simple Template Library.
Regards!
You can also access the class directly from within your view:
<?php if( $this->auth->is_logged_in() ): ?>
Hello!
<?php endif; ?>
It's not the greatest solution but I find it works well with user conditionals.
I've integrated GeoIP into my CakePHP. Now I have to call it from my view-file. I made in my controller such function:
function getCountry($ip)
{
$this->GeoIP->countryName($ip);
}
GeoIP is a included component.
When I wrote in my view globally something like this:
$this->GeoIP->countryName('8.8.8.8') it works well, but, as I remember, this is wrong for MCV architecture. So the right way is to call requestAction for my controller.
Here I have 2 problems: I have to do this in php function which is located in view-file:
// MyView.php:
<?php
function Foo()
{
$this->GeoIP->countryName(...);
}
?>
First mistake is that $this isn't available inside the function, the second one is how to call getCountry from my component and pass need ip address into $ip?
I've tried:
echo $this->requestAction('Monitoring/getCountry/8.8.8.8');
Monitoring is a controller name.
But this returns nothing without any errors. What's the right way and how to call this in function?
Something like this:
Layout -> View/Layouts/default.ctp (works on any other view/element or block)
<h1>My Website</h1>
<?php echo $this->element('GeoIP') ?>
Element -> View/Elements/GeoIP.ctp (use an element so you can cache it and don't request the controller every time)
<?php
$country = $this->requestAction(array('controller' => 'Monitoring', 'action' => 'ipToCountry'));
echo "You're from {$country}?";
?>
Controller -> Controller/MonitoringController.php
public function ipToCountry() {
// Only accessible via requestAction()
if (empty($this->request->params['requested']))
throw new ForbiddenException();
return $this->GeoIP->countryName('8.8.8.8');
}
One of the basic principles in MVC is that you must not use logic in your view files (except some conditions). In your controller you must set the value in the view and use it there.
I you absolutely need to call your method after all the logic in the controller, you can use the beforeRender() method in your controller and it will be called right before rendering. You can set your value from there.
I don't see why you'd like to call a controller function in the view, unless you have business logic in there. That should be moved in the controller.
Hope I helped!
Kohana (and probably other frameworks) allow you get a route and echo its URL, creating routes that are easy to maintain.
Contact
Is this OK to have in the view, or should I assign it to a variable, and then pass the view the variable?
Thanks
You aren't performing logic here. This is perfectly acceptable.
Of course your view code would be a bit cleaner if you created a variable in your controller, but this really is fine IMHO.
I find such a concatenation unnecessary. It seems url::base() going to be used in every link on the site. Why not to have a method to add it automatically? Something like Route::url("contact")
And usage of such a construct in the template is OK.
You can create a function or static method for generating urls:
public static function url($routename, array $params = NULL)
{
return url::base().Route::get($routename)->uri($params);
}