Make it possible to add relationships to layout builder

Created on 20 September 2018, over 6 years ago
Updated 4 August 2023, over 1 year ago

Problem/Motivation

Panelizer (at least in D7) allowed you to override a view mode for an entity and add relationships to pull in fields from additional entities (an obvious example being a User view which pulls in data from a profile attached to the user). Panelizer appears to be winding down now so much of what it did is in core, but this relationship aspect is not currently supported by core and is not easily possible in contrib either without swapping out large parts of core.

Proposed resolution

Make it possible for contrib to provide additional context for the layout builder. There are probably a few ways to do this, but the two obvious options to me seem to be one of:

  1. An event that can be subscribed to: Pro - OO with subscribers able to inject services and possibly better 'applies' logic
  2. A hook that modules can implement: Pro - quick and easy to implement!

The places I have identified which would need to invoke whatever process are:

  1. \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay::buildMultiple after adding the layout_builder.entity context: Implementers would need to provide real (potentially empty) context.
  2. \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage::getContexts: Implementors would need to provide sample context.
  3. \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage::getContexts: Implementors would need to provide real or sample context.

Remaining tasks

  • Decide what mechanism we want to use (events, hooks or other).
  • Trigger implementations in the identified locations.
  • Make sure there aren't other places that also need to trigger implementations.
  • Test coverage!

User interface changes

None - it would be down to contrib to implement any UI to configure relationships, or to provide them programatically.

API changes

Addition of a mechanism to add additional context.

Data model changes

None - it would be down to contrib to deal with any additional storage requirements.

✨ Feature request
Status

Needs work

Version

11.0 πŸ”₯

Component
Layout builderΒ  β†’

Last updated 1 day ago

Created by

πŸ‡¬πŸ‡§United Kingdom andrewbelcher

Live updates comments and jobs are added and updated live.
  • Contributed project blocker

    It denotes an issue that prevents porting of a contributed project to the stable version of Drupal due to missing APIs, regressions, and so on.

  • Blocks-Layouts

    Blocks and Layouts Initiative. See the #2811175 Add layouts to Drupal issue.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

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.

  • πŸ‡¨πŸ‡¦Canada liquidcms

    I feel like this is close to solving my issue.

    I have a block inside a block placed on a node layout. I need the inner block to control visibility based on the value of a node field. I have the block visibility patch ( ✨ Add visibility control conditions to blocks within Layout Builder Needs work ) and the patch from here. When i add this hook code:

    function mycustom_layout_builder_view_context_alter(&$contexts, SectionStorageInterface $section_storage = NULL, $sample = FALSE) {
      if (!isset($contexts['layout_builder.entity'])) {
        return;
      }
    
      /* @var \Drupal\Core\Plugin\Context\EntityContext $layout_entity_context */
      $layout_entity_context = $contexts['layout_builder.entity'];
    
      /* @var \Drupal\Core\Entity\EntityInterface $layout_entity */
      $layout_entity = $layout_entity_context->getContextData()->getValue();
    
      if ($layout_entity->getEntityTypeId() === 'block_content' && $layout_entity->bundle() === 'layout_block') {
        $entity = Node::create([
          'type' => 'service',
        ]);
        if (isset($entity)) {
          $contexts['layout_builder.entity'] = EntityContext::fromEntity($entity, 'Node');
        }
      }
    }

    This gives me the ability to add a field condition based off my node bundle when setting visibility of the inner block. But I don't see where, when it comes time to display the actual node, that the block has the context of the specific node it is on. And sure enough, on display, i get this error:

    Error: Call to a member function getValue() on null in Drupal\entity_field_condition\Plugin\Condition\FieldValue->evaluate() (line 415 of modules\contrib\entity_field_condition\src\Plugin\Condition\FieldValue.php).

    which makes sense as I would need to specify somewhere, the context from the actual node taken from route. What am i missing or is this not possible with the work being done here?

Production build 0.71.5 2024