-
Notifications
You must be signed in to change notification settings - Fork 0
Parent Function
The parent()
function in Twig allows child templates to access and render the content of the same block from their parent template. This is particularly useful when you want to extend content from the parent template rather than completely replacing it.
When using template inheritance with the extends
tag, you can use the parent()
function within a block to include the content of the same block from the parent template:
{# base.twig #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Website{% endblock %}</title>
{% block stylesheets %}
<link rel="stylesheet" href="/css/main.css">
{% endblock %}
</head>
<body>
<header>{% block header %}Default Header Content{% endblock %}</header>
<main>{% block content %}Default Content{% endblock %}</main>
<footer>{% block footer %}© 2025 My Website{% endblock %}</footer>
</body>
</html>
{# child.twig #}
{% extends "base.twig" %}
{% block title %}Page Title - {{ parent() }}{% endblock %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="/css/page.css">
{% endblock %}
{% block header %}
<h1>Welcome to My Page</h1>
{{ parent() }}
{% endblock %}
{% block content %}
<p>This is the child content that completely replaces the parent content.</p>
{% endblock %}
When child.twig
is rendered, the output will be:
-
<title>Page Title - My Website</title>
- Combines the child's content with the parent's - Stylesheets will include both main.css (from parent) and page.css (from child)
- Header will contain the child's h1 element followed by the parent's "Default Header Content"
- Content block will only show the child's content, completely replacing the parent's
One of the most common uses is to extend the stylesheets or scripts blocks:
{# base.twig #}
{% block stylesheets %}
<link rel="stylesheet" href="/css/main.css">
{% endblock %}
{% block javascripts %}
<script src="/js/main.js"></script>
{% endblock %}
{# child.twig #}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="/css/child.css">
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="/js/child.js"></script>
{% endblock %}
This pattern ensures that the child template includes all the required base styles and scripts while adding its own.
Another common use is to enhance the header or footer without duplicating content:
{# base.twig #}
{% block header %}
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
{% endblock %}
{# child.twig #}
{% block header %}
{{ parent() }}
<div class="breadcrumbs">
<a href="/">Home</a> > <a href="/products">Products</a>
</div>
{% endblock %}
You can use the parent function to wrap the parent's content in additional markup:
{# base.twig #}
{% block content %}
<p>Default content here.</p>
{% endblock %}
{# child.twig #}
{% block content %}
<div class="highlight-box">
{{ parent() }}
<p>Additional information here.</p>
</div>
{% endblock %}
The parent()
function works with multi-level inheritance, allowing you to access the immediate parent's content:
{# base.twig #}
{% block section %}Base content{% endblock %}
{# middle.twig #}
{% extends "base.twig" %}
{% block section %}
<div class="middle">
{{ parent() }}
</div>
{% endblock %}
{# child.twig #}
{% extends "middle.twig" %}
{% block section %}
<div class="child">
{{ parent() }}
</div>
{% endblock %}
When child.twig
is rendered, you'll get nested content:
<div class="child">
<div class="middle">
Base content
</div>
</div>
This allows for complex template hierarchies while maintaining clean and reusable code.
-
Use parent() at the beginning or end of a block: This makes it clear where the parent content will appear.
-
Avoid multiple parent() calls: Generally, you should only call
parent()
once within a block. -
Be mindful of whitespace: Remember that
parent()
includes all whitespace from the parent block. -
Combine with whitespace control: Use
{{- parent() -}}
to control unwanted whitespace. -
Document inheritance chains: For complex multi-level inheritance, document the chain to make it easier to understand.
You can conditionally include the parent content:
{% block content %}
{% if showParent %}
{{ parent() }}
{% endif %}
<p>Additional content</p>
{% endblock %}
You can offer different placement options for parent content:
{% block content %}
{% if placement == 'before' %}
{{ parent() }}
<div class="new-content">New content</div>
{% elseif placement == 'after' %}
<div class="new-content">New content</div>
{{ parent() }}
{% else %}
<div class="new-content">New content only</div>
{% endif %}
{% endblock %}
The parent()
function also works well with empty parent blocks:
{# base.twig #}
{% block sidebar %}{% endblock %}
{# child.twig #}
{% block sidebar %}
{{ parent() }}
<div class="widget">
<h3>Recent Posts</h3>
<ul>
{% for post in recent_posts %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</div>
{% endblock %}
Even though the parent block is empty, this pattern allows for flexible template hierarchies where some templates might provide default content.
-
Missing parent block: If the referenced block doesn't exist in the parent template, you'll get an error.
-
Calling parent() outside of a block: The
parent()
function only works within a block definition. -
Calling parent() in a template that doesn't extend another: This will result in an error, as there's no parent to access.
-
Overriding variables: Remember that variables set in a child template's block are not available to the parent when using
parent()
.