Skip to content

Commit

Permalink
[FEATURE] Support comma-separated paths in all extension config options
Browse files Browse the repository at this point in the history
backend, content, layouts, layouts_backend,
partials, partials_backend, preview
  • Loading branch information
cweiske committed Feb 10, 2025
1 parent f830fc6 commit 19488e0
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 52 deletions.
36 changes: 27 additions & 9 deletions Classes/CodeGenerator/TyposcriptCodeGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,21 +214,24 @@ public function generateSetupTyposcript(): string
// for base paths to fluid templates configured in extension settings
$paths = [];
if ($this->maskExtensionConfiguration['content'] ?? false) {
$paths['templateRootPaths'] = [
10 => $this->maskExtensionConfiguration['content'],
];
$paths['templateRootPaths'] = $this->getTyposcriptPathArray(
$this->maskExtensionConfiguration['content'],
10
);
}

if ($this->maskExtensionConfiguration['partials'] ?? false) {
$paths['partialRootPaths'] = [
10 => $this->maskExtensionConfiguration['partials'],
];
$paths['partialRootPaths'] = $this->getTyposcriptPathArray(
$this->maskExtensionConfiguration['partials'],
10
);
}

if ($this->maskExtensionConfiguration['layouts'] ?? false) {
$paths['layoutRootPaths'] = [
10 => $this->maskExtensionConfiguration['layouts'],
];
$paths['layoutRootPaths'] = $this->getTyposcriptPathArray(
$this->maskExtensionConfiguration['layouts'],
10
);
}

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

return implode("\n\n", $setupContent) . "\n\n";
}

/**
* @return string[]
*/
protected function getTyposcriptPathArray(string $commaSeparatedPaths, int $startKey): array
{
$paths = TemplatePathUtility::getPaths($commaSeparatedPaths);
if (count($paths) === 0) {
return [];
}
return array_combine(
range($startKey, $startKey + count($paths) - 1),
$paths
);
}
}
17 changes: 13 additions & 4 deletions Classes/Controller/AjaxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1128,12 +1128,21 @@ protected function getMissingFolders(): array
if (!isset($this->maskExtensionConfiguration[$key])) {
continue;
}
$path = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration[$key]);
if ($path === '') {
$origPaths = TemplatePathUtility::getPaths($this->maskExtensionConfiguration[$key]);
if (count($origPaths) === 0) {
continue;
}
if (!file_exists($path)) {
$missingFolders[$key] = $this->maskExtensionConfiguration[$key];
foreach ($origPaths as $origPath) {
$path = GeneralUtility::getFileAbsFileName($origPath);
if (!file_exists($path)) {
$suffix = '';
$num = 1;
while (isset($missingFolders[$key . $suffix])) {
$num++;
$suffix = ' #' . $num;
}
$missingFolders[$key . $suffix] = $origPath;
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions Classes/EventListeners/MaskBackendPreviewEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ public function __invoke(PageContentPreviewRenderingEvent $event): void
$view = GeneralUtility::makeInstance(StandaloneView::class, $renderingContext);
$view->setTemplatePathAndFilename($templatePathAndFilename);
if (!empty($this->maskExtensionConfiguration['layouts_backend'])) {
$layoutRootPath = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration['layouts_backend']);
$view->setLayoutRootPaths([$layoutRootPath]);
$layoutRootPaths = TemplatePathUtility::getAbsolutePaths($this->maskExtensionConfiguration['layouts_backend']);
$view->setLayoutRootPaths($layoutRootPaths);
}
if (!empty($this->maskExtensionConfiguration['partials_backend'])) {
$partialRootPath = GeneralUtility::getFileAbsFileName($this->maskExtensionConfiguration['partials_backend']);
$view->setPartialRootPaths([$partialRootPath]);
$partialRootPaths = TemplatePathUtility::getAbsolutePaths($this->maskExtensionConfiguration['partials_backend']);
$view->setPartialRootPaths($partialRootPaths);
}

// Fetch and assign some useful variables
Expand Down
22 changes: 13 additions & 9 deletions Classes/Imaging/PreviewIconResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace MASK\Mask\Imaging;

use MASK\Mask\Utility\TemplatePathUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;

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

public function getPreviewIconPath(string $key): string
{
if (!($this->maskExtensionConfiguration['preview'] ?? false)) {
$previewPaths = TemplatePathUtility::getPaths($this->maskExtensionConfiguration['preview']);
if (!count($previewPaths)) {
return '';
}
// search a fitting png or svg file in this path
$fileExtensions = ['png', 'svg'];
$previewPath = rtrim($this->maskExtensionConfiguration['preview'], '/');
foreach ($fileExtensions as $fileExtension) {
$extPathToIcon = $previewPath . '/' . $key . '.' . $fileExtension;
$absolutePathToIcon = GeneralUtility::getFileAbsFileName($extPathToIcon);
if ($absolutePathToIcon === '' || !file_exists($absolutePathToIcon)) {
continue;
foreach ($previewPaths as $previewPath) {
$previewPath = rtrim($previewPath, '/');
foreach ($fileExtensions as $fileExtension) {
$extPathToIcon = $previewPath . '/' . $key . '.' . $fileExtension;
$absolutePathToIcon = GeneralUtility::getFileAbsFileName($extPathToIcon);
if ($absolutePathToIcon === '' || !file_exists($absolutePathToIcon)) {
continue;
}
$resource = PathUtility::getPublicResourceWebPath($extPathToIcon);
return '/' . ltrim($resource, '/');
}
$resource = PathUtility::getPublicResourceWebPath($extPathToIcon);
return '/' . ltrim($resource, '/');
}

return '';
Expand Down
65 changes: 47 additions & 18 deletions Classes/Utility/TemplatePathUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,50 @@ public static function getTemplatePath(
array $settings,
string $elementKey,
bool $onlyTemplateName = false,
?string $path = null,
?string $commaSeparatedPaths = null,
bool $removeExtension = false
): string {
if ($path === null) {
$path = GeneralUtility::getFileAbsFileName(rtrim($settings['content'] ?? '', '/') . '/');
if ($commaSeparatedPaths === null) {
$paths = static::getAbsolutePaths($settings['content']);
} else {
$paths = static::getAbsolutePaths($commaSeparatedPaths);
}
if ($path === '' || $elementKey === '') {
if (count($paths) === 0 || $elementKey === '') {
return '';
}
$path = rtrim($path, '/') . '/';
$fileExtension = '.html';

// check if a html file with underscores exist
if (file_exists($path . GeneralUtility::underscoredToUpperCamelCase($elementKey) . $fileExtension)) {
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
} elseif (file_exists($path . ucfirst($elementKey) . $fileExtension)) {
$fileName = ucfirst($elementKey);
} elseif (file_exists($path . $elementKey . $fileExtension)) {
$fileName = $elementKey;
} else {
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
}
foreach ($paths as $path) {
$path = rtrim($path, '/') . '/';
$fileExtension = '.html';

// check if a html file with underscores exist
$exists = false;
if (file_exists($path . GeneralUtility::underscoredToUpperCamelCase($elementKey) . $fileExtension)) {
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
$exists = true;
} elseif (file_exists($path . ucfirst($elementKey) . $fileExtension)) {
$fileName = ucfirst($elementKey);
$exists = true;
} elseif (file_exists($path . $elementKey . $fileExtension)) {
$fileName = $elementKey;
$exists = true;
} else {
$fileName = GeneralUtility::underscoredToUpperCamelCase($elementKey);
}

if ($removeExtension) {
$fileExtension = '';
if ($removeExtension) {
$fileExtension = '';
}

if ($exists) {
if ($onlyTemplateName) {
return $fileName . $fileExtension;
}
return $path . $fileName . $fileExtension;
}
}

//non-existing template file
if ($onlyTemplateName) {
return $fileName . $fileExtension;
}
Expand All @@ -80,4 +97,16 @@ public static function getAbsolutePaths(string $commaSeparatedPaths): array
}
return array_filter($paths);
}

/**
* Split a string of comma-separated paths into an array.
* Remove empty values.
*
* @return string[]
*/
public static function getPaths(string $commaSeparatedPaths): array
{
$paths = GeneralUtility::trimExplode(',', $commaSeparatedPaths);
return array_filter($paths);
}
}
14 changes: 7 additions & 7 deletions Resources/Private/Language/locallang_mask.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@
<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>
</trans-unit>
<trans-unit id="ext_conf_template-content">
<source>Folder for Content Fluid Templates</source>
<source>Folder for Content Fluid Templates: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-backend">
<source>Folder for Backend Preview Templates</source>
<source>Folder for Backend Preview Templates: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-preview">
<source>Folder for 32x32px png/svg content element preview icons (e.g. mykey.(png|svg))</source>
<source>Folder for content element preview icons: 32x32px png/svg files, e.g. mykey.(png|svg). Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-layouts">
<source>Folder for Content Fluid Layouts</source>
<source>Folder for Content Fluid Layouts: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-partials">
<source>Folder for Content Fluid Partials</source>
<source>Folder for Content Fluid Partials: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-layouts_backend">
<source>Folder for Backend Preview Layouts</source>
<source>Folder for Backend Preview Layouts: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-partials_backend">
<source>Folder for Backend Preview Partials</source>
<source>Folder for Backend Preview Partials: Multiple folders comma-separated</source>
</trans-unit>
<trans-unit id="ext_conf_template-backendlayout_pids">
<source>PageIds from where the in PageTS defined backend layouts should be loaded (comma separated)</source>
Expand Down
45 changes: 45 additions & 0 deletions Tests/Unit/CodeGenerator/TypoScriptCodeGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,51 @@ public static function generateSetupTyposcriptDataProvider(): iterable
templateName = Element1
}
',
];

yield 'comma-separated paths' => [
'json' => [
'tt_content' => [
'elements' => [
'element1' => [
'label' => 'Element 1',
'key' => 'element1',
],
'element2' => [
'label' => 'Element 2',
'key' => 'element2',
'hidden' => true,
],
],
],
],
'configuration' => [
'content' => 'EXT:sitepackage/Resources/Private/Mask/Templates,EXT:sitepackage/Resources/Private/Mask/Templates2',
'layouts' => 'EXT:sitepackage/Resources/Private/Mask/Layouts,EXT:sitepackage/Resources/Private/Mask/Layouts2',
'partials' => 'EXT:sitepackage/Resources/Private/Mask/Partials,EXT:sitepackage/Resources/Private/Mask/Partials2',
],
'expected' =>
'lib.maskContentElement {
templateRootPaths {
10 = EXT:sitepackage/Resources/Private/Mask/Templates
11 = EXT:sitepackage/Resources/Private/Mask/Templates2
}
partialRootPaths {
10 = EXT:sitepackage/Resources/Private/Mask/Partials
11 = EXT:sitepackage/Resources/Private/Mask/Partials2
}
layoutRootPaths {
10 = EXT:sitepackage/Resources/Private/Mask/Layouts
11 = EXT:sitepackage/Resources/Private/Mask/Layouts2
}
}
tt_content.mask_element1 =< lib.maskContentElement
tt_content.mask_element1 {
templateName = Element1
}
',
];

Expand Down
Empty file.
18 changes: 17 additions & 1 deletion Tests/Unit/Utility/TemplatePathUtilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public static function getTemplatePathDataProvider(): iterable
false,
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates/UpperExists.html',
],
'Comma-separated content path' => [
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/,EXT:mask/Tests/Unit/Fixtures/Templates2/'],
'upper_exists2',
false,
null,
false,
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates2/UpperExists2.html',
],
'File does not exist' => [
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/'],
'noelement',
Expand Down Expand Up @@ -66,7 +74,7 @@ public static function getTemplatePathDataProvider(): iterable
false,
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/',
false,
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/UpperExists.html',
Environment::getProjectPath() . '/.Build/Web/typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/UpperExists.html',
],
'Manually configured absolute path works' => [
['content' => ''],
Expand All @@ -76,6 +84,14 @@ public static function getTemplatePathDataProvider(): iterable
false,
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates/UpperExists.html',
],
'Manually configured comma-separated path works' => [
['content' => ''],
'upper_exists2',
false,
'typo3conf/ext/mask/Tests/Unit/Fixtures/Templates/,EXT:mask/Tests/Unit/Fixtures/Templates2/',
false,
Environment::getProjectPath() . '/Tests/Unit/Fixtures/Templates2/UpperExists2.html',
],
'Only template is returned' => [
['content' => 'EXT:mask/Tests/Unit/Fixtures/Templates/'],
'upper_exists',
Expand Down

0 comments on commit 19488e0

Please sign in to comment.