1``extends`` 2=========== 3 4The ``extends`` tag can be used to extend a template from another one. 5 6.. note:: 7 8 Like PHP, Twig does not support multiple inheritance. So you can only have 9 one extends tag called per rendering. However, Twig supports horizontal 10 :doc:`reuse<use>`. 11 12Let's define a base template, ``base.html``, which defines a simple HTML 13skeleton document: 14 15.. code-block:: html+twig 16 17 <!DOCTYPE html> 18 <html> 19 <head> 20 {% block head %} 21 <link rel="stylesheet" href="style.css"/> 22 <title>{% block title %}{% endblock %} - My Webpage</title> 23 {% endblock %} 24 </head> 25 <body> 26 <div id="content">{% block content %}{% endblock %}</div> 27 <div id="footer"> 28 {% block footer %} 29 © Copyright 2011 by <a href="http://domain.invalid/">you</a>. 30 {% endblock %} 31 </div> 32 </body> 33 </html> 34 35In this example, the :doc:`block<block>` tags define four blocks that child 36templates can fill in. 37 38All the ``block`` tag does is to tell the template engine that a child 39template may override those portions of the template. 40 41Child Template 42-------------- 43 44A child template might look like this: 45 46.. code-block:: html+twig 47 48 {% extends "base.html" %} 49 50 {% block title %}Index{% endblock %} 51 {% block head %} 52 {{ parent() }} 53 <style type="text/css"> 54 .important { color: #336699; } 55 </style> 56 {% endblock %} 57 {% block content %} 58 <h1>Index</h1> 59 <p class="important"> 60 Welcome on my awesome homepage. 61 </p> 62 {% endblock %} 63 64The ``extends`` tag is the key here. It tells the template engine that this 65template "extends" another template. When the template system evaluates this 66template, first it locates the parent. The extends tag should be the first tag 67in the template. 68 69Note that since the child template doesn't define the ``footer`` block, the 70value from the parent template is used instead. 71 72You can't define multiple ``block`` tags with the same name in the same 73template. This limitation exists because a block tag works in "both" 74directions. That is, a block tag doesn't just provide a hole to fill - it also 75defines the content that fills the hole in the *parent*. If there were two 76similarly-named ``block`` tags in a template, that template's parent wouldn't 77know which one of the blocks' content to use. 78 79If you want to print a block multiple times you can however use the 80``block`` function: 81 82.. code-block:: html+twig 83 84 <title>{% block title %}{% endblock %}</title> 85 <h1>{{ block('title') }}</h1> 86 {% block body %}{% endblock %} 87 88Parent Blocks 89------------- 90 91It's possible to render the contents of the parent block by using the 92:doc:`parent<../functions/parent>` function. This gives back the results of 93the parent block: 94 95.. code-block:: html+twig 96 97 {% block sidebar %} 98 <h3>Table Of Contents</h3> 99 ... 100 {{ parent() }} 101 {% endblock %} 102 103Named Block End-Tags 104-------------------- 105 106Twig allows you to put the name of the block after the end tag for better 107readability (the name after the ``endblock`` word must match the block name): 108 109.. code-block:: twig 110 111 {% block sidebar %} 112 {% block inner_sidebar %} 113 ... 114 {% endblock inner_sidebar %} 115 {% endblock sidebar %} 116 117Block Nesting and Scope 118----------------------- 119 120Blocks can be nested for more complex layouts. Per default, blocks have access 121to variables from outer scopes: 122 123.. code-block:: html+twig 124 125 {% for item in seq %} 126 <li>{% block loop_item %}{{ item }}{% endblock %}</li> 127 {% endfor %} 128 129Block Shortcuts 130--------------- 131 132For blocks with little content, it's possible to use a shortcut syntax. The 133following constructs do the same thing: 134 135.. code-block:: twig 136 137 {% block title %} 138 {{ page_title|title }} 139 {% endblock %} 140 141.. code-block:: twig 142 143 {% block title page_title|title %} 144 145Dynamic Inheritance 146------------------- 147 148Twig supports dynamic inheritance by using a variable as the base template: 149 150.. code-block:: twig 151 152 {% extends some_var %} 153 154If the variable evaluates to a ``\Twig\Template`` or a ``\Twig\TemplateWrapper`` 155instance, Twig will use it as the parent template:: 156 157 // {% extends layout %} 158 159 $layout = $twig->load('some_layout_template.twig'); 160 161 $twig->display('template.twig', ['layout' => $layout]); 162 163You can also provide a list of templates that are checked for existence. The 164first template that exists will be used as a parent: 165 166.. code-block:: twig 167 168 {% extends ['layout.html', 'base_layout.html'] %} 169 170Conditional Inheritance 171----------------------- 172 173As the template name for the parent can be any valid Twig expression, it's 174possible to make the inheritance mechanism conditional: 175 176.. code-block:: twig 177 178 {% extends standalone ? "minimum.html" : "base.html" %} 179 180In this example, the template will extend the "minimum.html" layout template 181if the ``standalone`` variable evaluates to ``true``, and "base.html" 182otherwise. 183 184How do blocks work? 185------------------- 186 187A block provides a way to change how a certain part of a template is rendered 188but it does not interfere in any way with the logic around it. 189 190Let's take the following example to illustrate how a block works and more 191importantly, how it does not work: 192 193.. code-block:: html+twig 194 195 {# base.twig #} 196 {% for post in posts %} 197 {% block post %} 198 <h1>{{ post.title }}</h1> 199 <p>{{ post.body }}</p> 200 {% endblock %} 201 {% endfor %} 202 203If you render this template, the result would be exactly the same with or 204without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way 205to make it overridable by a child template: 206 207.. code-block:: html+twig 208 209 {# child.twig #} 210 {% extends "base.twig" %} 211 212 {% block post %} 213 <article> 214 <header>{{ post.title }}</header> 215 <section>{{ post.text }}</section> 216 </article> 217 {% endblock %} 218 219Now, when rendering the child template, the loop is going to use the block 220defined in the child template instead of the one defined in the base one; the 221executed template is then equivalent to the following one: 222 223.. code-block:: html+twig 224 225 {% for post in posts %} 226 <article> 227 <header>{{ post.title }}</header> 228 <section>{{ post.text }}</section> 229 </article> 230 {% endfor %} 231 232Let's take another example: a block included within an ``if`` statement: 233 234.. code-block:: html+twig 235 236 {% if posts is empty %} 237 {% block head %} 238 {{ parent() }} 239 240 <meta name="robots" content="noindex, follow"> 241 {% endblock head %} 242 {% endif %} 243 244Contrary to what you might think, this template does not define a block 245conditionally; it just makes overridable by a child template the output of 246what will be rendered when the condition is ``true``. 247 248If you want the output to be displayed conditionally, use the following 249instead: 250 251.. code-block:: html+twig 252 253 {% block head %} 254 {{ parent() }} 255 256 {% if posts is empty %} 257 <meta name="robots" content="noindex, follow"> 258 {% endif %} 259 {% endblock head %} 260 261.. seealso:: 262 263 :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` 264