Ok that's pretty cool, but I'm not sure it quite fits everything.

Areas where I'm uncertain:

   * Exceptions -- I assume that if one wanted to throw an exception
     and have it wrapped in a friendly manor it's not possible with a
     helper.
     It's always possible to wrap the ...Action() in a try {} catch
     block and fill the view appropriately.
   * Debugging -- The only way to trigger this behavior is via
     XMLHttpRequest, thus making it hard to debug the response (e.g.
     debug with print_r).  Ok, you could easily add a getParam('_json')
     that forces the behavior, but feels a little funky -- see "over use".
   * Over Use - This feels like it makes an application open to some
     form of abuse where anybody who "fakes" an XMLHttpRequest has
     access to your raw view data.  Since it could be regulated on a
     per-action basis with selective use of view scripts, the real case
     is with _everything_ serializing out in JSON that the typical case
     (as you mentioned) is to have the helper run everything into a
     single view script -- thus making all of your pages accessible.

Thanks,
--koblas

Matthew Weier O'Phinney wrote:
-- David Koblas <[EMAIL PROTECTED]> wrote
(on Monday, 06 August 2007, 07:30 AM -0700):
In past projects I've had a whole separate controller pattern for AJAX returns, where for a response I could return a PHP array and it would be serialized out as JSON (or XML) depending on the caller's requirements. Including appropriate handlers for exceptions returning error AJAX/XML responses.

Similar to:
   class LoginController extends ApiController {
      ...
      function loginAction() {
         ... get parameters ..
         ... throw exceptions ...
         ... return ok response ...
      }
   }

Now in terms of the Zend Framework I've played with putting JSON response objects in the standard controllers, side-by-side with the normal HTML responses, but then I've got big boiler plate around turning off ViewRenderer and getting parameters. So, it's clear that I need to move them out to their own world... But, David's question did make me stop and think, what is the "better" way to do this.

1) Should I subclass Zend_Controller_Action replacing either dispatch(...) or run(...) 2) Stuff everything into the view object and write a plugin (similar to view render) 3) Force all rendering through a specific view render script -- this doesn't handle exceptions.
4) Continue with fat boilerplate around my action helpers
5) Find some parameters to the viewHelper to take over the rendering of JSON / XML

Other ideas?

Yep. :-)

The request object has a method, isXmlHttpRequest(), that checks for the
'X-Requested-With: XMLHttpRequest' header that many (most?) AJAX
libraries send. Create a helper that modifies the ViewRenderer to render
a different view script when this is detected:

    class My_Helper_AjaxView extends Zend_Controller_Action_Helper_Abstract
    {
        public function preDispatch()
        {
            $this->checkForAjax();
        }

        public function checkForAjax()
        {
            // Change the view script suffix to '.json.php' if XHR
            // detected:
            if ($this->getRequest()->isXmlHttpRequest()) {
                $viewRenderer = 
Zend_Controller_Action_HelperBroker::getExistingHelper('viewRenderer');
                $viewRenderer->setViewSuffix('json.php');
            }
        }
    }

Register this in your bootstrap so that preDispatch() can be triggered
by any controller. This would modify the ViewRenderer to use the
file suffix '.json.php' when an XHR is detected. You could use other
strategies as well, such as having a specific view script render any
time an XHR is detected; this would be useful, for instance, if you
basically just want to serialize any assigned variables as JSON to
return to your calling script:

    <? // view script ?>
    <?= Zend_Json::encode(get_object_vars($this)) ?>

Hope that makes sense.


David Mintz wrote:
Greetings all.

I am wondering about when it's appropriate to use/write a plugin versus a controller Action Helper. It would seem that the plugin is more general -- error handling, or the two-step view thing -- whereas the action helper is somewhat more specific. Yes? But if it's something like authentication, which approach is preferable? Or is the answer "it depends," as is so often the case?

Reply via email to