We have a number of custom blocks that we've created, and use Layout Builder so that our authors can just drag and drop as needed. We have one Hero block in particular that we would like to see on every page (customized per page), and would love to automatically insert one on node creation for ease of authoring. You can almost do this via default layouts for the content type, but the default block acts more like a reusable block. The first page gets the empty block, user edits it and saves. Any subsequent page then get that edited version.
I'm running the following in a hook_preprocess_HOOK
(hook_preprocess_page
specifically):
$layoutBuilder = $node->get('layout_builder__layout');
$sections = $layoutBuilder->getSections();
if (isset($sections) && !empty($sections)) {
$hasHero = FALSE;
$heroSection = $sections[0];
$components = $heroSection->getComponents();
foreach ($components as $component) {
$blockPlugin = $component->getPlugin();
if ($blockPlugin instanceof BlockBase) {
$blockConfig = $blockPlugin->getConfiguration();
if ($blockConfig['id'] === 'hero_cta') {
$hasHero = TRUE;
break;
}
}
}
if (!$hasHero) {
$blockEntityManager = \Drupal::entityTypeManager()
->getStorage('block_content');
$block = $blockEntityManager->create(
[
'info' => 'Hero CTA for node/' . $nid,
'type' => 'hero_cta',
'langcode' => 'en',
]
);
$block->save();
$newBlockConfig = [
'id' => 'hero_cta',
'provider' => 'hero_cta',
'label_display' => TRUE,
'block_id' => $block->id(),
'context_mapping' => [],
];
$newComponent = new SectionComponent($node->uuid(), 'content', $newBlockConfig);
$heroSection->appendComponent($newComponent);
$node->save();
}
}
The above almost works... When I go to the View tab, I can see it. But, when I go to the layout tab, it is not there. If you save the layout override, and then refresh again, it suddenly appears.
So, what am I doing wrong?