Problem/Motivation

On a node page, a prop bound to a field of a referenced node resolves against the route's node. The source chain is "[Entity] ➜ Referenced [Entity]" on an entity reference field, then "[Entity] ➜ [Field]" and a field property.

Display Builder's entity view passes view_mode, entity and display plus every global runtime context, including @node.node_route_context:node (EntityViewDisplayTrait::getContextsForEntity()). EntityReferencedDerivableContext::getDerivedContexts() removes entity from these contexts and appends the referenced entity as entity with array_merge(). The route's node now comes before it. The next step takes the first context that matches each definition, in DerivableContextPluginBase::setDefinedContextValues():

$matching_context = \reset($matches);

Both nodes match the entity:node definition, so reset() returns the route's node. That node has no such field, the value is NULL, and a required prop throws on render:

Drupal\Core\Render\Component\Exception\InvalidComponentException: [hda_theme:progress_bar/current] The property current is required.

The same page renders a video through a Media reference correctly, because the global contexts hold no Media entity. A reference to a user entity would meet @user.current_user_context:current_user first by the same order; we have not tested that.

In drush, without a route, the same source configuration returns the referenced node's value.

Steps to reproduce

  1. Install Drupal 11.4.7, UI Patterns 2.0.21 and Display Builder 1.0.0-beta7 with display_builder_entity_view.
  2. Create a content type Campaign with an integer field field_anteile_current, and a content type Page with an entity reference field field_campaign that targets Campaign.
  3. Add a component with a required integer prop current.
  4. Enable Display Builder with overrides on the Page view display. On a Page node, place the component and bind current to "[Entity] ➜ Referenced [Entity]" on field_campaign, then "[Entity] ➜ [Field]" field_anteile_current, property value.
  5. Publish and open the Page node. The request fails with the exception above.

Proposed resolution

Prefer the context whose key equals the definition name, and fall back to the first match:

-      $matching_context = \reset($matches);
+      // Prefer the context with the definition's own name, so a derived
+      // 'entity' wins over another context of the same entity type, such as
+      // the route's node.
+      $matching_context = $matches[$name] ?? \reset($matches);

EntityReferencedDerivableContext keys the referenced entity as entity, the same name as the entity context definition of the next step, so the referenced node wins.

We run this as a local patch on 2.0.21. The prop renders the Campaign's value (520000 of 800000), and the other bindings on the page render as before: the title, the video through the Media reference, and field formatters.

SourcePluginBase::setDefinedContextValues() selects only through context_mapping, so the order of contexts does not affect it.

Remaining tasks

  • Add a kernel test with a node that references another node, rendered with a node route context.
  • Open a merge request against 2.0.x.

User interface changes

None.

API changes

None.

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

anruether created an issue. See original summary.

just_like_good_vibes’s picture

Assigned: Unassigned » just_like_good_vibes

hello,
thank you for reporting that issue. let’s fix that asap.

just_like_good_vibes’s picture

let’s follow your suggestions and also let’s carry a little other investigation in where exactly do we also merge contexts and if that would help to set an overriden context as being the first candidate to a reset function instead of being the last selected one despite being the freshest one. i mean your issue raised the question of context selection priority when multiple matches.
elsewhere in the code, were already played a lot with context keys (to fill the gap with existing core code in terms of context matching), and the spirit of your proposed fix makes perfect sense.

anruether’s picture

just_like_good_vibes’s picture

Assigned: just_like_good_vibes » Unassigned
Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.