Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Adding Twig Blocks to your Dynamic Layout

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

So we just completely replaced our homepage with a dynamic layout. But, that's not really that interesting. What I really want to be able to do is use my existing homepage template and all this good content I've prepared:

{% extends nglayouts.layoutTemplate %}
{% block body %}
<div class="hero-wrapper">
<h1 class="header">Bark & Bake</h1>
<p class="text-center">Doggone Good Treat & Meal Recipes</p>
<div class="d-flex justify-content-center">
<img src="{{ asset('images/dog-bone.png') }}" width="auto" height="50" alt="dog bone icon">
... lines 11 - 58
{% endblock %}

but then tweak it by adding little bits of dynamic content here and there... or even rearrange things. To do that in the layout, under the blocks, at the bottom, add a special one called "Twig Block"... and let's put that right below the title. Notice that you can put as many blocks as you want inside of a single zone. These zones don't really end up being all that important.

Anyways, when you click a block, on the right side, you'll see that block's options. This has an important one called "Twig block name". Enter body to match the {% block body %} that we have in the template:

{% extends nglayouts.layoutTemplate %}
{% block body %}
... lines 4 - 58
{% endblock %}

Ok, hit "publish and continue editing"... then go over and refresh the homepage. Holy content batman! Our Twig content now lives inside this dynamic page. That's awesome! And everything still works: even the fancy "live component" in the center of the page.

Adding More Blocks to your Template

Okay, so this is cool... but it's still just a bunch of dynamic content on top... then Twig template content on the bottom: we can't really mix anything into the middle of our page.

Unless... we add more blocks to our template. For example, keep the block body... just so the page keeps working even if we don't map a layout... but then add a {% block hero %} around the top section, a block called, how about, latest_recipes, {% endblock %}, another called subscribe_newsletter, {% endblock %} and a final one called featured_skills, {% endblock %}:

... lines 1 - 2
{% block body %}
{% block hero %}
<div class="hero-wrapper">
... lines 7 - 11
{% endblock %}
{% block latest_recipes %}
<div class="container">
... lines 17 - 31
{% endblock %}
{% block subscribe_newsletter %}
<div class="text-center pt-4 pb-5 my-4" style="background-color: #fdedf0;">
... lines 37 - 40
{% endblock %}
{% block featured_skills %}
<div class="container py-4 my-5">
... lines 46 - 65
{% endblock %}
{% endblock %}

If we stopped now, this would make no difference to our app: we're still rendering the body block down here... which includes all of those. But we just gave ourselves a lot of new power.

Check it out: change the body block name to hero. And then let's add a few more Twig blocks. Render latest_recipes for this one. Oh, by the way, the block "labels" are just for us in the admin area: just for clarity. If I enter "Latest Recipes", that shows up above the block. Totally optional.

Add two more blocks: one that renders subscribe_newsletter and finally one for featured_skills. Then, up here, I'm going to remove the title block for now.

By the way, I'm using the word "block" to mean two different things at once. Blocks are the "things" we add to our layout - like a title, Google map, or list of items. But blocks also refer to the Twig blocks in our templates. And of course, one of the types of blocks we can add... is one that renders... Twig blocks. A little confusing - but that's as bad as it gets.

Anyways, say "Publish and continue editing"... then go refresh the frontend. And... sweet! Our page works. I know, it looks exactly like it did a minute ago, but it's now being rendered by layouts... and we can rearrange the pieces!

Watch: I'll move the subscribe_newsletter down to the bottom, hit "Publish and continue editing", refresh, and... boom! That static part of the page magically moved to the bottom. That is cool.

Or, we could move that back up... then add some dynamic content, like text, in between one of the other blocks.

Next, let's get even more aggressive and flexible by allowing the top navigation and bottom footer to be optional, but easy to add, inside the Layout.

Leave a comment!

Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=8.1.0",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "babdev/pagerfanta-bundle": "^3.7", // v3.7.0
        "doctrine/doctrine-bundle": "^2.7", // 2.7.0
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.13", // 2.13.3
        "easycorp/easyadmin-bundle": "^4.4", // v4.4.1
        "netgen/layouts-contentful": "^1.3", // 1.3.2
        "netgen/layouts-standard": "^1.3", // 1.3.1
        "pagerfanta/doctrine-orm-adapter": "^3.6",
        "sensio/framework-extra-bundle": "^6.2", // v6.2.8
        "stof/doctrine-extensions-bundle": "^1.7", // v1.7.0
        "symfony/console": "5.4.*", // v5.4.14
        "symfony/dotenv": "5.4.*", // v5.4.5
        "symfony/flex": "^1.17|^2", // v2.2.3
        "symfony/framework-bundle": "5.4.*", // v5.4.14
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/proxy-manager-bridge": "5.4.*", // v5.4.6
        "symfony/runtime": "5.4.*", // v5.4.11
        "symfony/security-bundle": "5.4.*", // v5.4.11
        "symfony/twig-bundle": "5.4.*", // v5.4.8
        "symfony/ux-live-component": "^2.x-dev", // 2.x-dev
        "symfony/ux-twig-component": "^2.x-dev", // 2.x-dev
        "symfony/validator": "5.4.*", // v5.4.14
        "symfony/webpack-encore-bundle": "^1.15", // v1.16.0
        "symfony/yaml": "5.4.*", // v5.4.14
        "twig/extra-bundle": "^2.12|^3.0", // v3.4.0
        "twig/twig": "^2.12|^3.0" // v3.4.3
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
        "symfony/debug-bundle": "5.4.*", // v5.4.11
        "symfony/maker-bundle": "^1.47", // v1.47.0
        "symfony/stopwatch": "5.4.*", // v5.4.13
        "symfony/web-profiler-bundle": "5.4.*", // v5.4.14
        "zenstruck/foundry": "^1.22" // v1.22.1