Template reuse: inheritance and template functions¶
Inheritance¶
The layout template should be marked up with <py:block> tags to indicate customization points:
<!DOCTYPE html>
<html>
<head>
<title py:block="title">Default title</title>
</head>
<body>
<py:block name="content">
Content goes here
</py:block>
</body>
</html>
Child templates then use <py:extends href="...">
to pull in the parent’s
layout.
Template functions¶
You can also define reusable template functions:
<!--! File: widgets.html
-->
<py:def function="modal(content, title='hello')">
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" data-dismiss="modal">X</button>
<h4 class="modal-title">$title</h4>
</div>
<div class="modal-body">
${content() if callable(content) else content}
</div>
<div class="modal-footer">
<button type="button">Close</button>
<button type="button">Save changes</button>
</div>
</div>
</div>
</div>
</py:def>
Template functions can be imported into other templates:
<py:import href="widgets.html" alias="widgets"/>
<p>
${widgets.modal(content="Hello world!")}
</p>
Notice the ${content() if callable content else content}
interpolation in the function body?
That’s to support calling the function with py:call,
which can pass chunks of template code as keyword arguments. In this case the
passed argument will be a callable, which outputs template content.
<py:call function="widgets.modal(fullpage=True)">
<py:keyword name="content">
This is the modal content.
You can include <a href="#">markup</a>
<py:if test="True">and template directives</py:if> too!
</py:keyword>
</py:call>