Example:
The base template:
base.html
Code: Select all
<!DOCTYPE html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}Base content{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2011 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>
child.html
Code: Select all
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ parent() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}
Code: Select all
!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<title>Index - My Webpage</title>
<style type="text/css">
.important { color: #336699; }
</style>
</head>
<body>
<div id="content"> <h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p></div>
<div id="footer">=
© Copyright 2011 by <a href="http://domain.invalid/">you</a>.=
</div>
</body>
</html>
But it's not the only way to use the blocks because at any time we can request Twig to render a specific block in a given template but to send this request we need to have the Template element himself and that is currently not possible. It can be useful to define many different blocks for a set of module (ie: menu, toolbar, content, footer...) and then render each block of each module in different places in the code.
Example:
Code: Select all
[...]
{% for template in templates %}
{{ template.renderBlock('menu', {<arguments>}) }}
{% endfor %}
[...]
{% for template in templates %}
{{ template.renderBlock('footer', {<arguments>}) }}
{% endfor %}
[...]
- Define one template file per block and include them
Code: Select all
[...] {% for module_name in modules %} {% include module_name ~ '_menu.html' %} {% endfor %} [...] {% for module_name in modules %} {% include module_name ~ '_footer.html' %} {% endfor %} [...]
- Define a variable in the base template and use a combination of if in the included template
Base templateIncluded templateCode: Select all
[...] {% for template_path in templates %} {% include template_path with { 'in_menu': true } %} {% endfor %} [...] {% for template_path in templates %} {% include template_path with { 'in_footer': true } %} {% endfor %} [...]
Code: Select all
{% if in_menu %} MENU {% endif %} {% if in_footer %} FOOTER {% endif %}
- Now we are using Twig and \phpbb\template\template is only a BC interface => the template engine can extends \Twig_Environment and implements the interface
- \phpbb\template\template is a generic interface which allows us to change the template engine without changing all the code, only the templates could have to be updated => we can provide a get_engine() method to get the real template engine but in this case we can return anything and the user has to manage with (he has to test which engine is returned and then generate an appropriate code)
personally, after some thought,i don't think that we should support this feature but in the other case we should use the first solution (extend \Twig_Environment)