I am trying to build a piece of application using cakephp; which will generate output in multiple formats (xml, json, custom, html).
Based on certain property, output format will be decided. What I want is, if html is output ype; then I want application to render view as usual (Regular Controller->render); else data should be rendered in other formats
Here is what I am trying to do. I have overridden function render in AppController.php as following -
public function render($view = null, $layout = null) {
if ($this->rType == "json") {
$this->_renderJson();
} else if ($this->rType == "xml") {
$this->_renderXml();
} else if ($this->rType == "custom") {
$this->_renderCustom();
} else {
parent::render($view,$layout);
}
}
This works perfectly with other formats but html.
I want call should be forwarded to Controller::render as normal cakephp flow would do. Instead it gives me below error
Error: Call to a member function send() on a non-object File: /xx/lib/Cake/Routing/Dispatcher.php Line: 174
Any thoughts - how can I resolve this ?
When overwriting things you must make sure that your overriden method matches the original implementation with regards to the arguments that it takes and values that it returns.
Your render()
method lacks the proper return value, which should be an instance of CakeResponse
, which is used later on by the dispatcher.
https://github.com/cakephp/cakephp/blob/2.6.0/lib/Cake/Controller/Controller.php#L930
https://github.com/cakephp/cakephp/blob/2.6.0/lib/Cake/Routing/Dispatcher.php#L174
So, change your custom rendering methods to return $this->response
, and add appropriate returns in the overwritten render()
method:
public function render($view = null, $layout = null) {
if ($this->rType == "json") {
return $this->_renderJson();
} else if ($this->rType == "xml") {
return $this->_renderXml();
} else if ($this->rType == "custom") {
return $this->_renderCustom();
} else {
return parent::render($view,$layout);
}
}
Adding return to the Controller::render() statement did the trick indeed as told by ndm. Also, one more work around I found was to use beforeRender().
public function beforeRender(){
parent::beforeRender();
if ($this->rType == "json") {
$this->_renderJson();
return false;
} else if ($this->rType == "xml") {
$this->_renderXml();
return false;
} else if ($this->rType == "custom") {
$this->_renderCustom();
return false;
}
return true;
}
This worked as well....
thanks.