added a paragraph in the docs about how the Twig blocks work (based on an explanation...
authorFabien Potencier <fabien.potencier@gmail.com>
Tue, 30 Oct 2012 18:13:42 +0000 (19:13 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Tue, 30 Oct 2012 18:13:42 +0000 (19:13 +0100)
doc/tags/extends.rst

index 8d64436..f995a5d 100644 (file)
@@ -33,8 +33,10 @@ skeleton document:
     </html>
 
 In this example, the :doc:`block<block>` tags define four blocks that child
-templates can fill in. All the ``block`` tag does is to tell the template
-engine that a child template may override those portions of the template.
+templates can fill in.
+
+All the ``block`` tag does is to tell the template engine that a child
+template may override those portions of the template.
 
 Child Template
 --------------
@@ -184,4 +186,83 @@ In this example, the template will extend the "minimum.html" layout template
 if the ``standalone`` variable evaluates to ``true``, and "base.html"
 otherwise.
 
+How blocks work?
+----------------
+
+A block provides a way to change how a certain part of a template is rendered
+but it does not interfere in any way with the logic around it.
+
+Let's take the following example to illustrate how a block work and more
+importantly, how it does not work:
+
+.. code-block:: jinja
+
+    {# base.twig #}
+
+    {% for post in posts %}
+        {% block post %}
+            <h1>{{ post.title }}</h1>
+            <p>{{ post.body }}</p>
+        {% endblock %}
+    {% endfor %}
+
+If you render this template, the result would be exactly the same with or
+without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way
+to make it overridable by a child template:
+
+.. code-block:: jinja
+
+    {# child.twig #}
+
+    {% extends "base.twig" %}
+
+    {% block post %}
+        <article>
+            <header>{{ post.title }}</header>
+            <section>{{ post.text }}</section>
+        </article>
+    {% endblock %}
+
+Now, when rendering the child template, the loop is going to use the block
+defined in the child template instead of the one defined in the base one; the
+executed template is then equivalent to the following one:
+
+.. code-block:: jinja
+
+    {% for post in posts %}
+        <article>
+            <header>{{ post.title }}</header>
+            <section>{{ post.text }}</section>
+        </article>
+    {% endfor %}
+
+Let's take another example: a block included within an ``if`` statement:
+
+.. code-block:: jinja
+
+    {% if posts is empty %}
+        {% block head %}
+            {{ parent() }}
+
+            <meta name="robots" content="noindex, follow">
+        {% endblock head %}
+    {% endif %}
+
+Contrary to what you might think, this template does not define a block
+conditionally; it just makes overridable by a child template the output of
+what will be rendered when the condition is ``true``.
+
+If you want the output to be displayed conditionally, use the following
+instead:
+
+.. code-block:: jinja
+
+    {% block head %}
+        {{ parent() }}
+
+        {% if posts is empty %}
+            <meta name="robots" content="noindex, follow">
+        {% endif %}
+    {% endblock head %}
+
 .. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`