Skip to content

Commit 42a07b7

Browse files
authored
[FEATURE] Introduce optional .fluid.* file extension (#1258)
Historically, Fluid has always used generic file extensions for template files, such as `.html`, `.txt` or `.xml`. While this provides IDE integration out-of-the-box, it makes it hard to distinguish files that are interpreted by Fluid and others that are just text or html files. This patch introduces an optional (!) new file extension for Fluid template files that is added _in addition_ to the generic file extension: `.fluid.html` for html files, `.fluid.txt` for text files, and so on. Template files are now detected in the following order (first existing file wins): ``` templateRootPath: templates/ template: myTemplate format: html 1. templates/myTemplate.fluid.html 2. templates/myTemplate.html 3. templates/myTemplate 4. templates/MyTemplate.fluid.html 5. templates/MyTemplate.html 6. templates/MyTemplate ``` If multiple template paths are defined, this chain is executed for each path separately, before falling back to the next path. This means that (in the TYPO3 context) an extension can ship `.html` files and another extension can override these files with `.fluid.html` files. It also works in reverse: The extension can ship `.fluid.html`, which can be overwritten with `.html` files. In short: The order of paths is respected, regardless of the file extension. This will make it possible to ship TYPO3 extensions compatible with v13/v14 (= ships `.html`), while a sitepackage in a v14 project can already use `.fluid.html` files. It also means that the core can rename all templates to `.fluid.html` without breaking extensions that overwrite core templates (e. g. email templates) with `.html` files. The order of file extensions has been discussed intensively, but in the end we decided to land on `.fluid.*`. Major reasons: * We currently already have mediocre IDE/editor support at best. Using `.fluid` as primary file extension would remove code highlighting completely until we can address each highlighter individually. This would also include things like Gerrit, GitHub or GitLab. Our time is not well spent to introduce a completely new file extension when there's an easier alternative. * With `*.form.yaml` there is already precedent in the TYPO3 cosmos. Introducing this file extension not only helps users to recognize Fluid templates, it also allows us to create better IDE integrations in the future. Also, it enables us to scan a whole project for Fluid templates, which makes cache warmup and linting tasks config-free.
1 parent a834143 commit 42a07b7

9 files changed

+36
-0
lines changed

src/View/TemplatePaths.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
*/
4242
class TemplatePaths
4343
{
44+
public const FLUID_EXTENSION = 'fluid';
4445
public const DEFAULT_FORMAT = 'html';
4546
public const CONFIG_TEMPLATEROOTPATHS = 'templateRootPaths';
4647
public const CONFIG_LAYOUTROOTPATHS = 'layoutRootPaths';
@@ -544,13 +545,16 @@ protected function resolveFileInPaths(array $paths, string $fileName, string $fo
544545
{
545546
// Create array of possible template paths. This includes:
546547
// * with and without format as file extension
548+
// * with and without *.fluid.* file extension
547549
// * fallback to uppercase file name
548550
$possibleTemplates = [];
549551
foreach (array_reverse($paths) as $path) {
552+
$possibleTemplates[] = $path . $fileName . '.' . static::FLUID_EXTENSION . '.' . $format;
550553
$possibleTemplates[] = $path . $fileName . '.' . $format;
551554
$possibleTemplates[] = $path . $fileName;
552555
$uppercaseName = ucfirst($fileName);
553556
if ($uppercaseName !== $fileName) {
557+
$possibleTemplates[] = $path . $uppercaseName . '.' . static::FLUID_EXTENSION . '.' . $format;
554558
$possibleTemplates[] = $path . $uppercaseName . '.' . $format;
555559
$possibleTemplates[] = $path . $uppercaseName;
556560
}

tests/Unit/View/Fixtures/TemplateResolving/Templates1/FluidExtensionOverrideTest.fluid.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates1/FluidExtensionOverrideTest.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates1/FluidExtensionTest.fluid.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates1/OriginalWithFluidExtension.fluid.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates1/OriginalWithoutFluidExtension.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates2/OriginalWithFluidExtension.html

Whitespace-only changes.

tests/Unit/View/Fixtures/TemplateResolving/Templates2/OriginalWithoutFluidExtension.fluid.html

Whitespace-only changes.

tests/Unit/View/TemplatePathsTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,38 @@ public static function resolveTemplateFileForControllerAndActionAndFormatDataPro
265265
'OnlyInFirst',
266266
__DIR__ . '/Fixtures/TemplateResolving/Templates1/OnlyInFirst.html',
267267
],
268+
'fluid extension is used' => [
269+
[__DIR__ . '/Fixtures/TemplateResolving/Templates1'],
270+
'',
271+
'FluidExtensionTest',
272+
__DIR__ . '/Fixtures/TemplateResolving/Templates1/FluidExtensionTest.fluid.html',
273+
],
274+
'non-fluid extension can be used with full name' => [
275+
[__DIR__ . '/Fixtures/TemplateResolving/Templates1'],
276+
'',
277+
'FluidExtensionOverrideTest.html',
278+
__DIR__ . '/Fixtures/TemplateResolving/Templates1/FluidExtensionOverrideTest.html',
279+
],
280+
'fluid extension is preferred if both exist within one path' => [
281+
[__DIR__ . '/Fixtures/TemplateResolving/Templates1'],
282+
'',
283+
'FluidExtensionOverrideTest',
284+
__DIR__ . '/Fixtures/TemplateResolving/Templates1/FluidExtensionOverrideTest.fluid.html',
285+
],
286+
// Use case: TYPO3 extension ships .html files, TYPO3 sitepackage overrides with .fluid.html
287+
'fluid extension overrides non-fluid extension from previous paths' => [
288+
[__DIR__ . '/Fixtures/TemplateResolving/Templates1', __DIR__ . '/Fixtures/TemplateResolving/Templates2'],
289+
'',
290+
'OriginalWithoutFluidExtension',
291+
__DIR__ . '/Fixtures/TemplateResolving/Templates2/OriginalWithoutFluidExtension.fluid.html',
292+
],
293+
// Use case: TYPO3 core ships .fluid.html, TYPO3 extension overrides with .html
294+
'non-fluid extension overrides fluid extension from previous paths' => [
295+
[__DIR__ . '/Fixtures/TemplateResolving/Templates1', __DIR__ . '/Fixtures/TemplateResolving/Templates2'],
296+
'',
297+
'OriginalWithFluidExtension',
298+
__DIR__ . '/Fixtures/TemplateResolving/Templates2/OriginalWithFluidExtension.html',
299+
],
268300
];
269301
}
270302

0 commit comments

Comments
 (0)