Skip to content

Instantly share code, notes, and snippets.

@Karobwe
Last active March 20, 2024 10:23
Show Gist options
  • Save Karobwe/769f4f404c84113805e9cb5e584d9eb9 to your computer and use it in GitHub Desktop.
Save Karobwe/769f4f404c84113805e9cb5e584d9eb9 to your computer and use it in GitHub Desktop.
Showcase on how to use Twig's embed tag (supposing a Symfony app with Tailwind)

While working on a complex HTML structure, to facilitate readability of my Twig template, I divided my file onto many partial templates. In most case it's working well, but sometimes you need to use Twig blocks defined in partial templates across many files. But include will not let you overriding blocks defined in partial template, when extanding the main template.

To solve this, Twig provide the embed tag, but it took me some times to figure out how to use it. So here a little reminder, with the usecase on embed's doc.

preview vertical layout

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>{% block title %}Use Twig's "embed" tag{% endblock %}</title>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
</head>
<body class="flex flex-col h-screen bg-gray-100">
<!-- Header -->
{# {% include('header_skeleton.html.twig') %} will not allow to override sub-blocks #}
{% block header %}
{% embed 'header_skeleton.html.twig' %}{% endembed %}
{% endblock %}
<!-- Main content -->
{% block content %}
{# Deliberately using vertical skeleton as default layout #}
{% embed 'vertical_boxes_skeleton.twig' %}{% endembed %}
{% endblock %}
<!-- Footer -->
{# {{% include('footer_skeleton.html.twig') %} will not allow to override sub-blocks #}
{% block footer %}
{% embed 'footer_skeleton.html.twig' %}{% endembed %}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</body>
</html>
<div class="grid grid-flow-row grid-rows-2 h-full bg-pink-400">
<div class="top_box bg-gray-300">
{% block top %}
Top box default content
{% endblock %}
</div>
<div class="bottom_box bg-gray-600">
{% block bottom %}
Bottom box default content
{% endblock %}
</div>
</div>
<div class="grid grid-flow-col grid-cols-2 h-full bg-pink-400">
<div class="top_box bg-gray-300">
{% block left %}
Top box default content
{% endblock %}
</div>
<div class="bottom_box bg-gray-600">
{% block right %}
Bottom box default content
{% endblock %}
</div>
</div>
<header class="flex justify-center col-span-4 h-20 text-gray-300 bg-gray-800">
<h1 class="my-auto">
{% block title %}
Default title
{% endblock %}
</h1>
</header>
{% extends 'layout_skeleton.twig' %}
{% block header %}
{% embed 'header_skeleton.html.twig' %}
{% block title %}Vertical layout{% endblock %}
{% endembed %}
{% endblock %}
{% block content %}
{% embed 'vertical_boxes_skeleton.twig' %}
{% block top %}
<div class="text-gray-800 text-3xl h-full flex justify-center">
<span class="self-center">Some content for the top box</span>
</div>
{% endblock %}
{% block bottom %}
<div class="text-gray-300 text-3xl h-full flex justify-center">
<span class="self-center">Some content for the bottom box</span>
</div>
{% endblock %}
{% endembed %}
{% endblock %}
{% block footer %}
{% embed 'footer_skeleton.html.twig' %}
{% block footer_content %}
<div class="flex flex-row justify-center w-2/3 h-full mx-auto">
<a class="border border-gray-300 rounded-sm px-4 py-2 mx-8 my-auto bg-gray-800 hover:bg-gray-700" href="{{ path('foo_path') }}">Vertical layout</a>
<a class="border border-gray-500 rounded-sm px-4 py-2 mx-8 my-auto text-gray-400 hover:text-gray-300 border-gray-400 hover:bg-gray-700" href="{{ path('boom_path') }}">Horizontal layout</a>
</div>
{% endblock %}
{% endembed %}
{% endblock %}
{% extends 'layout_skeleton.twig' %}
{% block header %}
{% embed 'header_skeleton.html.twig' %}
{% block title %}Horizontal layout{% endblock %}
{% endembed %}
{% endblock %}
{% block content %}
{% embed 'horizontal_boxes_skeleton.twig' %}
{% block left %}
<div class="text-gray-800 text-3xl h-full flex justify-center">
<span class="self-center">Some content for the left box</span>
</div>
{% endblock %}
{% block right %}
<div class="text-gray-300 text-3xl h-full flex justify-center">
<span class="self-center">Some content for the right box</span>
</div>
{% endblock %}
{% endembed %}
{% endblock %}
{% block footer %}
{% embed 'footer_skeleton.html.twig' %}
{% block footer_content %}
<div class="flex flex-row justify-center w-2/3 h-full mx-auto">
<a class="border border-gray-500 rounded-sm px-4 py-2 mx-8 my-auto text-gray-400 hover:text-gray-300 border-gray-400 hover:bg-gray-700" href="{{ path('foo_path') }}">Vertical layout</a>
<a class="border border-gray-300 rounded-sm px-4 py-2 mx-8 my-auto bg-gray-800 hover:bg-gray-700" href="{{ path('boom_path') }}">Horizontal layout</a>
</div>
{% endblock %}
{% endembed %}
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment