Background
Layout section storage plugins (i.e., anything implementing \Drupal\layout_builder\SectionStorageInterface) are responsible for loading layout sections. Normally, they would do this by either being given a "section storage ID" -- an arbitrary string identifying where the layout sections are stored -- or deriving that storage ID from the current route. This resulted in a fairly awkward call chain and a couple of SectionStorageInterface methods that were never really supposed to be called by external code.
As of #2976148: Layout-based entity rendering should delegate to the correct section storage instead of hardcoding to either defaults or overrides, this is greatly simplified; section storage plugins use the context system to load layout sections, rather than depending on being given a storage ID. They can also derive a set of relevant contexts from the current route, which may in turn be used to load the layout sections.
Example
Before
This is how one would go about loading layout sections based on the current route (there are methods on \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface to do this grunt work for you, but this will serve to illustrate the general process):
$plugin = \Drupal::service('plugin.manager.layout_builder.section_storage')->loadEmpty('my_storage_plugin');
// Pass in relevant details from the current route to determine a storage ID, if possible.
$storage_id = $plugin->extractIdFromRoute($route_parameter_value, $route_parameter_definition, $route_parameter_name, $route_defaults);
if ($storage_id) {
$layout_sections = $plugin->getSectionListFromId($storage_id);
$plugin->setSectionList($layout_sections);
}
If you didn't have routing information, you pretty much had to load the section list yourself, then call setSectionList(), like so, and hope that the plugin would not reject what you gave it:
$section_list = get_section_list_somehow();
$plugin = \Drupal::service('plugin.manager.layout_builder.section_storage')->loadEmpty('my_storage_plugin');
// Of course, the plugin might throw an exception here if $section_list is not to its liking.
$plugin->setSectionList($section_list)
After
To do the same thing as above, you derive contexts from the route instead, then pass them to the plugin.
$manager = \Drupal::service('plugin.manager.layout_builder.section_storage');
$contexts = $manager->loadEmpty('my_storage_plugin')->deriveContextsFromRoute($route_parameter_value, $route_parameter_definition, $route_parameter_name, $route_defaults);
$plugin = $manager->load('my_storage_plugin', $contexts);
You don't need to use the routing system to load a section list; if you already have context values available, you can pass them directly to a section storage plugin like this:
use Drupal\node\Entity\Node;
use Drupal\Core\Plugin\Context\EntityContext;
$node = Node::load(34);
$node_context = EntityContext::fromEntity($node);
$plugin = \Drupal::service('plugin.manager.layout_builder.section_storage')->load('my_storage_plugin', ['node' => $node_context]);
Section storage plugins can also define the contexts they require, plus an arbitrary weight, like so:
use Drupal\layout_builder\Plugin\SectionStorage\SectionStorageBase;
/**
* @SectionStorage(
* id = "my_storage_plugin",
* context = {
* "entity" = @ContextDefinition("entity"),
* "view_mode" = @ContextDefinition("string", required = FALSE),
* },
* "weight" = -10,
* )
*/
class MyPlugin extends SectionStorageBase {...}
Additionally, it is possible to load a section list with nothing but a set of contexts. \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface now has a findByContext() method which will do this job for you:
use Drupal\node\Entity\Node;
use Drupal\Core\Plugin\Context\EntityContext;
$node = Node::load(34);
$node_context = EntityContext::fromEntity($node);
$plugin = \Drupal::service('plugin.manager.layout_builder.section_storage')->findByContext('my_operation', [
'node' => $node_context,
]);
All section storage plugins which match the given contexts will be evaluated in order of their weight, and the first one which is able to derive a section list from the given contexts will be returned (NULL if returned if none matched).
The first parameter is the $operation that will be passed to SectionStorageInterface::access().
API changes
The following methods have been deprecated:
\Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::loadFromStorageId($type, $id)\Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::loadFromRoute($type, $value, $definition, $name, array $defaults)
And the following methods have been added:
\Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::load($type, array $contexts)\Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::findByContext($operation, array $contexts)