Code snippets for symfony 1.x


Snippets by user Rick Beton

Sending application/xhtml+xml

All web browsers support the 'text/html' content type. However, since the introduction of XHTML, a new content type has been available that brings the benefits of XML, which is 'application/xhtml+xml' (more info, why do this)

Although not all browsers support 'application/xhtml+xml', fortunately, the designers of the HTTP protocol provided a good solution: the browser tells the server what content types it can accept and which it prefers. So the server is able to choose which content type to serve.

Firefox is one of the browsers that supports 'application/xhtml+xml' and with the new Firefox3 comes incremental rendering, which means that it has fixed the earlier disadvantage in Firefox2 that 'text/html' was faster to render (more info).

The most noticeable advantage of XHTML rendering is that errors are displayed by the browser, meaning that it's easier to identify and fix layout problems caused by muddled content. If your content is ill-formed, Firefox displays a yellow error page indicating where the error was located. This can be a most useful development tool.

So how can we serve 'application/xhtml+xml' content?

  1. Your content has to be written to be XHTML instead of HTML (the W3C website provides helpful information in explaining how to do this). Your pages must include the correct DOCTYPE (how to do this).

  2. Your application has to change the content-type header depending on whether the browser can accept XHTML or not. Obviously, it's useless to send 'application/xhtml+xml' to older browsers that don't support it.

This snippet helps with the second issue. I have written a filter (shown below) to change the response headers depending on what each browser is able to handle.

Create a new class in your lib folder called XHTMLFilter.class.php thus:

class XHTMLFilter extends sfFilter
  public function execute ($filterChain)
    $applyIn = $this->getParameter('environments', array('dev'));
    if (!is_array($applyIn))
      throw new sfException("XHTMLFilter param: not an array ".print_r($applyIn, true));
    if (in_array( SF_ENVIRONMENT, $applyIn ))
      $accept = $this->context->getRequest()->getAcceptableContentTypes();
      if (in_array('application/xhtml+xml', $accept))
        $this->context->getResponse()->setContentType( 'application/xhtml+xml' );

Now add it to your app/config/filters.yml:

rendering: ~
web_debug: ~
security:  ~
  class: XHTMLFilter
    environments:    [ dev ]
cache:     ~
common:    ~
flash:     ~
execution: ~

There is one configuration parameter (environments) that contains an array of the environments to which the filter will apply. By default, only the 'dev' environment is included but you can add any or all of your environments here.

by Rick Beton on 2008-05-25, tagged contenttype  filter  header  xhtml  xml