Puncte:1

Drupal 8/9 Layout Builder și bloc personalizat implicit

drapel fr

Avem o serie de blocuri personalizate pe care le-am creat și folosim Layout Builder, astfel încât autorii noștri să poată doar glisați și plasați după cum este necesar. Avem în special un bloc Hero pe care ne-am dori să-l vedem pe fiecare pagină (personalizat pe pagină) și ne-ar plăcea să inserăm automat unul la crearea nodurilor pentru ușurință de creare. Aproape că puteți face acest lucru prin aspecte implicite pentru tipul de conținut, dar blocul implicit acționează mai mult ca un bloc reutilizabil. Prima pagină primește blocul gol, utilizatorul îl editează și salvează. Orice pagină ulterioară obține apoi versiunea editată.

Rulez următoarele într-un hook_preprocess_HOOK (hook_preprocess_page specific):

$layoutBuilder = $node->get('layout_builder__layout');
$secțiuni = $layoutBuilder->getSections();
if (isset($secțiuni) && !empty($secțiuni)) {
  $hasHero = FALSE;
  $heroSection = $sectiuni[0];
  $componente = $heroSection->getComponents();
  foreach ($componente ca $component) {
    $blockPlugin = $component->getPlugin();
    if ($blockPlugin instanceof BlockBase) {
      $blockConfig = $blockPlugin->getConfiguration();
      dacă ($blockConfig['id'] === 'hero_cta') {
        $hasHero = TRUE;
        pauză;
      }
    }
  }
  dacă (!$hasHero) {
    $blockEntityManager = \Drupal::entityTypeManager()
      ->getStorage('block_content');

    $block = $blockEntityManager->create(
      [
        'info' => 'CTA erou pentru nod/' . $nid,
        'type' => 'hero_cta',
        'langcode' => 'ro',
      ]
    );
    $bloc->salvare();

    $newBlockConfig = [
      'id' => 'hero_cta',
      'provider' => 'hero_cta',
      'label_display' => TRUE,
      'block_id' => $block->id(),
      'context_mapping' => [],
    ];
    $newComponent = new SectionComponent($nod->uuid(), 'conţinut', $newBlockConfig);
    $heroSection->appendComponent($newComponent);

    $nod->salvare();
  }
}

Cele de mai sus aproape funcționează...Când merg la fila Vizualizare, o pot vedea. Dar, când merg la fila aspect, nu este acolo. Dacă salvați modificarea aspectului, apoi reîmprospăta din nou, apare brusc.

Deci, cu ce greșesc?

apaderno avatar
drapel us
În ce `hook_preprocess_HOOK()` este folosit exact acel cod? Totuși, `hook_preprocess_HOOK()` este probabil locul greșit pentru a salva un bloc.
drapel fr
Ooop, da, întrebarea editată cu acele informații suplimentare @apaderno - utilizând în prezent `hook_preprocess_page`. Se părea că acesta a fost cel mai bun loc pentru a încerca și a efectua această sarcină după ce tipul de conținut este salvat prima dată. Blocul este într-adevăr creat, dar conexiunea lui la componenta secțiunii este locul în care eșuează pentru mine. Deci, da, sincronizarea adecvată a funcției ar putea fi problema mea.
Puncte:0
drapel fr

Bine, echipa noastră a găsit în cele din urmă soluția pe care o căutam, așa că postați aici în cazul în care altcineva încearcă să facă asta! În cele din urmă, așa cum am subliniat, inițial făceam asta într-un cârlig de preprocesare - care a fost apoi suprascris de setările implicite de aspect. Iată ce a funcționat:

funcția protejată prepareLayout(SectionStorageInterface $section_storage) {
  parent::prepareLayout($section_storage);
  $storageContext = $section_storage->getContexts();
  $nod = $storageContext['entity']->getContextData()->getValue();
  dacă (isset($nod)) {
    dacă ($node->hasField(OverridesSectionStorage::FIELD_NAME)) {
      $nid = $nod->id();
      $layoutBuilder = $node->get(OverridesSectionStorage::FIELD_NAME);
      $secțiuni = $layoutBuilder->getSections();
      if (isset($secțiuni) && !empty($secțiuni)) {
        // Setați configurația implicită pentru a compara pentru a vă asigura că pagina a fost generată.
        $defaultHeroSection = $section_storage->getDefaultSectionStorage()->getSection(0);
        $defaultHeroCount = count($defaultHeroSection->getComponents());

        // Prima secțiune este regiunea noastră „Hero CTA”. Verificați existența.
        $hasHero = FALSE;
        $heroSection = $layoutBuilder->getSection(0);
        $heroComponents = $heroSection->getComponents();
        $currentHeroCount = count($heroComponents);
        dacă ($defaultHeroCount === $currentHeroCount) {
          foreach ($heroComponents ca $component) {
            $blockPlugin = $component->getPlugin();
            if ($blockPlugin instanceof BlockBase) {
              $blockConfig = $blockPlugin->getConfiguration();
              dacă ($blockConfig['id'] === 'hero_cta') {
                $hasHero = TRUE;
                pauză;
              }
            }
          }
          dacă (!$hasHero) {
            $blockEntityManager = \Drupal::entityTypeManager()->getStorage('block_content');

            // Creați un bloc nou, gol, Hero CTA.
            $block = $blockEntityManager->create(
              [
                'info' => 'CTA erou pentru nod/' . $nid,
                'type' => 'hero_cta',
                'langcode' => 'ro',
              ]
            );
            $bloc->salvare();

            // Inserați un nou bloc Hero CTA în secțiunea corespunzătoare.
            $newBlockConfig = [
              'id' => 'hero_cta',
              'provider' => 'hero_cta',
              'label_display' => TRUE,
              'block_id' => $block->id(),
              'context_mapping' => [],
            ];
            $newComponent = new SectionComponent($nod->uuid(), 'conţinut', $newBlockConfig);
            $heroSection->appendComponent($newComponent);
          }
          // Eliminați prima secțiune originală și blocurile neutilizate.
          $section_storage->removeSection(0);
          // Reintroduceți prima secțiune.
          $section_storage->insertSection(0, $heroSection);
          $this->layoutTempstoreRepository->set($section_storage);
          // Salvează modificările.
          $nod->salvare(); 
        }
      }
    }
  }
}
drapel fr
Și, dacă cineva întâlnește acest thread și are nevoie de o soluție D9, va trebui să mutați această funcționalitate într-un abonat la eveniment.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.