Is there a generally "good" way to achieve this functionality? I have read about the 'use' tag, which seems like the best option so far, but I still don't like that it wont let me bring in any outside html, only blocks.
I will use the 'include' tag in the example below to demonstrate the intent I'm trying to describe.
#base.html.twig
{% include 'elements/header.html.twig' %}
{% block content %}{% endblock %}
{% include 'elements/footer.html.twig' %}
#header.html.twig
<h1>This is my header</h1>
{% block page_title %} Default Page Title {% endblock %}
#index.html.twig
{% extends 'layouts/base.html.twig' %}
{# I want to be able to do this somehow #}
{% block page_title %} This is my overridden page title {% endblock %}
{% block content %} here is the index page content {% endblock %}
I found a solution. Use the block() function to get the child's block content and pass it to header.html.twig as a variable in the include statement:
I found a good and real solution reading the documentation for the embed tag. I'm using Twig 2.0 in Symfony 4.
My structure
With code above, when I create my index.html.twig the only code needed to show de default things is
and override blocks defined. But, when I need to create another page, that use these skeleton, if I try to override block sub_app_menu_itens in another _partial template included, doesn't work.
<li>Main App Menu Item</li>
is always showed and never overwritten (code above)<li>SubApp Menu Item</li>
is never showed. Tried a lot of things likeextends
and even conditionals with no luck.THE Solution
The embed tag solve the child partial templates blocks to be overwritten.
And simplifing _partial template to have only the html needed
Now
<li>SubApp Menu Item</li>
will be displayed on the right place of _menu template.Thinking in levels, a
include
works like a sublevel (parsed) and all things are only override on the same level, soinclude
doesn't allow to override in another include. Instead,embed
templates are bring to the same level (not parsed) and so you can override things.I got it to work with a very simple hack:
Basically it behaves this way because without a
{% extends "foo.html.twig" %}
it doesn't understand the blocks and simply renders them in place.So let's extend... nothing:
This nothing is really just 1 block:
The only thing is that you need to wrap everything in a block, this fake "main" block.
Check out the embed tag: http://twig.sensiolabs.org/doc/tags/embed.html
Doesn't work exactly like you want but I think it's as close as you can get right now.
It can be done. Here's my solution to the problem by passing a variable to the view.
Since I'm using SlimPHP the way I call it is by passing
sidebar
variable to the the view. This can be extended further by using different variables passed to the view, so you can selectedsidebar1
,sidebar2
etc.