diff --git a/Build/phpstan13.neon b/Build/phpstan13.neon
index 11670234..4ab3f99c 100644
--- a/Build/phpstan13.neon
+++ b/Build/phpstan13.neon
@@ -12,5 +12,5 @@ parameters:
- %currentWorkingDirectory%/Classes/Listener/PageContentPreviewRendering.php
- %currentWorkingDirectory%/Classes/Listener/ManipulateBackendLayoutColPosConfigurationForPage.php
- %currentWorkingDirectory%/Classes/Hooks/Datahandler/ContentElementRestriction
- - %currentWorkingDirectory%/Classes/Listener/IsReferenceConsideredForDependency.php
-
+ - %currentWorkingDirectory%/Classes/DataProcessing/ContentAreaProcessor.php
+ - %currentWorkingDirectory%/Classes/Listener/IsReferenceConsideredForDependency.php
\ No newline at end of file
diff --git a/Classes/DataProcessing/ContentAreaProcessor.php b/Classes/DataProcessing/ContentAreaProcessor.php
new file mode 100644
index 00000000..f189938a
--- /dev/null
+++ b/Classes/DataProcessing/ContentAreaProcessor.php
@@ -0,0 +1,136 @@
+
+ */
+#[Autoconfigure(public: true)]
+readonly class ContentAreaProcessor implements DataProcessorInterface
+{
+ public function __construct(
+ protected ContentDataProcessor $contentDataProcessor,
+ protected Context $context,
+ protected FrontendContainerFactory $frontendContainerFactory,
+ protected Registry $tcaRegistry,
+ protected RecordFactory $recordFactory,
+ protected Typo3Version $typo3Version,
+ protected LoggerInterface $logger,
+ ) {
+ }
+
+ public function process(
+ ContentObjectRenderer $cObj,
+ array $contentObjectConfiguration,
+ array $processorConfiguration,
+ array $processedData,
+ ): array {
+ if ($this->typo3Version->getMajorVersion() < 14) {
+ $this->logger->error(ContentAreaProcessor::class . ' requires TYPO3 v14 or higher. Please check your configuration.');
+ return $processedData;
+ }
+
+ if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
+ return $processedData;
+ }
+ $contentId = null;
+ if ($processorConfiguration['contentId.'] ?? false) {
+ $contentId = (int)$cObj->stdWrap($processorConfiguration['contentId'] ?? '', $processorConfiguration['contentId.']);
+ } elseif ($processorConfiguration['contentId'] ?? false) {
+ $contentId = (int)$processorConfiguration['contentId'];
+ }
+ if ($contentId !== null) {
+ $records = $cObj->getRecords('tt_content', ['uidInList' => $contentId, 'pidInList' => 0]);
+ if (empty($records)) {
+ return $processedData;
+ }
+ $record = $records[0];
+ } else {
+ $record = $cObj->data;
+ }
+
+ $CType = $record['CType'] ?? '';
+ if (!$this->tcaRegistry->isContainerElement($CType)) {
+ return $processedData;
+ }
+
+ $columnsColPos = $this->tcaRegistry->getAllAvailableColumnsColPos($CType);
+
+ $container = null;
+
+ $areas = [];
+ foreach ($columnsColPos as $colPos) {
+ $areas[$colPos] = new ContentAreaClosure(
+ function () use (&$container, $CType, $cObj, $record, $colPos): ContentArea {
+ $container ??= $this->frontendContainerFactory->buildContainer($cObj, $this->context, (int)$record['uid']);
+
+ $contentDefenderConfiguration = $this->tcaRegistry->getContentDefenderConfiguration($CType, $colPos);
+
+ $rows = $container->getChildrenByColPos($colPos);
+
+ $records = array_map(fn ($row) => $this->recordFactory->createFromDatabaseRow('tt_content', $row), $rows);
+ return new ContentArea(
+ (string)$colPos,
+ $this->tcaRegistry->getColPosName($record['CType'], $colPos),
+ $colPos,
+ ContentSlideMode::None,
+ GeneralUtility::trimExplode(',', $contentDefenderConfiguration['allowedContentTypes'] ?? '', true),
+ GeneralUtility::trimExplode(',', $contentDefenderConfiguration['disallowedContentTypes'] ?? '', true),
+ [
+ 'container' => $container,
+ ],
+ $records,
+ );
+ },
+ );
+ }
+
+ $processedData[$processorConfiguration['as'] ?? 'content'] = (new ContentAreaCollection($areas))->withRequest($cObj->getRequest());
+ return $processedData;
+ }
+}
diff --git a/Classes/Tca/Registry.php b/Classes/Tca/Registry.php
index 4cbe3002..f38c1b8f 100644
--- a/Classes/Tca/Registry.php
+++ b/Classes/Tca/Registry.php
@@ -232,6 +232,19 @@ public function getContainerLabel(string $cType): string
return $GLOBALS['TCA']['tt_content']['containerConfiguration'][$cType]['label'] ?? $cType;
}
+ public function getColPosName(string $cType, int $colPos): ?string
+ {
+ $grid = $this->getGrid($cType);
+ foreach ($grid as $row) {
+ foreach ($row as $column) {
+ if ($column['colPos'] === $colPos) {
+ return (string)$column['name'];
+ }
+ }
+ }
+ return null;
+ }
+
public function getAvailableColumns(string $cType): array
{
$columns = [];
diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml
index bde54796..1d38b620 100644
--- a/Configuration/Services.yaml
+++ b/Configuration/Services.yaml
@@ -16,4 +16,7 @@ services:
B13\Container\DataProcessing\ContainerProcessor:
tags:
- - { name: 'data.processor', identifier: 'container' }
\ No newline at end of file
+ - { name: 'data.processor', identifier: 'container' }
+ B13\Container\DataProcessing\ContentAreaProcessor:
+ tags:
+ - { name: 'data.processor', identifier: 'container-content-area' }
\ No newline at end of file
diff --git a/README.md b/README.md
index fb0c27f3..35a4e6cf 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,47 @@ The HTML template file goes in the folder you defined in your TypoScript above (
With explicit colPos defined use `{children_200|201}` as set in the example above
+## ContentAreaProcessor for TYPO3 v14 or above
+
+for TYPO3 v14 or higher you can use the ConentAreaProcessor
+Automatically detects if content element has container columns
+adds them lazily to the content variable.
+The ContentArea can be used in f:render.contentArea or f:render.record ViewHelper
+
+
+### TypoScript
+
+ tt_content.b13-2cols-with-header-container < lib.contentElement
+ tt_content.b13-2cols-with-header-container {
+ templateName = 2ColsWithHeader
+ templateRootPaths {
+ 10 = EXT:container_example/Resources/Private/Templates
+ }
+ dataProcessing {
+ 100 = B13\Container\DataProcessing\ContentAreaProcessor
+ }
+ }
+
+### Options for ContentAreaProcessor
+
+| Option | Description | Default | Parameter |
+|-----------------------------|-----------------------------------|-------------------------------------------------------|-------------|
+| `contentId` | id of container to to process | current uid of content element ``$cObj->data['uid']`` | ``?int`` |
+| `as` | variable to use for proceesedData | ``content`` | ``?string`` |
+
+### Template
+
+```html
+
+
+
+
+
+ {record -> f:render.record()}
+
+
+```
+
## PSR-14 Events
### BeforeContainerConfigurationIsAppliedEvent
diff --git a/Tests/Functional/Frontend/ContentArea/DefaultLanguageTest.php b/Tests/Functional/Frontend/ContentArea/DefaultLanguageTest.php
new file mode 100644
index 00000000..5e7e48f1
--- /dev/null
+++ b/Tests/Functional/Frontend/ContentArea/DefaultLanguageTest.php
@@ -0,0 +1,90 @@
+importCSVDataSet(__DIR__ . '/../Fixtures/default_language.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ ],
+ ]
+ );
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ // rendered content
+ self::assertStringContainsString('
container-default
', $body);
+ self::assertStringContainsString('', $body);
+ self::assertStringContainsString('left-side-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childrenAreRenderedAsSorted(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/ContainerWithTwoChildren.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/container_with_two_children.typoscript',
+ ],
+ ]
+ );
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('first child
second child
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function canRenderContainerFromOtherPage(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/ContainerFromOtherPage.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/container_from_other_page.typoscript',
+ ],
+ ]
+ );
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('', $body);
+ }
+}
diff --git a/Tests/Functional/Frontend/ContentArea/LanguageFallbackTest.php b/Tests/Functional/Frontend/ContentArea/LanguageFallbackTest.php
new file mode 100644
index 00000000..8ab4a68c
--- /dev/null
+++ b/Tests/Functional/Frontend/ContentArea/LanguageFallbackTest.php
@@ -0,0 +1,127 @@
+importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/setup.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ ],
+ ]
+ );
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function nothingTranslated(): void
+ {
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/fr'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-default
', $body);
+ self::assertStringNotContainsString('container-fr
', $body);
+ self::assertStringContainsString('header-default
', $body);
+ self::assertStringNotContainsString('header-fr
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function bothTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/tt_content_both_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/fr'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-fr
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ self::assertStringContainsString('header-fr
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function fallbackForStrictLanguageToOtherTranslationFreeMode(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/tt_content_fallback_for_strict_language_to_other_translation_free_mode.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/ch'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-de
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ // rendered content
+ self::assertStringContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function bothTranslatedTranslatedChildHidden(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/tt_content_both_translated_tranlated_child_hidden.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/fr'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-fr
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ self::assertStringNotContainsString('header-fr
', $body);
+ self::assertStringContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/tt_content_child_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/fr'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-default
', $body);
+ self::assertStringNotContainsString('container-fr
', $body);
+ // rendered content
+ self::assertStringContainsString('header-fr
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function containerTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageFallback/tt_content_container_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/fr'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-fr
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ // rendered content
+ self::assertStringNotContainsString('header-fr
', $body);
+ self::assertStringContainsString('header-default
', $body);
+ }
+}
diff --git a/Tests/Functional/Frontend/ContentArea/LanguageStrictTest.php b/Tests/Functional/Frontend/ContentArea/LanguageStrictTest.php
new file mode 100644
index 00000000..a0028896
--- /dev/null
+++ b/Tests/Functional/Frontend/ContentArea/LanguageStrictTest.php
@@ -0,0 +1,114 @@
+importCSVDataSet(__DIR__ . '/../Fixtures/LanguageStrict/setup.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ ],
+ ]
+ );
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function nothingTranslated(): void
+ {
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringNotContainsString('container-default
', $body);
+ self::assertStringNotContainsString('container-de
', $body);
+ // rendered content
+ self::assertStringNotContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function bothTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageStrict/tt_content_both_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-de
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ // rendered content
+ self::assertStringContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function bothTranslatedTranslatedChildHidden(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageStrict/tt_content_both_translated_tranlated_child_hidden.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-de
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ // rendered content
+ self::assertStringNotContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageStrict/tt_content_child_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringNotContainsString('container-default
', $body);
+ self::assertStringNotContainsString('container-de
', $body);
+ // rendered content
+ self::assertStringNotContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function containerTranslated(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/LanguageStrict/tt_content_container_translated.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('container-de
', $body);
+ self::assertStringNotContainsString('container-default
', $body);
+ // rendered content
+ self::assertStringNotContainsString('header-de
', $body);
+ self::assertStringNotContainsString('header-default
', $body);
+ }
+}
diff --git a/Tests/Functional/Frontend/ContentArea/SiteLanguageFreeTest.php b/Tests/Functional/Frontend/ContentArea/SiteLanguageFreeTest.php
new file mode 100644
index 00000000..078e93d4
--- /dev/null
+++ b/Tests/Functional/Frontend/ContentArea/SiteLanguageFreeTest.php
@@ -0,0 +1,47 @@
+importCSVDataSet(__DIR__ . '/../Fixtures/SiteLanguageFree/setup.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ ],
+ ]
+ );
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function containerTranslatedInFreeModeSiteConfiguration(): void
+ {
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/en-free'));
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringNotContainsString('header-default
', $body);
+ self::assertStringContainsString('header-translated
', $body);
+ }
+}
diff --git a/Tests/Functional/Frontend/ContentArea/WorkspaceTest.php b/Tests/Functional/Frontend/ContentArea/WorkspaceTest.php
new file mode 100644
index 00000000..68d0e7ce
--- /dev/null
+++ b/Tests/Functional/Frontend/ContentArea/WorkspaceTest.php
@@ -0,0 +1,138 @@
+importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/setup.csv');
+ $this->setUpFrontendRootPage(
+ 1,
+ [
+ 'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExampleContentArea/setup.typoscript',
+ ],
+ ]
+ );
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childInLiveIsRendered(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_with_ws_child.csv');
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest());
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('header-live
', $body);
+ self::assertStringNotContainsString('header-ws
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childInWorkspaceIsRendered(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_with_ws_child.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest(), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('header-ws
', $body);
+ self::assertStringNotContainsString('header-live
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childInWorkspaceIsRenderedIfMovedFromOutsideContainer(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_with_ws_child_moved_from_outside.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest(), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('header-ws
', $body);
+ self::assertStringNotContainsString('header-live
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childInWorkspaceIsRenderendIfContainerIsMovedToOtherPage(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/other_page.csv');
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_moved_to_other_page.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest(), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('header-ws
', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function containerInWorkspaceIsRenderedWhenLiveVersionIsHidden(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_in_ws_whith_hidden_live_version.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest(), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('ws-container-header', $body);
+ self::assertStringContainsString('live-child-header', $body);
+ self::assertStringNotContainsString('live-container-header', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function childInWorkspaceIsRenderedWhenLiveVersionIsHidden(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/child_in_ws_whith_hidden_live_version.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest(), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('live-container-header', $body);
+ self::assertStringContainsString('ws-child-header', $body);
+ self::assertStringNotContainsString('live-child-header', $body);
+ }
+
+ #[Test]
+ #[Group('frontend')]
+ #[Group('v14-only')]
+ public function localizedChildInWorkspaceIsRenderendIfContainerWithLocalizationIsMovedToOtherPage(): void
+ {
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/other_page.csv');
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/localized_pages.csv');
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/container_moved_to_other_page.csv');
+ $this->importCSVDataSet(__DIR__ . '/../Fixtures/Workspace/localized_container_moved_to_other_page.csv');
+ $context = (new InternalRequestContext())->withWorkspaceId(1)->withBackendUserId(1);
+ $response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/de/'), $context);
+ $body = (string)$response->getBody();
+ $body = $this->prepareContent($body);
+ self::assertStringContainsString('header-ws loc
', $body);
+ }
+}
diff --git a/Tests/Functional/Frontend/DataProcessorWithDataTest.php b/Tests/Functional/Frontend/DataProcessorWithDataTest.php
index 5dc7e722..a49db3e6 100644
--- a/Tests/Functional/Frontend/DataProcessorWithDataTest.php
+++ b/Tests/Functional/Frontend/DataProcessorWithDataTest.php
@@ -28,7 +28,7 @@ protected function setUp(): void
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
'setup' => [
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
- 'EXT:container_example/Configuration/TypoScript/2cols.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
],
]
);
diff --git a/Tests/Functional/Frontend/DataProcessorWithFilesTest.php b/Tests/Functional/Frontend/DataProcessorWithFilesTest.php
index b964f7d5..50895826 100644
--- a/Tests/Functional/Frontend/DataProcessorWithFilesTest.php
+++ b/Tests/Functional/Frontend/DataProcessorWithFilesTest.php
@@ -28,7 +28,7 @@ protected function setUp(): void
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
'setup' => [
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
- 'EXT:container_example/Configuration/TypoScript/2cols.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
],
]
);
diff --git a/Tests/Functional/Frontend/DataProcessorWithIrreTest.php b/Tests/Functional/Frontend/DataProcessorWithIrreTest.php
index 43b05458..d2b5f0a9 100644
--- a/Tests/Functional/Frontend/DataProcessorWithIrreTest.php
+++ b/Tests/Functional/Frontend/DataProcessorWithIrreTest.php
@@ -26,6 +26,7 @@ public function setUp(): void
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
'setup' => [
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/data_processor_with_irre.typoscript',
],
]
diff --git a/Tests/Functional/Frontend/DefaultLanguageTest.php b/Tests/Functional/Frontend/DefaultLanguageTest.php
index 7b0a0e58..1e062c39 100644
--- a/Tests/Functional/Frontend/DefaultLanguageTest.php
+++ b/Tests/Functional/Frontend/DefaultLanguageTest.php
@@ -25,7 +25,10 @@ public function childrenAreRendered(): void
1,
[
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
- 'setup' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript'],
+ 'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
+ ],
]
);
$response = $this->executeFrontendRequestWrapper(new InternalRequest('http://localhost/'));
@@ -50,6 +53,7 @@ public function childrenAreRenderedAsSorted(): void
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
'setup' => [
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/container_with_two_children.typoscript',
],
]
@@ -70,6 +74,8 @@ public function canRenderContainerFromOtherPage(): void
[
'constants' => ['EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/constants.typoscript'],
'setup' => [
+ 'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/setup.typoscript',
+ 'EXT:container_example/Configuration/Sets/ContainerExample/setup.typoscript',
'EXT:container/Tests/Functional/Frontend/Fixtures/TypoScript/container_from_other_page.typoscript',
],
]
diff --git a/Tests/Functional/Frontend/Fixtures/ContainerWithTwoChildren.csv b/Tests/Functional/Frontend/Fixtures/ContainerWithTwoChildren.csv
index 7eb406f7..eac66776 100644
--- a/Tests/Functional/Frontend/Fixtures/ContainerWithTwoChildren.csv
+++ b/Tests/Functional/Frontend/Fixtures/ContainerWithTwoChildren.csv
@@ -2,8 +2,8 @@
,"uid","pid","title","slug"
,1,0,"page-1","/"
"tt_content"
-,"uid","pid","CType","header","sorting","colPos","tx_container_parent"
-,"1","1","b13-2cols-with-header-container","container","256","0","0"
-,"2","1","header","second child","512","201","1"
-,"3","1","header","first child","384","201","1"
+,"uid","pid","CType","header","sorting","colPos","tx_container_parent","frame_class"
+,"1","1","b13-2cols-with-header-container","container","256","0","0","none"
+,"2","1","header","second child","512","201","1","none"
+,"3","1","header","first child","384","201","1","none"
diff --git a/Tests/Functional/Frontend/Fixtures/Templates/ContainerWithTwoChildren.html b/Tests/Functional/Frontend/Fixtures/Templates/ContainerWithTwoChildren.html
index 511491c8..19fb1958 100644
--- a/Tests/Functional/Frontend/Fixtures/Templates/ContainerWithTwoChildren.html
+++ b/Tests/Functional/Frontend/Fixtures/Templates/ContainerWithTwoChildren.html
@@ -2,7 +2,16 @@
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true"
>
-
- {child.header}
-
+content area
+
+
+ {record.header}
+
+
+container-processor
+
+
+ {child.header}
+
+