diff --git a/templating/formats.rst b/templating/formats.rst index faad3e55c9f..2c9ec990e27 100644 --- a/templating/formats.rst +++ b/templating/formats.rst @@ -4,7 +4,7 @@ How to Work with Different Output Formats in Templates ====================================================== -Templates are a generic way to render content in *any* format. And while in +Templates are a generic way to render content in *any* format. While in most cases you'll use templates to render HTML content, a template can just as easily generate JavaScript, CSS, XML or any other format you can dream of. @@ -12,8 +12,8 @@ For example, the same "resource" is often rendered in several formats. To render an article index page in XML, simply include the format in the template name: -* *XML template name*: ``article/index.xml.twig`` -* *XML template filename*: ``index.xml.twig`` +* *XML template name*: ``article/show.xml.twig`` +* *XML template filename*: ``show.xml.twig`` In reality, this is nothing more than a naming convention and the template isn't actually rendered differently based on its format. @@ -22,36 +22,71 @@ In many cases, you may want to allow a single controller to render multiple different formats based on the "request format". For that reason, a common pattern is to do the following:: - public function indexAction(Request $request) + // ... + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; + + class ArticleController extends Controller { - $format = $request->getRequestFormat(); + /** + * @Route("/{slug}") + */ + public function showAction(Request $request, $slug) + { + // retrieve the article based on $slug + $article = ...; + + $format = $request->getRequestFormat(); - return $this->render('article/index.'.$format.'.twig'); + return $this->render('article/show.'.$format.'.twig', array( + 'article' => $article, + )); + } } The ``getRequestFormat()`` on the ``Request`` object defaults to ``html``, but can return any other format based on the format requested by the user. The request format is most often managed by the routing, where a route can -be configured so that ``/contact`` sets the request format to ``html`` while -``/contact.xml`` sets the format to ``xml``. For more information, see this -:ref:`Advanced Routing Example `. +be configured so that ``/about-us`` sets the request format to ``html`` while +``/about-us.xml`` sets the format to ``xml``. This can be achieved by using the +special ``_format`` placeholder in your route definition:: + + /** + * @Route("/{slug}.{_format}", defaults={"_format": "html"}) + */ + public function showAction(Request $request, $slug) + { + // ... + } -To create links that include the format parameter, include a ``_format`` -key in the parameter hash: +Now, include the ``_format`` placeholder when generating a route for another +format: .. configuration-block:: .. code-block:: html+twig - - PDF Version + + View as XML .. code-block:: html+php - PDF Version + View as XML + +.. seealso:: + + For more information, see this :ref:`Advanced Routing Example `. + +.. tip:: + + When building APIs, using file name extensions often isn't the best + solution. The FOSRestBundle provides a request listener that uses content + negotiation. For more information, check out the bundle's `Request Format Listener`_ + documentation. + +.. _Request Format Listener: http://symfony.com/doc/current/bundles/FOSRestBundle/3-listener-support.html#format-listener