XML Views in CakePHP

Recently in a CakePHP app (2.x) I needed to return some XML from a Controller action, abnormally the manual was a little thin in this area and I just couldn't get it to return my specific view from an xml folder. This is what I had todo to get it running correctly.

First I opened up the app\Config\routes.php file and added the following line:

 * Parse XML Routes

This is inline with the manual and enables your Controller actions to start accepting the .xml postfix e.g. http://cakephp_app/controller/action.xml

Next up is to enable the RequestHandler component in your Controller like this:

public $components = array('RequestHandler');

Once that's done you have a few more methods at your disposal to start dealing with XML requests. First create a beforeFilter method in your Controller and add the following:

public function beforeFilter() {

    // Set XML
    if ($this->RequestHandler->isXml()) {

This changes the output type of the request so that XML is identified instead of the normal HTML. Head over to the manual for more info:

Once that's done create the action that you want to use and be sure to add in the respondAs & renderAs methods as the official documentation is a bit flakey with their use:

public function related() {
    // Only allow XML requests
    if (!$this->RequestHandler->isXml()) {
        throw new MethodNotAllowedException();

    // Set response as XML
    $this->RequestHandler->renderAs($this, 'xml');

Using those 2 methods as I was then able to create an xml folder in the corresponding View folder and inside that create my view file e.g. app\View\Uploads\xml\related.ctp

<?xml version="1.0"?>

Now if you visited the page in your browser you should see your XML output as per your View e.g. http://cakephp_app/uploads/related.xml

Wrapping Up

Further to this if you wanted to pass in some parameters to make the Controller action dynamic you can do by using the following e.g. http://cakephp_app/uploads/related/videos/1.xml

The "videos" parameter and the "1" ID will be available in the Controller like this:

// Get passed params
$uploadType = $this->request->params['pass'][0];
$uploadId = $this->request->params['pass'][1];

Hope this helps some people as I had some difficulty getting it all to work properly.

Posted on 7th February 2013
6 years, 2 weeks, 3 days ago

comments powered by Disqus