Drupal - Delete a block of all layouts

here it is, tried it with a custom content block and a views block

i executed the code in php/devel from devel_php module

$storage = \Drupal::entityTypeManager()->getStorage('entity_view_display');
foreach ($storage->loadMultiple() as $display) {
  foreach ($display->getSections() as $section) {
    foreach ($section->getComponents() as $component) {
      // Custom views block
      // $to_delete_plugin_id = 'views_block:my_news-block_1';
      // Custom block
      $to_delete_plugin_id = 'block_content:fb4ad848-0f3c-4296-a6ba-1a9da886335b';
      if ($component->getPluginId() == $to_delete_plugin_id) {
        $section->removeComponent($component->getUuid());
        $display->save();
      }
    }
  }
}

for a particular node :

// This can be adapted to be used for a set of nodes
$node = node_load(42);
$display = $node->layout_builder__layout;

foreach ($display->getSections() as $section) {
  foreach ($section->getComponents() as $component) {
    // Custom views block
    // $to_delete_plugin_id = 'views_block:my_news-block_1';
    // Custom block
    $to_delete_plugin_id = 'block_content:fb4ad848-0f3c-4296-a6ba-1a9da886335b';
    if ($component->getPluginId() == $to_delete_plugin_id) {
      $section->removeComponent($component->getUuid());
      $node->save();
    }
  }
} 

Hope this helps :)


Assuming you're using Layout Builder on a Node, and you're using "overrides" to allow each content to have it's own unique layout, the data you're looking for is in the node__layout_builder__layout table. You can look there and see that it stores a reference to the "ID" of the entity, and the UUID of the content. So, in the case of a block, because you may have deleted the instance, it will fail to find the UUID of this block content, and display the warning message.

I figured this would make a good contrib project, so I've created "Layout Builder Block Sanitizer", and released a dev version that allows you to go to a form, type in a node ID, and it will scan each section on that node automatically for "block_content" that no longer exists, and remove it. Let me know if this helps out. As I've noted on the project page, this could definitely scale up and improve quite a bit from the current state, but should possibly help you out in this situation.

Check out the project here: https://www.drupal.org/project/layout_builder_block_sanitizer

Tags:

8

Blocks