Trigger SDC render element when using Twig include or embed

Created on 30 October 2024, 6 months ago

Problem/Motivation

SDC documentation is currently promoting using Twig's include function and & embed tag to call components from template. And it seems to be a popular way of using SDC components (for now, let's hope it will disappear as soon as SDC components are becoming usable directly from the render API and the display builders)

There is a big issue about include and embed: they don't pass through the SDC render element and don't trigger the Render API mechanisms.

So, SDC is currently doing a complex workaround.

ComponentsTwigExtension is adding 2 twig functions:

  • add_component_context which is adding the attribute Attribute object if missing
  • validate_component_props which is executing the JSON schema validator

They are not supposed to be used by templates owner, there exists because ComponentNodeVisitor is printing those Twig functions on every template, which will be executed on rendering in this order:

  1. attach_library
  2. add_component_context
  3. validate_component_props

In order to make the use of "template to template" Twig functions or tags (include and embed) more similar to the use of the Render API, leveraging the render element. For example, attach_library is used here because #attached is not executed.

This is a mess which can be fixed.

Proposed resolution

  1. Add asset library attachments (#attached) and prop validation to the render element itself
  2. Override Twig native include and embed to return the SDC render element when the "template" is a full component plugin ID instead of a template path.
  3. Remove everything but ::getNodeVisitors() in ComponentsTwigExtension and most of ComponentNodeVisitor

So, people using SDC from the Render API and people using SDC from templates will have , implemented in a cleaner way.

API changes

If done right, this may be free of breaking changes.

📌 Task
Status

Active

Version

11.0 🔥

Component

single-directory components

Created by

🇫🇷France pdureau Paris

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

Comments & Activities

  • Issue created by @pdureau
  • 🇫🇷France pdureau Paris

    For information, UI Patterns 2.x team is also looking for such solution: 📌 [2.0.0-alpha3] Replace component() function by native Twig mechanisms? Active

  • 🇫🇷France pdureau Paris

    Remove everything but ::getNodeVisitors() in ComponentsTwigExtension and most of ComponentNodeVisitor

    It would also be the opportunity to also remove ComponentElement::generateComponentTemplate() and to simply render:

    [
       '#type' => 'inline_template',
       '#template' => $template_loaded_from_file,
      '#context' => $slots + $props,
    ];
  • 🇳🇿New Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to our policies.

  • Status changed to Closed: won't fix 24 days ago
  • 🇫🇷France pdureau Paris

    It was tied by UI Patterns team in 📌 [2.0.0-alpha3] Replace component() function by native Twig mechanisms? Active

    • It was working well with include function
    • But it was not possible with embed tag

    We can't visit EmbedNode because it doesn't know about:

    • the template ID (so the component ID) because it is the parent node (an expression)
    • and the blocks (so the slots) because their nodes are elswhere in the AST (in a blocks section)

    Maybe we can introduce our own EmbedTokenParser which will know:

    • the template ID (so the component ID): $parent->getAttribute("value")
    • the variables (so the props): [$variables, $only, $ignoreMissing] = $this->parseArguments();
    • and the blocks (so the slots) by exploring the ModuleNode: $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);

    But working at the parser level is way harder and risker than working at the AST level.

    So, let's not do that. The current rendering method is not perfect but work well anyway.

Production build 0.71.5 2024