diff --git a/src/LayoutParagraphsRendererService.php b/src/LayoutParagraphsRendererService.php index 0c7c29f56236b6897704e4d2c6e9af4a1feb8977..09791a3146e2f59c2cc0f6c7aa519f9673d46046 100644 --- a/src/LayoutParagraphsRendererService.php +++ b/src/LayoutParagraphsRendererService.php @@ -48,7 +48,9 @@ class LayoutParagraphsRendererService { /** * Renders a single Layout Paragraph Section for the provided paragraph. * - * @param Drupal\paragraphs\Entity\Paragraph $paragraph + * @param array $build + * The build array. + * @param \Drupal\paragraphs\Entity\Paragraph $paragraph * The paragraph entity. * @param string $view_mode * The view mode. diff --git a/src/Plugin/Field/FieldFormatter/LayoutParagraphsFormatter.php b/src/Plugin/Field/FieldFormatter/LayoutParagraphsFormatter.php index 2c3897f7f4705949ff7b3e33742d2ce69e257246..d9ae2bc51a5fe8ea4b0dc8b034d42e76bc3504b3 100644 --- a/src/Plugin/Field/FieldFormatter/LayoutParagraphsFormatter.php +++ b/src/Plugin/Field/FieldFormatter/LayoutParagraphsFormatter.php @@ -42,23 +42,25 @@ class LayoutParagraphsFormatter extends EntityReferenceRevisionsEntityFormatter $entities = []; foreach ($items as $delta => $item) { - // Ignore items where no entity could be loaded in prepareView() and - // items that are not root level components. - if (!empty($item->_loaded) - && LayoutParagraphsComponent::isRootComponent($item->entity)) { + // Ignore items where no entity could be loaded in prepareView(). + if (!empty($item->_loaded)) { $entity = $item->entity; - $access = $this->checkAccess($entity); // Add the access result's cacheability, ::view() needs it. $item->_accessCacheability = CacheableMetadata::createFromObject($access); if ($access->isAllowed()) { - // Set the entity in the correct language for display. - if ($entity instanceof TranslatableInterface) { - $entity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $langcode); - } // Add the referring item, in case the formatter needs it. $entity->_referringItem = $items[$delta]; - $entities[$delta] = $entity; + // Only include root level components. Nested components are rendered + // by their parent respective containers. + // @see Drupal\layout_paragraphs\LayoutParagraphsRendererService. + if (LayoutParagraphsComponent::isRootComponent($item->entity)) { + // Set the entity in the correct language for display. + if ($entity instanceof TranslatableInterface) { + $entity = \Drupal::service('entity.repository')->getTranslationFromContext($entity, $langcode); + } + $entities[$delta] = $entity; + } } } } diff --git a/tests/src/FunctionalJavascript/BuilderTestBase.php b/tests/src/FunctionalJavascript/BuilderTestBase.php index ef4d0917fa006d13e4c352361278427138d16ead..f3fa73b7539b9b2b67a8cd73c463ce453e0f3179 100644 --- a/tests/src/FunctionalJavascript/BuilderTestBase.php +++ b/tests/src/FunctionalJavascript/BuilderTestBase.php @@ -116,6 +116,13 @@ abstract class BuilderTestBase extends WebDriverTestBase { $button = $page->find('css', $css_selector); $button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); + + $title = $page->find('css', '.ui-dialog-title'); + if ($title->getText() == 'Choose a component') { + $page->clickLink('text'); + $this->assertSession()->assertWaitOnAjaxRequest(); + } + $this->assertSession()->pageTextContains('field_text'); $page->fillField('field_text[0][value]', $text); diff --git a/tests/src/FunctionalJavascript/NestedSectionsTest.php b/tests/src/FunctionalJavascript/NestedSectionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f95dad68aea2c03ce5cbfa130f1b9e8249233e2c --- /dev/null +++ b/tests/src/FunctionalJavascript/NestedSectionsTest.php @@ -0,0 +1,86 @@ +<?php + +namespace Drupal\Tests\layout_paragraphs\FunctionalJavascript; + +use Drupal\Core\Entity\Entity\EntityFormDisplay; + +/** + * Tests nested sections including the node preview screen. + * + * @group layout_paragraphs + */ +class NestedSectionsTest extends BuilderTestBase { + + /** + * {@inheritDoc} + */ + protected function setUp(): void { + parent::setUp(); + // Allow nesting sections. + $entity_form_display = EntityFormDisplay::load('node.page.default'); + $component = $entity_form_display->getComponent('field_content'); + $component['settings']['nesting_depth'] = 1; + $entity_form_display + ->setComponent('field_content', $component) + ->save(); + } + + /** + * Tests nested sections. + */ + public function testNestedSections() { + + $this->loginWithPermissions([ + 'create page content', + 'edit own page content', + ]); + + $this->drupalGet('node/add/page'); + $page = $this->getSession()->getPage(); + + // Add a two-column section. + $this->addSectionComponent(1, '.lpb-btn--add'); + // Add a one-column section in region 1. + $this->addSectionComponent(0, '.layout__region--first .lpb-btn--add'); + // Add a three-column section in region 2. + $this->addSectionComponent(2, '.layout__region--second .lpb-btn--add'); + + // Add a text component in each nested section. + $this->addTextComponent('First', '.layout__region--first .layout__region--content .lpb-btn--add'); + $this->addTextComponent('Second', '.layout__region--second .layout__region--first .lpb-btn--add'); + $this->addTextComponent('Third', '.layout__region--second .layout__region--second .lpb-btn--add'); + $this->addTextComponent('Fourth', '.layout__region--second .layout__region--third .lpb-btn--add'); + + // Preview the node. + $this->submitForm([ + 'title[0][value]' => 'Node title', + ], 'Preview'); + + // Check for all the added components. + $this->assertSession()->pageTextContains('First'); + $this->assertSession()->pageTextContains('Second'); + $this->assertSession()->pageTextContains('Third'); + $this->assertSession()->pageTextContains('Fourth'); + + // Back to editing. + $this->clickLink('Back to content editing'); + + // Check for all the added components still on edit tab. + $this->assertSession()->pageTextContains('First'); + $this->assertSession()->pageTextContains('Second'); + $this->assertSession()->pageTextContains('Third'); + $this->assertSession()->pageTextContains('Fourth'); + + // Save the node. + $this->submitForm([ + 'title[0][value]' => 'Node title', + ], 'Save'); + + // Check for all the added components still on view tab. + $this->assertSession()->pageTextContains('First'); + $this->assertSession()->pageTextContains('Second'); + $this->assertSession()->pageTextContains('Third'); + $this->assertSession()->pageTextContains('Fourth'); + } + +}