- 🇺🇸United States luke.leber Pennsylvania
Huge +1, but I think that adding a delete option may slow things down a bit.
Very rough attempt at something like this! Probably riddles with gotchas and short-sightedness, but I wanted to continue to conversation!
<?php use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Url; /** * Implements hook_form_alter(). */ function lb_block_fork_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id === 'layout_builder_add_block' || $form_id === 'layout_builder_update_block') { /** @var \Drupal\layout_builder\Form\ConfigureBlockFormBase $configure_form */ $configure_form = $form_state->getFormObject(); $component = $configure_form->getCurrentComponent(); $config = $component->get('configuration'); if (isset($config['id']) && str_starts_with($config['id'], 'block_content:')) { $form['#prefix'] = '<div id="fork-block">'; $form['#suffix'] = '</div>'; $form['settings']['fork'] = [ '#type' => 'container', ]; $form['settings']['fork']['notice'] = [ '#type' => 'html_tag', '#tag' => 'strong', '#value' => new TranslatableMarkup('This is a reusable block, create inline copy?'), ]; $form['settings']['fork']['action'] = [ '#type' => 'button', '#value' => new TranslatableMarkup('Copy'), '#ajax' => [ 'callback' => '_lb_block_fork_callback', 'wrapper' => 'fork-block', ], ]; } } } function _lb_block_fork_callback(array &$form, FormStateInterface $form_state) { /** @var \Drupal\layout_builder\Form\ConfigureBlockFormBase $configure_form */ $configure_form = $form_state->getFormObject(); $section_storage = $configure_form->getSectionStorage(); $section = $configure_form->getCurrentSection(); $component = $configure_form->getCurrentComponent(); $config = $component->get('configuration'); $parts = explode(':', $config['id']); /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository */ $entity_repository = \Drupal::service('entity.repository'); /** @var \Drupal\block_content\BlockContentInterface $block */ $block = $entity_repository->loadEntityByUuid('block_content', $parts[1]); if ($block) { $clone = $block->createDuplicate(); $clone->setNonReusable(); $component->setConfiguration([ 'id' => "inline_block:{$block->bundle()}", 'label' => $form_state->getValue(['settings', 'label']), 'label_display' => $form_state->getValue(['settings', 'label_display']), 'provider' => 'layout_builder', 'view_mode' => 'full', 'context_mapping' => [], 'block_revision_id' => $block->getRevisionId(), 'block_serialized' => NULL, ]); /** @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $tempstore */ $tempstore = \Drupal::service('layout_builder.tempstore_repository'); $tempstore->set($section_storage); $form_state->setRedirectUrl(Url::fromRoute('layout_builder.update_block', [ 'section_storage_type' => $section_storage->getStorageType(), 'section_storage' => $section_storage->getStorageId(), 'delta' => array_search($section, $section_storage->getSections()), 'region' => $component->getRegion(), 'uuid' => $component->getUuid(), ])); } return $form; }