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?