PageRenderTime 124ms CodeModel.GetById 46ms RepoModel.GetById 1ms app.codeStats 0ms

/quick_tour/the_view.rst

https://github.com/dcsg/symfony-docs
ReStructuredText | 293 lines | 209 code | 84 blank | 0 comment | 0 complexity | 340bb763a7795033100a1f920bd01140 MD5 | raw file
  1. The View
  2. ========
  3. After reading the first part of this tutorial, you have decided that Symfony2
  4. was worth another 10 minutes. Great choice! In this second part, you will
  5. learn more about the Symfony2 template engine, `Twig`_. Twig is a flexible,
  6. fast, and secure template engine for PHP. It makes your templates more
  7. readable and concise; it also makes them more friendly for web designers.
  8. .. note::
  9. Instead of Twig, you can also use :doc:`PHP </cookbook/templating/PHP>`
  10. for your templates. Both template engines are supported by Symfony2.
  11. Getting familiar with Twig
  12. --------------------------
  13. .. tip::
  14. If you want to learn Twig, it's highly recommended you read its official
  15. `documentation`_. This section is just a quick overview of the main
  16. concepts.
  17. A Twig template is a text file that can generate any type of content (HTML,
  18. XML, CSV, LaTeX, ...). Twig defines two kinds of delimiters:
  19. * ``{{ ... }}``: Prints a variable or the result of an expression;
  20. * ``{% ... %}``: Controls the logic of the template; it is used to execute
  21. ``for`` loops and ``if`` statements, for example.
  22. Below is a minimal template that illustrates a few basics, using two variables
  23. ``page_title`` and ``navigation``, which would be passed into the template:
  24. .. code-block:: html+jinja
  25. <!DOCTYPE html>
  26. <html>
  27. <head>
  28. <title>My Webpage</title>
  29. </head>
  30. <body>
  31. <h1>{{ page_title }}</h1>
  32. <ul id="navigation">
  33. {% for item in navigation %}
  34. <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
  35. {% endfor %}
  36. </ul>
  37. </body>
  38. </html>
  39. .. tip::
  40. Comments can be included inside templates using the ``{# ... #}`` delimiter.
  41. To render a template in Symfony, use the ``render`` method from within a controller
  42. and pass it any variables needed in the template::
  43. $this->render('AcmeDemoBundle:Demo:hello.html.twig', array(
  44. 'name' => $name,
  45. ));
  46. Variables passed to a template can be strings, arrays, or even objects. Twig
  47. abstracts the difference between them and lets you access "attributes" of a
  48. variable with the dot (``.``) notation:
  49. .. code-block:: jinja
  50. {# array('name' => 'Fabien') #}
  51. {{ name }}
  52. {# array('user' => array('name' => 'Fabien')) #}
  53. {{ user.name }}
  54. {# force array lookup #}
  55. {{ user['name'] }}
  56. {# array('user' => new User('Fabien')) #}
  57. {{ user.name }}
  58. {{ user.getName }}
  59. {# force method name lookup #}
  60. {{ user.name() }}
  61. {{ user.getName() }}
  62. {# pass arguments to a method #}
  63. {{ user.date('Y-m-d') }}
  64. .. note::
  65. It's important to know that the curly braces are not part of the variable
  66. but the print statement. If you access variables inside tags don't put the
  67. braces around.
  68. Decorating Templates
  69. --------------------
  70. More often than not, templates in a project share common elements, like the
  71. well-known header and footer. In Symfony2, you think about this problem
  72. differently: a template can be decorated by another one. This works exactly
  73. the same as PHP classes: template inheritance allows you to build a base
  74. "layout" template that contains all the common elements of your site and
  75. defines "blocks" that child templates can override.
  76. The ``hello.html.twig`` template inherits from ``layout.html.twig``, thanks to
  77. the ``extends`` tag:
  78. .. code-block:: html+jinja
  79. {# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #}
  80. {% extends "AcmeDemoBundle::layout.html.twig" %}
  81. {% block title "Hello " ~ name %}
  82. {% block content %}
  83. <h1>Hello {{ name }}!</h1>
  84. {% endblock %}
  85. The ``AcmeDemoBundle::layout.html.twig`` notation sounds familiar, doesn't it?
  86. It is the same notation used to reference a regular template. The ``::`` part
  87. simply means that the controller element is empty, so the corresponding file
  88. is directly stored under the ``Resources/views/`` directory.
  89. Now, let's have a look at a simplified ``layout.html.twig``:
  90. .. code-block:: jinja
  91. {# src/Acme/DemoBundle/Resources/views/layout.html.twig #}
  92. <div class="symfony-content">
  93. {% block content %}
  94. {% endblock %}
  95. </div>
  96. The ``{% block %}`` tags define blocks that child templates can fill in. All
  97. the block tag does is to tell the template engine that a child template may
  98. override those portions of the template.
  99. In this example, the ``hello.html.twig`` template overrides the ``content``
  100. block, meaning that the "Hello Fabien" text is rendered inside the ``div.symfony-content``
  101. element.
  102. Using Tags, Filters, and Functions
  103. ----------------------------------
  104. One of the best feature of Twig is its extensibility via tags, filters, and
  105. functions. Symfony2 comes bundled with many of these built-in to ease the
  106. work of the template designer.
  107. Including other Templates
  108. ~~~~~~~~~~~~~~~~~~~~~~~~~
  109. The best way to share a snippet of code between several distinct templates is
  110. to create a new template that can then be included from other templates.
  111. Create an ``embedded.html.twig`` template:
  112. .. code-block:: jinja
  113. {# src/Acme/DemoBundle/Resources/views/Demo/embedded.html.twig #}
  114. Hello {{ name }}
  115. And change the ``index.html.twig`` template to include it:
  116. .. code-block:: jinja
  117. {# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #}
  118. {% extends "AcmeDemoBundle::layout.html.twig" %}
  119. {# override the body block from embedded.html.twig #}
  120. {% block content %}
  121. {{ include("AcmeDemoBundle:Demo:embedded.html.twig") }}
  122. {% endblock %}
  123. Embedding other Controllers
  124. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  125. And what if you want to embed the result of another controller in a template?
  126. That's very useful when working with Ajax, or when the embedded template needs
  127. some variable not available in the main template.
  128. Suppose you've created a ``fancyAction`` controller method, and you want to
  129. "render" it inside the ``index`` template, which means including the result
  130. (e.g. ``HTML``) of the controller. To do this, use the ``render`` function:
  131. .. code-block:: jinja
  132. {# src/Acme/DemoBundle/Resources/views/Demo/index.html.twig #}
  133. {{ render(controller("AcmeDemoBundle:Demo:fancy", {'name': name, 'color': 'green'})) }}
  134. Here, the ``AcmeDemoBundle:Demo:fancy`` string refers to the ``fancy`` action
  135. of the ``Demo`` controller. The arguments (``name`` and ``color``) act like
  136. simulated request variables (as if the ``fancyAction`` were handling a whole
  137. new request) and are made available to the controller::
  138. // src/Acme/DemoBundle/Controller/DemoController.php
  139. class DemoController extends Controller
  140. {
  141. public function fancyAction($name, $color)
  142. {
  143. // create some object, based on the $color variable
  144. $object = ...;
  145. return $this->render('AcmeDemoBundle:Demo:fancy.html.twig', array(
  146. 'name' => $name,
  147. 'object' => $object,
  148. ));
  149. }
  150. // ...
  151. }
  152. Creating Links between Pages
  153. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  154. Speaking of web applications, creating links between pages is a must. Instead
  155. of hardcoding URLs in templates, the ``path`` function knows how to generate
  156. URLs based on the routing configuration. That way, all your URLs can be easily
  157. updated by just changing the configuration:
  158. .. code-block:: html+jinja
  159. <a href="{{ path('_demo_hello', { 'name': 'Thomas' }) }}">Greet Thomas!</a>
  160. The ``path`` function takes the route name and an array of parameters as
  161. arguments. The route name is the main key under which routes are referenced
  162. and the parameters are the values of the placeholders defined in the route
  163. pattern::
  164. // src/Acme/DemoBundle/Controller/DemoController.php
  165. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  166. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  167. // ...
  168. /**
  169. * @Route("/hello/{name}", name="_demo_hello")
  170. * @Template()
  171. */
  172. public function helloAction($name)
  173. {
  174. return array('name' => $name);
  175. }
  176. .. tip::
  177. The ``url`` function generates *absolute* URLs: ``{{ url('_demo_hello', {
  178. 'name': 'Thomas'}) }}``.
  179. Including Assets: images, JavaScripts, and stylesheets
  180. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  181. What would the Internet be without images, JavaScripts, and stylesheets?
  182. Symfony2 provides the ``asset`` function to deal with them easily:
  183. .. code-block:: jinja
  184. <link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />
  185. <img src="{{ asset('images/logo.png') }}" />
  186. The ``asset`` function's main purpose is to make your application more portable.
  187. Thanks to this function, you can move the application root directory anywhere
  188. under your web root directory without changing anything in your template's
  189. code.
  190. Escaping Variables
  191. ------------------
  192. Twig is configured to automatically escape all output by default. Read Twig
  193. `documentation`_ to learn more about output escaping and the Escaper
  194. extension.
  195. Final Thoughts
  196. --------------
  197. Twig is simple yet powerful. Thanks to layouts, blocks, templates and action
  198. inclusions, it is very easy to organize your templates in a logical and
  199. extensible way. However, if you're not comfortable with Twig, you can always
  200. use PHP templates inside Symfony without any issues.
  201. You have only been working with Symfony2 for about 20 minutes, but you can
  202. already do pretty amazing stuff with it. That's the power of Symfony2. Learning
  203. the basics is easy, and you will soon learn that this simplicity is hidden
  204. under a very flexible architecture.
  205. But I'm getting ahead of myself. First, you need to learn more about the controller
  206. and that's exactly the topic of the :doc:`next part of this tutorial <the_controller>`.
  207. Ready for another 10 minutes with Symfony2?
  208. .. _Twig: http://twig.sensiolabs.org/
  209. .. _documentation: http://twig.sensiolabs.org/documentation