Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix overridden blocks are not rendered #19

Merged
merged 3 commits into from
Apr 4, 2024
Merged

Fix overridden blocks are not rendered #19

merged 3 commits into from
Apr 4, 2024

Conversation

rybakit
Copy link
Owner

@rybakit rybakit commented Apr 2, 2024

Fixes #17.

--DATA--
return []
--EXPECT--
[bar-overridden][foo]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the expected output is incorrect, it must be : [foo][bar-overridden]
because foo block is defined first in parent template

so the issue isn't solved yet

Copy link
Owner Author

@rybakit rybakit Apr 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the expected output is incorrect, it must be : [foo][bar-overridden]
because foo block is defined first in parent template

It may be counter-intuitive, but it's expected behaviour. Hierarchical deferred blocks are resolved in FILO order, foo was defined first, and bar was defined last because it was extended in the child template.

In addition, the way the parent template is structured is also adding to the confusion. I don't know your use case, but normally, you don't need to make parent blocks deferred to be able to override them in the child template. To archive the [foo][bar-overridden] result, you can do

{% extends "layout.twig" %}
{% block bar deferred %}[bar-overridden]{% endblock %}

--TEMPLATE(layout.twig)--
{% block foo %}[foo]{% endblock %}
{% block bar %}[bar]{% endblock %}

Or, if you still need the parent blocks to be deferred for some reason:

{% extends "layout.twig" %}
{% block foo deferred %}{{ parent() }}{% endblock %}
{% block bar deferred %}[bar-overridden]{% endblock %}

--TEMPLATE(layout.twig)--
{% block foo deferred %}[foo]{% endblock %}
{% block bar deferred %}[bar]{% endblock %}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I understand the principle, but as you say it's really counter-intuitive. And being forced to overload all the deferred blocks just to maintain the desired order creates an extremely strong dependency between the potential evolutions of the parent template in regards of the child templates. In the case of a library for example this is very problematic.

I specify my use case, which I simplify here: I have two deferred blocks which follow one another in my base template. The first to include assets in preload and the second for other assets. It is absolutely necessary that the preloaded assets be displayed first for web performance reasons. However, with the behavior you indicate, the rendering of the two blocks will be reversed, if a child template overloads the second block, which is a bug.

That said, the initial problem that I indicated in the issue, namely the disappearance of intermediate portions, is resolved.
This second topic could be the subject of another ticket if you deem it relevant.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, with the behavior you indicate, the rendering of the two blocks will be reversed, if a child template overloads the second block, which is a bug.

Please note that this behavior only applies if you make the overridden block deferred in the child template as well, this is where hierarchy comes into play. It is not clear from your use case whether the block needs to be deferred in the child template or not. If not, then removing deferred from the child block will give you the expected result. For example, this will output [foo]L2(L1([bar2])):

--TEMPLATE--
{% extends "layout.twig" %}
{% block bar %}L2({{ parent() }}){% endblock %}
{% do data.append('[bar2]') %}

--TEMPLATE(layout.twig)--
{% block foo deferred %}[foo]{% endblock %}
{% block bar deferred %}L1({{ data|join(',') }}){% endblock %}

That said, the initial problem that I indicated in the issue, namely the disappearance of intermediate portions, is resolved. This second topic could be the subject of another ticket if you deem it relevant.

That's right, this behavior has always been the case and has never changed since the library was first released. Let me know if the above suggestion will work for you, and if not, feel free to file a new ticket. However, I'm afraid that changing the core behavior would require significant rework and would require a new major release.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, in my case, I need the overridden deferred block in the child template to be deferred too. Because this child template is an overload of the base template which is used in turn by other child templates.

With the details you provided, I will find a solution for my specific use case.

Thank you in any case

@rybakit rybakit merged commit 3e5d00c into master Apr 4, 2024
7 of 8 checks passed
@rybakit rybakit deleted the first_deferred branch April 4, 2024 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Redefining a deferred block that is not the first removes other blocks from rendering
2 participants