SDC: Prevent unwanted context passing with Twig include/embed functions

Created on 5 April 2023, over 1 year ago
Updated 19 August 2024, 3 months ago

This was a request from @bnjmnm during a meeting today to discuss committing SDC to core.

We want to investigate augmenting usage of include/embed with custom Twig function. This would have the benefit of not passing in context (similar to Twig's only keyword).

I think this leaves us with a custom function as our only option if we want to do this. However, I am increasingly convinced that we might now want to do this. The reason being documentation of the new method, and catching up with new features and bugfixes.

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component
single-directory componentsΒ  β†’

Last updated 2 days ago

Created by

πŸ‡ΊπŸ‡ΈUnited States mherchel Gainesville, FL, US

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @mherchel
  • πŸ‡¬πŸ‡§United Kingdom jonathanshaw Stroud, UK

    I think it should be possible to enforce with_context to be false when using include/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.

  • πŸ‡¬πŸ‡§United Kingdom jonathanshaw Stroud, UK
  • 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 and embed 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 that include and embed 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.

  • πŸ‡§πŸ‡ͺBelgium dieterholvoet Brussels
  • πŸ‡ΊπŸ‡ΈUnited States xjm
  • πŸ‡ΊπŸ‡Έ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>
    
Production build 0.71.5 2024