namespace Drupal\layout_builder\Controller;
+use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
use Drupal\layout_builder\SectionStorageInterface;
use AjaxHelperTrait;
use LayoutBuilderContextTrait;
+ use StringTranslationTrait;
/**
* The block manager.
*/
protected $blockManager;
+ /**
+ * The entity type manager.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+ */
+ protected $entityTypeManager;
+
/**
* ChooseBlockController constructor.
*
* @param \Drupal\Core\Block\BlockManagerInterface $block_manager
* The block manager.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
*/
- public function __construct(BlockManagerInterface $block_manager) {
+ public function __construct(BlockManagerInterface $block_manager, EntityTypeManagerInterface $entity_type_manager) {
$this->blockManager = $block_manager;
+ $this->entityTypeManager = $entity_type_manager;
}
/**
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('plugin.manager.block')
+ $container->get('plugin.manager.block'),
+ $container->get('entity_type.manager')
);
}
* A render array.
*/
public function build(SectionStorageInterface $section_storage, $delta, $region) {
- $build['#type'] = 'container';
- $build['#attributes']['class'][] = 'block-categories';
-
- $definitions = $this->blockManager->getDefinitionsForContexts($this->getAvailableContexts($section_storage));
- foreach ($this->blockManager->getGroupedDefinitions($definitions) as $category => $blocks) {
- $build[$category]['#type'] = 'details';
- $build[$category]['#open'] = TRUE;
- $build[$category]['#title'] = $category;
- $build[$category]['links'] = [
- '#theme' => 'links',
- ];
- foreach ($blocks as $block_id => $block) {
- $link = [
- 'title' => $block['admin_label'],
- 'url' => Url::fromRoute('layout_builder.add_block',
- [
- 'section_storage_type' => $section_storage->getStorageType(),
- 'section_storage' => $section_storage->getStorageId(),
- 'delta' => $delta,
- 'region' => $region,
- 'plugin_id' => $block_id,
- ]
- ),
- ];
- if ($this->isAjax()) {
- $link['attributes']['class'][] = 'use-ajax';
- $link['attributes']['data-dialog-type'][] = 'dialog';
- $link['attributes']['data-dialog-renderer'][] = 'off_canvas';
+ $build['#title'] = $this->t('Choose a block');
+ if ($this->entityTypeManager->hasDefinition('block_content_type') && $types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple()) {
+ if (count($types) === 1) {
+ $type = reset($types);
+ $plugin_id = 'inline_block:' . $type->id();
+ if ($this->blockManager->hasDefinition($plugin_id)) {
+ $url = Url::fromRoute('layout_builder.add_block', [
+ 'section_storage_type' => $section_storage->getStorageType(),
+ 'section_storage' => $section_storage->getStorageId(),
+ 'delta' => $delta,
+ 'region' => $region,
+ 'plugin_id' => $plugin_id,
+ ]);
}
- $build[$category]['links']['#links'][] = $link;
+ }
+ else {
+ $url = Url::fromRoute('layout_builder.choose_inline_block', [
+ 'section_storage_type' => $section_storage->getStorageType(),
+ 'section_storage' => $section_storage->getStorageId(),
+ 'delta' => $delta,
+ 'region' => $region,
+ ]);
+ }
+ if (isset($url)) {
+ $build['add_block'] = [
+ '#type' => 'link',
+ '#url' => $url,
+ '#title' => $this->t('Create @entity_type', [
+ '@entity_type' => $this->entityTypeManager->getDefinition('block_content')->getSingularLabel(),
+ ]),
+ '#attributes' => $this->getAjaxAttributes(),
+ ];
+ $build['add_block']['#attributes']['class'][] = 'inline-block-create-button';
}
}
+
+ $block_categories['#type'] = 'container';
+ $block_categories['#attributes']['class'][] = 'block-categories';
+
+ // @todo Explicitly cast delta to an integer, remove this in
+ // https://www.drupal.org/project/drupal/issues/2984509.
+ $delta = (int) $delta;
+
+ $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
+ 'section_storage' => $section_storage,
+ 'delta' => $delta,
+ 'region' => $region,
+ ]);
+ $grouped_definitions = $this->blockManager->getGroupedDefinitions($definitions);
+ foreach ($grouped_definitions as $category => $blocks) {
+ $block_categories[$category]['#type'] = 'details';
+ $block_categories[$category]['#open'] = TRUE;
+ $block_categories[$category]['#title'] = $category;
+ $block_categories[$category]['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks);
+ }
+ $build['block_categories'] = $block_categories;
return $build;
}
+ /**
+ * Provides the UI for choosing a new inline block.
+ *
+ * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
+ * The section storage.
+ * @param int $delta
+ * The delta of the section to splice.
+ * @param string $region
+ * The region the block is going in.
+ *
+ * @return array
+ * A render array.
+ */
+ public function inlineBlockList(SectionStorageInterface $section_storage, $delta, $region) {
+ $definitions = $this->blockManager->getFilteredDefinitions('layout_builder', $this->getAvailableContexts($section_storage), [
+ 'section_storage' => $section_storage,
+ 'region' => $region,
+ 'list' => 'inline_blocks',
+ ]);
+ $blocks = $this->blockManager->getGroupedDefinitions($definitions);
+ $build = [];
+ if (isset($blocks['Inline blocks'])) {
+ $build['links'] = $this->getBlockLinks($section_storage, $delta, $region, $blocks['Inline blocks']);
+ $build['links']['#attributes']['class'][] = 'inline-block-list';
+ foreach ($build['links']['#links'] as &$link) {
+ $link['attributes']['class'][] = 'inline-block-list__item';
+ }
+ $build['back_button'] = [
+ '#type' => 'link',
+ '#url' => Url::fromRoute('layout_builder.choose_block',
+ [
+ 'section_storage_type' => $section_storage->getStorageType(),
+ 'section_storage' => $section_storage->getStorageId(),
+ 'delta' => $delta,
+ 'region' => $region,
+ ]
+ ),
+ '#title' => $this->t('Back'),
+ '#attributes' => $this->getAjaxAttributes(),
+ ];
+ }
+ return $build;
+ }
+
+ /**
+ * Gets a render array of block links.
+ *
+ * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
+ * The section storage.
+ * @param int $delta
+ * The delta of the section to splice.
+ * @param string $region
+ * The region the block is going in.
+ * @param array $blocks
+ * The information for each block.
+ *
+ * @return array
+ * The block links render array.
+ */
+ protected function getBlockLinks(SectionStorageInterface $section_storage, $delta, $region, array $blocks) {
+ $links = [];
+ foreach ($blocks as $block_id => $block) {
+ $link = [
+ 'title' => $block['admin_label'],
+ 'url' => Url::fromRoute('layout_builder.add_block',
+ [
+ 'section_storage_type' => $section_storage->getStorageType(),
+ 'section_storage' => $section_storage->getStorageId(),
+ 'delta' => $delta,
+ 'region' => $region,
+ 'plugin_id' => $block_id,
+ ]
+ ),
+ 'attributes' => $this->getAjaxAttributes(),
+ ];
+
+ $links[] = $link;
+ }
+ return [
+ '#theme' => 'links',
+ '#links' => $links,
+ ];
+ }
+
+ /**
+ * Get dialog attributes if an ajax request.
+ *
+ * @return array
+ * The attributes array.
+ */
+ protected function getAjaxAttributes() {
+ if ($this->isAjax()) {
+ return [
+ 'class' => ['use-ajax'],
+ 'data-dialog-type' => 'dialog',
+ 'data-dialog-renderer' => 'off_canvas',
+ ];
+ }
+ return [];
+ }
+
}