Outbound processor is not triggered for link prop

Created on 8 July 2025, 2 months ago

Overview

For some reason \Drupal\path_alias\PathProcessor\AliasPathProcessor::processOutbound is not triggered for XB link fields. This should convert for example /page/1 to use its alias. Should we run

Proposed resolution

We should potentially run \Drupal\Core\PathProcessor\PathProcessorManager::processOutbound for the value of the link field before passing it to a component.

This does raise a question though; what if I want to generate a link inside a code component. How would I do that? This is critical especially when building multilingual sites because of \Drupal\language\HttpKernel\PathProcessorLanguage::processOutbound is responsible for adding the correct langcode to the URL.

User interface changes

🐛 Bug report
Status

Active

Version

0.0

Component

… to be triaged

Created by

🇫🇮Finland lauriii Finland

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

Merge Requests

Comments & Activities

  • Issue created by @lauriii
  • 🇫🇮Finland lauriii Finland
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
    1. Can you please create a Pattern that shows this problem, so I can easily reproduce this?

      And just tell me what path alias to create/to expect.

    2. This does raise a question though; what if I want to generate a link inside a code component. How would I do that? This is critical especially when building multilingual sites because of \Drupal\language\HttpKernel\PathProcessorLanguage::processOutbound is responsible for adding the correct langcode to the URL.

      Please provide a concrete example of this too. Too much room for interpretation here. Is it a hardcoded <a href="/node/42"> that you'd expect to be transformed to <a href="/nice-alias">? That's what it sounds like to me right now.

    I bet this is related to \Drupal\link\Plugin\Field\FieldType\LinkItem::propertyDefinitions()'s uri property not calling path processing, and neither does XB's \Drupal\experience_builder\Plugin\Field\FieldTypeOverride\LinkItemOverride::propertyDefinitions() for the url property.

  • 🇺🇸United States effulgentsia

    The cause of this is that the value of the inputs column for a link prop is stored as: {"uri":"/page/1","options":[]}, but it should be stored as {"uri":"internal:/page/1","options":[]}. Outbound processors are only run on paths in the internal: scheme. The adding of the internal: prefix to user-entered paths that start with / normally happens in LinkWidget::massageFormValues(). Are we skipping that step for component instance forms for widgets that have client-side transforms?

  • 🇺🇸United States effulgentsia

    The adding of the internal: prefix to user-entered paths that start with / normally happens in LinkWidget::massageFormValues(). Are we skipping that step for component instance forms for widgets that have client-side transforms?

    I'm not positive, but I think the answer to this is yes, because GeneratedFieldExplicitInputUxComponentSourceBase::clientModelToInput()assumes that client-side transforms are responsible for replicating that kind of server-side widget processing. Based on this assumption, here's a quick and dirty patch for what I think would solve this, but I haven't tested it. Marking "needs review" for feedback on approach, even though this is just an untested patch and not a proper MR.

  • 🇺🇸United States bnjmnm Ann Arbor, MI
  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    First of all, I verified that \Drupal\Tests\experience_builder\Kernel\ClientDataToEntityConverterTest has specific tests for massaging values in a widget.

    The problem is not with link fields, but somewhere with the page entity type, or the widget settings we are using for the component prop.

    STR:

    1. Create an article "my test article with alias" (with alias).
    2. Create a page "my test page with alias" (with alias)
    3. Create a code component with a Link, and code like:
      const CodeWithLink = ({
        title = "<h3>code-with-link</h3>",
        link
      }) => {
        return (
          <div className="max-w-sm min-h-36 p-2 font-bold rounded-lg text-2xl gap-4 relative mx-auto flex w-full flex-col items-center justify-center bg-[#ffc423] text-[#12285f]">
            <ControlDots className="top-4 left-4 stroke-white absolute" />
            <FormattedText>{title}</FormattedText>
            <a href={link}>my link</a>
          </div>
        );
      };
      
    4. Add two instances to a new page.
    5. Try to link to "my test article" and "my test page" in each of them
      1. For article, we get autocomplete, and the value changes to internal:/node/1
      2. For page, we don't get autocomplete.
    6. Save the page.
    7. We can see the article link using the alias, while the page one doesn't.
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    If I use autocomplete widget outside of XB I get the same results, so is not related with our transforms.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    And... \Drupal\link\Plugin\Field\FieldWidget\LinkWidget::formElement links to 📌 Allow multiple target entity types in the 'entity_autocomplete' Form API element Needs work while hardcoding "node", so that's the real issue.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Haven't read this in detail, but I wanted to offer a worst case escape hatch: we could do something like \Drupal\Core\EventSubscriber\RssResponseRelativeUrlFilter as a temporary work-around; that wouldn't work in the XB preview, but would work on the live site.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    Even then, outbound processor is triggered if I directly input "/node/1" in a link widget on Drupal, but not on a code component.
    So the autocomplete is a related issue, but we still need to fix the outbound in XB.

    @wimleers I hope we can avoid that, because it would need to parse the complete response, but would be a last resort.
  • 🇮🇳India ankithashetty Karnataka, India

    Sharing another observation regarding the link prop:

    1. Within your component, add a link prop and choose the Link type as 'Full URL' from the dropdown.
    2. Now navigate away from this component, perhaps visit another page, and then return to edit the component.

    Expectation:
    You should see the link prop with the Link type still set as 'Full URL'.

    Current Behavior:
    The Link type is shown as 'Relative link' in the dropdown.

    Attaching a screenshot and a video for reference.

    Note:
    In the AJAX call payload, the type is set correctly. This issue appears to be only in the UI, which might confuse editors.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Why is this ? 🤔 There's no MR?

    #11 contains a tiny patch (love the elegance, @effulgentsia! 🤩) that should get converted into an MR — which should hopefully pass tests 🤞 😄

    Then we'll still need the actual (e2e) tests written.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    #11 works great, but have some UX implications. I think we should be fine with it, but wanted to highlight them.

    tl;dr: if I type /, it automatically enters "internal:/" which might be confusing to some editors. What is even more confusing, if I change focus to a different component and select this one again, it displays <front>.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    Lauri thinks we shouldn't expose the internal: protocol to editors at all, so changed to a different approach where we do the outbount in the backend on render.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    This is ready for review.

    #15 needs a different follow-up issue.

  • 🇪🇸Spain isholgueras

    I've left a couple of comments in Gitlab in case something is missing.

    Everything else looks good to me

  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    Left a comment about how I think we can fix this in a more generic way

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺
  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺
  • 🇺🇸United States tedbow Ithaca, NY, USA

    I think there is just 1 change Wim asked for that has not been addressed. Otherwise looks good to me.

    The summary does not reflect the actual solution though

  • 🇺🇸United States tedbow Ithaca, NY, USA

    @penyaskito thanks for the clarification. I will update the issue summary and then merge in a bit

  • Pipeline finished with Skipped
    about 1 month ago
    #559964
  • Pipeline finished with Skipped
    about 1 month ago
    #559968
  • Pipeline finished with Skipped
    about 1 month ago
    #559970
  • Pipeline finished with Skipped
    about 1 month ago
    #559979
  • 🇺🇸United States tedbow Ithaca, NY, USA

    Leaving to assigned to myself to update the summary with the basics of the actual fix.

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    Needs followup for checking if we are missing something no specific to this widget, but site-wide.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Changing status for #33.

    (Also crediting @tedbow who obviously helped land this!)

  • @tedbow, Could you please update the summary to include details on which issues have been fixed in this ticket, along with the steps to reproduce them?

  • Found below issues :

    Issue 1: Outbound processor not triggered for lk prop (alias not used)


    Issue 2: Article gets autocomplete and proper alias, page does not


    Issue 3: "Full URL" link type not retained in UI

  • For Issue 3 mentioned in #36, created separate issue - https://www.drupal.org/project/experience_builder/issues/3541331 🐛 Link Type "Full URL" is Not Retained After Navigation While Adding Prop Active

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    I cannot reproduce TC1.1. This is tricky, but the react component needs to use

          <a href={link}>test</a>
    

    See there are no quotes around link

  • 🇪🇸Spain penyaskito Seville 💃, Spain 🇪🇸, UTC+2 🇪🇺

    Mayur re-tested this and confirmed it worked for him

  • Assigned to tedbow
  • Status changed to Downport 3 days ago
  • 🇺🇸United States effulgentsia

    #33 doesn't need to block a stable release unless we already know of or suspect a problem.

Production build 0.71.5 2024