Рейтинг:1

Drupal 8/9 Layout Builder и пользовательский блок по умолчанию

флаг fr

У нас есть несколько пользовательских блоков, которые мы создали, и мы используем Layout Builder, чтобы наши авторы могли просто перетаскивать их по мере необходимости. В частности, у нас есть один блок Hero, который мы хотели бы видеть на каждой странице (настраиваемый для каждой страницы), и хотели бы автоматически вставлять его при создании узла для простоты разработки. Вы почти можете сделать это с помощью макетов по умолчанию для типа контента, но блок по умолчанию больше похож на повторно используемый блок. Первая страница получает пустой блок, пользователь редактирует его и сохраняет. Любая последующая страница получит эту отредактированную версию.

Я запускаю следующее в hook_preprocess_HOOK (hook_preprocess_page конкретно):

$layoutBuilder = $node->get('layout_builder__layout');
$sections = $layoutBuilder->getSections();
если (isset($sections) && !пусто($sections)) {
  $hasHero = ЛОЖЬ;
  $heroSection = $sections[0];
  $components = $heroSection->getComponents();
  foreach ($components as $component) {
    $blockPlugin = $component->getPlugin();
    если ($blockPlugin instanceof BlockBase) {
      $blockConfig = $blockPlugin->getConfiguration();
      если ($blockConfig['id'] === 'hero_cta') {
        $hasHero = ИСТИНА;
        сломать;
      }
    }
  }
  если (!$hasHero) {
    $blockEntityManager = \Drupal::entityTypeManager()
      ->getStorage('block_content');

    $block = $blockEntityManager->создать(
      [
        'info' => 'Главный призыв к действию для узла/' . $нид,
        'тип' => 'hero_cta',
        'langcode' => 'en',
      ]
    );
    $блок->сохранить();

    $newBlockConfig = [
      'id' => 'hero_cta',
      'поставщик' => 'hero_cta',
      'label_display' => ИСТИНА,
      'block_id' => $block->id(),
      'context_mapping' => [],
    ];
    $newComponent = новый SectionComponent($node->uuid(), 'content', $newBlockConfig);
    $heroSection->appendComponent($newComponent);

    $узел->сохранить();
  }
}

Вышеупомянутое почти работает...Когда я перехожу на вкладку «Вид», я вижу это. Но, когда я перехожу на вкладку макета, его там нет. Если вы сохраните переопределение макета, а затем обновить опять вдруг появляется.

Итак, что я делаю неправильно?

apaderno avatar
флаг us
В каком именно `hook_preprocess_HOOK()` используется именно этот код? Однако `hook_preprocess_HOOK()`, вероятно, не подходит для сохранения блока.
флаг fr
Ой, да, отредактировал вопрос с этой дополнительной информацией @apaderno - в настоящее время используется `hook_preprocess_page`. Казалось, что это лучшее место, где можно попытаться выполнить эту задачу после того, как тип контента будет сохранен в первый раз. Блок действительно создается, но его соединение с компонентом раздела у меня немного не работает. Так что да, подходящее время функции может быть моей проблемой.
Рейтинг:0
флаг fr

Хорошо, наша команда в конце концов нашла решение, которое нам было нужно, так что пишите сюда на случай, если кто-то еще попытается это сделать! В конечном счете, как уже отмечалось, я изначально делал это в хуке предварительной обработки - который затем перезаписывался макетом по умолчанию. Вот что сработало:

защищенная функция prepareLayout(SectionStorageInterface $section_storage) {
  родитель::prepareLayout($section_storage);
  $storageContext = $section_storage->getContexts();
  $node = $storageContext['entity']->getContextData()->getValue();
  если (установить ($ узел)) {
    если ($node->hasField(OverridesSectionStorage::FIELD_NAME)) {
      $nid = $node->id();
      $layoutBuilder = $node->get(OverridesSectionStorage::FIELD_NAME);
      $sections = $layoutBuilder->getSections();
      если (isset($sections) && !пусто($sections)) {
        // Установите конфигурацию по умолчанию для сравнения, чтобы убедиться, что страница создана.
        $defaultHeroSection = $section_storage->getDefaultSectionStorage()->getSection(0);
        $defaultHeroCount = количество($defaultHeroSection->getComponents());

        // Первый раздел — это наш регион «Герой CTA». Проверить наличие.
        $hasHero = ЛОЖЬ;
        $heroSection = $layoutBuilder->getSection(0);
        $heroComponents = $heroSection->getComponents();
        $currentHeroCount = количество($heroComponents);
        если ($ defaultHeroCount === $currentHeroCount) {
          foreach ($heroComponents как $component) {
            $blockPlugin = $component->getPlugin();
            если ($blockPlugin instanceof BlockBase) {
              $blockConfig = $blockPlugin->getConfiguration();
              если ($blockConfig['id'] === 'hero_cta') {
                $hasHero = ИСТИНА;
                сломать;
              }
            }
          }
          если (!$hasHero) {
            $blockEntityManager = \Drupal::entityTypeManager()->getStorage('block_content');

            // Создать новый пустой блок призыва к действию Hero.
            $block = $blockEntityManager->создать(
              [
                'info' => 'Главный призыв к действию для узла/' . $нид,
                'тип' => 'hero_cta',
                'langcode' => 'en',
              ]
            );
            $блок->сохранить();

            // Вставьте новый блок призыва к действию Hero в соответствующий раздел.
            $newBlockConfig = [
              'id' => 'hero_cta',
              'поставщик' => 'hero_cta',
              'label_display' => ИСТИНА,
              'block_id' => $block->id(),
              'context_mapping' => [],
            ];
            $newComponent = новый SectionComponent($node->uuid(), 'content', $newBlockConfig);
            $heroSection->appendComponent($newComponent);
          }
          // Удалить исходный первый раздел и неиспользуемые блоки.
          $section_storage->удалитьраздел(0);
          // Повторно вставляем первый раздел.
          $section_storage->insertSection(0, $heroSection);
          $this->layoutTempstoreRepository->set($section_storage);
          // Сохраняем изменения.
          $узел->сохранить(); 
        }
      }
    }
  }
}
флаг fr
И если кто-то наткнется на этот поток и ему понадобится решение D9, вам нужно будет переместить эту функциональность в подписчик событий.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.