This question is a case in hand.
Let's imagine a website page that displays a filtered products list :
-
If I request
/products?foo=bar
in my browser, I get a full page wrapped in a layout, the layout contains a header with a form allowing to change search criterias. -
If I change
foo
value tobaz
and submit the form, it reloads dynamically the results (with a jQuery$.load()
, for example), calling/products?foo=baz
in Ajax. - If I enter the same criteria into my iPhone app, the app requests
/products?foo=bar
to the server, which replies with a json object.
All 3 calls refer to the same resource ("the products list", resource is intended as in REST resource), but all need different rendering.
- In the first case, I need a full HTML page (with layout)
- In the second case, I need a partial HTML page (without layout)
- In the third case, I need a plain json response
This rendering switch can be triggered by the headers X-Requested-With
(with or without layout) and Accept
(html/json).
In Phalcon, the given example could be implemented as :
class ProductsController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
// Build data
$products = Products::find(array(
'foo' => $this->request->get('foo')
));
// JSON is identified
if ($this->request->getBestAccept() == 'application/json')
{
// JSON rendering (case 3)
$this->response->setContentType('application/json');
$this->response->setJsonContent($products);
$this->view->disable();
return $this->response;
}
// Otherwise, defaults to HTML
else
{
// Passing data to the view
$this->view->products = $products;
// Ajax call is identified
if ($this->request->isAjax())
{
// Partial rendering (case 2)
$view->disableLevel(array(
View::LEVEL_LAYOUT => true,
View::LEVEL_MAIN_LAYOUT => true
));
}
// Defaults to normal rendering
else
{
// Layout rendering (case 1)
}
}
}
}
How could I implement this mechanism application-wide, rather than duplicate this behavior in every single action ?
Originally posted at https://stackoverflow.com/questions/23291132/switch-rendering-according-to-headers-application-wide