I think I can't see the tree in the wood.
I'm using Zend Framework, with an layout.phtml which is rendering and partial
<?php echo $this->partial('_header.phtml') ?>
My goal is to render an form from my IndexController into the "_header.phtml" with
<?php echo $this->form; ?>
How can I pass the form to the partial view?
View partials are rendered with a clean variable scope... That is, they do not inherit view variables from the calling Zend_View instance.
There's a few options available to you here:
One, simply call:
echo $this->render('_header.phtml');
instead of using a partial. This file will have access to all your view variables, so you can just assign the form to your view in your controller, like anything else.
Another way is to explicitly pass your form as a variable to the partial, like so:
echo $this->partial('_header.phtml', array('form' => $this->form));
// $this->form inside your partial will be your form
Your other option is to either use placeholders, or layout response segments. Here's an example of placeholders:
In your _header.phtml, or layout... where ever you want the form to render:
<?php echo $this->placeholder('header'); ?>
And in your controller:
$this->view->placeholder('header')->append($form);
// I'm not sure, but you _may_ want to pass in $form->render() here.
// I can't remember if implode() (which is used in placeholders internally)
// will trigger the __toString() method of an object.
This has the added bonus of not polluting your view instance with one-off variables, like the form.
Note: I'll link to the manual pages as soon as the ZF site is back up; 1.9 launch is today, so the site's getting updated currently.
Here's some relevant manual pages:
Placeholder view helper
Partial view helper
Related
In the past I've used a proprietary framework that kinda followed an Objective-C like View Controller scheme.
Basically I was able to in one controller instantiate another and pass it some values like an array of products and then inject the reference to the controller to my view and render it whenever I wanted by issuing: $controllerReference->render();
This could be useful in many cases, eg. if I had a controller responsible for rendering a catalog, I would just pass it an array with all the items I would like to see and it would take take of pagination and displaying the items by itself...
Example:
At \UI\Homepage\Controller.php (the controller responsible for the homepage):
// Instantiate a ProductDisplay Controller
$controllRef = new \UI\ProductDisplay\Controller();
$controllRef->setProducts( ... ); // Inject the product array
// Load the current view for this controller and pass it a reference for the ProductDisplay controller
$this->loadSelfView(["controllRef" => $controllRef]);
At \UI\Homepage\View.php (the view loaded before):
// some html of the view
$controllRef->render(); // Render the ProductDisplay view here!
// some other html
How should this functionality be accomplished in Laravel? From what I've been reading Laravel tries to avoid this kind of actions, why? What are the workarounds?
Thank you.
Here is how I will do this, it only work if the called controller method return a View object like return view('home');):
// Get the controller class from the IOC container
$myController= \App::make(MyController::class);
// Execute the controller method (which return a View object)
$view = $myController->myControllerMethod($someParams);
// Return the View html content
$html = $view->render();
you can use the Controller.php class which is extended by all other controller to make a generic method in it to:
Get a controller instance
Call the right method with x parameters
Return the rendered content if it's a view class OR throw an exception (for exemple)
In recent versions of Laravel, it's possible to use Blade's #inject directive. It seems its main purpose is to inject services but I successfully injected controller actions.
Here is a snippet on what you have to do:
#inject('productController', 'App\Http\Controllers\ProductController')
{!! $productController->index() !!}
Just remember: since you're calling the controller method directly, and not through the router, you'll have to pass all required params. If that action requires a request instance, you may call it this way:
{!! $productController->index(request()) !!}
Probably the view returned by the called action contains HTML code. It's important to wrap the method call within {!! and !!}. Using regular {{ }} tags will cause the HTML code be escaped by the template engine.
I have created my own view helper according to this example. The view helper calls my model to create a form. The view Helper returns a form object.
My question is wether it is possible to assign a custom view script to the View Helper for the form. Or should i just use a partial for the script?
Thanks very much
View helpers should be used to help construct HTML that requires anything more that the normal control logic, the <?php if ($foo) : and <? foreach($foo....
You will want to avoid cases where you view logic becomes too complex or repetitive, as this results in hard to maintain code.
The example you posted, a <span> tag is returned based on the the number of days ($numberOfDays) arguments passed to it. This is something that is most likely repetitive to check every time you wish to output the 'new' item, hence the need for a view helper.
In your case, what would be ideal, would be to fetch the form via the FormElementManager from within the controller.
class FooController {
function someAction() {
$serviceManager = $this-getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
$myForm = $formElementManager->get('My\Form\Class\Name\Or\Alias');
return new \Zend\View\Model\Model(array(
'form' => $myForm
);
}
}
Calling the form from the FormElementManager will ensure its dependencies are correctly injected and init() called.
In the view you would then render the form using Zend's built in ViewHelpers (Like FormRow taking our complex form object and return all the required HTML)
With the above in place the need for you to 'assign view scripts to the form' disappears as the form can be injected, via the controller, into any view script.
I've got a partial that I'm using in a Symfony 1.4 admin generated module but I have some logic that I would prefer to keep in my action. Is there anyway to access action vars in the partial? In a regular template (ie: non admin generated), I could simply declare my var in my action as $this->myVar and then access it from within my template as $myVar, but is there any way to do this in an admin partial?
I've tried declaring it in my preExecute() method but the var is undefined in my partial template.
Am I doing something wrong, or is my only choice to use a component instead of a partial?
Partials and components don't have automatic access to action variables. They only see variables which are explicitly passed to them. In an admin generator module they usually get some useful parameters (e.g. the current object, helper object, configuration, form) but it depends on the current place of invocation (you can see the generated templates in the cache directory to find out which parameters they get). Partials also have access some global objects (e.g. request, user, response,...) which are available in every template file. You can use e.g. request attributes or slots:
// in an action
$this->getResponse()->setSlot('my_slot', $myVariable);
// in a partial
<?php include_slot('my_slot'); ?>
// or
<?php $my_variable = get_slot('my_slot'); ?>
But I think using a component is a better idea.
When you call this partial try to put the variable as a second parameter (or array of parameters) in the include_partial().
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 Entry controller with index action that lists all entries, and of course views/scripts/index.phtml. I also have the main page index/index.phtml. How can I include entry/index.phtml in index/index.phtml so I can see the results of entries as part of the structure of the home page?
try something like this towards the end of your indexAction() in the index controller:
$this->_helper->actionStack('index', 'entry');
Alternatively, I think you may be able to to do think in the index/index.phtml script:
<?php echo $this->action('index', 'entry');?>
First example is the actionStack action helper the second is the action view helper
Good luck!
You may create view helper for this, in which you:
retrieve the data (e.g. from database)
pass the data to the view
render the view you need ($this->view->render('pathoto/scriptname.phtml')). You may also add script path using addScriptPath().
Then use this helper in those two scripts you need.
If AJAX it the root of your needs, take a look at actionContext and ajaxContext action helpers.
http://framework.zend.com/manual/en/zend.controller.actionhelpers.html