Skip to content

Commit 291b4fe

Browse files
committed
[FEATURE] Support comma-separated paths in all extension config options
backend, content, layouts, layouts_backend, partials, partials_backend, preview
1 parent 393435d commit 291b4fe

9 files changed

Lines changed: 173 additions & 52 deletions

File tree

Classes/CodeGenerator/TyposcriptCodeGenerator.php

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,21 +214,24 @@ public function generateSetupTyposcript(): string
214214
// for base paths to fluid templates configured in extension settings
215215
$paths = [];
216216
if ($this->maskExtensionConfiguration['content'] ?? false) {
217-
$paths['templateRootPaths'] = [
218-
10 => $this->maskExtensionConfiguration['content'],
219-
];
217+
$paths['templateRootPaths'] = $this->getTyposcriptPathArray(
218+
$this->maskExtensionConfiguration['content'],
219+
10
220+
);
220221
}
221222

222223
if ($this->maskExtensionConfiguration['partials'] ?? false) {
223-
$paths['partialRootPaths'] = [
224-
10 => $this->maskExtensionConfiguration['partials'],
225-
];
224+
$paths['partialRootPaths'] = $this->getTyposcriptPathArray(
225+
$this->maskExtensionConfiguration['partials'],
226+
10
227+
);
226228
}
227229

228230
if ($this->maskExtensionConfiguration['layouts'] ?? false) {
229-
$paths['layoutRootPaths'] = [
230-
10 => $this->maskExtensionConfiguration['layouts'],
231-
];
231+
$paths['layoutRootPaths'] = $this->getTyposcriptPathArray(
232+
$this->maskExtensionConfiguration['layouts'],
233+
10
234+
);
232235
}
233236

234237
$setupContent[] = ArrayToTypoScriptConverter::convert($paths, 'lib.maskContentElement');
@@ -250,4 +253,19 @@ public function generateSetupTyposcript(): string
250253

251254
return implode("\n\n", $setupContent) . "\n\n";
252255
}
256+
257+
/**
258+
* @return string[]
259+
*/
260+
protected function getTyposcriptPathArray(string $commaSeparatedPaths, int $startKey): array
261+
{
262+
$paths = TemplatePathUtility::getPaths($commaSeparatedPaths);
263+
if (count($paths) === 0) {
264+
return [];
265+
}
266+
return array_combine(
267+
range($startKey, $startKey + count($paths) - 1),
268+
$paths
269+
);
270+
}
253271
}

Classes/Controller/AjaxController.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,12 +1128,21 @@ protected function getMissingFolders(): array
11281128
if (!isset($this->maskExtensionConfiguration[$key])) {
11291129
continue;
11301130
}
1131-
$path = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration[$key]);
1132-
if ($path === '') {
1131+
$origPaths = TemplatePathUtility::getPaths($this->maskExtensionConfiguration[$key]);
1132+
if (count($origPaths) === 0) {
11331133
continue;
11341134
}
1135-
if (!file_exists($path)) {
1136-
$missingFolders[$key] = $this->maskExtensionConfiguration[$key];
1135+
foreach ($origPaths as $origPath) {
1136+
$path = GeneralUtility::getFileAbsFileName($origPath);
1137+
if (!file_exists($path)) {
1138+
$suffix = '';
1139+
$num = 1;
1140+
while (isset($missingFolders[$key . $suffix])) {
1141+
$num++;
1142+
$suffix = ' #' . $num;
1143+
}
1144+
$missingFolders[$key . $suffix] = $origPath;
1145+
}
11371146
}
11381147
}
11391148

Classes/EventListeners/MaskBackendPreviewEventListener.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ public function __invoke(PageContentPreviewRenderingEvent $event): void
9393
$view = GeneralUtility::makeInstance(StandaloneView::class, $renderingContext);
9494
$view->setTemplatePathAndFilename($templatePathAndFilename);
9595
if (!empty($this->maskExtensionConfiguration['layouts_backend'])) {
96-
$layoutRootPath = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration['layouts_backend']);
97-
$view->setLayoutRootPaths([$layoutRootPath]);
96+
$layoutRootPaths = TemplatePathUtility::getAbsolutePaths($this->maskExtensionConfiguration['layouts_backend']);
97+
$view->setLayoutRootPaths($layoutRootPaths);
9898
}
9999
if (!empty($this->maskExtensionConfiguration['partials_backend'])) {
100-
$partialRootPath = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration['partials_backend']);
101-
$view->setPartialRootPaths([$partialRootPath]);
100+
$partialRootPaths = TemplatePathUtility::getAbsolutePaths($this->maskExtensionConfiguration['partials_backend']);
101+
$view->setPartialRootPaths($partialRootPaths);
102102
}
103103

104104
// Fetch and assign some useful variables

Classes/Imaging/PreviewIconResolver.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace MASK\Mask\Imaging;
1919

20+
use MASK\Mask\Utility\TemplatePathUtility;
2021
use TYPO3\CMS\Core\Utility\GeneralUtility;
2122
use TYPO3\CMS\Core\Utility\PathUtility;
2223

@@ -43,20 +44,23 @@ public function isPreviewIconAvailable(string $key): bool
4344

4445
public function getPreviewIconPath(string $key): string
4546
{
46-
if (!($this->maskExtensionConfiguration['preview'] ?? false)) {
47+
$previewPaths = TemplatePathUtility::getPaths($this->maskExtensionConfiguration['preview']);
48+
if (!count($previewPaths)) {
4749
return '';
4850
}
4951
// search a fitting png or svg file in this path
5052
$fileExtensions = ['png', 'svg'];
51-
$previewPath = rtrim($this->maskExtensionConfiguration['preview'], '/');
52-
foreach ($fileExtensions as $fileExtension) {
53-
$extPathToIcon = $previewPath . '/' . $key . '.' . $fileExtension;
54-
$absolutePathToIcon = GeneralUtility::getFileAbsFileName($extPathToIcon);
55-
if ($absolutePathToIcon === '' || !file_exists($absolutePathToIcon)) {
56-
continue;
53+
foreach ($previewPaths as $previewPath) {
54+
$previewPath = rtrim($previewPath, '/');
55+
foreach ($fileExtensions as $fileExtension) {
56+
$extPathToIcon = $previewPath . '/' . $key . '.' . $fileExtension;
57+
$absolutePathToIcon = GeneralUtility::getFileAbsFileName($extPathToIcon);
58+
if ($absolutePathToIcon === '' || !file_exists($absolutePathToIcon)) {
59+
continue;
60+
}
61+
$resource = PathUtility::getPublicResourceWebPath($extPathToIcon);
62+
return '/' . ltrim($resource, '/');
5763
}
58-
$resource = PathUtility::getPublicResourceWebPath($extPathToIcon);
59-
return '/' . ltrim($resource, '/');
6064
}
6165

6266
return '';

Classes/Utility/TemplatePathUtility.php

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,50 @@ public static function getTemplatePath(
3333
array $settings,
3434
string $elementKey,
3535
bool $onlyTemplateName = false,
36-
?string $path = null,
36+
?string $commaSeparatedPaths = null,
3737
bool $removeExtension = false
3838
): string {
39-
if ($path === null) {
40-
$path = GeneralUtility::getFileAbsFileName(rtrim($settings['content'] ?? '', '/') . '/');
39+
if ($commaSeparatedPaths === null) {
40+
$paths = static::getAbsolutePaths($settings['content']);
41+
} else {
42+
$paths = static::getAbsolutePaths($commaSeparatedPaths);
4143
}
42-
if ($path === '' || $elementKey === '') {
44+
if (count($paths) === 0 || $elementKey === '') {
4345
return '';
4446
}
45-
$path = rtrim($path, '/') . '/';
46-
$fileExtension = '.html';
4747

48-
// check if a html file with underscores exist
49-
if (file_exists($path . GeneralUtility::underscoredToUpperCamelCase($elementKey) . $fileExtension)) {
50-
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
51-
} elseif (file_exists($path . ucfirst($elementKey) . $fileExtension)) {
52-
$fileName = ucfirst($elementKey);
53-
} elseif (file_exists($path . $elementKey . $fileExtension)) {
54-
$fileName = $elementKey;
55-
} else {
56-
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
57-
}
48+
foreach ($paths as $path) {
49+
$path = rtrim($path, '/') . '/';
50+
$fileExtension = '.html';
51+
52+
// check if a html file with underscores exist
53+
$exists = false;
54+
if (file_exists($path . GeneralUtility::underscoredToUpperCamelCase($elementKey) . $fileExtension)) {
55+
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
56+
$exists = true;
57+
} elseif (file_exists($path . ucfirst($elementKey) . $fileExtension)) {
58+
$fileName = ucfirst($elementKey);
59+
$exists = true;
60+
} elseif (file_exists($path . $elementKey . $fileExtension)) {
61+
$fileName = $elementKey;
62+
$exists = true;
63+
} else {
64+
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
65+
}
5866

59-
if ($removeExtension) {
60-
$fileExtension = '';
67+
if ($removeExtension) {
68+
$fileExtension = '';
69+
}
70+
71+
if ($exists) {
72+
if ($onlyTemplateName) {
73+
return $fileName . $fileExtension;
74+
}
75+
return $path . $fileName . $fileExtension;
76+
}
6177
}
6278

79+
//non-existing template file
6380
if ($onlyTemplateName) {
6481
return $fileName . $fileExtension;
6582
}
@@ -80,4 +97,16 @@ public static function getAbsolutePaths(string $commaSeparatedPaths): array
8097
}
8198
return array_filter($paths);
8299
}
100+
101+
/**
102+
* Split a string of comma-separated paths into an array.
103+
* Remove empty values.
104+
*
105+
* @return string[]
106+
*/
107+
public static function getPaths(string $commaSeparatedPaths): array
108+
{
109+
$paths = GeneralUtility::trimExplode(',', $commaSeparatedPaths);
110+
return array_filter($paths);
111+
}
83112
}

Resources/Private/Language/locallang_mask.xlf

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,25 @@
3131
<source>Override shared fields per content element.:Careful! As soon as this option is enabled and you save content elements, the fields are not synced anymore and this action can not be undone! Please back up your Mask element definitions before.</source>
3232
</trans-unit>
3333
<trans-unit id="ext_conf_template-content">
34-
<source>Folder for Content Fluid Templates</source>
34+
<source>Folder for Content Fluid Templates: Multiple folders comma-separated</source>
3535
</trans-unit>
3636
<trans-unit id="ext_conf_template-backend">
37-
<source>Folder for Backend Preview Templates</source>
37+
<source>Folder for Backend Preview Templates: Multiple folders comma-separated</source>
3838
</trans-unit>
3939
<trans-unit id="ext_conf_template-preview">
40-
<source>Folder for 32x32px png/svg content element preview icons (e.g. mykey.(png|svg))</source>
40+
<source>Folder for content element preview icons: 32x32px png/svg files, e.g. mykey.(png|svg). Multiple folders comma-separated</source>
4141
</trans-unit>
4242
<trans-unit id="ext_conf_template-layouts">
43-
<source>Folder for Content Fluid Layouts</source>
43+
<source>Folder for Content Fluid Layouts: Multiple folders comma-separated</source>
4444
</trans-unit>
4545
<trans-unit id="ext_conf_template-partials">
46-
<source>Folder for Content Fluid Partials</source>
46+
<source>Folder for Content Fluid Partials: Multiple folders comma-separated</source>
4747
</trans-unit>
4848
<trans-unit id="ext_conf_template-layouts_backend">
49-
<source>Folder for Backend Preview Layouts</source>
49+
<source>Folder for Backend Preview Layouts: Multiple folders comma-separated</source>
5050
</trans-unit>
5151
<trans-unit id="ext_conf_template-partials_backend">
52-
<source>Folder for Backend Preview Partials</source>
52+
<source>Folder for Backend Preview Partials: Multiple folders comma-separated</source>
5353
</trans-unit>
5454
<trans-unit id="ext_conf_template-backendlayout_pids">
5555
<source>PageIds from where the in PageTS defined backend layouts should be loaded (comma separated)</source>

Tests/Unit/CodeGenerator/TypoScriptCodeGeneratorTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,51 @@ public static function generateSetupTyposcriptDataProvider(): iterable
7474
templateName = Element1
7575
}
7676
77+
',
78+
];
79+
80+
yield 'comma-separated paths' => [
81+
'json' => [
82+
'tt_content' => [
83+
'elements' => [
84+
'element1' => [
85+
'label' => 'Element 1',
86+
'key' => 'element1',
87+
],
88+
'element2' => [
89+
'label' => 'Element 2',
90+
'key' => 'element2',
91+
'hidden' => true,
92+
],
93+
],
94+
],
95+
],
96+
'configuration' => [
97+
'content' => 'EXT:sitepackage/Resources/Private/Mask/Templates,EXT:sitepackage/Resources/Private/Mask/Templates2',
98+
'layouts' => 'EXT:sitepackage/Resources/Private/Mask/Layouts,EXT:sitepackage/Resources/Private/Mask/Layouts2',
99+
'partials' => 'EXT:sitepackage/Resources/Private/Mask/Partials,EXT:sitepackage/Resources/Private/Mask/Partials2',
100+
],
101+
'expected' =>
102+
'lib.maskContentElement {
103+
templateRootPaths {
104+
10 = EXT:sitepackage/Resources/Private/Mask/Templates
105+
11 = EXT:sitepackage/Resources/Private/Mask/Templates2
106+
}
107+
partialRootPaths {
108+
10 = EXT:sitepackage/Resources/Private/Mask/Partials
109+
11 = EXT:sitepackage/Resources/Private/Mask/Partials2
110+
}
111+
layoutRootPaths {
112+
10 = EXT:sitepackage/Resources/Private/Mask/Layouts
113+
11 = EXT:sitepackage/Resources/Private/Mask/Layouts2
114+
}
115+
}
116+
117+
tt_content.mask_element1 =< lib.maskContentElement
118+
tt_content.mask_element1 {
119+
templateName = Element1
120+
}
121+
77122
',
78123
];
79124

Tests/Unit/Fixtures/Templates2/UpperExists2.html

Whitespace-only changes.

Tests/Unit/Utility/TemplatePathUtilityTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ public static function getTemplatePathDataProvider(): iterable
3636
false,
3737
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates/UpperExists.html',
3838
],
39+
'Comma-separated content path' => [
40+
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/,EXT:mask/Tests/Unit/Fixtures/Templates2/'],
41+
'upper_exists2',
42+
false,
43+
null,
44+
false,
45+
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates2/UpperExists2.html',
46+
],
3947
'File does not exist' => [
4048
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/'],
4149
'noelement',
@@ -66,7 +74,7 @@ public static function getTemplatePathDataProvider(): iterable
6674
false,
6775
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/',
6876
false,
69-
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/UpperExists.html',
77+
Environment::getProjectPath() . '/.Build/Web/typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/UpperExists.html',
7078
],
7179
'Manually configured absolute path works' => [
7280
['content' => ''],
@@ -76,6 +84,14 @@ public static function getTemplatePathDataProvider(): iterable
7684
false,
7785
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates/UpperExists.html',
7886
],
87+
'Manually configured comma-separated path works' => [
88+
['content' => ''],
89+
'upper_exists2',
90+
false,
91+
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/,EXT:mask/Tests/Unit/Fixtures/Templates2/',
92+
false,
93+
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates2/UpperExists2.html',
94+
],
7995
'Only template is returned' => [
8096
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/'],
8197
'upper_exists',

0 commit comments

Comments
 (0)