- Issue created by @mherchel
- π¬π§United Kingdom jonathanshaw Stroud, UK
I think it should be possible to enforce
with_context
to befalse
when usinginclude
/embed
with a component, using a Twig NodeVisitor.For those innocent souls who have not yet encountered the unholy mystery that is Twig's NodeVisitors, see
lib/Drupal/Core/Template/TwigNodeVisitor.php
for an example of how Drupal is already altering the functionality of Twig's provided functions. - e0ipso Can Picafort
Another idea is to add a warning during development (in a similar fashion we use for validation errors). This warning could show a message in the page whenever a component is put in the page without the
only
keyword. This check should probably happen in the same node visitor we use for attaching the library to the page, like @jonathanshaw suggests. - e0ipso Can Picafort
Doing this in the
include
andembed
will be a backwards compatibility break. Since SDC is beta experimental, we need to maintain BC. Additionally, this would be a departure from the expectations thatinclude
andembed
work the same way as described in Twig's documentation. - π¬π§United Kingdom jonathanshaw Stroud, UK
As a version of #7, it should be possible to detect and warn in a node visitor if a variable that is not a defined slot/prop is used inside a component.
We now do something very similar to this to detect usage of deprecated variables, allowing us to deprecate variables passed to twig templates.
This would allow us to continue to use include/embed, with the documented behavior developers expect.
- πΊπΈUnited States brayn7 Lexington, Ky
I have encountered this issue in tandem with https://www.drupal.org/project/drupal/issues/3464719 π Twig embed leads to recursion and InvalidComponentException Needs review . If the only keyword is forced that would be good but we gotta make sure blocks from embed still get passed down and not blocked. Let me know if I need to post an example. I find myself needing to pass down a block for an embed to a nested embed block basically. Maybe thats bad practice. let me know. Cheers.
- πΊπΈUnited States brayn7 Lexington, Ky
Here is something I am curious what others are doing.
Backstory, I was originally passing most things as properties to an include when @Pierre (pdureau) pointed out it would be better to use slots for most things and prevent prop drilling of sorts. I think this is a great idea and I am on the path to solving it and wrapping my head around it completely and refactoring as we go. Here is what I am coming across:
Property context may get contaminated when not using ONLY or with_context:false.
When using ONLY or with_context: TRUE I am blocked from passing a content.field_item to a embed block.// block--component.html.twig {% embed 'theme:my-component' with {option} %} {% block slot_1 %} {{ content.field_item.0 }} // when ONLY is used I can't do this if not then contamination happens. {% endblock %} {% endembed %}
What is everyone doing in this situation?
Here is what I thought of as a workaround for the time being maybe// block--my-component.html.twig {% embed 'theme:my-component' with { option, _content: content // create a namespace that shouldn't collide only in files inside the template dir //(drupal templates not sdcs) } only %} // add only back {% block slot_1 %} {{ content.field_item.0 }} // when ONLY is used I can't do this if not then contamination happens. {% endblock %} {% endembed %}
Here is another thing I am wanting a solve for but it doesn't fall inside the scope of this ticket so sorry about that:
When I have the render of an embed slot area twig calls for this type of syntax to wrap it with html. The thing is i want the the dom to render conditionally which obviously i can check if the block is empty or not but seems like we could create a new embed area called something that handles that use case for more concise conditional block areas. Of course i can use regular twig and or css to make sure that space don't have a height or render but I am curious if we should solve it.
<div class="desc"> {% block description %} {{ description }} {% endblock %} </div>