-- Arthur M. Kang <[EMAIL PROTECTED]> wrote
(on Wednesday, 27 February 2008, 05:35 PM -0800):
> Can anybody help me understand the way the partials view helper was designed
> and how it works?  My tests are showing results that are not intuitive. 
> Perhaps my setup is incorrect, or my usage is.  If anyone could help or help 
> me
> understand the workings, that would be GREAT!
> 
> Setup:
> Simple test setup using module structure
> modules/
>   default/
>     controllers/
>       VtestController.php
>     views/
>     scripts/
>       vtest/
>         index.phtml
>         test1.phtml
>         partials/
>           test2.phtml
> 
> VtestController.php:
> public function indexAction() {}
> 
> index.phtml:
> Hello
> 
> test1.phtml:
> Test 1
> 
> partials/test2.phtml
> Test 2
> 
> Starting Setup : works (Hello)
> 
>   • VtestController - $this->render('test1') : works (Test 1)
>   • VtestController - $this->render('test1.phtml') : fails script 'vtest/
>     test1-phtml.phtml' not found in path (/directory/modules/default/views/
>     scripts/)

render() takes an action name -- it then appends the suffix and prepends
the controller directory. The above is expected behaviour.

>   • VtestController - $this->render('partials/test2') : works (Test 2)
>   • VtestController - $this->render('partials/test2.phtml') : fails script
>     'vtest/partials/test2-phtml.phtml' not found in path (/directory/modules/
>     default/views/scripts/)

Again, the ViewRenderer expects an action. You can specifically request
a script with the following:

    $this->_helper->viewRenderer->renderScript('vtest/partials/test2.phtml');

BTW, render() in the action controllers actually proxies to the
ViewRenderer's render() method, which resolves the action to a view
script, and then renders it using Zend_View::render(). If you want to
use partials, you will need to call the partial() helper on the view
object itself (which is registered as the view property of the
controller):

    $content = $this->view->partial('vtest/partials/test2.phtml');

> Ok...  So far so good.  From inside the action controller, rendering works
> without passing the extension and subdirectories are ok.  Right?

Correct, as explained above.

> Now, back to a blank VtestController and playing around with the partials view
> helper.
> 
>   • index.phtml = 'Hello <?=$this->partial('test1')?>' : fails script 'test1'
>     not found in path (/directory/modules/default/views/scripts/)
>   • index.phtml = 'Hello <?=$this->partial('test1.phtml')?>' : fails script
>     'test1.phtml' not found in path 
> (/directory/modules/default/views/scripts/)
>   • index.phtml = 'Hello <?=$this->partial('vtest/test1.phtml')?>' : works 
>     (Hello. Test 1)

Expected behavior. The view object does not have the same logic
regarding script lookup as the ViewRenderer does, so you need to do a
path and script name (including suffix) based on a script path
registered with the view object. This is why the first two fail, and the
third works.

We may add inflection as is found in the ViewRenderer (the portion that
prepends the controller directory and appends the suffix) into the 1.6
series.

>   • index.phtml = 'Hello <?=$this->partial('vtest/test1')?>' : fails script
>     'vtest/test1' not found in path 
> (/directory/modules/default/views/scripts/)

Again, need the suffix. But you appear to have answered your own
questions below...

>   • index.phtml = 'Hello <?=$this->partial('partials/test2')?>' : fails script
>     'partials/test2' not found in path (/directory/modules/default/views/
>     scripts/)
>   • index.phtml = 'Hello <?=$this->partial('partials/test2.phtml')?>' : fails 
>     script 'partials/test2.phtml' not found in path 
> (/directory/modules/default
>     /views/scripts/)
>   • index.phtml = 'Hello <?=$this->partial('vtest/partials/test2.phtml')?>' :
>     works (Hello. Test 2)
>   • index.phtml = 'Hello <?=$this->partial('vtest/partials/test2')?>' : fails 
>     script 'vtest/partials/test2' not found in path 
> (/directory/modules/default
>     /views/scripts/)
> 
> Ok.  So, if partials are used, you have to include the controller name and
> include the extension.  Right?

Correct. Same as if you call render() within a view script.

> Now, I'll try to get partial test1 to include partial test2.
> 
>   • index.phtml = 'Hello <?=$this->partial('vtest/test1.phtml')?>' -
>     test1.phtml = 'Test 1 <?=$this->partial('vtest/partials/test2.phtml')?>' :
>     works (Hello. Test 1 Test 2)
> 
> And I'm sure you can imagine all of the other iterations that will fail.
> 
> I know I can extend the include path and/or use __FILE__ for a relative
> starting position for the partial, but wouldn't it make sense for that to be
> the default?  Also, shouldn't the extension be automatically appended, like
> when using render inside of an action controller?

So, a little history is needed here.

Zend_View came first. It allowed the ability to register helper, filter,
and script paths. Its render() method requires a script name (including
suffix and any path information) relative to a registered script path.
Zend_View itself is a standalone component, and can be used with or
without Zend_Controller; there's no coupling whatsoever.

Later, just prior to the 1.0.0 release, we added the ViewRenderer. This
component (an action helper, actually) provides integration between the
action controllers and view object. Basically, it simplifies and
automates calling views; by default, without ever calling render(), it
will render a view named after the current action in a directory named
after the current controller. We wanted to make it relatively simple to
map actions to their views.

The problem we're now seeing, as you have detailed so well, is that this
is really nice at the controller level, but now makes things really
inconsistent when it gets down to the views -- there's different
conventions for when you're in the views themselves than when you're in
the controllers.

Now that we've added partials into the mix, those issues get a bit
compounded.

This should be fairly easy to resolve for 1.6; I've added an issue if
you want to track it: http://framework.zend.com/issues/browse/ZF-2745

-- 
Matthew Weier O'Phinney
PHP Developer            | [EMAIL PROTECTED]
Zend - The PHP Company   | http://www.zend.com/

Reply via email to