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
:
$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 you 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?