diff --git a/.build/phpcs.xml b/.build/phpcs.xml
deleted file mode 100644
index 9a21299..0000000
--- a/.build/phpcs.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- error
-
-
- error
-
-
- warning
-
-
- error
-
-
- error
-
-
- error
-
-
- warning
-
-
- error
-
-
- error
-
-
- error
-
-
- error
-
-
- error
-
-
-
-
-
- error
-
-
\ No newline at end of file
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 264c4e9..3a51f4a 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: remindgmbh/commitlint-action@v1.0.0
- phpcs:
+ static-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -18,4 +18,4 @@ jobs:
extensions: intl
tools: composer:v2
- run: composer install
- - run: composer run-script phpcs
+ - run: composer run-script static-analysis
diff --git a/.gitignore b/.gitignore
index 886cc03..8f49cf2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,2 @@
-### IDE ###
-nbproject/
-.idea/
-
-### Composer ###
-composer.phar
-
-### General ###
-*.log
-cache.properties
-
-### CI ###
-.build/bin/
-.build/logs/
-.build/var/
-.build/vendor/
-.build/web/
-coverage.xml
+/vendor
+/public
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2326d1c..6c03ad3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,6 @@
{
- "phpCodeSniffer.exec.linux": "./.build/bin/phpcs",
+ "phpCodeSniffer.exec.linux": "./vendor/bin/phpcs",
"phpCodeSniffer.standard": "Custom",
- "phpCodeSniffer.standardCustom": "./.build/phpcs.xml",
- "phpCodeSniffer.exclude": [
- "**/.build/vendor/**"
- ]
+ "phpCodeSniffer.standardCustom": "./phpcs.xml",
+ "phpCodeSniffer.exclude": []
}
diff --git a/Classes/BreadcrumbTitle/AbstractBreadcrumbTitleProvider.php b/Classes/BreadcrumbTitle/AbstractBreadcrumbTitleProvider.php
new file mode 100644
index 0000000..4cbb58c
--- /dev/null
+++ b/Classes/BreadcrumbTitle/AbstractBreadcrumbTitleProvider.php
@@ -0,0 +1,17 @@
+title;
+ }
+}
diff --git a/Classes/BreadcrumbTitle/BreadcrumbTitleProviderInterface.php b/Classes/BreadcrumbTitle/BreadcrumbTitleProviderInterface.php
new file mode 100644
index 0000000..546fe7e
--- /dev/null
+++ b/Classes/BreadcrumbTitle/BreadcrumbTitleProviderInterface.php
@@ -0,0 +1,10 @@
+getBreadcrumbTitleProviderConfiguration();
+ $titleProviders = $this->setProviderOrder($titleProviders);
+
+ $orderedTitleProviders = GeneralUtility::makeInstance(DependencyOrderingService::class)
+ ->orderByDependencies($titleProviders);
+
+ $this->logger?->debug('Breadcrumb title providers ordered', [
+ 'orderedTitleProviders' => $orderedTitleProviders,
+ ]);
+
+ foreach ($orderedTitleProviders as $provider => $configuration) {
+ if (
+ class_exists($configuration['provider']) &&
+ is_subclass_of($configuration['provider'], BreadcrumbTitleProviderInterface::class)
+ ) {
+ /** @var BreadcrumbTitleProviderInterface $titleProviderObject */
+ $titleProviderObject = GeneralUtility::makeInstance($configuration['provider']);
+ if (
+ ($breadcrumbTitle = $titleProviderObject->getTitle())
+ || ($breadcrumbTitle = $this->breadcrumbTitleCache[$configuration['provider']] ?? '') !== ''
+ ) {
+ $this->logger?->debug('Breadcrumb title provider {provider} used on page {title}', [
+ 'provider' => $configuration['provider'],
+ 'title' => $breadcrumbTitle,
+ ]);
+ $this->breadcrumbTitleCache[$configuration['provider']] = $breadcrumbTitle;
+ break;
+ }
+ $this->logger?->debug('Breadcrumb title provider {provider} skipped on page {title}', [
+ 'provider' => $configuration['provider'],
+ 'providerUsed' => $configuration['provider'],
+ 'title' => $breadcrumbTitle,
+ ]);
+ }
+ }
+
+ return $breadcrumbTitle;
+ }
+
+ /**
+ * @param mixed[] $orderInformation
+ * @return mixed[]
+ */
+ protected function setProviderOrder(array $orderInformation): array
+ {
+ foreach ($orderInformation as $provider => &$configuration) {
+ if (isset($configuration['before'])) {
+ if (is_string($configuration['before'])) {
+ $configuration['before'] = GeneralUtility::trimExplode(',', $configuration['before'], true);
+ } elseif (!is_array($configuration['before'])) {
+ throw new UnexpectedValueException(
+ 'The specified "before" order configuration for provider "' . $provider . '" is invalid.',
+ 1535803185
+ );
+ }
+ }
+ if (isset($configuration['after'])) {
+ if (is_string($configuration['after'])) {
+ $configuration['after'] = GeneralUtility::trimExplode(',', $configuration['after'], true);
+ } elseif (!is_array($configuration['after'])) {
+ throw new UnexpectedValueException(
+ 'The specified "after" order configuration for provider "' . $provider . '" is invalid.',
+ 1535803186
+ );
+ }
+ }
+ }
+ return $orderInformation;
+ }
+
+ /**
+ * @return mixed[]
+ */
+ private function getBreadcrumbTitleProviderConfiguration(): array
+ {
+ $typoscriptService = GeneralUtility::makeInstance(TypoScriptService::class);
+ $config = $typoscriptService->convertTypoScriptArrayToPlainArray(
+ $GLOBALS['TSFE']->config['config'] ?? []
+ );
+
+ return $config['breadcrumbTitleProviders'] ?? [];
+ }
+}
diff --git a/Classes/DataProcessing/FilesCategoryProcessor.php b/Classes/DataProcessing/FilesCategoryProcessor.php
new file mode 100644
index 0000000..31110a0
--- /dev/null
+++ b/Classes/DataProcessing/FilesCategoryProcessor.php
@@ -0,0 +1,203 @@
+processorConf = $processorConf;
+ $this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+
+ $filesProcessorIndex = array_search(FilesProcessor::class, $contentObjectConf['dataProcessing.']);
+ if ($filesProcessorIndex !== false) {
+ $filesProcessorConf = $contentObjectConf['dataProcessing.'][$filesProcessorIndex . '.'];
+ $filesAs = $filesProcessorConf['as'];
+
+ if (isset($processedData[$filesAs])) {
+ $categoriesAs = $processorConf['as'] ?? 'categories';
+ $this->legacyReturn = (bool) ($filesProcessorConf['processingConfiguration.']['legacyReturn'] ?? true);
+ $fileUids = [];
+ foreach ($processedData[$filesAs] as &$file) {
+ $uid = $this->getFileUid($file);
+ if ($uid) {
+ $fileUids[] = (int) $uid;
+ }
+ }
+ $fileCategoryMap = $this->getFileCategoryMap($fileUids);
+
+ $this->categories = array_fill_keys(array_unique(array_merge(...$fileCategoryMap)), []);
+
+ $this->fetchCategoryProperties();
+
+ if (!($processorConf['images.']['disabled'] ?? false)) {
+ $this->fetchCategoryImages();
+ }
+
+ foreach ($processedData[$filesAs] as &$file) {
+ $uid = $this->getFileUid($file);
+ $file = ArrayUtility::setValueByPath(
+ $file,
+ $this->legacyReturn ? ['properties', $categoriesAs] : $categoriesAs,
+ array_map(function (int $categoryUid) {
+ return $this->categories[$categoryUid];
+ }, $fileCategoryMap[$uid] ?? [])
+ );
+ }
+ }
+ }
+ return $processedData;
+ }
+
+ /**
+ * @param mixed[] $file
+ */
+ private function getFileUid(array $file): int
+ {
+ // uidLocal may be null while fileReferenceUid contains the actual file uid
+ // see: https://github.com/TYPO3-Headless/headless/pull/761
+ return $this->legacyReturn
+ ? $file['properties']['uidLocal'] ?? $file['properties']['fileReferenceUid']
+ : $file['uidLocal'] ?? $file['fileReferenceUid'];
+ }
+
+ /**
+ * @param int[] $fileUids
+ * @return mixed[]
+ */
+ private function getFileCategoryMap(array $fileUids): array
+ {
+ $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::SYS_CATEGORY);
+
+ $queryBuilder = $queryBuilder
+ ->select(
+ self::SYS_CATEGORY_RECORD_MM . '.uid_local',
+ self::SYS_FILE_METADATA . '.file',
+ )
+ ->distinct()
+ ->from(self::SYS_CATEGORY_RECORD_MM)
+ ->join(
+ self::SYS_CATEGORY_RECORD_MM,
+ self::SYS_FILE_METADATA,
+ self::SYS_FILE_METADATA,
+ (string) $queryBuilder->expr()->and(
+ $queryBuilder->expr()->eq(
+ self::SYS_CATEGORY_RECORD_MM . '.uid_foreign',
+ $queryBuilder->quoteIdentifier(self::SYS_FILE_METADATA . '.uid')
+ ),
+ $queryBuilder->expr()->eq(
+ self::SYS_CATEGORY_RECORD_MM . '.fieldname',
+ $queryBuilder->createNamedParameter('categories')
+ ),
+ $queryBuilder->expr()->eq(
+ self::SYS_CATEGORY_RECORD_MM . '.tablenames',
+ $queryBuilder->createNamedParameter(self::SYS_FILE_METADATA)
+ ),
+ )
+ )
+ ->where(
+ $queryBuilder->expr()->and(
+ $queryBuilder->expr()->in(
+ self::SYS_FILE_METADATA . '.file',
+ $queryBuilder->createNamedParameter($fileUids, Connection::PARAM_INT_ARRAY),
+ )
+ )
+ );
+
+ $queryResult = $queryBuilder->executeQuery();
+
+ $result = [];
+
+ while ($row = $queryResult->fetchAssociative()) {
+ if (!isset($result[$row['file']])) {
+ $result[$row['file']] = [];
+ }
+ $result[$row['file']][] = $row['uid_local'];
+ }
+
+ return $result;
+ }
+
+ private function fetchCategoryProperties(): void
+ {
+ $fields = isset($this->processorConf['fields'])
+ ? GeneralUtility::trimExplode(',', $this->processorConf['fields'])
+ : ['title'];
+
+ $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::SYS_CATEGORY);
+
+ $queryBuilder = $queryBuilder
+ ->select(
+ 'uid',
+ ...$fields,
+ )
+ ->distinct()
+ ->from(self::SYS_CATEGORY)
+ ->where(
+ $queryBuilder->expr()->in(
+ 'uid',
+ $queryBuilder->createNamedParameter(array_keys($this->categories), Connection::PARAM_INT_ARRAY),
+ )
+ );
+
+ $queryResult = $queryBuilder->executeQuery();
+
+
+ while ($row = $queryResult->fetchAssociative()) {
+ $this->categories[$row['uid']] = $row;
+ }
+ }
+
+ private function fetchCategoryImages(): void
+ {
+ $filesService = GeneralUtility::makeInstance(FilesService::class);
+ $imageField = $this->processorConf['images.']['field'] ?? 'image';
+
+ $processingConfiguration = $this->processorConf['images.']['processingConfiguration.'] ?? [];
+
+ foreach (array_keys($this->categories) as $categoryUid) {
+ $this->categories[$categoryUid][$imageField] = $filesService->processImages(
+ self::SYS_CATEGORY,
+ 'images',
+ $categoryUid,
+ $processingConfiguration,
+ );
+ }
+ }
+}
diff --git a/Classes/DataProcessing/FilesProcessor.php b/Classes/DataProcessing/FilesProcessor.php
deleted file mode 100644
index df60f74..0000000
--- a/Classes/DataProcessing/FilesProcessor.php
+++ /dev/null
@@ -1,27 +0,0 @@
-contentDataProcessor = GeneralUtility::makeInstance(ContentDataProcessor::class);
+ }
+
+ /**
+ * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
+ * @param mixed[] $contentObjectConf
+ * @param mixed[] $processorConf
+ * @param mixed[] $processedData
+ * @return mixed[]
*/
public function process(
ContentObjectRenderer $cObj,
@@ -30,12 +44,13 @@ public function process(
array $processedData
): array {
$this->cObj = $cObj;
+ $this->processorConf = $processorConf;
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
$flexFormTools->reNumberIndexesOfSectionData = true;
$flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
- $fieldName = $cObj->stdWrapValue('fieldName', $processorConf);
+ $fieldName = (string) $cObj->stdWrapValue('fieldName', $processorConf);
// default flexform field name
if (empty($fieldName)) {
@@ -65,7 +80,10 @@ public function process(
0,
'T3FlexForms',
0,
- $flexFormTools->flexArray2Xml_options
+ [
+ ...$flexFormTools->flexArray2Xml_options,
+ 'disableTypeAttrib' => 0,
+ ]
)
);
@@ -83,26 +101,32 @@ public function process(
$flexformData = ArrayUtility::removeByPath($flexformData, $ignoredField, '.');
}
+ $overrideData = [];
+ $overrideData = $this->contentDataProcessor?->process($cObj, $processorConf, $overrideData) ?? [];
+ foreach ($overrideData as $key => &$value) {
+ $flexformData = empty($key) ? $value : ArrayUtility::setValueByPath($flexformData, $key, $value, '.');
+ }
+
// save result in "data" (default) or given variable name
$targetVariableName = $cObj->stdWrapValue('as', $processorConf);
if (!empty($targetVariableName)) {
$processedData[$targetVariableName] = $flexformData;
} else {
- if ($processedData['data'][$fieldName]) {
- $processedData['data'][$fieldName] = $flexformData;
- } else {
- $processedData[$fieldName] = $flexformData;
- }
+ $processedData['data'][$fieldName] = $flexformData;
}
return $processedData;
}
+ /**
+ * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
+ * @param mixed[] $element
+ */
public function parseElement(
array $element,
string $value,
- $additionalParameters,
+ mixed $additionalParameters,
string $path,
FlexFormTools $flexFormTools
): void {
@@ -123,35 +147,33 @@ public function parseElement(
}
if ($type === 'text') {
- $newValue = $this->cObj->parseFunc($value, [], '< lib.parseFunc_links');
+ $newValue = $this->cObj->parseFunc($value, null, '< lib.parseFunc_links');
}
if ($type === 'file') {
$fieldName = $element['config']['foreign_match_fields']['fieldname'];
- $filesProcessor = GeneralUtility::makeInstance(FilesProcessor::class);
- $as = 'file';
- $processorConfiguration = [
- 'as' => $as,
- 'references.' => [
- 'fieldName' => $fieldName,
- ],
- ];
- $processedData = [
- 'data' => $this->cObj->data,
- 'current' => null,
- ];
- $processedData = $filesProcessor->process(
- $this->cObj,
- [
- 'dataProcessing.' => [
- '10' => FilesProcessor::class,
- '10.' => $processorConfiguration,
- ],
- ],
- $processorConfiguration,
- $processedData,
+
+ $overrule = [];
+
+ try {
+ $overrule = ArrayUtility::getValueByPath(
+ $this->processorConf,
+ ['filesConfiguration.', ...array_map(function ($value) {
+ return $value . '.';
+ },
+ explode('.', $fieldName))]
+ );
+ } catch (MissingArrayPathException $e) {
+ }
+
+ $filesService = GeneralUtility::makeInstance(FilesService::class);
+
+ $newValue = $filesService->processImages(
+ $this->cObj->getCurrentTable(),
+ $fieldName,
+ $this->cObj->data['uid'],
+ $overrule
);
- $newValue = $processedData[$as];
}
$flexFormTools->cleanFlexFormXML = ArrayUtility::setValueByPath(
diff --git a/Classes/Event/Listener/AfterCacheableContentIsGeneratedEventListener.php b/Classes/Event/Listener/AfterCacheableContentIsGeneratedEventListener.php
new file mode 100644
index 0000000..a4d1b3c
--- /dev/null
+++ b/Classes/Event/Listener/AfterCacheableContentIsGeneratedEventListener.php
@@ -0,0 +1,36 @@
+getController()->content, true, 512, JSON_THROW_ON_ERROR);
+
+ $breadcrumbTitle = $this->breadcrumbTitleProviderManager->getTitle();
+
+ if ($breadcrumbTitle) {
+ $content['breadcrumbs'][array_key_last($content['breadcrumbs'])]['title'] = $breadcrumbTitle;
+ }
+
+ $event->getController()->content = $this->encoder->encode($content);
+ } catch (Throwable) {
+ return;
+ }
+ }
+}
diff --git a/Classes/Event/Listener/AfterFlexFormDataStructureIdentifierInitializedEventListener.php b/Classes/Event/Listener/AfterFlexFormDataStructureIdentifierInitializedEventListener.php
index 8e1d020..b06929e 100644
--- a/Classes/Event/Listener/AfterFlexFormDataStructureIdentifierInitializedEventListener.php
+++ b/Classes/Event/Listener/AfterFlexFormDataStructureIdentifierInitializedEventListener.php
@@ -1,5 +1,7 @@
getParsedBody();
+ $body = (array) $request->getParsedBody();
$context = json_decode($body['ajax']['context'] ?? null, true);
$config = json_decode($context['config'] ?? null, true);
$queryParams = parse_url($config['originalReturnUrl'], PHP_URL_QUERY);
- parse_str($queryParams, $queryParams);
+ parse_str($queryParams ?: '', $queryParams);
$type = $queryParams['defVals'][$foreignTable][$foreignField] ?? null;
} else {
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
@@ -54,7 +56,7 @@ public function __invoke(AfterFlexFormDataStructureIdentifierInitializedEvent $e
$type = $queryBuilder->executeQuery()->fetchOne();
}
} else {
- $body = $request->getParsedBody();
+ $body = (array) $request->getParsedBody();
$foreignRow = current($body['data'][$foreignTable]);
$type = $foreignRow[$foreignField];
}
diff --git a/Classes/Event/Listener/AfterTcaCompilationEventListener.php b/Classes/Event/Listener/AfterTcaCompilationEventListener.php
new file mode 100644
index 0000000..9c54941
--- /dev/null
+++ b/Classes/Event/Listener/AfterTcaCompilationEventListener.php
@@ -0,0 +1,26 @@
+setTca($GLOBALS['TCA']);
+ }
+}
diff --git a/Classes/Event/Listener/EnrichFileDataEventListener.php b/Classes/Event/Listener/EnrichFileDataEventListener.php
index 593d68b..61817ec 100644
--- a/Classes/Event/Listener/EnrichFileDataEventListener.php
+++ b/Classes/Event/Listener/EnrichFileDataEventListener.php
@@ -5,6 +5,8 @@
namespace Remind\Headless\Event\Listener;
use FriendsOfTYPO3\Headless\Event\EnrichFileDataEvent;
+use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
class EnrichFileDataEventListener
{
@@ -12,7 +14,49 @@ public function __invoke(EnrichFileDataEvent $event): void
{
$originalFile = $event->getOriginal();
$properties = $event->getProperties();
- $properties['lazyLoading'] = (bool) $originalFile->getProperty('tx_headless_lazy_loading') ?? true;
+ $processingConfiguration = $event->getProcessingConfiguration();
+
+ $defaultFields = $processingConfiguration->defaultFieldsByType ?? [];
+ $imageFields = array_merge($defaultFields, $processingConfiguration->defaultImageFields ?? []);
+ $videoFields = array_merge($defaultFields, $processingConfiguration->defaultVideoFields ?? []);
+
+ $fields = match ($properties['type']) {
+ 'image' => $imageFields,
+ 'video' => $videoFields,
+ default => $defaultFields,
+ };
+
+ foreach ($fields as $field) {
+ $as = $field;
+ if (str_contains($field, ' as ')) {
+ [$field, $as] = GeneralUtility::trimExplode(' as ', $field, true);
+ }
+ if (
+ $originalFile->hasProperty($field) &&
+ !array_key_exists($as, $properties)
+ ) {
+ $properties[$as] = $originalFile->getProperty($field);
+ }
+ }
+
+ /**
+ * Crop Variants with non-empty crop areas of SVG Images are converted to SVG
+ * so these images have to be treated different than pure SVGs in frontend
+ */
+
+ if ($originalFile->getExtension() === 'svg') {
+ $crop = $originalFile->getProperty('crop');
+ $cropVariantCollection = CropVariantCollection::create($crop);
+ $cropVariants = empty($crop) ? [] : array_keys(json_decode($crop, true));
+ foreach ($cropVariants as $cropVariant) {
+ $cropArea = $cropVariantCollection->getCropArea((string) $cropVariant);
+ if (!$cropArea->isEmpty()) {
+ $properties['extension'] = 'mixed';
+ break;
+ }
+ }
+ }
+
$event->setProperties($properties);
}
}
diff --git a/Classes/Form/AbstractModelDecorator.php b/Classes/Form/AbstractModelDecorator.php
index 72a63ad..8492f79 100644
--- a/Classes/Form/AbstractModelDecorator.php
+++ b/Classes/Form/AbstractModelDecorator.php
@@ -4,17 +4,25 @@
namespace Remind\Headless\Form;
-use FriendsOfTYPO3\Headless\Form\Decorator\AbstractFormDefinitionDecorator;
use Psr\Http\Message\ServerRequestInterface;
-abstract class AbstractModelDecorator extends AbstractFormDefinitionDecorator
+abstract class AbstractModelDecorator extends FormDefinitionDecorator
{
protected string $actionName = '';
+
protected string $controllerName = '';
+
protected string $valueName = '';
+ /**
+ * @param mixed[] $decorated
+ * @param mixed[] $definition
+ * @return mixed[]
+ */
protected function overrideDefinition(array $decorated, array $definition, int $currentPage): array
{
+ $decorated = parent::overrideDefinition($decorated, $definition, $currentPage);
+
$request = $this->getRequest();
/** @var \TYPO3\CMS\Core\Routing\PageArguments $pageArguments */
@@ -24,15 +32,18 @@ protected function overrideDefinition(array $decorated, array $definition, int $
$controllerArguments = $arguments[$this->controllerName] ?? null;
- if ($controllerArguments) {
- $uid = (int) $controllerArguments[$this->valueName] ?? null;
+ if (is_array($controllerArguments)) {
+ $uid = (int) $controllerArguments[$this->valueName];
$action = $controllerArguments['action'] ?? null;
- if ($action === $this->actionName && $uid) {
+ if (
+ $action === $this->actionName &&
+ $uid
+ ) {
$decorated['elements'][] = [
- 'type' => 'Hidden',
'defaultValue' => $uid,
'name' => $this->controllerName . '[' . $this->valueName . ']',
+ 'type' => 'Hidden',
];
}
}
diff --git a/Classes/Form/FormDefinitionDecorator.php b/Classes/Form/FormDefinitionDecorator.php
new file mode 100644
index 0000000..8cd747b
--- /dev/null
+++ b/Classes/Form/FormDefinitionDecorator.php
@@ -0,0 +1,127 @@
+cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
+ }
+
+ /**
+ * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
+ * @param mixed[] $decorated
+ * @param mixed[] $definition
+ * @return mixed[]
+ */
+ protected function overrideDefinition(array $decorated, array $definition, int $currentPage): array
+ {
+ foreach ($decorated['elements'] as &$element) {
+ $this->setNotEmptyValidationErrorMessages($element);
+ $this->setCheckboxLinks($element);
+ $this->setFileSizeValidatorBytes($element);
+ $this->setMimeTypeValidator($element);
+ }
+ return $decorated;
+ }
+
+ /**
+ * @param mixed[] $element
+ */
+ private function setNotEmptyValidationErrorMessages(array &$element): void
+ {
+ $notEmptyValidators = array_filter($element['validators'] ?? [], function (array $validator) {
+ return $validator['identifier'] === 'NotEmpty';
+ });
+ if ($notEmptyValidators) {
+ foreach ($element['properties']['validationErrorMessages'] ?? [] as $validationErrorMessageKey => $validationErrorMessage) {
+ if (in_array($validationErrorMessage['code'], self::NOT_EMPTY_ERROR_CODES)) {
+ foreach (array_keys($notEmptyValidators) as $validatorKey) {
+ $element['validators'][$validatorKey]['customErrorMessage'] = $validationErrorMessage['customMessage'];
+ }
+ unset($element['properties']['validationErrorMessages'][$validationErrorMessageKey]);
+ }
+ }
+ if (empty($element['properties']['validationErrorMessages'])) {
+ unset($element['properties']['validationErrorMessages']);
+ }
+ }
+ unset($element['properties']['fluidAdditionalAttributes']);
+ }
+
+ /**
+ * @param mixed[] $element
+ */
+ private function setCheckboxLinks(array &$element): void
+ {
+ if (
+ $element['type'] === 'Checkbox' &&
+ isset($element['properties']['links'])
+ ) {
+ $links = array_map(function ($pageUid, $label) {
+ $link = $this->cObj->createLink($label, ['parameter' => $pageUid]);
+ return $link instanceof LinkResult ? $link->getHtml() : null;
+ }, array_keys($element['properties']['links']), $element['properties']['links']);
+
+ $element['label'] = sprintf($element['label'], ...$links);
+ if (isset($element['properties']['elementDescription'])) {
+ $element['properties']['elementDescription'] = sprintf($element['properties']['elementDescription'], ...$links);
+ }
+
+ unset($element['properties']['links']);
+ }
+ }
+
+ /**
+ * @param mixed[] $element
+ */
+ private function setFileSizeValidatorBytes(array &$element): void
+ {
+ foreach ($element['validators'] ?? [] as $key => $value) {
+ if ($value['identifier'] === 'FileSize') {
+ $element['validators'][$key]['options']['minimum'] = GeneralUtility::getBytesFromSizeMeasurement($value['options']['minimum']);
+ $element['validators'][$key]['options']['maximum'] = GeneralUtility::getBytesFromSizeMeasurement($value['options']['maximum']);
+ }
+ }
+ }
+
+ /**
+ * @param mixed[] $element
+ */
+ private function setMimeTypeValidator(array &$element): void
+ {
+ if ($element['type'] === 'FileUpload') {
+ $mimeTypes = $element['properties']['allowedMimeTypes'] ?? [];
+
+ if (!empty($mimeTypes)) {
+ $element['validators'][] = [
+ 'identifier' => 'MimeType',
+ 'options' => [
+ 'allowed' => $mimeTypes,
+ ],
+ ];
+ }
+ }
+ }
+}
diff --git a/Classes/Middleware/AssetMiddleware.php b/Classes/Middleware/AssetMiddleware.php
new file mode 100644
index 0000000..a29b450
--- /dev/null
+++ b/Classes/Middleware/AssetMiddleware.php
@@ -0,0 +1,159 @@
+imageService = $imageService;
+ }
+
+ public function injectResponseFactory(ResponseFactoryInterface $responseFactory): void
+ {
+ $this->responseFactory = $responseFactory;
+ }
+
+ public function injectResourceFactory(ResourceFactory $resourceFactory): void
+ {
+ $this->resourceFactory = $resourceFactory;
+ }
+
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ /** @var \TYPO3\CMS\Core\Routing\SiteRouteResult $routing */
+ $routing = $request->getAttribute('routing');
+ $path = $routing->getUri()->getPath();
+ $queryParams = $request->getQueryParams();
+ $uid = $queryParams['uid'] ?? null;
+ $uidLocal = $queryParams['uidLocal'] ?? null;
+ if (
+ $path === '/asset' &&
+ (
+ $uid ||
+ $uidLocal
+ )
+ ) {
+ $resource = $uid
+ ? $this->resourceFactory->getFileReferenceObject($uid)
+ : $this->resourceFactory->getFileObject($uidLocal);
+
+ $tstamp = intval($resource->getProperty('tstamp'));
+ $lastModified = gmdate('D, d M Y H:i:s', $tstamp) . ' GMT';
+ $ifModifiedSince = $request->getHeader('if-modified-since')[0] ?? null;
+
+ if ($lastModified === $ifModifiedSince) {
+ return $this->responseFactory->createResponse(304);
+ }
+
+ $type = (int) $resource->getProperty('type');
+
+ $processedResource = $resource;
+
+ if ($type === AbstractFile::FILETYPE_IMAGE) {
+ $targetFileExtension = $queryParams['fileExtension'] ?? null;
+
+ $cropName = $queryParams['crop'] ?? null;
+ $breakpoint = $queryParams['breakpoint'] ?? null;
+
+ $cropVariants = array_filter([
+ implode('-', array_filter([$cropName, $breakpoint])),
+ $cropName,
+ $breakpoint,
+ ]);
+
+ $crop = $resource->getProperty('crop') ?? '';
+ $cropVariantCollection = CropVariantCollection::create($crop);
+
+ $cropArea = Area::createEmpty();
+
+ foreach ($cropVariants as $cropVariant) {
+ $cropArea = $cropVariantCollection->getCropArea($cropVariant);
+ if (!$cropArea->isEmpty()) {
+ break;
+ }
+ }
+
+ $skipProcessing = false;
+
+ // Use default cropVariant if breakpoint cropVariant does not exist
+ if ($cropArea->isEmpty()) {
+ $cropArea = $cropVariantCollection->getCropArea();
+
+ /**
+ * Skip processing if cropArea is empty and
+ * - targetFileExtension is SVG because TYPO3 cannot process SVGs
+ * - source is SVG and targetFileExtension is not set
+ * (normally TYPO3 would convert SVGs to PNGs with targetFileExtension not set,
+ * but there is no need with an empty cropArea)
+ */
+ if (
+ $targetFileExtension === 'svg' ||
+ $resource->getExtension() === 'svg' &&
+ !$targetFileExtension
+ ) {
+ $skipProcessing = true;
+ }
+ } elseif (
+ $resource->getExtension() === 'svg' &&
+ $targetFileExtension === 'svg'
+ ) {
+ // TYPO3 converts SVGs to PNGs if targetFileExtension is not set
+ $targetFileExtension = null;
+ }
+
+ if (!$skipProcessing) {
+ $processingInstructions = [
+ 'crop' => $cropArea->makeAbsoluteBasedOnFile($resource),
+ 'fileExtension' => $targetFileExtension ?? null,
+ 'height' => $queryParams['height'] ?? null,
+ 'maxHeight' => $queryParams['maxHeight'] ?? null,
+ 'maxWidth' => $queryParams['maxWidth'] ?? null,
+ 'width' => $queryParams['width'] ?? null,
+ ];
+
+ $processedResource = $this->imageService->applyProcessingInstructions(
+ $resource,
+ $processingInstructions
+ );
+ }
+ }
+
+ $mimeType = $processedResource->getMimeType();
+ $contents = $processedResource->getContents();
+
+ $title = $resource->getProperty('title') ?? $resource->getNameWithoutExtension();
+ $filename = str_replace(' ', '-', strtolower($title)) . '.' . $processedResource->getExtension();
+
+ $response = $this->responseFactory
+ ->createResponse()
+ ->withHeader('Content-Type', $mimeType)
+ ->withHeader('Content-Disposition', 'inline;filename="' . $filename . '"')
+ ->withHeader('Cache-Control', 'no-cache')
+ ->withHeader('Last-Modified', $lastModified);
+
+ $response->getBody()->write($contents);
+ return $response;
+ }
+ return $handler->handle($request);
+ }
+}
diff --git a/Classes/Middleware/ImageProcessingMiddleware.php b/Classes/Middleware/ImageProcessingMiddleware.php
deleted file mode 100644
index fb58869..0000000
--- a/Classes/Middleware/ImageProcessingMiddleware.php
+++ /dev/null
@@ -1,98 +0,0 @@
-imageService = GeneralUtility::makeInstance(ImageService::class);
- }
-
- public function injectResponseFactory(ResponseFactoryInterface $responseFactory)
- {
- $this->responseFactory = $responseFactory;
- }
-
- public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
- {
- /** @var \TYPO3\CMS\Core\Routing\SiteRouteResult $routing */
- $routing = $request->getAttribute('routing');
- $path = $routing->getUri()->getPath();
- $queryParams = $request->getQueryParams();
- $uid = $queryParams['uid'] ?? null;
- if ($path === '/image' && $uid) {
- $image = $this->imageService->getImage($uid, null, true);
-
- $tstamp = intval($image->getProperty('tstamp'));
- $lastModified = gmdate('D, d M Y H:i:s', $tstamp) . ' GMT';
- $ifModifiedSince = $request->getHeader('if-modified-since')[0] ?? null;
-
- if ($lastModified === $ifModifiedSince) {
- return $this->responseFactory->createResponse(304);
- }
-
- $targetFileExtension = $queryParams['fileExtension'] ?? null;
-
- // Skip processing for SVGs without changing image type
- if ($image->getExtension() === 'svg' && (!$targetFileExtension || $targetFileExtension === 'svg')) {
- $processedImage = $image;
- } else {
- $cropVariant = $queryParams['breakpoint'] ?? 'default';
-
- $crop = $image->getProperty('crop');
- $cropVariantCollection = CropVariantCollection::create($crop);
- $cropArea = $cropVariantCollection->getCropArea($cropVariant);
-
- // Use default cropVariant if breakpoint cropVariant does not exist
- if ($cropArea == Area::createEmpty()) {
- $cropArea = $cropVariantCollection->getCropArea();
- }
-
- $processingInstructions = [
- 'width' => $queryParams['width'] ?? null,
- 'height' => $queryParams['height'] ?? null,
- 'maxWidth' => $queryParams['maxWidth'] ?? null,
- 'maxHeight' => $queryParams['maxHeight'] ?? null,
- 'fileExtension' => $queryParams['fileExtension'] ?? null,
- 'crop' => $cropArea->makeAbsoluteBasedOnFile($image),
- ];
-
- $processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
- }
-
- $mimeType = $processedImage->getMimeType();
- $contents = $processedImage->getContents();
-
- $title = $image->getProperty('title') ?? $image->getNameWithoutExtension();
- $filename = str_replace(' ', '-', strtolower($title)) . '.' . $targetFileExtension;
-
- $response = $this->responseFactory
- ->createResponse()
- ->withHeader('Content-Type', $mimeType)
- ->withHeader('Content-Disposition', 'inline;filename="' . $filename . '"')
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', $lastModified);
-
- $response->getBody()->write($contents);
- return $response;
- }
- return $handler->handle($request);
- }
-}
diff --git a/Classes/Preview/ContentWithItemsPreviewRenderer.php b/Classes/Preview/ContentWithItemsPreviewRenderer.php
index fac2cb6..94d45b3 100644
--- a/Classes/Preview/ContentWithItemsPreviewRenderer.php
+++ b/Classes/Preview/ContentWithItemsPreviewRenderer.php
@@ -58,6 +58,9 @@ public function renderPageModulePreviewContent(GridColumnItem $item): string
return $out;
}
+ /**
+ * @param mixed[] $item
+ */
private function renderItemHeader(array $item): string
{
$outHeader = '';
@@ -67,7 +70,7 @@ private function renderItemHeader(array $item): string
$hiddenHeaderNote = '';
// If header layout is set to 'hidden', display an accordant note:
- if ($item['header_layout'] == 100) {
+ if (((int) $item['header_layout']) === 100) {
$hiddenHeaderNote = ' [' . htmlspecialchars($this->getLanguageService()->sL(
'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.hidden'
)) . ']';
diff --git a/Classes/Service/FilesService.php b/Classes/Service/FilesService.php
new file mode 100644
index 0000000..30fbc80
--- /dev/null
+++ b/Classes/Service/FilesService.php
@@ -0,0 +1,85 @@
+getRequest();
+ $frontendTypoScript = $request->getAttribute('frontend.typoscript');
+ $fullTypoScript = $frontendTypoScript?->getSetupArray();
+
+ $this->defaultConfiguration = $fullTypoScript ? $fullTypoScript['lib.']['assetProcessingConfiguration.'] : [];
+ $this->fileUtility = GeneralUtility::makeInstance(FileUtility::class);
+ $this->fileRepository = GeneralUtility::makeInstance(FileRepository::class);
+ $this->imageService = GeneralUtility::makeInstance(ImageService::class);
+ }
+
+ /**
+ * @param mixed[] $configuration
+ * @return mixed[]
+ */
+ public function processImage(int $uid, array $configuration = []): array
+ {
+ $processingConfiguration = $this->getProcessingConfiguration($configuration);
+ $imageObj = $this->imageService->getImage(strval($uid), null, true);
+ return $this->fileUtility->process($imageObj, $processingConfiguration);
+ }
+
+ /**
+ * @param mixed[] $configuration
+ * @return ?mixed[]
+ */
+ public function processImages(string $tableName, string $fieldName, int $uid, array $configuration = []): ?array
+ {
+ $processingConfiguration = $this->getProcessingConfiguration($configuration);
+
+ /** @var \TYPO3\CMS\Core\Resource\FileInterface[] $fileObjects */
+ $fileObjects = $this->fileRepository->findByRelation($tableName, $fieldName, $uid);
+
+ $processedFiles = [];
+
+ foreach ($fileObjects as $fileObject) {
+ $processedFiles[] = $this->fileUtility->process($fileObject, $processingConfiguration);
+ }
+
+ return $processingConfiguration->flattenObject ? $processedFiles[0] ?? null : $processedFiles;
+ }
+
+ /**
+ * @param mixed[] $overrule
+ */
+ private function getProcessingConfiguration(array $overrule = []): ProcessingConfiguration
+ {
+ $configuration = $this->defaultConfiguration;
+
+ ArrayUtility::mergeRecursiveWithOverrule($configuration, $overrule);
+
+ return ProcessingConfiguration::fromOptions($configuration);
+ }
+
+ private function getRequest(): ServerRequestInterface
+ {
+ return $GLOBALS['TYPO3_REQUEST'];
+ }
+}
diff --git a/Classes/Service/JsonService.php b/Classes/Service/JsonService.php
index 515f038..57681fc 100644
--- a/Classes/Service/JsonService.php
+++ b/Classes/Service/JsonService.php
@@ -4,34 +4,24 @@
namespace Remind\Headless\Service;
-use FriendsOfTYPO3\Headless\Utility\FileUtility;
use Psr\Http\Message\ServerRequestInterface;
-use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Pagination\PaginationInterface;
-use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Web\RequestBuilder;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
-use TYPO3\CMS\Extbase\Service\ImageService;
class JsonService
{
- private array $settings = [];
-
public function __construct(
private readonly UriBuilder $uriBuilder,
- private readonly LoggerInterface $logger,
- private readonly ImageService $imageService,
- private readonly FileUtility $fileUtility,
RequestBuilder $requestBuilder,
- ConfigurationManagerInterface $configurationManager
) {
$extbaseRequest = $requestBuilder->build($this->getRequest());
$this->uriBuilder->setRequest($extbaseRequest);
- $this->settings = $configurationManager->getConfiguration(
- ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS
- );
}
+ /**
+ * @return mixed[]
+ */
public function serializePagination(PaginationInterface $pagination, string $queryParam, int $currentPage): array
{
$firstPageNumber = $pagination->getFirstPageNumber();
@@ -49,14 +39,20 @@ public function serializePagination(PaginationInterface $pagination, string $que
->setAddQueryString('untrusted')
->uriFor(null, [$queryParam => $lastPageNumber]);
- if ($previousPageNumber && $previousPageNumber >= $firstPageNumber) {
+ if (
+ $previousPageNumber &&
+ $previousPageNumber >= $firstPageNumber
+ ) {
$prev = $this->uriBuilder
->reset()
->setAddQueryString('untrusted')
->uriFor(null, [$queryParam => $previousPageNumber]);
}
- if ($nextPageNumber && $nextPageNumber <= $lastPageNumber) {
+ if (
+ $nextPageNumber &&
+ $nextPageNumber <= $lastPageNumber
+ ) {
$next = $this->uriBuilder
->reset()
->setAddQueryString('untrusted')
@@ -72,31 +68,25 @@ public function serializePagination(PaginationInterface $pagination, string $que
->uriFor(null, [$queryParam => $page]);
$pages[] = [
- 'pageNumber' => $page,
- 'link' => $link,
'active' => $page === $currentPage,
+ 'link' => $link,
+ 'pageNumber' => $page,
];
}
$result = [
- 'startRecordNumber' => $pagination->getStartRecordNumber(),
'endRecordNumber' => $pagination->getEndRecordNumber(),
'first' => $first,
'last' => $last,
- 'prev' => $prev ?? null,
'next' => $next ?? null,
'pages' => $pages,
+ 'prev' => $prev ?? null,
+ 'startRecordNumber' => $pagination->getStartRecordNumber(),
];
return $result;
}
- public function processImage(int $uid): ?array
- {
- $imageObj = $this->imageService->getImage(strval($uid), null, true);
- return $this->fileUtility->processFile($imageObj);
- }
-
private function getRequest(): ServerRequestInterface
{
return $GLOBALS['TYPO3_REQUEST'];
diff --git a/Classes/TCA/DisplayCond.php b/Classes/TCA/DisplayCond.php
index 25c6108..d9ec961 100644
--- a/Classes/TCA/DisplayCond.php
+++ b/Classes/TCA/DisplayCond.php
@@ -10,6 +10,9 @@
class DisplayCond
{
+ /**
+ * @param mixed[] $args
+ */
public function parentIsRoot(array $args): bool
{
['record' => $record] = $args;
diff --git a/Classes/Utility/ConfigUtility.php b/Classes/Utility/ConfigUtility.php
index fc5f7e1..bf25ff3 100644
--- a/Classes/Utility/ConfigUtility.php
+++ b/Classes/Utility/ConfigUtility.php
@@ -12,6 +12,9 @@
class ConfigUtility
{
+ /**
+ * @return mixed[]
+ */
public static function getRootPageConfig(): array
{
$request = self::getRequest();
diff --git a/Classes/Utility/TcaUtility.php b/Classes/Utility/TcaUtility.php
index dafa24e..0816667 100644
--- a/Classes/Utility/TcaUtility.php
+++ b/Classes/Utility/TcaUtility.php
@@ -12,7 +12,7 @@
class TcaUtility
{
/**
- * @param array $variants array with breakpoint names as key and aspect-ratios as value
+ * @param mixed[] $variants array with breakpoint names as key and aspect-ratios as value
* the value can contain multple aspect ratios consisting of value and title
* e.g. [
* 'lg' => [
@@ -23,16 +23,16 @@ class TcaUtility
* ['value' => 16 / 9, 'title' => '16:9']
* ]
* ]
+ * @return mixed[]
*/
public static function getCropVariants(array $variants): array
{
return array_reduce(array_keys($variants), function (array $result, string $breakpoint) use ($variants) {
$aspectRatios = $variants[$breakpoint];
$result[$breakpoint] = [
- 'title' => $breakpoint,
'allowedAspectRatios' => array_reduce(array_keys($aspectRatios), function (
array $result,
- string $key
+ string|int $key
) use (
$aspectRatios,
$breakpoint,
@@ -41,11 +41,16 @@ public static function getCropVariants(array $variants): array
$result[$breakpoint . '_' . $aspectRatio['value']] = $aspectRatio;
return $result;
}, []),
+ 'title' => $breakpoint,
];
return $result;
}, []);
}
+ /**
+ * @param mixed[] $breakpoints
+ * @return mixed[]
+ */
public static function getCropVariantsFree(array $breakpoints): array
{
return self::getCropVariants(
@@ -54,8 +59,8 @@ public static function getCropVariantsFree(array $breakpoints): array
function (array $result, string $breakpoint) {
$result[$breakpoint] = [
[
- 'value' => 0.0,
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.ratio.free',
+ 'value' => 0.0,
],
];
return $result;
@@ -65,8 +70,8 @@ function (array $result, string $breakpoint) {
);
}
- /**
- * @param array|string $dataStructure either a xml flexform file path, a xml flexform string or a flexform array
+ /**
+ * @param mixed[]|string $dataStructure either a xml flexform file path, a xml flexform string or a flexform array
*/
public static function addPageConfigFlexForm(array|string $dataStructure): void
{
@@ -86,6 +91,22 @@ public static function addPageConfigFlexForm(array|string $dataStructure): void
$GLOBALS['TCA']['pages']['columns']['tx_headless_config']['config']['ds']['default'] = $newFlexFormString;
}
+ /**
+ * @param mixed[]|string $dataStructure either a xml flexform file path, a xml flexform string or a flexform array
+ */
+ public static function setFooterFlexForm(array|string $dataStructure): void
+ {
+ $newFlexFormArray = self::getFlexFormArray($dataStructure);
+ $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
+ $newFlexFormString = $flexFormTools->flexArray2Xml($newFlexFormArray, true);
+
+ $GLOBALS['TCA']['pages']['columns']['tx_headless_footer']['config']['ds']['default'] = $newFlexFormString;
+ }
+
+ /**
+ * @param mixed[]|string $dataStructure either a xml flexform file path, a xml flexform string or a flexform array
+ * @return mixed[]
+ */
private static function getFlexFormArray(array|string $dataStructure): array
{
if (is_array($dataStructure)) {
@@ -94,7 +115,10 @@ private static function getFlexFormArray(array|string $dataStructure): array
// Taken from TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools
if (strpos(trim($dataStructure), 'FILE:') === 0) {
$file = GeneralUtility::getFileAbsFileName(substr(trim($dataStructure), 5));
- if (empty($file) || !@is_file($file)) {
+ if (
+ empty($file) ||
+ !@is_file($file)
+ ) {
throw new RuntimeException(
'Data structure file ' . $file . ' could not be resolved to an existing file',
1478105826
diff --git a/Configuration/Form/BaseSetup.yaml b/Configuration/Form/BaseSetup.yaml
index 775213f..10c0b23 100644
--- a/Configuration/Form/BaseSetup.yaml
+++ b/Configuration/Form/BaseSetup.yaml
@@ -1,42 +1,65 @@
-TYPO3:
- CMS:
- Form:
- prototypes:
- standard:
- formEditor:
- translationFiles:
- 20: "EXT:rmnd_headless/Resources/Private/Language/locallang_form.xlf"
- formEngine:
- translationFiles:
- 20: "EXT:rmnd_headless/Resources/Private/Language/locallang_form.xlf"
- formElementsDefinition:
- DatePicker: null
- Form:
- formEditor:
- predefinedDefaults:
- i18n:
- identifier: i18n
- editors:
- # Overwrite submitButtonLabel propertyPath to be included in json output
- 300:
- propertyPath: i18n.properties.submit
- 400:
- identifier: successText
- templateName: Inspector-TextEditor
- label: formEditor.elements.Form.editor.successText.label
- propertyPath: i18n.properties.success
- 401:
- identifier: loadingText
- templateName: Inspector-TextEditor
- label: formEditor.elements.Form.editor.loadingText.label
- propertyPath: i18n.properties.loading
- 402:
- identifier: requiredHint
- templateName: Inspector-TextEditor
- label: formEditor.elements.Form.editor.requiredHint.label
- propertyPath: i18n.properties.required
- 900:
- selectOptions:
- # Remove redirect (non JSON) and confirmation finisher
- 40: null
- 60: null
+imports:
+ - { resource: './FormElements/AdvancedPassword.yaml' }
+ - { resource: './FormElements/Checkbox.yaml' }
+ - { resource: './FormElements/Date.yaml' }
+ - { resource: './FormElements/Email.yaml' }
+ - { resource: './FormElements/FileUpload.yaml' }
+ - { resource: './FormElements/GridRow.yaml' }
+ - { resource: './FormElements/Fieldset.yaml' }
+ - { resource: './FormElements/MultiCheckbox.yaml' }
+ - { resource: './FormElements/MultiSelect.yaml' }
+ - { resource: './FormElements/Number.yaml' }
+ - { resource: './FormElements/Password.yaml' }
+ - { resource: './FormElements/RadioButton.yaml' }
+ - { resource: './FormElements/SingleSelect.yaml' }
+ - { resource: './FormElements/StaticText.yaml' }
+ - { resource: './FormElements/Telephone.yaml' }
+ - { resource: './FormElements/Text.yaml' }
+ - { resource: './FormElements/Textarea.yaml' }
+ - { resource: './FormElements/Url.yaml' }
+
+ - { resource: './Finishers/JsonRedirectFinisher.yaml' }
+
+prototypes:
+ standard:
+ formEditor:
+ translationFiles:
+ 20: "EXT:rmnd_headless/Resources/Private/Language/locallang_form.xlf"
+ formEngine:
+ translationFiles:
+ 20: "EXT:rmnd_headless/Resources/Private/Language/locallang_form.xlf"
+ formElementsDefinition:
+ DatePicker:
+ formEditor:
+ group: null
+ Form:
+ formEditor:
+ predefinedDefaults:
+ i18n:
+ identifier: i18n
+ renderingOptions:
+ formDecorator: Remind\Headless\Form\FormDefinitionDecorator
+ editors:
+ # Overwrite submitButtonLabel propertyPath to be included in json output
+ 300:
+ propertyPath: i18n.properties.submit
+ 400:
+ identifier: successText
+ templateName: Inspector-TextEditor
+ label: formEditor.elements.Form.editor.successText.label
+ propertyPath: i18n.properties.success
+ 401:
+ identifier: loadingText
+ templateName: Inspector-TextEditor
+ label: formEditor.elements.Form.editor.loadingText.label
+ propertyPath: i18n.properties.loading
+ 402:
+ identifier: requiredHint
+ templateName: Inspector-TextEditor
+ label: formEditor.elements.Form.editor.requiredHint.label
+ propertyPath: i18n.properties.required
+ 900:
+ selectOptions:
+ # Remove redirect (non JSON) and confirmation finisher
+ 40: null
+ 60: null
diff --git a/Configuration/Form/Finishers/JsonRedirectFinisher.yaml b/Configuration/Form/Finishers/JsonRedirectFinisher.yaml
new file mode 100644
index 0000000..34001fe
--- /dev/null
+++ b/Configuration/Form/Finishers/JsonRedirectFinisher.yaml
@@ -0,0 +1,57 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Form:
+ formEditor:
+ editors:
+ 900:
+ selectOptions:
+ 70:
+ value: JsonRedirect
+ label: formEditor.elements.Form.editor.finishers.Redirect.label
+ propertyCollections:
+ finishers:
+ 70:
+ identifier: JsonRedirect
+ editors:
+ 100:
+ identifier: header
+ templateName: Inspector-CollectionElementHeaderEditor
+ label: formEditor.elements.Form.finisher.Redirect.editor.header.label
+ 200:
+ identifier: pageUid
+ templateName: Inspector-Typo3WinBrowserEditor
+ label: formEditor.elements.Form.finisher.Redirect.editor.pageUid.label
+ buttonLabel: formEditor.elements.Form.finisher.Redirect.editor.pageUid.buttonLabel
+ browsableType: pages
+ iconIdentifier: apps-pagetree-page-default
+ propertyPath: options.pageUid
+ propertyValidatorsMode: OR
+ propertyValidators:
+ 10: Integer
+ 20: FormElementIdentifierWithinCurlyBracesExclusive
+ finishersDefinition:
+ JsonRedirect:
+ implementationClassName: 'FriendsOfTYPO3\Headless\Form\Finisher\JsonRedirectFinisher'
+ formEditor:
+ iconIdentifier: form-finisher
+ label: formEditor.elements.Form.finisher.Redirect.editor.header.label
+ predefinedDefaults:
+ options:
+ pageUid: ""
+ additionalParameters: ""
+ FormEngine:
+ label: tt_content.finishersDefinition.Redirect.label
+ elements:
+ pageUid:
+ label: tt_content.finishersDefinition.Redirect.pageUid.label
+ config:
+ type: group
+ internal_type: db
+ allowed: pages
+ size: 1
+ minitems: 1
+ maxitems: 1
+ fieldWizard:
+ recordsOverview:
+ disabled: 1
diff --git a/Configuration/Form/FormElementSize.yaml b/Configuration/Form/FormElementSize.yaml
deleted file mode 100644
index dc4df14..0000000
--- a/Configuration/Form/FormElementSize.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-TYPO3:
- CMS:
- Form:
- prototypes:
- standard:
- formElementsDefinition:
- AdvancedPassword: &size
- formEditor:
- editors:
- # Remove default Grid viewport configuration
- 700: null
- 701:
- identifier: size
- templateName: Inspector-SingleSelectEditor
- label: formEditor.elements.FormElement.editor.size.label
- propertyPath: properties.size
- selectOptions:
- 10:
- value: ""
- label: formEditor.elements.FormElement.editor.size.default.label
- 20:
- value: 25
- label: 1/4
- 30:
- value: 33
- label: 1/3
- 40:
- value: 50
- label: 1/2
- 50:
- value: 66
- label: 2/3
- 60:
- value: 75
- label: 3/4
- Checkbox:
- <<: *size
- ContentElement:
- <<: *size
- Date:
- <<: *size
- Email:
- <<: *size
- Fieldset:
- <<: *size
- FileUpload:
- <<: *size
- GridRow:
- <<: *size
- Hidden:
- <<: *size
- ImageUpload:
- <<: *size
- MultiCheckbox:
- <<: *size
- MultiSelect:
- <<: *size
- Number:
- <<: *size
- Password:
- <<: *size
- RadioButton:
- <<: *size
- SingleSelect:
- <<: *size
- StaticText:
- <<: *size
- Telephone:
- <<: *size
- Url:
- <<: *size
- Text:
- <<: *size
- Textarea:
- <<: *size
diff --git a/Configuration/Form/FormElements/AdvancedPassword.yaml b/Configuration/Form/FormElements/AdvancedPassword.yaml
new file mode 100644
index 0000000..1d6561d
--- /dev/null
+++ b/Configuration/Form/FormElements/AdvancedPassword.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ AdvancedPassword:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Checkbox.yaml b/Configuration/Form/FormElements/Checkbox.yaml
new file mode 100644
index 0000000..88a44f1
--- /dev/null
+++ b/Configuration/Form/FormElements/Checkbox.yaml
@@ -0,0 +1,46 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Checkbox:
+ formEditor:
+ editors:
+ 300:
+ identifier: links
+ templateName: Inspector-PropertyGridEditor
+ label: formEditor.elements.FormElement.editor.links.label
+ propertyPath: properties.links
+ isSortable: true
+ enableAddRow: true
+ enableDeleteRow: true
+ useLabelAsFallbackValue: false
+ gridColumns:
+ - name: label
+ title: formEditor.elements.FormElement.editor.links.linkText
+ - name: value
+ title: formEditor.elements.FormElement.editor.links.pageUid
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/Date.yaml b/Configuration/Form/FormElements/Date.yaml
new file mode 100644
index 0000000..b4b7725
--- /dev/null
+++ b/Configuration/Form/FormElements/Date.yaml
@@ -0,0 +1,94 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Date:
+ formEditor:
+ editors:
+ 550:
+ propertyPath: properties.step
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ predefinedDefaults:
+ properties: null
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 250:
+ additionalElementPropertyPaths: null
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 250:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Email.yaml b/Configuration/Form/FormElements/Email.yaml
new file mode 100644
index 0000000..3a3807d
--- /dev/null
+++ b/Configuration/Form/FormElements/Email.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Email:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Fieldset.yaml b/Configuration/Form/FormElements/Fieldset.yaml
new file mode 100644
index 0000000..72c4ec3
--- /dev/null
+++ b/Configuration/Form/FormElements/Fieldset.yaml
@@ -0,0 +1,32 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Fieldset:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/FileUpload.yaml b/Configuration/Form/FormElements/FileUpload.yaml
new file mode 100644
index 0000000..804bd13
--- /dev/null
+++ b/Configuration/Form/FormElements/FileUpload.yaml
@@ -0,0 +1,40 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ FileUpload:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/GridRow.yaml b/Configuration/Form/FormElements/GridRow.yaml
new file mode 100644
index 0000000..f47f397
--- /dev/null
+++ b/Configuration/Form/FormElements/GridRow.yaml
@@ -0,0 +1,32 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ GridRow:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/MultiCheckbox.yaml b/Configuration/Form/FormElements/MultiCheckbox.yaml
new file mode 100644
index 0000000..3b4ded3
--- /dev/null
+++ b/Configuration/Form/FormElements/MultiCheckbox.yaml
@@ -0,0 +1,40 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ MultiCheckbox:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/MultiSelect.yaml b/Configuration/Form/FormElements/MultiSelect.yaml
new file mode 100644
index 0000000..49b4b67
--- /dev/null
+++ b/Configuration/Form/FormElements/MultiSelect.yaml
@@ -0,0 +1,40 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ MultiSelect:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Number.yaml b/Configuration/Form/FormElements/Number.yaml
new file mode 100644
index 0000000..7d20f93
--- /dev/null
+++ b/Configuration/Form/FormElements/Number.yaml
@@ -0,0 +1,96 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Number:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ 550:
+ propertyPath: properties.step
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ predefinedDefaults:
+ properties: null
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
\ No newline at end of file
diff --git a/Configuration/Form/FormElements/Password.yaml b/Configuration/Form/FormElements/Password.yaml
new file mode 100644
index 0000000..117bd02
--- /dev/null
+++ b/Configuration/Form/FormElements/Password.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Password:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/RadioButton.yaml b/Configuration/Form/FormElements/RadioButton.yaml
new file mode 100644
index 0000000..2072920
--- /dev/null
+++ b/Configuration/Form/FormElements/RadioButton.yaml
@@ -0,0 +1,32 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ RadioButton:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/SingleSelect.yaml b/Configuration/Form/FormElements/SingleSelect.yaml
new file mode 100644
index 0000000..eae787e
--- /dev/null
+++ b/Configuration/Form/FormElements/SingleSelect.yaml
@@ -0,0 +1,32 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ SingleSelect:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/StaticText.yaml b/Configuration/Form/FormElements/StaticText.yaml
new file mode 100644
index 0000000..d7d848f
--- /dev/null
+++ b/Configuration/Form/FormElements/StaticText.yaml
@@ -0,0 +1,32 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ StaticText:
+ formEditor:
+ editors:
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
diff --git a/Configuration/Form/FormElements/Telephone.yaml b/Configuration/Form/FormElements/Telephone.yaml
new file mode 100644
index 0000000..951f6c8
--- /dev/null
+++ b/Configuration/Form/FormElements/Telephone.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Telephone:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Text.yaml b/Configuration/Form/FormElements/Text.yaml
new file mode 100644
index 0000000..4039cba
--- /dev/null
+++ b/Configuration/Form/FormElements/Text.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Text:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Textarea.yaml b/Configuration/Form/FormElements/Textarea.yaml
new file mode 100644
index 0000000..a51411f
--- /dev/null
+++ b/Configuration/Form/FormElements/Textarea.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Textarea:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/FormElements/Url.yaml b/Configuration/Form/FormElements/Url.yaml
new file mode 100644
index 0000000..e19b607
--- /dev/null
+++ b/Configuration/Form/FormElements/Url.yaml
@@ -0,0 +1,92 @@
+prototypes:
+ standard:
+ formElementsDefinition:
+ Url:
+ formEditor:
+ editors:
+ 400:
+ propertyPath: properties.placeholder
+ # Remove default Grid viewport configuration
+ 700: null
+ 701:
+ identifier: size
+ templateName: Inspector-SingleSelectEditor
+ label: formEditor.elements.FormElement.editor.size.label
+ propertyPath: properties.size
+ selectOptions:
+ 10:
+ value: ""
+ label: formEditor.elements.FormElement.editor.size.default.label
+ 20:
+ value: xs
+ label: formEditor.elements.FormElement.editor.size.xs.label
+ 30:
+ value: sm
+ label: formEditor.elements.FormElement.editor.size.sm.label
+ 40:
+ value: md
+ label: formEditor.elements.FormElement.editor.size.md.label
+ 50:
+ value: lg
+ label: formEditor.elements.FormElement.editor.size.lg.label
+ 60:
+ value: xl
+ label: formEditor.elements.FormElement.editor.size.xl.label
+ propertyCollections:
+ validators:
+ 10:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 20:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 30:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 40:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 50:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 60:
+ editors:
+ 200:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 70:
+ editors:
+ 200:
+ additionalElementPropertyPaths: null
+ 300:
+ additionalElementPropertyPaths: null
+ 400:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
+ 80:
+ editors:
+ 300:
+ templateName: Inspector-TextEditor
+ propertyPath: customErrorMessage
+ doNotSetIfPropertyValueIsEmpty: true
diff --git a/Configuration/Form/JsonRedirectFinisher.yaml b/Configuration/Form/JsonRedirectFinisher.yaml
deleted file mode 100644
index 5134061..0000000
--- a/Configuration/Form/JsonRedirectFinisher.yaml
+++ /dev/null
@@ -1,60 +0,0 @@
-TYPO3:
- CMS:
- Form:
- prototypes:
- standard:
- formElementsDefinition:
- Form:
- formEditor:
- editors:
- 900:
- selectOptions:
- 70:
- value: JsonRedirect
- label: formEditor.elements.Form.editor.finishers.Redirect.label
- propertyCollections:
- finishers:
- 70:
- identifier: JsonRedirect
- editors:
- 100:
- identifier: header
- templateName: Inspector-CollectionElementHeaderEditor
- label: formEditor.elements.Form.finisher.Redirect.editor.header.label
- 200:
- identifier: pageUid
- templateName: Inspector-Typo3WinBrowserEditor
- label: formEditor.elements.Form.finisher.Redirect.editor.pageUid.label
- buttonLabel: formEditor.elements.Form.finisher.Redirect.editor.pageUid.buttonLabel
- browsableType: pages
- iconIdentifier: apps-pagetree-page-default
- propertyPath: options.pageUid
- propertyValidatorsMode: OR
- propertyValidators:
- 10: Integer
- 20: FormElementIdentifierWithinCurlyBracesExclusive
- finishersDefinition:
- JsonRedirect:
- implementationClassName: 'FriendsOfTYPO3\Headless\Form\Finisher\JsonRedirectFinisher'
- formEditor:
- iconIdentifier: form-finisher
- label: formEditor.elements.Form.finisher.Redirect.editor.header.label
- predefinedDefaults:
- options:
- pageUid: ""
- additionalParameters: ""
- FormEngine:
- label: tt_content.finishersDefinition.Redirect.label
- elements:
- pageUid:
- label: tt_content.finishersDefinition.Redirect.pageUid.label
- config:
- type: group
- internal_type: db
- allowed: pages
- size: 1
- minitems: 1
- maxitems: 1
- fieldWizard:
- recordsOverview:
- disabled: 1
diff --git a/Configuration/RequestMiddlewares.php b/Configuration/RequestMiddlewares.php
index b245b48..dcd398e 100644
--- a/Configuration/RequestMiddlewares.php
+++ b/Configuration/RequestMiddlewares.php
@@ -1,17 +1,19 @@
[
- 'rmnd_headless/imageprocessing' => [
- 'target' => ImageProcessingMiddleware::class,
+ 'rmnd_headless/asset' => [
'after' => [
'typo3/cms-frontend/site',
],
'before' => [
'typo3/cms-frontend/backend-user-authentication',
],
+ 'target' => AssetMiddleware::class,
],
],
];
diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml
index 8bea0d7..148249d 100644
--- a/Configuration/Services.yaml
+++ b/Configuration/Services.yaml
@@ -15,3 +15,11 @@ services:
tags:
-
name: event.listener
+ Remind\Headless\Event\Listener\AfterCacheableContentIsGeneratedEventListener:
+ tags:
+ -
+ name: event.listener
+ Remind\Headless\Event\Listener\AfterTcaCompilationEventListener:
+ tags:
+ -
+ name: event.listener
\ No newline at end of file
diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php
index 302a220..4f168d2 100644
--- a/Configuration/TCA/Overrides/pages.php
+++ b/Configuration/TCA/Overrides/pages.php
@@ -1,5 +1,7 @@
[
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:breadcrumbs_background_color',
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => null,
'items' => [
[
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:breadcrumbs_background_color.none',
'value' => null,
],
],
- 'default' => null,
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:breadcrumbs_background_color',
],
'tx_headless_config' => [
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:page_config',
'config' => [
+ 'behaviour' => [
+ 'allowLanguageSynchronization' => true,
+ ],
+ 'ds' => [
+ 'default' => 'FILE:EXT:rmnd_headless/Configuration/FlexForms/Empty.xml',
+ ],
'type' => 'flex',
+ ],
+ 'displayCond' => 'FIELD:is_siteroot:REQ:true',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:page_config',
+ ],
+ 'tx_headless_footer' => [
+ 'config' => [
'behaviour' => [
'allowLanguageSynchronization' => true,
],
'ds' => [
'default' => 'FILE:EXT:rmnd_headless/Configuration/FlexForms/Empty.xml',
],
+ 'type' => 'flex',
],
'displayCond' => 'FIELD:is_siteroot:REQ:true',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:footer',
],
'tx_headless_overview_label' => [
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:overview_label',
'config' => [
'type' => 'input',
],
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:overview_label',
],
]
);
@@ -59,5 +74,14 @@
ExtensionManagementUtility::addToAllTCAtypes(
'pages',
- 'tx_headless_config',
+ '--div--;LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:page_config,tx_headless_config',
+ '',
+ 'after:rowDescription'
+);
+
+ExtensionManagementUtility::addToAllTCAtypes(
+ 'pages',
+ '--div--;LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_pages.xlf:footer,tx_headless_footer',
+ '',
+ 'after:rowDescription'
);
diff --git a/Configuration/TCA/Overrides/sys_file_reference.php b/Configuration/TCA/Overrides/sys_file_reference.php
index 687c355..a992ab9 100644
--- a/Configuration/TCA/Overrides/sys_file_reference.php
+++ b/Configuration/TCA/Overrides/sys_file_reference.php
@@ -1,5 +1,7 @@
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_file.xlf:lazy_loading',
- 'description' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_file.xlf:lazy_loading.description',
'config' => [
- 'type' => 'check',
- 'renderType' => 'checkboxToggle',
'default' => 0,
+ 'renderType' => 'checkboxToggle',
+ 'type' => 'check',
],
+ 'description' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_file.xlf:lazy_loading.description',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_file.xlf:lazy_loading',
],
]);
-$GLOBALS
- ['TCA']
- ['sys_file_reference']
- ['types']
- [AbstractFile::FILETYPE_IMAGE]
- ['columnsOverrides']
- ['tx_headless_lazy_loading']
- ['config']
- ['default'] = 1;
+$GLOBALS['TCA']['sys_file_reference']['types'][AbstractFile::FILETYPE_IMAGE]['columnsOverrides']['tx_headless_lazy_loading']['config']['default'] = 1;
ExtensionManagementUtility::addFieldsToPalette(
'sys_file_reference',
diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php
index e2e554d..59014ac 100644
--- a/Configuration/TCA/Overrides/sys_template.php
+++ b/Configuration/TCA/Overrides/sys_template.php
@@ -1,5 +1,7 @@
[
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:background_color',
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => null,
'items' => [
[
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:background_color.none',
'value' => null,
],
],
- 'default' => null,
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:background_color',
'onChange' => 'reload',
],
'tx_headless_background_full_width' => [
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:background_full_width',
'config' => [
- 'type' => 'check',
- 'renderType' => 'checkboxToggle',
'items' => [
[
'label' => '',
'value' => 0,
],
],
+ 'renderType' => 'checkboxToggle',
+ 'type' => 'check',
],
'displayCond' => 'FIELD:tx_headless_background_color:REQ:true',
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:background_full_width',
],
'tx_headless_cookie_category' => [
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category',
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => null,
'items' => [
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category.none',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category.none',
'value' => null,
],
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category.necessary',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category.necessary',
'value' => 0,
],
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category.preferences',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category.preferences',
'value' => 1,
],
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category.statistics',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category.statistics',
'value' => 2,
],
[
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.category.marketing',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category.marketing',
'value' => 3,
],
],
- 'default' => null,
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.category',
],
'tx_headless_cookie_message' => [
- 'l10n_mode' => 'prefixLangTitle',
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookie.message',
'config' => [
- 'type' => 'text',
'cols' => 80,
+ 'enableRichtext' => true,
'rows' => 10,
'softref' => 'typolink_tag,email[subst],url',
- 'enableRichtext' => true,
+ 'type' => 'text',
],
+ 'l10n_mode' => 'prefixLangTitle',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:cookies.message',
],
'tx_headless_item' => [
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:tx_headless_item',
'config' => [
- 'type' => 'inline',
- 'foreign_table' => 'tx_headless_item',
'foreign_field' => 'foreign_uid',
+ 'foreign_table' => 'tx_headless_item',
'foreign_table_field' => 'foreign_table',
+ 'type' => 'inline',
],
- ],
- 'tx_headless_space_before_inside' => [
'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_before_inside',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:tx_headless_item',
+ ],
+ 'tx_headless_space_after_inside' => [
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => '',
'items' => [
[
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none',
@@ -123,16 +122,16 @@
'value' => 'extra-large',
],
],
- 'default' => '',
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
'displayCond' => 'FIELD:tx_headless_background_color:REQ:true',
- ],
- 'tx_headless_space_after_inside' => [
'exclude' => 0,
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_after_inside',
+ ],
+ 'tx_headless_space_before_inside' => [
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => '',
'items' => [
[
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none',
@@ -159,9 +158,12 @@
'value' => 'extra-large',
],
],
- 'default' => '',
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
'displayCond' => 'FIELD:tx_headless_background_color:REQ:true',
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_before_inside',
],
]
);
@@ -187,8 +189,15 @@
'after:space_after_class'
);
-ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'tx_headless_cookie_category');
-ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'tx_headless_cookie_message');
+/**
+ * Palette will be added in AfterTcaCompilationEventListener so Content Elements
+ * added in Extensions after this one will also have the palette
+ */
+ExtensionManagementUtility::addFieldsToPalette(
+ 'tt_content',
+ 'cookies',
+ 'tx_headless_cookie_category,--linebreak--,tx_headless_cookie_message',
+);
$GLOBALS['TCA']['tt_content']['ctrl']['previewRenderer'] = ContentWithItemsPreviewRenderer::class;
@@ -228,21 +237,5 @@
];
// Workaround for TCEFORM (https://forge.typo3.org/issues/100775)
- $GLOBALS
- ['TCA']
- ['tt_content']
- ['columns']
- ['space_after_class']
- ['config']
- ['items']
- [0]
- ['label'] = 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none';
- $GLOBALS
- ['TCA']
- ['tt_content']
- ['columns']
- ['space_before_class']
- ['config']
- ['items']
- [0]
- ['label'] = 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none';
+$GLOBALS['TCA']['tt_content']['columns']['space_after_class']['config']['items'][0]['label'] = 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none';
+$GLOBALS['TCA']['tt_content']['columns']['space_before_class']['config']['items'][0]['label'] = 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:space_none';
diff --git a/Configuration/TCA/Overrides/tt_content_accordion.php b/Configuration/TCA/Overrides/tt_content_accordion.php
index 6d35cc5..17dcb32 100644
--- a/Configuration/TCA/Overrides/tt_content_accordion.php
+++ b/Configuration/TCA/Overrides/tt_content_accordion.php
@@ -1,5 +1,7 @@
'default',
+ 'icon' => 'content-accordion',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:accordion.title',
+ 'value' => 'accordion',
],
- 'header',
- 'after'
);
$GLOBALS['TCA']['tt_content']['types']['accordion'] = [
- 'showitem' => '
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
- --palette--;;general,
- --palette--;;headers,
- tx_headless_item,
- --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
- --palette--;;frames,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
- --palette--;;language,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
- --palette--;;hidden,
- --palette--;;access,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
- categories,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
- rowDescription,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
- ',
'columnsOverrides' => [
'tx_headless_item' => [
'config' => [
@@ -59,4 +42,22 @@
],
],
],
+ 'showitem' => '
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
+ --palette--;;general,
+ --palette--;;headers,
+ tx_headless_item,
+ --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
+ --palette--;;frames,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+ --palette--;;language,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
+ --palette--;;hidden,
+ --palette--;;access,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
+ categories,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
+ rowDescription,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
+ ',
];
diff --git a/Configuration/TCA/Overrides/tt_content_footer_content.php b/Configuration/TCA/Overrides/tt_content_footer_content.php
deleted file mode 100644
index ec6f5e3..0000000
--- a/Configuration/TCA/Overrides/tt_content_footer_content.php
+++ /dev/null
@@ -1,36 +0,0 @@
- '
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
- --palette--;;general,
- header,
- pi_flexform,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
- --palette--;;language,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
- --palette--;;hidden,
- --palette--;;access,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
- categories,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
- rowDescription,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
- ',
-];
diff --git a/Configuration/TCA/Overrides/tt_content_form_formframework.php b/Configuration/TCA/Overrides/tt_content_form_formframework.php
index 892aa98..ba5b603 100644
--- a/Configuration/TCA/Overrides/tt_content_form_formframework.php
+++ b/Configuration/TCA/Overrides/tt_content_form_formframework.php
@@ -1,5 +1,7 @@
'default',
+ 'icon' => 'content-gallery',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:image_gallery.title',
+ 'value' => 'image_gallery',
],
- 'header',
- 'after'
);
$GLOBALS['TCA']['tt_content']['types']['image_gallery'] = [
diff --git a/Configuration/TCA/Overrides/tt_content_tabs.php b/Configuration/TCA/Overrides/tt_content_tabs.php
index b334c42..a254a5d 100644
--- a/Configuration/TCA/Overrides/tt_content_tabs.php
+++ b/Configuration/TCA/Overrides/tt_content_tabs.php
@@ -1,5 +1,7 @@
'default',
+ 'icon' => 'content-tab',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:tabs.title',
+ 'value' => 'tabs',
],
- 'header',
- 'after'
);
$GLOBALS['TCA']['tt_content']['types']['tabs'] = [
- 'showitem' => '
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
- --palette--;;general,
- --palette--;;headers,
- tx_headless_item,
- --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
- --palette--;;frames,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
- --palette--;;language,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
- --palette--;;hidden,
- --palette--;;access,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
- categories,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
- rowDescription,
- --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
- ',
'columnsOverrides' => [
'tx_headless_item' => [
'config' => [
@@ -59,4 +42,22 @@
],
],
],
+ 'showitem' => '
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
+ --palette--;;general,
+ --palette--;;headers,
+ tx_headless_item,
+ --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
+ --palette--;;frames,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
+ --palette--;;language,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
+ --palette--;;hidden,
+ --palette--;;access,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
+ categories,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
+ rowDescription,
+ --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
+ ',
];
diff --git a/Configuration/TCA/tx_headless_item.php b/Configuration/TCA/tx_headless_item.php
index 19134dd..25b996c 100644
--- a/Configuration/TCA/tx_headless_item.php
+++ b/Configuration/TCA/tx_headless_item.php
@@ -1,40 +1,37 @@
[
- 'title' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:title',
- 'label' => 'header',
- 'label_alt' => 'subheader,bodytext',
- 'tstamp' => 'tstamp',
- 'crdate' => 'crdate',
- 'hideTable' => true,
- 'sortby' => 'sorting',
- 'delete' => 'deleted',
- 'versioningWS' => true,
- 'languageField' => 'sys_language_uid',
- 'transOrigPointerField' => 'l10n_parent',
- 'transOrigDiffSourceField' => 'l10n_diffsource',
- 'translationSource' => 'l10n_source',
- 'enablecolumns' => [
- 'disabled' => 'hidden',
- 'starttime' => 'starttime',
- 'endtime' => 'endtime',
+ 'columns' => [
+ 'bodytext' => [
+ 'config' => [
+ 'cols' => 80,
+ 'enableRichtext' => true,
+ 'rows' => 10,
+ 'softref' => 'typolink_tag,email[subst],url',
+ 'type' => 'text',
+ ],
+ 'l10n_mode' => 'prefixLangTitle',
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.text',
],
- 'searchFields' => 'header,subheader,bodytext',
- 'iconfile' => 'EXT:core/Resources/Public/Icons/T3Icons/svgs/actions/actions-folder.svg',
- 'security' => [
- 'ignorePageTypeRestriction' => true,
+ 'endtime' => [
+ 'config' => [
+ 'default' => 0,
+ 'range' => [
+ 'upper' => mktime(0, 0, 0, 1, 1, 2038),
+ ],
+ 'type' => 'datetime',
+ ],
+ 'exclude' => true,
+ 'l10n_display' => 'defaultAsReadonly',
+ 'l10n_mode' => 'exclude',
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
],
- ],
- 'columns' => [
'flexform' => [
- 'l10n_display' => 'hideDiff',
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:columns.flexform',
'config' => [
- // FlexForm according to tt_content:CType is selected in Remind\Headless\Event\Listener\AfterFlexFormDataStructureIdentifierInitializedEventListener
- 'type' => 'flex',
'ds' => [
'default' => '
@@ -54,117 +51,43 @@
',
],
+ // FlexForm according to tt_content:CType is selected in Remind\Headless\Event\Listener\AfterFlexFormDataStructureIdentifierInitializedEventListener
+ 'type' => 'flex',
],
+ 'l10n_display' => 'hideDiff',
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:columns.flexform',
],
- 'sys_language_uid' => [
- 'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.language',
- 'config' => [
- 'type' => 'language',
- 'renderType' => 'selectSingle',
- ],
- ],
- 'l10n_parent' => [
- 'displayCond' => 'FIELD:sys_language_uid:>:0',
- 'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
- 'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
- 'items' => [
- [
- 'label' => '',
- 'value' => 0,
- ],
- ],
- 'foreign_table' => 'tx_headless_item',
- 'foreign_table_where' => 'AND tx_headless_item.uid=###REC_FIELD_l10n_parent### AND tx_headless_item.sys_language_uid IN (-1,0)',
- 'default' => 0,
- ],
- ],
- 'l10n_diffsource' => [
- 'config' => [
- 'type' => 'passthrough',
- 'default' => '',
- ],
- ],
- 'l10n_source' => [
- 'config' => [
- 'type' => 'passthrough',
- ],
- ],
- 'hidden' => [
- 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
- 'config' => [
- 'type' => 'check',
- 'default' => 0,
- ],
- ],
- 'starttime' => [
- 'exclude' => true,
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
- 'config' => [
- 'type' => 'datetime',
- 'default' => 0,
- ],
- 'l10n_mode' => 'exclude',
- 'l10n_display' => 'defaultAsReadonly',
- ],
- 'endtime' => [
- 'exclude' => true,
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
+ 'foreign_table' => [
'config' => [
- 'type' => 'datetime',
- 'default' => 0,
- 'range' => [
- 'upper' => mktime(0, 0, 0, 1, 1, 2038),
- ],
+ 'eval' => 'trim',
+ 'size' => 30,
+ 'type' => 'input',
],
'l10n_mode' => 'exclude',
- 'l10n_display' => 'defaultAsReadonly',
],
'foreign_uid' => [
- 'exclude' => true,
'config' => [
'allowed' => '',
- 'type' => 'group',
- 'size' => 1,
'maxitems' => 1,
'minitems' => 0,
+ 'size' => 1,
+ 'type' => 'group',
],
+ 'exclude' => true,
],
- 'foreign_table' => [
- 'l10n_mode' => 'exclude',
+ 'header' => [
'config' => [
+ 'max' => 256,
+ 'size' => 50,
'type' => 'input',
- 'size' => 30,
- 'eval' => 'trim',
- ],
- ],
- 'tx_headless_item' => [
- 'exclude' => 0,
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:tx_headless_item',
- 'config' => [
- 'type' => 'inline',
- 'foreign_table' => 'tx_headless_item',
- 'foreign_field' => 'foreign_uid',
- 'foreign_table_field' => 'foreign_table',
],
- ],
- 'header' => [
- 'l10n_mode' => 'prefixLangTitle',
'l10n_cat' => 'text',
+ 'l10n_mode' => 'prefixLangTitle',
'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header',
- 'config' => [
- 'type' => 'input',
- 'size' => 50,
- 'max' => 256,
- ],
],
'header_layout' => [
- 'exclude' => true,
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.type',
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => 0,
'items' => [
[
'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:columns.header_layout.text',
@@ -199,15 +122,23 @@
'value' => '100',
],
],
- 'default' => 0,
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.type',
],
- 'header_position' => [
- 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_position',
+ 'header_link' => [
+ 'config' => [
+ 'size' => 50,
+ 'type' => 'link',
+ ],
'exclude' => true,
+ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_link',
+ ],
+ 'header_position' => [
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => '',
'items' => [
[
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value',
@@ -226,51 +157,57 @@
'value' => 'left',
],
],
- 'default' => '',
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
- ],
- 'header_link' => [
'exclude' => true,
- 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_link',
+ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_position',
+ ],
+ 'hidden' => [
'config' => [
- 'type' => 'link',
- 'size' => 50,
+ 'default' => 0,
+ 'type' => 'check',
],
+ 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
],
- 'subheader' => [
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.subheader',
+ 'image' => [
'config' => [
- 'type' => 'input',
- 'size' => 50,
- 'max' => 256,
- 'softref' => 'email[subst]',
+ 'allowed' => 'common-image-types',
+ 'type' => 'file',
],
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.images',
],
- 'title' => [
- 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:columns.title',
+ 'l10n_diffsource' => [
'config' => [
- 'type' => 'input',
- 'size' => 50,
- 'max' => 256,
+ 'default' => '',
+ 'type' => 'passthrough',
],
],
- 'bodytext' => [
- 'l10n_mode' => 'prefixLangTitle',
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.text',
+ 'l10n_parent' => [
'config' => [
- 'type' => 'text',
- 'cols' => 80,
- 'rows' => 10,
- 'softref' => 'typolink_tag,email[subst],url',
- 'enableRichtext' => true,
+ 'default' => 0,
+ 'foreign_table' => 'tx_headless_item',
+ 'foreign_table_where' => 'AND tx_headless_item.uid=###REC_FIELD_l10n_parent### AND tx_headless_item.sys_language_uid IN (-1,0)',
+ 'items' => [
+ [
+ 'label' => '',
+ 'value' => 0,
+ ],
+ ],
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'displayCond' => 'FIELD:sys_language_uid:>:0',
+ 'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
],
- 'space_before_class' => [
- 'exclude' => true,
- 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_before_class',
+ 'l10n_source' => [
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'type' => 'passthrough',
+ ],
+ ],
+ 'space_after_class' => [
+ 'config' => [
+ 'default' => '',
'items' => [
[
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value',
@@ -297,15 +234,15 @@
'value' => 'extra-large',
],
],
- 'default' => '',
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
- ],
- 'space_after_class' => [
'exclude' => true,
'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_after_class',
+ ],
+ 'space_before_class' => [
'config' => [
- 'type' => 'select',
- 'renderType' => 'selectSingle',
+ 'default' => '',
'items' => [
[
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value',
@@ -332,18 +269,98 @@
'value' => 'extra-large',
],
],
- 'default' => '',
+ 'renderType' => 'selectSingle',
+ 'type' => 'select',
],
+ 'exclude' => true,
+ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_before_class',
],
- 'image' => [
- 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.images',
+ 'starttime' => [
'config' => [
- 'type' => 'file',
- 'allowed' => 'common-image-types',
+ 'default' => 0,
+ 'type' => 'datetime',
],
+ 'exclude' => true,
+ 'l10n_display' => 'defaultAsReadonly',
+ 'l10n_mode' => 'exclude',
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
+ ],
+ 'subheader' => [
+ 'config' => [
+ 'max' => 256,
+ 'size' => 50,
+ 'softref' => 'email[subst]',
+ 'type' => 'input',
+ ],
+ 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.subheader',
+ ],
+ 'sys_language_uid' => [
+ 'config' => [
+ 'renderType' => 'selectSingle',
+ 'type' => 'language',
+ ],
+ 'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.language',
+ ],
+ 'title' => [
+ 'config' => [
+ 'max' => 256,
+ 'size' => 50,
+ 'type' => 'input',
+ ],
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:columns.title',
+ ],
+ 'tx_headless_item' => [
+ 'config' => [
+ 'foreign_field' => 'foreign_uid',
+ 'foreign_table' => 'tx_headless_item',
+ 'foreign_table_field' => 'foreign_table',
+ 'type' => 'inline',
+ ],
+ 'exclude' => 0,
+ 'label' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:tx_headless_item',
],
],
+ 'ctrl' => [
+ 'crdate' => 'crdate',
+ 'delete' => 'deleted',
+ 'enablecolumns' => [
+ 'disabled' => 'hidden',
+ 'endtime' => 'endtime',
+ 'starttime' => 'starttime',
+ ],
+ 'hideTable' => true,
+ 'iconfile' => 'EXT:core/Resources/Public/Icons/T3Icons/svgs/actions/actions-folder.svg',
+ 'label' => 'header',
+ 'label_alt' => 'subheader,bodytext',
+ 'languageField' => 'sys_language_uid',
+ 'searchFields' => 'header,subheader,bodytext',
+ 'security' => [
+ 'ignorePageTypeRestriction' => true,
+ ],
+ 'sortby' => 'sorting',
+ 'title' => 'LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_item.xlf:title',
+ 'translationSource' => 'l10n_source',
+ 'transOrigDiffSourceField' => 'l10n_diffsource',
+ 'transOrigPointerField' => 'l10n_parent',
+ 'tstamp' => 'tstamp',
+ 'versioningWS' => true,
+ ],
'palettes' => [
+
+ 'access' => [
+ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.access',
+ 'showitem' => '
+ starttime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:starttime_formlabel,
+ endtime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:endtime_formlabel,
+ ',
+ ],
+ 'frames' => [
+ 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.frames',
+ 'showitem' => '
+ space_before_class;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_before_class_formlabel,
+ space_after_class;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_after_class_formlabel,
+ ',
+ ],
'header' => [
'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.headers',
'showitem' => '
@@ -376,25 +393,10 @@
',
],
- 'access' => [
- 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.access',
- 'showitem' => '
- starttime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:starttime_formlabel,
- endtime;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:endtime_formlabel,
- ',
- ],
- 'frames' => [
- 'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.frames',
- 'showitem' => '
- space_before_class;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_before_class_formlabel,
- space_after_class;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:space_after_class_formlabel,
- ',
- ],
-
// hidden but needs to be included all the time, so sys_language_uid is set correctly
'hiddenLanguagePalette' => [
- 'showitem' => 'sys_language_uid, l10n_parent',
'isHiddenPalette' => true,
+ 'showitem' => 'sys_language_uid, l10n_parent',
],
],
'types' => [
diff --git a/Configuration/TSConfig/Page/BackendLayouts/default.tsconfig b/Configuration/TSConfig/Page/BackendLayouts/default.tsconfig
index 65c19a0..e0249f3 100644
--- a/Configuration/TSConfig/Page/BackendLayouts/default.tsconfig
+++ b/Configuration/TSConfig/Page/BackendLayouts/default.tsconfig
@@ -13,9 +13,6 @@ mod {
1 {
name = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_bl.xlf:column.above_breadcrumbs
colPos = 1687238554
- disallowed {
- CType = footer_content
- }
}
}
}
@@ -24,9 +21,6 @@ mod {
1 {
name = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_bl.xlf:column.main
colPos = 0
- disallowed {
- CType = footer_content
- }
}
}
}
diff --git a/Configuration/TSConfig/Page/BackendLayouts/root.tsconfig b/Configuration/TSConfig/Page/BackendLayouts/root.tsconfig
index 8e2c726..b895df4 100644
--- a/Configuration/TSConfig/Page/BackendLayouts/root.tsconfig
+++ b/Configuration/TSConfig/Page/BackendLayouts/root.tsconfig
@@ -6,28 +6,13 @@ mod {
config {
backend_layout {
colCount = 1
- rowCount = 2
+ rowCount = 1
rows {
1 {
columns {
1 {
name = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_bl.xlf:column.main
colPos = 0
- disallowed {
- CType = footer_content
- }
- }
- }
- }
- 2 {
- columns {
- 1 {
- name = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_bl.xlf:column.footer
- colPos = 1687238527
- allowed {
- CType = footer_content
- }
- maxitems = 1
}
}
}
diff --git a/Configuration/TSConfig/Page/TCEFORM.tsconfig b/Configuration/TSConfig/Page/TCEFORM.tsconfig
index cb30e18..f1a4f87 100644
--- a/Configuration/TSConfig/Page/TCEFORM.tsconfig
+++ b/Configuration/TSConfig/Page/TCEFORM.tsconfig
@@ -7,21 +7,22 @@ TCEFORM {
tt_content {
assets.types {
textmedia.config.maxitems = 1
+ textmedia.config.minitems = 1
}
bullets_type {
keepItems = 0,1
}
cols.disabled = 1
CType {
+ keepItems = ""
altLabels.image = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:image.title
}
frame_class.disabled = 1
- header.types {
- footer_content.label = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ttc.xlf:header.label.backendOnly
- }
image.types {
image.config.maxitems = 1
+ image.config.minitems = 1
textpic.config.maxitems = 1
+ textpic.config.minitems = 1
}
imagecols.types {
textpic {
@@ -65,7 +66,6 @@ TCEFORM {
}
}
linkToTop.disabled = 1
- media.disabled = 1
sectionIndex.disabled = 1
// wait for this issue to be resolved: https://forge.typo3.org/issues/100775
// Workaround in tt_content.php
diff --git a/Configuration/TSConfig/Page/WizardItems.tsconfig b/Configuration/TSConfig/Page/WizardItems.tsconfig
index 0a620c0..f5daaf1 100644
--- a/Configuration/TSConfig/Page/WizardItems.tsconfig
+++ b/Configuration/TSConfig/Page/WizardItems.tsconfig
@@ -9,14 +9,6 @@ mod.wizards.newContentElement.wizardItems {
CType = accordion
}
}
- footer_content {
- iconIdentifier = content-footer
- title = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:footer_content.title
- description = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:footer_content.description
- tt_content_defValues {
- CType = footer_content
- }
- },
// Element already exsists, only modify title and description
image {
title = LLL:EXT:rmnd_headless/Resources/Private/Language/locallang_ce.xlf:image.title
@@ -40,7 +32,6 @@ mod.wizards.newContentElement.wizardItems {
}
}
show := addToList(accordion)
- show := addToList(footer_content)
show := addToList(image_gallery)
show := addToList(tabs)
}
diff --git a/Configuration/TypoScript/Configuration/InitialDataConfiguration.typoscript b/Configuration/TypoScript/Configuration/InitialDataConfiguration.typoscript
index 9cca5c0..66e4a8c 100644
--- a/Configuration/TypoScript/Configuration/InitialDataConfiguration.typoscript
+++ b/Configuration/TypoScript/Configuration/InitialDataConfiguration.typoscript
@@ -16,15 +16,15 @@ initialData {
}
}
}
- footer = CONTENT
+ footer = JSON
footer {
- table = tt_content
- select {
- orderBy = sorting
- where = {#colPos} = 1687238527
- max = 1
+ dataProcessing {
+ 10 = Remind\Headless\DataProcessing\FlexFormProcessor
+ 10 {
+ fieldName = tx_headless_footer
+ as = flexform
+ }
}
- slide = -1
}
}
}
diff --git a/Configuration/TypoScript/Configuration/PageConfiguration.typoscript b/Configuration/TypoScript/Configuration/PageConfiguration.typoscript
new file mode 100644
index 0000000..4eb7bd2
--- /dev/null
+++ b/Configuration/TypoScript/Configuration/PageConfiguration.typoscript
@@ -0,0 +1,16 @@
+page {
+ 10 {
+ fields {
+ media {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/FooterContent.typoscript b/Configuration/TypoScript/ContentElement/FooterContent.typoscript
deleted file mode 100644
index ec99ef8..0000000
--- a/Configuration/TypoScript/ContentElement/FooterContent.typoscript
+++ /dev/null
@@ -1,10 +0,0 @@
-tt_content.footer_content = JSON
-tt_content.footer_content {
- dataProcessing {
- 10 = Remind\Headless\DataProcessing\FlexFormProcessor
- 10 {
- fieldName = pi_flexform
- as = flexform
- }
- }
-}
diff --git a/Configuration/TypoScript/ContentElement/Image.typoscript b/Configuration/TypoScript/ContentElement/Image.typoscript
index 465ade9..71acfe6 100644
--- a/Configuration/TypoScript/ContentElement/Image.typoscript
+++ b/Configuration/TypoScript/ContentElement/Image.typoscript
@@ -3,13 +3,14 @@ tt_content.image {
content {
fields {
gallery >
- images = TEXT
- images {
+ image = TEXT
+ image {
dataProcessing {
10 = FriendsOfTYPO3\Headless\DataProcessing\FilesProcessor
10 {
references.fieldName = image
as = files
+ processingConfiguration < lib.assetProcessingConfiguration
}
}
}
diff --git a/Configuration/TypoScript/ContentElement/ImageGallery.typoscript b/Configuration/TypoScript/ContentElement/ImageGallery.typoscript
index fa40a00..6518ed8 100644
--- a/Configuration/TypoScript/ContentElement/ImageGallery.typoscript
+++ b/Configuration/TypoScript/ContentElement/ImageGallery.typoscript
@@ -10,6 +10,10 @@ tt_content.image_gallery {
10 {
references.fieldName = image
as = files
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
}
}
}
diff --git a/Configuration/TypoScript/ContentElement/ImageOrient.typoscript b/Configuration/TypoScript/ContentElement/ImageOrient.typoscript
new file mode 100644
index 0000000..2114907
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/ImageOrient.typoscript
@@ -0,0 +1,19 @@
+lib.imageOrient = COA
+lib.imageOrient {
+ 10 = TEXT
+ 10 {
+ if {
+ value = 25
+ equals.field = imageorient
+ }
+ value = right
+ }
+ 20 = TEXT
+ 20 {
+ if {
+ value = 26
+ equals.field = imageorient
+ }
+ value = left
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/Items.typoscript b/Configuration/TypoScript/ContentElement/Items.typoscript
index ec26749..1ede775 100644
--- a/Configuration/TypoScript/ContentElement/Items.typoscript
+++ b/Configuration/TypoScript/ContentElement/Items.typoscript
@@ -59,13 +59,17 @@ lib.items {
parseFunc =< lib.parseFunc_links
}
items =< lib.items
- images = TEXT
- images {
+ image = TEXT
+ image {
dataProcessing {
10 = FriendsOfTYPO3\Headless\DataProcessing\FilesProcessor
10 {
references.fieldName = image
as = files
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 1
+ }
}
}
}
diff --git a/Configuration/TypoScript/ContentElement/MenuAbstract.typoscript b/Configuration/TypoScript/ContentElement/MenuAbstract.typoscript
new file mode 100644
index 0000000..f29b5ee
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuAbstract.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_abstract {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/MenuCategorizedPages.typoscript b/Configuration/TypoScript/ContentElement/MenuCategorizedPages.typoscript
new file mode 100644
index 0000000..80cae87
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuCategorizedPages.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_categorized_pages {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/MenuRecentlyUpdated.typoscript b/Configuration/TypoScript/ContentElement/MenuRecentlyUpdated.typoscript
new file mode 100644
index 0000000..fadb9f0
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuRecentlyUpdated.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_recently_updated {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/MenuRelatedPages.typoscript b/Configuration/TypoScript/ContentElement/MenuRelatedPages.typoscript
new file mode 100644
index 0000000..4a88455
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuRelatedPages.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_related_pages {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/MenuSitemap.typoscript b/Configuration/TypoScript/ContentElement/MenuSitemap.typoscript
new file mode 100644
index 0000000..eb423ad
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuSitemap.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_sitemap {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/MenuSitemapPages.typoscript b/Configuration/TypoScript/ContentElement/MenuSitemapPages.typoscript
new file mode 100644
index 0000000..fc57add
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/MenuSitemapPages.typoscript
@@ -0,0 +1,22 @@
+tt_content.menu_sitemap_pages {
+ fields {
+ content {
+ fields {
+ menu {
+ dataProcessing {
+ 10 {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/ContentElement/Textmedia.typoscript b/Configuration/TypoScript/ContentElement/Textmedia.typoscript
index 85a0a10..99c6e80 100644
--- a/Configuration/TypoScript/ContentElement/Textmedia.typoscript
+++ b/Configuration/TypoScript/ContentElement/Textmedia.typoscript
@@ -2,38 +2,21 @@ tt_content.textmedia {
fields {
content {
fields {
+ gallery >
ratio = TEXT
ratio {
field = imagecols
intval = 1
}
- assetPosition = COA
- assetPosition {
- 10 = TEXT
- 10 {
- if {
- value = 25
- equals.field = imageorient
- }
- value = right
- }
- 20 = TEXT
- 20 {
- if {
- value = 26
- equals.field = imageorient
- }
- value = left
- }
- }
- gallery >
- assets = TEXT
- assets {
+ mediaPosition =< lib.imageOrient
+ media = TEXT
+ media {
dataProcessing {
10 = FriendsOfTYPO3\Headless\DataProcessing\FilesProcessor
10 {
references.fieldName = assets
as = files
+ processingConfiguration < lib.assetProcessingConfiguration
}
}
}
diff --git a/Configuration/TypoScript/ContentElement/Textpic.typoscript b/Configuration/TypoScript/ContentElement/Textpic.typoscript
index 2ef3147..b0efcc2 100644
--- a/Configuration/TypoScript/ContentElement/Textpic.typoscript
+++ b/Configuration/TypoScript/ContentElement/Textpic.typoscript
@@ -1,13 +1,22 @@
-tt_content.textpic =< tt_content.textmedia
tt_content.textpic {
fields {
content {
fields {
gallery >
- assets {
+ ratio = TEXT
+ ratio {
+ field = imagecols
+ intval = 1
+ }
+ imagePosition =< lib.imageOrient
+ image = TEXT
+ image {
dataProcessing {
+ 10 = FriendsOfTYPO3\Headless\DataProcessing\FilesProcessor
10 {
references.fieldName = image
+ as = files
+ processingConfiguration < lib.assetProcessingConfiguration
}
}
}
diff --git a/Configuration/TypoScript/ContentElement/Uploads.typoscript b/Configuration/TypoScript/ContentElement/Uploads.typoscript
new file mode 100644
index 0000000..ec64c9d
--- /dev/null
+++ b/Configuration/TypoScript/ContentElement/Uploads.typoscript
@@ -0,0 +1,18 @@
+tt_content.uploads {
+ fields {
+ content {
+ fields {
+ media {
+ dataProcessing {
+ 10 {
+ processingConfiguration < lib.assetProcessingConfiguration
+ processingConfiguration {
+ returnFlattenObject = 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Configuration/TypoScript/Extensions/tx_form.typoscript b/Configuration/TypoScript/Extensions/tx_form.typoscript
index 5c4bd13..0e36eff 100644
--- a/Configuration/TypoScript/Extensions/tx_form.typoscript
+++ b/Configuration/TypoScript/Extensions/tx_form.typoscript
@@ -1,9 +1,7 @@
plugin.tx_form {
settings {
yamlConfigurations {
- 100 = EXT:rmnd_headless/Configuration/Form/BaseSetup.yaml
- 101 = EXT:rmnd_headless/Configuration/Form/FormElementSize.yaml
- 102 = EXT:rmnd_headless/Configuration/Form/JsonRedirectFinisher.yaml
+ 1731482571 = EXT:rmnd_headless/Configuration/Form/BaseSetup.yaml
}
}
}
@@ -11,9 +9,7 @@ plugin.tx_form {
module.tx_form {
settings {
yamlConfigurations {
- 100 = EXT:rmnd_headless/Configuration/Form/BaseSetup.yaml
- 101 = EXT:rmnd_headless/Configuration/Form/FormElementSize.yaml
- 102 = EXT:rmnd_headless/Configuration/Form/JsonRedirectFinisher.yaml
+ 1731482571 = EXT:rmnd_headless/Configuration/Form/BaseSetup.yaml
}
}
}
\ No newline at end of file
diff --git a/Configuration/TypoScript/Helpers/AssetProcessingConfiguration.typoscript b/Configuration/TypoScript/Helpers/AssetProcessingConfiguration.typoscript
new file mode 100644
index 0000000..85a8202
--- /dev/null
+++ b/Configuration/TypoScript/Helpers/AssetProcessingConfiguration.typoscript
@@ -0,0 +1,12 @@
+lib.assetProcessingConfiguration {
+ returnFlattenObject = 1
+ legacyReturn = 0
+ linkResult = 1
+ delayProcessing = 1
+ properties {
+ byType = 1
+ defaultFieldsByType = uidLocal,fileReferenceUid,type,extension,title,description,tx_headless_lazy_loading as lazyLoading
+ defaultImageFields = alternative,link,dimensions
+ defaultVideoFields = autoplay
+ }
+}
\ No newline at end of file
diff --git a/Configuration/TypoScript/Page/Meta.typoscript b/Configuration/TypoScript/Page/Meta.typoscript
index 191e386..19834c5 100644
--- a/Configuration/TypoScript/Page/Meta.typoscript
+++ b/Configuration/TypoScript/Page/Meta.typoscript
@@ -1,22 +1,27 @@
-lib.meta {
- fields {
- ogTitle {
- stdWrap.ifEmpty.cObject {
- field = seo_title
+page {
+ // can be removed in future version of EXT:headless, see https://github.com/TYPO3-Headless/headless/releases/tag/v4.4.0
+ 10 {
+ fields {
+ meta >
+ }
+ }
+
+ meta {
+ og:title = TEXT
+ og:title {
+ field = seo_title
stdWrap.ifEmpty.cObject = TEXT
stdWrap.ifEmpty.cObject {
field = title
}
- }
}
- twitterTitle {
- stdWrap.ifEmpty.cObject {
- field = seo_title
+ twitter:title = TEXT
+ twitter:title {
+ field = seo_title
stdWrap.ifEmpty.cObject = TEXT
stdWrap.ifEmpty.cObject {
field = title
}
- }
}
}
}
diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript
index a2516fb..d729bd2 100644
--- a/Configuration/TypoScript/setup.typoscript
+++ b/Configuration/TypoScript/setup.typoscript
@@ -1,4 +1,5 @@
@import 'EXT:headless/Configuration/TypoScript/setup.typoscript'
+@import 'EXT:rmnd_headless/Configuration/TypoScript/Helpers/*.typoscript'
@import 'EXT:rmnd_headless/Configuration/TypoScript/Configuration/*.typoscript'
@import 'EXT:rmnd_headless/Configuration/TypoScript/ContentElement/*.typoscript'
@import 'EXT:rmnd_headless/Configuration/TypoScript/Extensions/*.typoscript'
diff --git a/README.md b/README.md
index 39495cd..0c1ec65 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Use comoser to install the extension using `composer install remind/headless`. I
Add the following to your site config:
```yaml
-headless: true
+headless: 1
```
## Dependencies
@@ -29,11 +29,7 @@ Required dependencies are [headless](https://github.com/TYPO3-Headless/headless)
### Default
-The default layout consists of 1 column with 3 rows. Besides the main content (colPos = 0) there is also one column for content above the breadcrumbs (colPos = 1) and the footer (colPos = 10).
-
-The [content defender](https://extensions.typo3.org/extension/content_defender) extension is used to only allow exactly one footer_content content element in the footer column. The footer_content content element can not be used in the other columns.
-
-
+The default layout consists of 1 column with 2 rows. Besides the main content (colPos = 0) there is also one column for content above the breadcrumbs (colPos = 1).
## TCA
@@ -126,6 +122,14 @@ Similar to `space_before_inside`.
### pages
+#### tx_headless_footer
+
+The `tx_headless_footer` flexform field contains the footer content. Use the following code to set a flexform:
+
+```php
+\Remind\Headless\Utility::setFooterFlexForm('FILE:EXT:provider_extension/Configuration/FlexForms/Footer.xml');
+```
+
#### tx_headless_overview_label
An `tx_headless_overview_label` field is added to the page TCA. The field should be used to customize the label for the overview pages.
@@ -177,18 +181,6 @@ $GLOBALS['TCA']['tt_content']['types']['accordion']['columnsOverrides']['tx_head
Uses `tx_headless_item`, items consist of text (header, subheader, bodytext, title), a flexform field and images.
-### footer_content
-
-Basic definition without any actual content fields. Add a flexform in your provider extension to use `footer_content`:
-
-```php
-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
- '*',
- 'FILE:EXT:provider_extension/Configuration/FlexForms/FooterContent.xml',
- 'footer_content'
-);
-```
-
### tabs
Uses `tx_headless_item`, items consist of text (header, subheader, bodytext) only.
diff --git a/Resources/Private/Language/de.locallang_bl.xlf b/Resources/Private/Language/de.locallang_bl.xlf
index f902e64..bf17b80 100644
--- a/Resources/Private/Language/de.locallang_bl.xlf
+++ b/Resources/Private/Language/de.locallang_bl.xlf
@@ -9,9 +9,6 @@
Ãœber Breadcrumbs
-
- Fußzeile
-
Standard
diff --git a/Resources/Private/Language/de.locallang_ce.xlf b/Resources/Private/Language/de.locallang_ce.xlf
index 00e1184..ca81028 100644
--- a/Resources/Private/Language/de.locallang_ce.xlf
+++ b/Resources/Private/Language/de.locallang_ce.xlf
@@ -12,12 +12,6 @@
Akkordion Titel
-
-
Einzelnes Bild
diff --git a/Resources/Private/Language/de.locallang_form.xlf b/Resources/Private/Language/de.locallang_form.xlf
index a8e1e5b..12b1262 100644
--- a/Resources/Private/Language/de.locallang_form.xlf
+++ b/Resources/Private/Language/de.locallang_form.xlf
@@ -12,12 +12,36 @@
Pflichtfeld Hinweis
+
+ Links
+
+
+ Link Text
+
+
+ Seite
+
Größe
Gesamte Breite
+
+ Sehr klein
+
+
+ Klein
+
+
+ Mittel
+
+
+ Groß
+
+
+ Sehr groß
+