diff --git a/typo3/sysext/fluid/Classes/View/TemplatePaths.php b/typo3/sysext/fluid/Classes/View/TemplatePaths.php index fa4572790239942c36206826a20dd1295f06be0d..721b784fd80d317cc4f54e20ae4c68985d3e633d 100644 --- a/typo3/sysext/fluid/Classes/View/TemplatePaths.php +++ b/typo3/sysext/fluid/Classes/View/TemplatePaths.php @@ -109,7 +109,11 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths foreach ($paths as $name => $defaultPaths) { if (!empty($configuredPaths[$name])) { - $paths[$name] = array_merge($defaultPaths, ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name])); + $configured = ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name]); + // calculate implicit default paths which have not been explicitly configured + $implicitDefaultPaths = array_diff($defaultPaths, $configured); + // prepend implicit default paths (which have not been found in configured paths), as fallbacks + $paths[$name] = array_merge($implicitDefaultPaths, $configured); } } diff --git a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php index f6db5213621426e99390f6bb7a9134c92787c2d7..f02d1ee5ae9a514bad5a6e0465dcf7ba94e48f08 100644 --- a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php +++ b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php @@ -266,4 +266,52 @@ class TemplatePathsTest extends UnitTestCase ], ], $result); } + + /** + * @test + */ + public function getContextSpecificViewConfigurationRespectsTypoScriptConfiguredPaths(): void + { + $configurationManager = $this->createMock(ConfigurationManagerInterface::class); + $configurationManager->expects(self::once())->method('getConfiguration')->willReturn([ + 'plugin.' => [ + 'tx_test.' => [ + 'view.' => [ + 'templateRootPaths.' => [ + '0' => 'base/Templates/', + '10' => 'test/Templates/', + ], + 'partialRootPaths.' => [ + '0' => 'base/Partials/', + '10' => 'test/Partials/', + ], + 'layoutRootPaths.' => [ + '0' => 'base/Layouts/', + '10' => 'test/Layouts/', + ], + ], + ], + ], + ]); + $subject = $this->getAccessibleMock(TemplatePaths::class, ['getConfigurationManager', 'getExtensionPrivateResourcesPath', 'isBackendMode', 'isFrontendMode']); + $subject->expects(self::once())->method('getExtensionPrivateResourcesPath')->with('test')->willReturn('test/'); + $subject->expects(self::once())->method('getConfigurationManager')->willReturn($configurationManager); + $subject->expects(self::once())->method('isBackendMode')->willReturn(false); + $subject->expects(self::once())->method('isFrontendMode')->willReturn(true); + $result = $subject->_call('getContextSpecificViewConfiguration', 'test'); + self::assertSame([ + 'templateRootPaths' => [ + 'base/Templates/', + 'test/Templates/', + ], + 'partialRootPaths' => [ + 'base/Partials/', + 'test/Partials/', + ], + 'layoutRootPaths' => [ + 'base/Layouts/', + 'test/Layouts/', + ], + ], $result); + } }