Skip to content

Parent Function

semihalev edited this page Mar 11, 2025 · 1 revision

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.

Basic Usage

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

Common Use Cases

Adding to CSS/JavaScript

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.

Enhancing Headers and Footers

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> &gt; <a href="/products">Products</a>
    </div>
{% endblock %}

Wrapping Content

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 %}

Multi-Level Inheritance

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.

Best Practices

  1. Use parent() at the beginning or end of a block: This makes it clear where the parent content will appear.

  2. Avoid multiple parent() calls: Generally, you should only call parent() once within a block.

  3. Be mindful of whitespace: Remember that parent() includes all whitespace from the parent block.

  4. Combine with whitespace control: Use {{- parent() -}} to control unwanted whitespace.

  5. Document inheritance chains: For complex multi-level inheritance, document the chain to make it easier to understand.

Tips and Tricks

Conditional parent() Use

You can conditionally include the parent content:

{% block content %}
    {% if showParent %}
        {{ parent() }}
    {% endif %}
    <p>Additional content</p>
{% endblock %}

Multiple Placement Options

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 %}

Adding Default Block Content

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.

Common Pitfalls

  1. Missing parent block: If the referenced block doesn't exist in the parent template, you'll get an error.

  2. Calling parent() outside of a block: The parent() function only works within a block definition.

  3. Calling parent() in a template that doesn't extend another: This will result in an error, as there's no parent to access.

  4. Overriding variables: Remember that variables set in a child template's block are not available to the parent when using parent().

Clone this wiki locally