Skip to content

Zend Framework content negotiation plugin

2010 July 10
by Richard Knop

Even though most designers write nice and valid XHTML it usually gets served to browser as text/html. In other words, what browser sees is a chaotic tag soup instead of XML (remember that while HTML was based on SGML, XHTML is based on XML or it is a reformulation of HTML in XML). The major reason why XHTML pages are getting served as text/html is infamous Internet Explorer which does not support serving XHTML the correct way (as XML). But why should your website suffer because of one browser? You can serve the tag soup to IE and serve XML to other browsers. This is called content negotiation and I’m going to show you a simple Zend Fraemwork controller plugin that will negotiate different content to different browsers:

  1. class My_Controller_Plugin_NegotiateContent extends Zend_Controller_Plugin_Abstract
  2. {
  3.     public function preDispatch(Zend_Controller_Request_Abstract $request)
  4.     {
  5.         $viewRenderer = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer');
  6.         $viewRenderer->initView();
  7.         $view = $viewRenderer->view;
  8.  
  9.         // content negotiation
  10.         header('Vary: Accept');
  11.         if (false === stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml')) {
  12.  
  13.             header('Content-Type: text/html; charset=utf-8');
  14.             $view->doctype('HTML4_STRICT');
  15.             $view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8');
  16.             $view->xhtmlAllowed = false;
  17.  
  18.        } else {
  19.  
  20.            header('Content-Type: application/xhtml+xml; charset=utf-8');
  21.            $view->doctype('XHTML1_STRICT');
  22.            $view->headMeta()->appendHttpEquiv('Content-Type', 'application/xhtml+xml; charset=UTF-8');
  23.            $view->xhtmlAllowed = true;
  24.        }
  25.     }
  26. }

This plugin will serve HTML 4.01 Strict as text/html to IE and XHTML 1.0 Strict as application/xhtml+xml to other browsers.

The only thing you need to do is to register the plugin to the front controller during bootstrapping:

  1. $frontController->registerPlugin(new My_Controller_Plugin_NegotiateContent());

And it will take care of content negotiation. The plugin will also set a boolean view variable $view->xhtmlAllowed so you can use different markups in layouts and views if needed (<img> in HTML and <img /> in XHTML).

One Response leave one →
  1. simukti permalink
    July 29, 2010

    nice post, i’ve been looking for this for my meta generator plugin.
    thank you for sharing.

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS