Unverified Commit c8054435 authored by larowlan's avatar larowlan

Issue #2927349 by tim.plunkett: Decouple the Layout Builder UI from entities

parent bcb5afd4
layout_builder.choose_section: layout_builder.choose_section:
path: '/layout_builder/choose/section/{entity_type_id}/{entity}/{delta}' path: '/layout_builder/choose/section/{section_storage_type}/{section_storage}/{delta}'
defaults: defaults:
_controller: '\Drupal\layout_builder\Controller\ChooseSectionController::build' _controller: '\Drupal\layout_builder\Controller\ChooseSectionController::build'
requirements: requirements:
...@@ -7,12 +7,11 @@ layout_builder.choose_section: ...@@ -7,12 +7,11 @@ layout_builder.choose_section:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.add_section: layout_builder.add_section:
path: '/layout_builder/add/section/{entity_type_id}/{entity}/{delta}/{plugin_id}' path: '/layout_builder/add/section/{section_storage_type}/{section_storage}/{delta}/{plugin_id}'
defaults: defaults:
_controller: '\Drupal\layout_builder\Controller\AddSectionController::build' _controller: '\Drupal\layout_builder\Controller\AddSectionController::build'
requirements: requirements:
...@@ -20,12 +19,11 @@ layout_builder.add_section: ...@@ -20,12 +19,11 @@ layout_builder.add_section:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.configure_section: layout_builder.configure_section:
path: '/layout_builder/configure/section/{entity_type_id}/{entity}/{delta}/{plugin_id}' path: '/layout_builder/configure/section/{section_storage_type}/{section_storage}/{delta}/{plugin_id}'
defaults: defaults:
_title: 'Configure section' _title: 'Configure section'
_form: '\Drupal\layout_builder\Form\ConfigureSectionForm' _form: '\Drupal\layout_builder\Form\ConfigureSectionForm'
...@@ -37,12 +35,11 @@ layout_builder.configure_section: ...@@ -37,12 +35,11 @@ layout_builder.configure_section:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.remove_section: layout_builder.remove_section:
path: '/layout_builder/remove/section/{entity_type_id}/{entity}/{delta}' path: '/layout_builder/remove/section/{section_storage_type}/{section_storage}/{delta}'
defaults: defaults:
_form: '\Drupal\layout_builder\Form\RemoveSectionForm' _form: '\Drupal\layout_builder\Form\RemoveSectionForm'
requirements: requirements:
...@@ -50,12 +47,11 @@ layout_builder.remove_section: ...@@ -50,12 +47,11 @@ layout_builder.remove_section:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.choose_block: layout_builder.choose_block:
path: '/layout_builder/choose/block/{entity_type_id}/{entity}/{delta}/{region}' path: '/layout_builder/choose/block/{section_storage_type}/{section_storage}/{delta}/{region}'
defaults: defaults:
_controller: '\Drupal\layout_builder\Controller\ChooseBlockController::build' _controller: '\Drupal\layout_builder\Controller\ChooseBlockController::build'
requirements: requirements:
...@@ -63,12 +59,11 @@ layout_builder.choose_block: ...@@ -63,12 +59,11 @@ layout_builder.choose_block:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.add_block: layout_builder.add_block:
path: '/layout_builder/add/block/{entity_type_id}/{entity}/{delta}/{region}/{plugin_id}' path: '/layout_builder/add/block/{section_storage_type}/{section_storage}/{delta}/{region}/{plugin_id}'
defaults: defaults:
_form: '\Drupal\layout_builder\Form\AddBlockForm' _form: '\Drupal\layout_builder\Form\AddBlockForm'
requirements: requirements:
...@@ -76,12 +71,11 @@ layout_builder.add_block: ...@@ -76,12 +71,11 @@ layout_builder.add_block:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.update_block: layout_builder.update_block:
path: '/layout_builder/update/block/{entity_type_id}/{entity}/{delta}/{region}/{uuid}' path: '/layout_builder/update/block/{section_storage_type}/{section_storage}/{delta}/{region}/{uuid}'
defaults: defaults:
_form: '\Drupal\layout_builder\Form\UpdateBlockForm' _form: '\Drupal\layout_builder\Form\UpdateBlockForm'
requirements: requirements:
...@@ -89,12 +83,11 @@ layout_builder.update_block: ...@@ -89,12 +83,11 @@ layout_builder.update_block:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.remove_block: layout_builder.remove_block:
path: '/layout_builder/remove/block/{entity_type_id}/{entity}/{delta}/{region}/{uuid}' path: '/layout_builder/remove/block/{section_storage_type}/{section_storage}/{delta}/{region}/{uuid}'
defaults: defaults:
_form: '\Drupal\layout_builder\Form\RemoveBlockForm' _form: '\Drupal\layout_builder\Form\RemoveBlockForm'
requirements: requirements:
...@@ -102,12 +95,11 @@ layout_builder.remove_block: ...@@ -102,12 +95,11 @@ layout_builder.remove_block:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
layout_builder.move_block: layout_builder.move_block:
path: '/layout_builder/move/block/{entity_type_id}/{entity}/{delta_from}/{delta_to}/{region_from}/{region_to}/{block_uuid}/{preceding_block_uuid}' path: '/layout_builder/move/block/{section_storage_type}/{section_storage}/{delta_from}/{delta_to}/{region_from}/{region_to}/{block_uuid}/{preceding_block_uuid}'
defaults: defaults:
_controller: '\Drupal\layout_builder\Controller\MoveBlockController::build' _controller: '\Drupal\layout_builder\Controller\MoveBlockController::build'
delta_from: null delta_from: null
...@@ -121,8 +113,7 @@ layout_builder.move_block: ...@@ -121,8 +113,7 @@ layout_builder.move_block:
options: options:
_admin_route: TRUE _admin_route: TRUE
parameters: parameters:
entity: section_storage:
type: entity:{entity_type_id}
layout_builder_tempstore: TRUE layout_builder_tempstore: TRUE
route_callbacks: route_callbacks:
......
services: services:
layout_builder.tempstore_repository: layout_builder.tempstore_repository:
class: Drupal\layout_builder\LayoutTempstoreRepository class: Drupal\layout_builder\LayoutTempstoreRepository
arguments: ['@user.shared_tempstore', '@entity_type.manager'] arguments: ['@user.shared_tempstore']
access_check.entity.layout: access_check.entity.layout:
class: Drupal\layout_builder\Access\LayoutSectionAccessCheck class: Drupal\layout_builder\Access\LayoutSectionAccessCheck
tags: tags:
...@@ -15,9 +15,12 @@ services: ...@@ -15,9 +15,12 @@ services:
- { name: route_enhancer } - { name: route_enhancer }
layout_builder.param_converter: layout_builder.param_converter:
class: Drupal\layout_builder\Routing\LayoutTempstoreParamConverter class: Drupal\layout_builder\Routing\LayoutTempstoreParamConverter
arguments: ['@entity.manager', '@layout_builder.tempstore_repository'] arguments: ['@layout_builder.tempstore_repository', '@class_resolver']
tags: tags:
- { name: paramconverter, priority: 10 } - { name: paramconverter, priority: 10 }
layout_builder.section_storage_param_converter.overrides:
class: Drupal\layout_builder\Routing\SectionStorageOverridesParamConverter
arguments: ['@entity.manager']
cache_context.layout_builder_is_active: cache_context.layout_builder_is_active:
class: Drupal\layout_builder\Cache\LayoutBuilderIsActiveCacheContext class: Drupal\layout_builder\Cache\LayoutBuilderIsActiveCacheContext
arguments: ['@current_route_match'] arguments: ['@current_route_match']
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
namespace Drupal\layout_builder\Access; namespace Drupal\layout_builder\Access;
use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Routing\Access\AccessInterface; use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\layout_builder\SectionStorageInterface;
/** /**
* Provides an access check for the Layout Builder UI. * Provides an access check for the Layout Builder UI.
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
class LayoutSectionAccessCheck implements AccessInterface { class LayoutSectionAccessCheck implements AccessInterface {
/** /**
* Checks routing access to layout for the entity. * Checks routing access to the layout.
* *
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match. * The current route match.
...@@ -27,24 +27,20 @@ class LayoutSectionAccessCheck implements AccessInterface { ...@@ -27,24 +27,20 @@ class LayoutSectionAccessCheck implements AccessInterface {
* The access result. * The access result.
*/ */
public function access(RouteMatchInterface $route_match, AccountInterface $account) { public function access(RouteMatchInterface $route_match, AccountInterface $account) {
// Attempt to retrieve the generic 'entity' parameter, otherwise look up the $section_storage = $route_match->getParameter('section_storage');
// specific entity via the entity type ID.
$entity = $route_match->getParameter('entity') ?: $route_match->getParameter($route_match->getParameter('entity_type_id'));
// If we don't have an entity, forbid access. if (empty($section_storage)) {
if (empty($entity)) {
return AccessResult::forbidden()->addCacheContexts(['route']); return AccessResult::forbidden()->addCacheContexts(['route']);
} }
// If the entity isn't fieldable, forbid access. if (!$section_storage instanceof SectionStorageInterface) {
if (!$entity instanceof FieldableEntityInterface || !$entity->hasField('layout_builder__layout')) {
$access = AccessResult::forbidden(); $access = AccessResult::forbidden();
} }
else { else {
$access = AccessResult::allowedIfHasPermission($account, 'configure any layout'); $access = AccessResult::allowedIfHasPermission($account, 'configure any layout');
} }
return $access->addCacheableDependency($entity); return $access->addCacheableDependency($section_storage);
} }
} }
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\Section; use Drupal\layout_builder\Section;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
...@@ -51,10 +51,10 @@ public static function create(ContainerInterface $container) { ...@@ -51,10 +51,10 @@ public static function create(ContainerInterface $container) {
} }
/** /**
* Add the layout to the entity field in a tempstore. * Adds the new section.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* @param int $delta * @param int $delta
* The delta of the section to splice. * The delta of the section to splice.
* @param string $plugin_id * @param string $plugin_id
...@@ -63,18 +63,16 @@ public static function create(ContainerInterface $container) { ...@@ -63,18 +63,16 @@ public static function create(ContainerInterface $container) {
* @return \Symfony\Component\HttpFoundation\Response * @return \Symfony\Component\HttpFoundation\Response
* The controller response. * The controller response.
*/ */
public function build(EntityInterface $entity, $delta, $plugin_id) { public function build(SectionStorageInterface $section_storage, $delta, $plugin_id) {
/** @var \Drupal\layout_builder\SectionStorageInterface $field_list */ $section_storage->insertSection($delta, new Section($plugin_id));
$field_list = $entity->layout_builder__layout;
$field_list->insertSection($delta, new Section($plugin_id));
$this->layoutTempstoreRepository->set($entity); $this->layoutTempstoreRepository->set($section_storage);
if ($this->isAjax()) { if ($this->isAjax()) {
return $this->rebuildAndClose($entity); return $this->rebuildAndClose($section_storage);
} }
else { else {
$url = $entity->toUrl('layout-builder'); $url = $section_storage->getLayoutBuilderUrl();
return new RedirectResponse($url->setAbsolute()->toString()); return new RedirectResponse($url->setAbsolute()->toString());
} }
} }
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
use Drupal\Core\Block\BlockManagerInterface; use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
...@@ -46,8 +46,8 @@ public static function create(ContainerInterface $container) { ...@@ -46,8 +46,8 @@ public static function create(ContainerInterface $container) {
/** /**
* Provides the UI for choosing a new block. * Provides the UI for choosing a new block.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* @param int $delta * @param int $delta
* The delta of the section to splice. * The delta of the section to splice.
* @param string $region * @param string $region
...@@ -56,7 +56,7 @@ public static function create(ContainerInterface $container) { ...@@ -56,7 +56,7 @@ public static function create(ContainerInterface $container) {
* @return array * @return array
* A render array. * A render array.
*/ */
public function build(EntityInterface $entity, $delta, $region) { public function build(SectionStorageInterface $section_storage, $delta, $region) {
$build['#type'] = 'container'; $build['#type'] = 'container';
$build['#attributes']['class'][] = 'block-categories'; $build['#attributes']['class'][] = 'block-categories';
...@@ -72,8 +72,8 @@ public function build(EntityInterface $entity, $delta, $region) { ...@@ -72,8 +72,8 @@ public function build(EntityInterface $entity, $delta, $region) {
'title' => $block['admin_label'], 'title' => $block['admin_label'],
'url' => Url::fromRoute('layout_builder.add_block', 'url' => Url::fromRoute('layout_builder.add_block',
[ [
'entity_type_id' => $entity->getEntityTypeId(), 'section_storage_type' => $section_storage->getStorageType(),
'entity' => $entity->id(), 'section_storage' => $section_storage->getStorageId(),
'delta' => $delta, 'delta' => $delta,
'region' => $region, 'region' => $region,
'plugin_id' => $block_id, 'plugin_id' => $block_id,
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
namespace Drupal\layout_builder\Controller; namespace Drupal\layout_builder\Controller;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface; use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
...@@ -49,15 +49,15 @@ public static function create(ContainerInterface $container) { ...@@ -49,15 +49,15 @@ public static function create(ContainerInterface $container) {
/** /**
* Choose a layout plugin to add as a section. * Choose a layout plugin to add as a section.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* @param int $delta * @param int $delta
* The delta of the section to splice. * The delta of the section to splice.
* *
* @return array * @return array
* The render array. * The render array.
*/ */
public function build(EntityInterface $entity, $delta) { public function build(SectionStorageInterface $section_storage, $delta) {
$output['#title'] = $this->t('Choose a layout'); $output['#title'] = $this->t('Choose a layout');
$items = []; $items = [];
...@@ -75,8 +75,8 @@ public function build(EntityInterface $entity, $delta) { ...@@ -75,8 +75,8 @@ public function build(EntityInterface $entity, $delta) {
'#url' => Url::fromRoute( '#url' => Url::fromRoute(
$layout instanceof PluginFormInterface ? 'layout_builder.configure_section' : 'layout_builder.add_section', $layout instanceof PluginFormInterface ? 'layout_builder.configure_section' : 'layout_builder.add_section',
[ [
'entity_type_id' => $entity->getEntityTypeId(), 'section_storage_type' => $section_storage->getStorageType(),
'entity' => $entity->id(), 'section_storage' => $section_storage->getStorageId(),
'delta' => $delta, 'delta' => $delta,
'plugin_id' => $plugin_id, 'plugin_id' => $plugin_id,
] ]
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand; use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityInterface; use Drupal\layout_builder\SectionStorageInterface;
/** /**
* Provides AJAX responses to rebuild the Layout Builder. * Provides AJAX responses to rebuild the Layout Builder.
...@@ -24,15 +24,15 @@ trait LayoutRebuildTrait { ...@@ -24,15 +24,15 @@ trait LayoutRebuildTrait {
/** /**
* Rebuilds the layout. * Rebuilds the layout.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* *
* @return \Drupal\Core\Ajax\AjaxResponse * @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response to either rebuild the layout and close the dialog, or * An AJAX response to either rebuild the layout and close the dialog, or
* reload the page. * reload the page.
*/ */
protected function rebuildAndClose(EntityInterface $entity) { protected function rebuildAndClose(SectionStorageInterface $section_storage) {
$response = $this->rebuildLayout($entity); $response = $this->rebuildLayout($section_storage);
$response->addCommand(new CloseDialogCommand('#drupal-off-canvas')); $response->addCommand(new CloseDialogCommand('#drupal-off-canvas'));
return $response; return $response;
} }
...@@ -40,17 +40,17 @@ protected function rebuildAndClose(EntityInterface $entity) { ...@@ -40,17 +40,17 @@ protected function rebuildAndClose(EntityInterface $entity) {
/** /**
* Rebuilds the layout. * Rebuilds the layout.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* *
* @return \Drupal\Core\Ajax\AjaxResponse * @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response to either rebuild the layout and close the dialog, or * An AJAX response to either rebuild the layout and close the dialog, or
* reload the page. * reload the page.
*/ */
protected function rebuildLayout(EntityInterface $entity) { protected function rebuildLayout(SectionStorageInterface $section_storage) {
$response = new AjaxResponse(); $response = new AjaxResponse();
$layout_controller = $this->classResolver->getInstanceFromDefinition(LayoutBuilderController::class); $layout_controller = $this->classResolver->getInstanceFromDefinition(LayoutBuilderController::class);
$layout = $layout_controller->layout($entity, TRUE); $layout = $layout_controller->layout($section_storage, TRUE);
$response->addCommand(new ReplaceCommand('#layout-builder', $layout)); $response->addCommand(new ReplaceCommand('#layout-builder', $layout));
return $response; return $response;
} }
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface; use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
...@@ -50,8 +50,8 @@ public static function create(ContainerInterface $container) { ...@@ -50,8 +50,8 @@ public static function create(ContainerInterface $container) {
/** /**
* Moves a block to another region. * Moves a block to another region.
* *
* @param \Drupal\Core\Entity\EntityInterface $entity * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The entity. * The section storage.
* @param int $delta_from * @param int $delta_from
* The delta of the original section. * The delta of the original section.
* @param int $delta_to * @param int $delta_to
...@@ -68,10 +68,8 @@ public static function create(ContainerInterface $container) { ...@@ -68,10 +68,8 @@ public static function create(ContainerInterface $container) {
* @return \Drupal\Core\Ajax\AjaxResponse * @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response. * An AJAX response.
*/ */
public function build(EntityInterface $entity, $delta_from, $delta_to, $region_from, $region_to, $block_uuid, $preceding_block_uuid = NULL) { public function build(SectionStorageInterface $section_storage, $delta_from, $delta_to, $region_from, $region_to, $block_uuid, $preceding_block_uuid = NULL) {
/** @var \Drupal\layout_builder\SectionStorageInterface $field_list */ $section = $section_storage->getSection($delta_from);
$field_list = $entity->layout_builder__layout;
$section = $field_list->getSection($delta_from);