diff --git a/Classes/Backend/Preview/DefaultPreviewRenderer.php b/Classes/Backend/Preview/DefaultPreviewRenderer.php new file mode 100644 index 00000000..bd288cfc --- /dev/null +++ b/Classes/Backend/Preview/DefaultPreviewRenderer.php @@ -0,0 +1,248 @@ +getRecord(); + $itemLabels = $item->getContext()->getItemLabels(); + $outHeader = ''; + + $content = parent::renderPageModulePreviewContent($item); + if ( ($content && $record['CType'] === 'list') + || ($content && $record['CType'] === 'bullets') + || ($content && $record['CType'] === 'table') + || ($content && $record['CType'] === 'uploads') + || ($content && $record['CType'] === 'login') + || ($content && $record['CType'] === 'shortcut') + || ($content && $record['CType'] === 'div') + || ($content && $record['CType'] === 'html') + ) { + return ''; + } + + if ($record['CType'] === 't3sbs_card') { + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['pi_flexform']); + if ( $flexconf['header']['text'] ) { + $outHeader .= parent::linkEditContent(parent::renderText($flexconf['header']['text']), $record) . '
'; + } + } + + if ($record['header']) { + $infoArr = []; + parent::getProcessedValue($item, 'header_position,header_layout,header_link', $infoArr); + $hiddenHeaderNote = ''; + // If header layout is set to 'hidden', display an accordant note: + if ($record['header_layout'] == 100) { + $hiddenHeaderNote = ' [' . htmlspecialchars(parent::getLanguageService()->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_layout.I.6')) . ']'; + } + $outHeader .= $record['date'] + ? htmlspecialchars($itemLabels['date'] . ' ' . BackendUtility::date($record['date'])) . '
' + : ''; + $outHeader .= '' . parent::linkEditContent(parent::renderText($record['header']), $record) + . $hiddenHeaderNote . '
'; + } + + $info = ''; + $contentTypeLabels = $item->getContext()->getContentTypeLabels(); + $contentType = $contentTypeLabels[$record['CType']]; + $info = '
'.$contentType.'
'; + + return $info.$outHeader; + + } + + + /** + * Dedicated method for rendering preview body HTML for + * the page module only. + * + * @param GridColumnItem $item + * @return string + */ + public function renderPageModulePreviewContent(GridColumnItem $item): string + { + $out = ''; + $record = $item->getRecord(); + $content = parent::renderPageModulePreviewContent($item); + + if ( ($content && $record['CType'] === 'list') + || ($content && substr($record['CType'], 0, 4) === 'menu') + || ($content && $record['CType'] === 'bullets') + || ($content && $record['CType'] === 'table') + || ($content && $record['CType'] === 'uploads') + || ($content && $record['CType'] === 'login') + || ($content && $record['CType'] === 'shortcut') + || ($content && $record['CType'] === 'div') + || ($content && $record['CType'] === 'html') + ) { + return $content; + } + + $contentTypeLabels = $item->getContext()->getContentTypeLabels(); + $languageService = parent::getLanguageService(); + + $contentType = $contentTypeLabels[$record['CType']]; + if (isset($contentType)) { + + $extconf = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class)->get('t3sbootstrap'); + $maxCharacters = $extconf['previewCropMaxCharacters']; + $append = ' ...'; + + if ($record['subheader']) { + $out .= parent::linkEditContent(parent::renderText($record['subheader']), $record) . '
'; + } + if ($record['bodytext']) { + if ($extconf['previewCrop']) { + $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); + $text = $contentObject->cropHTML($record['bodytext'], $maxCharacters . '|' . $append . '|' . true); + } else { + $text = $record['bodytext']; + } + $out .= parent::linkEditContent(parent::renderText($text), $record); + } + if ($record['CType'] == 't3sbs_gallery') { + $out .= 'Columns: '.$record['imagecols']; + if ($record['CType'] == 't3sbs_gallery') { + $out .= '
Aspect ratio: '.$record['tx_t3sbootstrap_image_ratio']; + } + } + if ($record['CType'] === 't3sbs_card') { + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['pi_flexform']); + if ( $flexconf['text']['top'] ) { + if ($extconf['previewCrop']) { + $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); + $text = $contentObject->cropHTML($flexconf['text']['top'], $maxCharacters . '|' . $append . '|' . true); + } else { + $text = $flexconf['text']['top']; + } + $out .= parent::linkEditContent(parent::renderText($text), $record) . '
'; + } + if ( $flexconf['text']['bottom'] ) { + if ($extconf['previewCrop']) { + $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); + $text = $contentObject->cropHTML($flexconf['text']['bottom'], $maxCharacters . '|' . $append . '|' . true); + } else { + $text = $flexconf['text']['bottom']; + } + $out .= parent::linkEditContent(parent::renderText($text), $record) . '
'; + } + } + if ($record['CType'] === 't3sbs_carousel') { + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['tx_t3sbootstrap_flexform']); + if ( $flexconf['shift'] ) { + $flexconfOut .= '
- Shift: '.$flexconf['shift']; + } + if ( $flexconf['bgOverlay'] ) { + $flexconfOut .= '
- Background-Overlay'; + } + if ( $flexconf['shift'] ) { + $flexconfOut .= '
- Shift: '.$flexconf['shift']; + } + } + if ($record['CType'] === 't3sbs_button') { + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['tx_t3sbootstrap_flexform']); + + if ( $flexconf['style'] ) { + $flexconfOut .= '
- Style: '.$flexconf['style']; + } + if ( $flexconf['size'] ) { + $flexconfOut .= '
- Size: '.$flexconf['size']; + } + if ( $flexconf['block'] ) { + $flexconfOut .= '
- Block: '.$flexconf['block']; + } + if ( $flexconf['outline'] ) { + $flexconfOut .= '
- Outline'; + } + } + if ($record['CType'] === 't3sbs_toast') { + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['tx_t3sbootstrap_flexform']); + + if ( $flexconf['animation'] ) { + $flexconfOut .= '
- Animation'; + } + if ( $flexconf['autohide'] ) { + $flexconfOut .= '
- Autohide'; + } + if ( $flexconf['delay'] ) { + $flexconfOut .= '
- Delay: '.$flexconf['delay']; + } + if ( $flexconf['placement'] ) { + $flexconfOut .= '
- Placement: '.$flexconf['placement']; + } + } + + if ($flexconfOut) + $out = $out.substr($flexconfOut, 6); + + $media = $record['assets'] ?: $record['image']; + if ($media) { + $field = $record['assets'] ? 'assets' : 'image'; + $out .= '
'. parent::linkEditContent($this->getThumbCodeUnlinked($record, 'tt_content', $field), $record) . '
'; + } + + } else { + $message = sprintf( + $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue'), + $record['CType'] + ); + $out .= '' . htmlspecialchars($message) . ''; + } + + return $out; + } + + + /** + * Dedicated method for wrapping a preview header and body HTML. + * + * @param string $previewHeader + * @param string $previewContent + * @param GridColumnItem $item + * @return string + */ + public function wrapPageModulePreview($previewHeader, $previewContent, GridColumnItem $item): string + { + $content = '' . $previewHeader . $previewContent . ''; + if ($item->isDisabled()) { + return '' . $content . ''; + } + + return $content; + } + + +} diff --git a/Classes/Backend/Preview/T3sbPreviewRenderer.php b/Classes/Backend/Preview/T3sbPreviewRenderer.php new file mode 100644 index 00000000..fff4647f --- /dev/null +++ b/Classes/Backend/Preview/T3sbPreviewRenderer.php @@ -0,0 +1,341 @@ +tcaRegistry = $tcaRegistry ?? GeneralUtility::makeInstance(Registry::class); + $this->containerFactory = $containerFactory ?? GeneralUtility::makeInstance(ContainerFactory::class); + } + + + /** + * Dedicated method for rendering preview header HTML for + * the page module only. Receives $item which is an instance of + * GridColumnItem which has a getter method to return the record. + * + * @param GridColumnItem + * @return string + */ + public function renderPageModulePreviewHeader(GridColumnItem $item): string + { + $record = $item->getRecord(); + $itemLabels = $item->getContext()->getItemLabels(); + $outHeader = ''; + + if ($record['header']) { + $infoArr = []; + $this->getProcessedValue($item, 'header_position,header_layout,header_link', $infoArr); + $hiddenHeaderNote = ''; + // If header layout is set to 'hidden', display an accordant note: + if ($record['header_layout'] == 100) { + $hiddenHeaderNote = ' [' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:header_layout.I.6')) . ']'; + } + $outHeader = $record['date'] + ? htmlspecialchars($itemLabels['date'] . ' ' . BackendUtility::date($record['date'])) . '
' + : ''; + $outHeader .= '' . $this->linkEditContent($this->renderText($record['header']), $record) + . $hiddenHeaderNote . '
'; + } + + if ($record['subheader']) { + $outHeader .= parent::linkEditContent(parent::renderText($record['subheader']), $record) . '
'; + } + + $info = ''; + $contentTypeLabels = $item->getContext()->getContentTypeLabels(); + $contentType = $contentTypeLabels[$record['CType']]; + + switch ($record['CType']) { + case 'tabs_tab': + $info = '
'.$contentType.'
'; + break; + case 'collapsible_accordion': + $info = '
'.$contentType.'
'; + break; + default: + $info = '
'.$contentType.'
'; + } + + return $info.$outHeader; + + } + + + public function renderPageModulePreviewContent(GridColumnItem $item): string + { + + $content = parent::renderPageModulePreviewContent($item); + $context = $item->getContext(); + $record = $item->getRecord(); + $grid = GeneralUtility::makeInstance(Grid::class, $context); + try { + $container = $this->containerFactory->buildContainer((int)$record['uid']); + } catch (Exception $e) { + // not a container + return $content; + } + + $flexformService = GeneralUtility::makeInstance(FlexFormService::class); + $flexconf = $flexformService->convertFlexFormContentToArray($record['tx_t3sbootstrap_flexform']); + + if ($record['CType'] == 'two_columns' || $record['CType'] == 'three_columns' || $record['CType'] == 'four_columns' || $record['CType'] == 'six_columns') { + if ( $flexconf['equalWidth'] ) { + $out .= '
- Equal Width'; + } + if ( $flexconf['equalHeight'] ) { + $out .= '
- Equal Height'; + } + if ( $flexconf['noGutters'] ) { + $out .= '
- No Gutters'; + } + } + if ($record['CType'] == 'button_group') { + if ( $flexconf['vertical'] ) { + $out .= '
- Vertical: '.$flexconf['vertical']; + } + if ( $flexconf['size'] ) { + $out .= '
- Size: '.$flexconf['size']; + } + if ( $flexconf['align'] ) { + $out .= '
- Align: '.$flexconf['align']; + } + if ( $flexconf['fixedPosition'] ) { + $out .= '
- FixedPosition: '.$flexconf['fixedPosition']; + } + } + if ($record['CType'] == 'collapsible_accordion') { + $active = $flexconf['active'] ? 'TRUE' : 'FALSE'; + $out .= '
- Active: '.$active; + } + if ($record['CType'] == 'collapsible_container' && is_string($flexconf['appearance'])) { + $out .= '
- Appearance: '.ucfirst($flexconf['appearance']); + } + if ($record['CType'] == 'carousel_container') { + if ( $flexconf['width'] ) { + $out .= '
- Width: '.$flexconf['width'].'px'; + } + if ( $flexconf['ratio'] ) { + $out .= '
- Aspect ratio: '.$flexconf['ratio']; + } + if ( $flexconf['interval'] ) { + $out .= '
- Interval: '.$flexconf['interval']; + } + if ( $flexconf['link'] ) { + $out .= '
- Link: '.$flexconf['link']; + } + if ( $flexconf['multislider'] ) { + $out .= '
- Multislider'; + } + if ( $flexconf['zoom'] ) { + $out .= '
- Zoom'; + } + } + if ($record['CType'] == 'card_wrapper') { + $out .= '
- Wrapper: Card '.$flexconf['card_wrapper']; + if ( $flexconf['visibleCards'] ) { + $out .= '
- Visible Cards: '.$flexconf['visibleCards']; + } + if ( $flexconf['interval'] ) { + $out .= '
- Interval: '.$flexconf['interval']; + } + } + if ($record['CType'] == 'background_wrapper') { + if ( $flexconf['bgwlink'] ) { + $out .= '
- Link the entire Content Element'; + } + if ( $flexconf['origImage'] ) { + $out .= '
- Image inside (no background-image but a real image)'; + } + if ( $flexconf['bgAttachmentFixed'] ) { + $out .= '
- Background-attachment - fixed'; + } + if ( $flexconf['enableAutoheight'] ) { + $out .= '
- Enable content overlay and autoheight for background-image'; + } + if ( $flexconf['paddingTopBottom'] ) { + $out .= '
- Padding (top and bottom ): '.$flexconf['paddingTopBottom'].' rem'; + } + if ( $flexconf['noMediaPaddingTopBottom'] ) { + $out .= '
- Padding (top and bottom ): '.$flexconf['noMediaPaddingTopBottom'].' rem'; + } + if ( $flexconf['imgGrayscale'] ) { + $out .= '
- Grayscale: '.$flexconf['imgGrayscale']; + } + if ( $flexconf['imgSepia'] ) { + $out .= '
- Sepia: '.$flexconf['imgSepia']; + } + if ( $flexconf['imgOpacity'] ) { + $out .= '
- Opacity: '.$flexconf['imgOpacity']; + } + if ( $flexconf['imageRaster'] ) { + $out .= '
- Raster over the image/color'; + } + } + if ($record['CType'] == 'parallax_wrapper') { + if ( $flexconf['speedFactor'] ) { + $out .= '
- Speed Factor: '.$flexconf['speedFactor']; + } + if ( $flexconf['paddingTopBottom'] ) { + $out .= '
- Padding (top and bottom ): '.$flexconf['paddingTopBottom']; + } + if ( $flexconf['imageRaster'] ) { + $out .= '
- Image Raster'; + } + } + if ($record['CType'] === 'modal') { + + if ( $flexconf['animation'] ) { + $out .= '
- Animation'; + } + if ( $flexconf['size'] ) { + $out .= '
- Size: '.$flexconf['size']; + } + if ( $flexconf['buttonText'] ) { + $out .= '
- Button Text: '.$flexconf['buttonText']; + } + if ( $flexconf['button'] ) { + $out .= '
- Button: '.$flexconf['button']; + } + if ( $flexconf['style'] ) { + $out .= '
- Style: '.$flexconf['style']; + } + if ( $flexconf['fixedPosition'] ) { + $out .= '
- Fixed Position'; + } + } + if ($record['CType'] == 'tabs_container') { + if ( $flexconf['display_type'] && is_string($flexconf['display_type']) ) { + $out .= '
- Appearance: '.ucfirst($flexconf['display_type']); + } + if ( $flexconf['switch_effect'] ) { + $out .= '
- Fade effect: '.$flexconf['switch_effect']; + } + if ( $flexconf['fill'] ) { + $out .= '
- Fill and justify: '.$flexconf['fill']; + } + } + + $flexconfOut = ''; + if ($out) + $flexconfOut .= parent::linkEditContent('
'.substr($out, 6).'
', $record); + + $containerGrid = $this->tcaRegistry->getGrid($record['CType']); + + foreach ($containerGrid as $row => $cols) { + $rowObject = GeneralUtility::makeInstance(GridRow::class, $context); + + foreach ($cols as $col) { + $columnObject = GeneralUtility::makeInstance(ContainerGridColumn::class, $context, $col, $container); + $rowObject->addColumn($columnObject); + if (isset($col['colPos'])) { + $records = $container->getChildrenByColPos($col['colPos']); + foreach ($records as $contentRecord) { + $columnItem = GeneralUtility::makeInstance(ContainerGridColumnItem::class, $context, $columnObject, $contentRecord, $container); + $columnObject->addItem($columnItem); + } + } + } + $grid->addRow($rowObject); + } + + $gridTemplate = $this->tcaRegistry->getGridTemplate($record['CType']); + + $view = GeneralUtility::makeInstance(StandaloneView::class); + $view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials/', 'EXT:container/Resources/Private/Partials/']); + $view->setTemplatePathAndFilename($gridTemplate); + + $view->assign('hideRestrictedColumns', (bool)(BackendUtility::getPagesTSconfig($context->getPageId())['mod.']['web_layout.']['hideRestrictedCols'] ?? false)); + $view->assign('newContentTitle', $this->getLanguageService()->getLL('newContentElement')); + $view->assign('newContentTitleShort', $this->getLanguageService()->getLL('content')); + $view->assign('allowEditContent', $this->getBackendUser()->check('tables_modify', 'tt_content')); + $view->assign('containerGrid', $grid); + + $rendered = $view->render(); + + $media = $record['assets'] ?: $record['image']; + if ($media) { + $field = $record['assets'] ? 'assets' : 'image'; + $flexconfOut .= '
'. parent::linkEditContent($this->getThumbCodeUnlinked($record, 'tt_content', $field), $record) . '
'; + } + + $extconf = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class)->get('t3sbootstrap'); + + if ($extconf['previewClosedCollapsible']) { + $content = '

+
'.$content . $rendered.'
'; + } else { + $content = '

+ + + + + +

+
'.$content . $rendered.'
'; + } + + return $flexconfOut.$content; + } + + + /** + * Dedicated method for wrapping a preview header and body HTML. + * + * @param string $previewHeader + * @param string $previewContent + * @param GridColumnItem $item + * @return string + */ + public function wrapPageModulePreview($previewHeader, $previewContent, GridColumnItem $item): string + { + $content = '' . $previewHeader . $previewContent . ''; + if ($item->isDisabled()) { + return '' . $content . ''; + } + + return $content; + } + +} diff --git a/Classes/Controller/ConfigController.php b/Classes/Controller/ConfigController.php index 8e166b2b..633a17df 100644 --- a/Classes/Controller/ConfigController.php +++ b/Classes/Controller/ConfigController.php @@ -23,7 +23,6 @@ use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\Query\QueryHelper; -use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Information\Typo3Version; /** @@ -118,16 +117,6 @@ public function initializeAction() $this->rootConfig = $this->configRepository->findOneByPid($this->rootPageId); $typo3Version = GeneralUtility::makeInstance(Typo3Version::class); $this->version = (int)$typo3Version->getVersion(); - - $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); - $pageRenderer->loadRequireJsModule( - 'TYPO3/CMS/T3sbootstrap/T3sBootstrap', - 'function() { console.log("Loaded own module."); }' - ); - - if ($this->version === 11) { - $pageRenderer->addCssFile('/typo3conf/ext/t3sbootstrap/Resources/Public/Backend/bestyles11.css'); - } } @@ -198,6 +187,7 @@ public function newAction(): void $assignedOptions = self::getFieldsOptions(); $assignedOptions['pid'] = $this->currentUid; $assignedOptions['tcaColumns'] = self::getTcaColumns(); + $assignedOptions['t3version'] = $this->version; if ( $this->rootConfig ) { // config from rootline @@ -542,7 +532,7 @@ public function getCustomScss( string $file ): array } } - return $assignedOptions; + return (array)$assignedOptions; } diff --git a/Classes/DataProcessing/BootstrapProcessor.php b/Classes/DataProcessing/BootstrapProcessor.php index ff2bc11a..2618ca6c 100644 --- a/Classes/DataProcessing/BootstrapProcessor.php +++ b/Classes/DataProcessing/BootstrapProcessor.php @@ -308,6 +308,8 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu $processedData['style'] = ''; } + $processedData['origImage'] = $parentflexconf['origImage']; + if ($parentflexconf['buttontext']) $processedData['buttontext'] = trim(explode('|', $parentflexconf['buttontext'])[$processedData['data']['sys_language_uid']]); @@ -439,7 +441,9 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu || $processedData['data']['CType'] == 'image' ) { // if codesnippet if ($extConf['codesnippet'] && $processedData['data']['bodytext']) { - $processedData['codesnippet'] = strpos($processedData['data']['bodytext'], '
') ? TRUE : FALSE;
+				if (strpos($processedData['data']['bodytext'], '
') !== FALSE) {
+					$processedData['codesnippet'] = TRUE;
+				}
 			}
 			// if media
 			if ($processedData['data']['assets'] || $processedData['data']['image'] || $processedData['data']['media']) {
@@ -449,6 +453,8 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 				if (is_array($processedData['files'])) {
 					foreach ($processedData['files'] as $file ) {
 						if ($file->getProperties()['tx_t3sbootstrap_hover_effect'])	$processedData['hoverEffect'] = TRUE;
+
+
 					}
 				}
 				$galleryUtility = GeneralUtility::makeInstance(GalleryHelper::class);
@@ -495,6 +501,7 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 			$processedData['addmedia']['imagezoom'] = $processedData['data']['image_zoom'];
 			$processedData['addmedia']['CType'] = $processedData['data']['CType'];
 			$processedData['addmedia']['ratio'] = $processedData['data']['tx_t3sbootstrap_image_ratio'];
+			$processedData['addmedia']['origImg'] = $processedData['data']['tx_t3sbootstrap_image_orig'];
 		}
 
 		// container class
diff --git a/Classes/DataProcessing/ConfigProcessor.php b/Classes/DataProcessing/ConfigProcessor.php
index bd399124..967aea11 100644
--- a/Classes/DataProcessing/ConfigProcessor.php
+++ b/Classes/DataProcessing/ConfigProcessor.php
@@ -18,6 +18,9 @@
 use T3SBS\T3sbootstrap\Utility\BackgroundImageUtility;
 use TYPO3\CMS\Core\Resource\FileRepository;
 use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
+use TYPO3\CMS\Core\Database\QueryGenerator;
+
 
 class ConfigProcessor implements DataProcessorInterface
 {
@@ -208,18 +211,28 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 
 			$navbarClass .= $processedRecordVariables['navbarClass'] ? ' '.$processedRecordVariables['navbarClass'] : '';
 
-			if ( $processedRecordVariables['navbarColor'] == 'color' ) {
-				if ( $processedRecordVariables['navbarBackground'] ) {
-					$navbarStyle = 'background-color: '.$processedRecordVariables['navbarBackground'].';';
-					$processedData['config']['navbar']['style'] = $navbarStyle;
+			if ( $processedRecordVariables['navbarTransparent'] && $processedRecordVariables['navbarPlacement'] == 'fixed-top') {
+				if ( $processedRecordVariables['navbarColor'] == 'color' && $processedRecordVariables['navbarBackground'] ) {
+					$processedData['config']['navbar']['colorschemes'] = $processedRecordVariables['navbarBackground'];
+				} else {
+					$processedData['config']['navbar']['colorschemes'] = 'var(--'.$processedRecordVariables['navbarColor'].')';
+				}
+				$processedData['config']['navbar']['transparent'] = true;
+			} else {
+
+				if ( $processedRecordVariables['navbarColor'] == 'color' ) {
+					if ( $processedRecordVariables['navbarBackground'] ) {
+						$navbarStyle = 'background-color: '.$processedRecordVariables['navbarBackground'].';';
+						$processedData['config']['navbar']['style'] = $navbarStyle;
+					} else {
+						$processedData['config']['navbar']['shrinkColorschemes'] = 'bg-'.$processedRecordVariables['navbarShrinkcolorschemes'];
+						$processedData['config']['navbar']['colorschemes'] = 'bg-'.$processedRecordVariables['navbarColor'];
+					}
 				} else {
+					$navbarClass .= ' bg-'.$processedRecordVariables['navbarColor'];
 					$processedData['config']['navbar']['shrinkColorschemes'] = 'bg-'.$processedRecordVariables['navbarShrinkcolorschemes'];
 					$processedData['config']['navbar']['colorschemes'] = 'bg-'.$processedRecordVariables['navbarColor'];
 				}
-			} else {
-				$navbarClass .= ' bg-'.$processedRecordVariables['navbarColor'];
-				$processedData['config']['navbar']['shrinkColorschemes'] = 'bg-'.$processedRecordVariables['navbarShrinkcolorschemes'];
-				$processedData['config']['navbar']['colorschemes'] = 'bg-'.$processedRecordVariables['navbarColor'];
 			}
 
 			if ( ($processedRecordVariables['navbarPlacement'] == 'fixed-top' && $processedRecordVariables['navbarShrinkcolor'])
@@ -253,10 +266,16 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 			}
 			$processedData['config']['navbar']['justify'] = $processedRecordVariables['navbarJustify'] ? ' nav-fill w-100' : '';
 			$processedData['config']['navbar']['offcanvas'] = $processedRecordVariables['navbarOffcanvas'];
+			$processedData['config']['navbar']['animatedToggler'] = $processedRecordVariables['navbarAnimatedtoggler'];
 			if ( $processedRecordVariables['navbarSearchbox'] ) {
 				$processedData['config']['navbar']['searchbox'] = $processedRecordVariables['navbarSearchbox'];
 				$processedData['config']['navbar']['searchboxcolor'] = $processedRecordVariables['navbarEnable'] == 'light' ? 'dark' : 'light';
 			}
+
+			$extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('t3sbootstrap');
+			if ( $extConf['navigationColor'] ) {
+				$processedData['config']['navbar']['navColorCSS'] = self::getNavigationColor();
+			}
 		}
 
 		/**
@@ -288,11 +307,11 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 				if ( count($fileObjects) > 1 ) {
 					// slider
 					$processedData['bgSlides'] =
-					 self::getBackgroundImageUtility()->getBgImage($uid, 'pages', TRUE, FALSE, [], FALSE, 0, $webp);
+					 self::getBackgroundImageUtility()->getBgImage($uid, 'pages', TRUE, FALSE, [], FALSE, 0, $webp, $contentObjectConfiguration['settings.']['bgMediaQueries']);
 				} else {
 					// background image
 					$processedData['config']['jumbotron']['bgImage'] =
-					 self::getBackgroundImageUtility()->getBgImage($uid, 'pages', TRUE, FALSE, [], FALSE, $processedData['data']['uid'], $webp);
+					 self::getBackgroundImageUtility()->getBgImage($uid, 'pages', TRUE, FALSE, [], FALSE, $processedData['data']['uid'], $webp, $contentObjectConfiguration['settings.']['bgMediaQueries']);
 				}
 
 			} elseif ( $processedRecordVariables['jumbotronBgimage'] == 'page' ) {
@@ -300,21 +319,20 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu
 				if ( count($fileObjects) > 1 ) {
 					// slider
 					$processedData['bgSlides'] =
-					 self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', TRUE, FALSE, [], FALSE, 0, $webp);
+					 self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', TRUE, FALSE, [], FALSE, 0, $webp, $contentObjectConfiguration['settings.']['bgMediaQueries']);
 				} else {
 					// background image
 				$processedData['config']['jumbotron']['bgImage'] =
-				 self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', TRUE, FALSE, [], FALSE, 0, $webp);
+				 self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', TRUE, FALSE, [], FALSE, 0, $webp, $contentObjectConfiguration['settings.']['bgMediaQueries']);
 				}
 			}
 		}
 
-
 		/**
 		 * Background Image (body)
 		 */
 		if ( $contentObjectConfiguration['settings.']['config.']['backgroundImageEnable'] ) {
-			$bgImage = self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', FALSE, FALSE, [], TRUE, 0, $webp);
+			$bgImage = self::getBackgroundImageUtility()->getBgImage($frontendController->id, 'pages', FALSE, FALSE, [], TRUE, 0, $webp, $contentObjectConfiguration['settings.']['bgMediaQueries']);
 			if ( empty($bgImage) && $contentObjectConfiguration['settings.']['config.']['backgroundImageSlide'] ) {
 				foreach ($frontendController->rootLine as $page) {
 					$bgImage = self::getBackgroundImageUtility()
@@ -452,4 +470,79 @@ protected function getBackgroundImageUtility(): BackgroundImageUtility
 	}
 
 
+	/**
+	 * Generate CSS for navigation color
+	 *
+	 * @return string
+	 */
+	protected function getNavigationColor(): string
+	{
+		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
+		$result = $queryBuilder
+			 ->select('uid','tx_t3sbootstrap_navigationcolor', 'tx_t3sbootstrap_navigationactivecolor', 'tx_t3sbootstrap_navigationhover','tx_t3sbootstrap_navigationbgcolor')
+			 ->from('pages')
+			 ->where(
+				$queryBuilder->expr()->orX(
+					$queryBuilder->expr()->neq('tx_t3sbootstrap_navigationcolor', $queryBuilder->createNamedParameter('')),
+					$queryBuilder->expr()->neq('tx_t3sbootstrap_navigationactivecolor', $queryBuilder->createNamedParameter('')),
+					$queryBuilder->expr()->neq('tx_t3sbootstrap_navigationhover', $queryBuilder->createNamedParameter('')),
+					$queryBuilder->expr()->neq('tx_t3sbootstrap_navigationbgcolor', $queryBuilder->createNamedParameter(''))
+				)
+			 )
+			 ->execute();
+
+		$navbarColors = $result->fetchAll();
+		$navbarColorCSS = '';
+
+		foreach($navbarColors as $navbarColor) {
+
+			$treePages = $this->getTreePids($navbarColor['uid']);
+
+			foreach($treePages as $treepageUid) {
+
+				if ($navbarColor['uid'] == $treepageUid) {
+
+					$item = '#nav-item-'.(int)$treepageUid;
+
+					if ($navbarColor['tx_t3sbootstrap_navigationactivecolor']) {
+						$navbarColorCSS .= $item.'.active .nav-link{color:'.$navbarColor['tx_t3sbootstrap_navigationbgcolor'].' !important}';
+					}
+
+				} else {
+
+					$item = '.dropdown-item-'.(int)$treepageUid;
+
+					if ($navbarColor['tx_t3sbootstrap_navigationcolor']) {
+						$navbarColorCSS .= $item.'{color:'.$navbarColor['tx_t3sbootstrap_navigationcolor'].' !important}';
+					}
+					if ($navbarColor['tx_t3sbootstrap_navigationactivecolor']) {
+						$navbarColorCSS .= $item.'.active{color:'.$navbarColor['tx_t3sbootstrap_navigationactivecolor'].' !important}';
+					}
+					if ($navbarColor['tx_t3sbootstrap_navigationbgcolor']) {
+						$navbarColorCSS .= $item.'.active{background:'.$navbarColor['tx_t3sbootstrap_navigationbgcolor'].' !important}';
+						$navbarColorCSS .= $item.':hover,'.$item.':focus{background:'.$navbarColor['tx_t3sbootstrap_navigationbgcolor'].' !important}';
+					}
+					if ($navbarColor['tx_t3sbootstrap_navigationhover']) {
+						$navbarColorCSS .= $item.':hover,'.$item.':focus{color:'.$navbarColor['tx_t3sbootstrap_navigationhover'].' !important}';
+						$navbarColorCSS .= $item.'.active:hover,'.$item.'.active:focus{color:'.$navbarColor['tx_t3sbootstrap_navigationhover'].' !important}';
+					}
+				}
+			}
+
+		}
+
+		return $navbarColorCSS;
+	}
+
+
+	function getTreePids($parent = 0): array
+	{
+		$queryGenerator = GeneralUtility::makeInstance(QueryGenerator::class);
+
+		 $childPids = $queryGenerator->getTreeList($parent, 999999, 0, 1);
+		 $childPids = explode(',',$childPids );
+
+	    return $childPids;
+	}
+
 }
diff --git a/Classes/Domain/Model/Config.php b/Classes/Domain/Model/Config.php
index 0fd6f325..4f3892a8 100644
--- a/Classes/Domain/Model/Config.php
+++ b/Classes/Domain/Model/Config.php
@@ -257,6 +257,13 @@ class Config extends AbstractEntity
 	 */
 	protected $navbarToggler = '';
 
+	/**
+	 * navbarAnimatedtoggler
+	 *
+	 * @var bool
+	 */
+	protected $navbarAnimatedtoggler = false;
+
 	/**
 	 * navbarBreakpoint
 	 *
@@ -271,6 +278,14 @@ class Config extends AbstractEntity
 	 */
 	protected $navbarOffcanvas = false;
 
+
+	/**
+	 * navbarTransparent
+	 *
+	 * @var bool
+	 */
+	protected $navbarTransparent = false;
+
 	/**
 	 * navbarHeight
 	 *
@@ -1730,6 +1745,68 @@ public function isNavbarOffcanvas()
 		return $this->navbarOffcanvas;
 	}
 
+	/**
+	 * Returns the navbarAnimatedtoggler
+	 *
+	 * @return bool $navbarAnimatedtoggler
+	 */
+	public function getNavbarAnimatedtoggler()
+	{
+		return $this->navbarAnimatedtoggler;
+	}
+
+	/**
+	 * Sets the navbarAnimatedtoggler
+	 *
+	 * @param bool $navbarAnimatedtoggler
+	 * @return void
+	 */
+	public function setNavbarAnimatedtoggler($navbarAnimatedtoggler)
+	{
+		$this->navbarAnimatedtoggler = $navbarAnimatedtoggler;
+	}
+
+	/**
+	 * Returns the boolean state of navbarAnimatedtoggler
+	 *
+	 * @return bool
+	 */
+	public function isNavbarAnimatedtoggler()
+	{
+		return $this->navbarAnimatedtoggler;
+	}
+
+	/**
+	 * Returns the navbarTransparent
+	 *
+	 * @return bool $navbarTransparent
+	 */
+	public function getNavbarTransparent()
+	{
+		return $this->navbarTransparent;
+	}
+
+	/**
+	 * Sets the navbarTransparent
+	 *
+	 * @param bool $navbarTransparent
+	 * @return void
+	 */
+	public function setNavbarTransparent($navbarTransparent)
+	{
+		$this->navbarTransparent = $navbarTransparent;
+	}
+
+	/**
+	 * Returns the boolean state of navbarTransparent
+	 *
+	 * @return bool
+	 */
+	public function isNavbarTransparent()
+	{
+		return $this->navbarTransparent;
+	}
+
 	/**
 	 * Returns the navbarHeight
 	 *
diff --git a/Classes/Helper/ClassHelper.php b/Classes/Helper/ClassHelper.php
index c00afe41..be54d5af 100644
--- a/Classes/Helper/ClassHelper.php
+++ b/Classes/Helper/ClassHelper.php
@@ -220,15 +220,24 @@ public function getTxContainerClass($data, $flexconf, $isVideo, $extConf): strin
 	 */
 	public function getHeaderClass($data): array
 	{
-		$header['class'] = $data['header_position'] ? ' text-'.$data['header_position'] : '';
+		$header['class'] = $data['header_position'] ? 'text-'.$data['header_position'] : '';
 		$header['hClass'] = '';
-
+		$header['hColorVar'] = '';
+		$header['hLine'] = '';
+	
 		if ( $data['tx_t3sbootstrap_header_class'] ) {
+			if (strpos($data['tx_t3sbootstrap_header_class'], 'h-line-1') !== false) {
+				$header['hLine'] = 'h-line-1';
+			}
+			if (strpos($data['tx_t3sbootstrap_header_class'], 'h-line-2') !== false) {
+				$header['hLine'] = 'h-line-2';
+			}
 			$textColors = explode(',','text-primary,text-secondary,text-danger,text-success,text-warning,
 			text-info,text-light,text-dark,text-body,text-muted,text-white');
 			foreach ($textColors as $textColor) {
 				if (strpos($data['tx_t3sbootstrap_header_class'], $textColor) !== false) {
 					$header['hClass'] .= $textColor;
+					$header['hColorVar'] = 'var(--'.substr($textColor, 5).')';
 					$data['tx_t3sbootstrap_header_class'] = trim(str_replace($textColor, '', $data['tx_t3sbootstrap_header_class']));
 					break;
 				}
diff --git a/Classes/Hooks/PageLayoutView/CardPreviewRenderer.php b/Classes/Hooks/PageLayoutView/CardPreviewRenderer.php
deleted file mode 100644
index e5c487ac..00000000
--- a/Classes/Hooks/PageLayoutView/CardPreviewRenderer.php
+++ /dev/null
@@ -1,80 +0,0 @@
-convertFlexFormContentToArray($row['pi_flexform']);
-
-			if ( $flexconf['text']['top'] ) {
-				$itemContent .= $parentObject->linkEditContent($parentObject->renderText($flexconf['text']['top']), $row) . '
'; - } elseif ( $flexconf['text']['bottom'] ) { - $itemContent .= $parentObject->linkEditContent($parentObject->renderText($flexconf['text']['bottom']), $row) . '
'; - } - - if ($row['assets']) { - $itemContent .= $parentObject->linkEditContent($parentObject->getThumbCodeUnlinked($row, 'tt_content', 'assets'), $row) . '
'; - - $fileReferences = BackendUtility::resolveFileReferences('tt_content', 'assets', $row); - - if (!empty($fileReferences)) { - $linkedContent = ''; - - foreach ($fileReferences as $fileReference) { - $description = $fileReference->getDescription(); - if ($description !== null && $description !== '') { - $linkedContent .= htmlspecialchars($description) . '
'; - } - } - - $itemContent .= $parentObject->linkEditContent($linkedContent, $row); - - unset($linkedContent); - } - } - - $drawItem = false; - } - } -} diff --git a/Classes/UserFunction/TcaMatcher.php b/Classes/UserFunction/TcaMatcher.php index 173bffa0..2921cfc0 100644 --- a/Classes/UserFunction/TcaMatcher.php +++ b/Classes/UserFunction/TcaMatcher.php @@ -339,4 +339,22 @@ public function isImage($arguments): bool } + /** + * isDropdownMenu + * + * @return bool + */ + public function isDropdownMenu($arguments): bool + { + $level = false; + $pageRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Domain\Repository\PageRepository::class); + $parentPage = $pageRepository->getPage($arguments['record']['pid']); + if ($parentPage['is_siteroot']) { + $level = true; + } + + return $level; + } + + } diff --git a/Classes/Utility/BackgroundImageUtility.php b/Classes/Utility/BackgroundImageUtility.php index 8a7e78cc..10415dd6 100644 --- a/Classes/Utility/BackgroundImageUtility.php +++ b/Classes/Utility/BackgroundImageUtility.php @@ -33,10 +33,11 @@ class BackgroundImageUtility implements SingletonInterface * @param bool $body * @param int $currentUid * @param bool $webp + * @param string $bgMediaQueries * * @return array */ - public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColorOnly=FALSE, $flexconf=[], $body=FALSE, $currentUid=0, $webp=FALSE) + public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColorOnly=FALSE, $flexconf=[], $body=FALSE, $currentUid=0, $webp=FALSE, $bgMediaQueries='2560,1920,1200,992,768,576') { $frontendController = $this->getFrontendController(); $fileRepository = GeneralUtility::makeInstance(FileRepository::class); @@ -56,7 +57,7 @@ public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColor $image = $this->imageService()->getImage($file->getOriginalFile()->getUid(), $file->getOriginalFile(), 1); $bgImages = $this->generateSrcsetImages($file, $image); $imageUri_mobile = $webp ? $bgImages[576].'.webp' : $bgImages[576]; - $css .= $this->generateCss('s'.$uid.'-'.$flexconf['bgimagePosition'], $file, $image, $webp, $flexconf); + $css .= $this->generateCss('s'.$uid.'-'.$flexconf['bgimagePosition'], $file, $image, $webp, $flexconf, FALSE, $bgMediaQueries); } else { // slider in jumbotron or two bg-images in two-columns $uid = $frontendController->id; @@ -65,7 +66,7 @@ public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColor $image[$fileKey] = $this->imageService()->getImage((string)$file->getOriginalFile()->getUid(), $file->getOriginalFile(), true); $bgImages[$fileKey] = $this->generateSrcsetImages($file, $image[$fileKey]); $imageUri_mobile[$fileKey] = $webp ? $bgImages[$fileKey][576].'.webp' : $bgImages[$fileKey][576]; - $css .= $this->generateCss('s'.$uid.'-'.$fileKey, $file, $image[$fileKey], $webp, $flexconf); + $css .= $this->generateCss('s'.$uid.'-'.$fileKey, $file, $image[$fileKey], $webp, $flexconf, FALSE, $bgMediaQueries); } } } else { @@ -79,9 +80,9 @@ public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColor $uid = $uid . '-' . $flexconf['bgimagePosition']; } if ($jumbotron) { - $css = $this->generateCss('s'.$uid, $file, $image, $webp, $flexconf); + $css = $this->generateCss('s'.$uid, $file, $image, $webp, $flexconf, FALSE, $bgMediaQueries); } elseif ($body) { - $css = $this->generateCss('page-'.$uid, $file, $image, $webp, $flexconf, TRUE); + $css = $this->generateCss('page-'.$uid, $file, $image, $webp, $flexconf, TRUE, $bgMediaQueries); } else { if ( $flexconf['enableAutoheight'] ) { if ( $flexconf['addHeight'] ) { @@ -90,9 +91,9 @@ public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColor GeneralUtility::makeInstance(AssetCollector::class) ->addInlineJavaScript('addheight-'.$uid, $inline); } - $css = $this->generateCss('bg-img-'.$uid, $file, $image, $webp, $flexconf); + $css = $this->generateCss('bg-img-'.$uid, $file, $image, $webp, $flexconf, FALSE, $bgMediaQueries); } else { - $css = $this->generateCss('s'.$uid, $file, $image, $webp, $flexconf); + $css = $this->generateCss('s'.$uid, $file, $image, $webp, $flexconf, FALSE, $bgMediaQueries); } } @@ -126,7 +127,7 @@ public function getBgImage($uid, $table='tt_content', $jumbotron=FALSE, $bgColor * * @return string $css */ - private function generateCss( $uid, $file, $image, $webp, $flexconf=[], $body=FALSE ): string + private function generateCss( $uid, $file, $image, $webp, $flexconf=[], $body=FALSE, $bgMediaQueries): string { $imageRaster = $flexconf['imageRaster'] ? 'url(/typo3conf/ext/t3sbootstrap/Resources/Public/Images/raster.png), ' : ''; @@ -134,9 +135,10 @@ private function generateCss( $uid, $file, $image, $webp, $flexconf=[], $body=FA $cropVariantCollection = CropVariantCollection::create((string) $processingInstructions['crop']); $css = ''; + $mediaQueries = explode(',', $bgMediaQueries); - $mediaQueries = [2560,1920,1200,992,768,576]; foreach ($mediaQueries as $querie) { + $querie = (int)$querie; if ($querie == 576) { $cropVariant = 'mobile'; } elseif ($querie == 768) { @@ -153,9 +155,10 @@ private function generateCss( $uid, $file, $image, $webp, $flexconf=[], $body=FA $processedImage = $this->imageService()->applyProcessingInstructions($image, $processingInstructions); + + $css .= '@media (max-width: '.$querie.'px) {'; if ($webp) { - if ($body) { $css .= '#'.$uid.'.no-webp {background-image:'.$imageRaster.' url("'.$this->imageService()->getImageUri($processedImage).'");}'; $css .= '#'.$uid.'.webp {background-image:'.$imageRaster.' url("'.$this->imageService()->getImageUri($processedImage).'.webp");}'; @@ -163,7 +166,6 @@ private function generateCss( $uid, $file, $image, $webp, $flexconf=[], $body=FA $css .= '.no-webp #'.$uid.' {background-image:'.$imageRaster.' url("'.$this->imageService()->getImageUri($processedImage).'");}'; $css .= '.webp #'.$uid.' {background-image:'.$imageRaster.' url("'.$this->imageService()->getImageUri($processedImage).'.webp");}'; } - } else { $css .= '#'.$uid.' {background-image:'.$imageRaster.' url("'.$this->imageService()->getImageUri($processedImage).'");}'; } diff --git a/Classes/ViewHelpers/MediaViewHelper.php b/Classes/ViewHelpers/MediaViewHelper.php index ca6906a9..bfb2eea9 100644 --- a/Classes/ViewHelpers/MediaViewHelper.php +++ b/Classes/ViewHelpers/MediaViewHelper.php @@ -49,6 +49,7 @@ public function initializeArguments() '(min-width: %1$dpx) %1$dpx, 100vw' ); $this->registerArgument('breakpoints', 'array', 'Image breakpoints from responsive design.', false, []); + $this->registerArgument('imgtag', 'bool', 'Use rendering suggested by picturefill.js', false, true); $this->registerArgument('picturefill', 'bool', 'Use rendering suggested by picturefill.js', false, true); $this->registerArgument('lazyload', 'int', 'Generate markup that supports lazyloading', false, 0); $this->registerArgument('ratio', 'string', 'Image ratio', false, ''); @@ -76,12 +77,16 @@ public function initializeArguments() */ protected function renderImage(FileInterface $image, $width, $height, ?string $fileExtension=null) { - if ($this->arguments['breakpoints']) { - return $this->renderPicture($image, $width, $height); - } elseif ($this->arguments['srcset']) { - return $this->renderImageSrcset($image, $width, $height); + if ($this->arguments['imgtag']) { + return self::renderImageTag($image, $width, $height, $fileExtension); } else { - return parent::renderImage($image, $width, $height, $fileExtension); + if ($this->arguments['breakpoints']) { + return $this->renderPicture($image, $width, $height); + } elseif ($this->arguments['srcset']) { + return $this->renderImageSrcset($image, $width, $height); + } else { + return parent::renderImage($image, $width, $height, $fileExtension); + } } } @@ -248,7 +253,71 @@ protected function generateFallbackImage(FileInterface $image, $width, Area $cro return $fallbackImage; } + /** + * Render image tag + * + * @param FileInterface $image + * @param string $width + * @param string $height + * + * @return string Rendered image tag + */ + protected function renderImageTag(FileInterface $image, $width, $height) + { + $cropVariant = 'default'; + $cropString = $image instanceof FileReference ? $image->getProperty('crop') : ''; + if ( $this->arguments['ratio'] ) { + $cropString = self::getCropString($image); + } + + $cropVariantCollection = CropVariantCollection::create((string)$cropString); + $cropArea = $cropVariantCollection->getCropArea($cropVariant); + + if ( $this->arguments['ratio'] ) { + $m = $cropArea->getHeight() / $cropArea->getWidth(); + $height = (int) ceil($height * $m); + } + + $processingInstructions = [ + 'width' => $width, + 'height' => $height, + 'crop' => $cropArea->isEmpty() ? null : $cropArea->makeAbsoluteBasedOnFile($image), + ]; + + if (!empty($fileExtension)) { + $processingInstructions['fileExtension'] = $fileExtension; + } + $imageService = $this->getImageService(); + $processedImage = $imageService->applyProcessingInstructions($image, $processingInstructions); + $imageUri = $imageService->getImageUri($processedImage); + + if (!$this->tag->hasAttribute('data-focus-area')) { + $focusArea = $cropVariantCollection->getFocusArea($cropVariant); + if (!$focusArea->isEmpty()) { + $this->tag->addAttribute('data-focus-area', $focusArea->makeAbsoluteBasedOnFile($image)); + } + } + $this->tag->addAttribute('src', $imageUri); + $this->tag->addAttribute('width', $processedImage->getProperty('width')); + $this->tag->addAttribute('height', $processedImage->getProperty('height')); + if (in_array($this->arguments['loading'] ?? '', ['lazy', 'eager', 'auto'], true)) { + $this->tag->addAttribute('loading', $this->arguments['loading']); + } + + $alt = $image->getProperty('alternative'); + $title = $image->getProperty('title'); + + // The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty + if (empty($this->arguments['alt'])) { + $this->tag->addAttribute('alt', $alt); + } + if (empty($this->arguments['title']) && $title) { + $this->tag->addAttribute('title', $title); + } + + return $this->tag->render(); + } /** * Returns an $cropString diff --git a/Configuration/FlexForms/Container/CarouselContainer.xml b/Configuration/FlexForms/Container/CarouselContainer.xml index b7349534..699c76cb 100644 --- a/Configuration/FlexForms/Container/CarouselContainer.xml +++ b/Configuration/FlexForms/Container/CarouselContainer.xml @@ -87,6 +87,15 @@ + + + + + check + + + + diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php index ea770933..210be68c 100644 --- a/Configuration/TCA/Overrides/pages.php +++ b/Configuration/TCA/Overrides/pages.php @@ -103,7 +103,7 @@ 'label' => 'e.g.: fab fa-typo3 fa-lg', 'config' => [ 'type' => 'input', - 'size' => '20', + 'size' => 20, ] ], 'tx_t3sbootstrap_icon_only' => [ @@ -116,25 +116,127 @@ 'tx_t3sbootstrap_titlecolor' => [ 'label' => 'Page Title Color', 'exclude' => 1, - 'description' => 'default if empty', + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', 'config' => [ 'type' => 'input', - 'renderType' => 'colorpicker', - 'size' => 20 + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], ], ], 'tx_t3sbootstrap_subtitlecolor' => [ 'label' => 'Subtitle Color', 'exclude' => 1, - 'description' => 'default if empty', + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', 'config' => [ 'type' => 'input', - 'renderType' => 'colorpicker', - 'size' => 20 + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], + ], + ], + 'tx_t3sbootstrap_navigationcolor' => [ + 'label' => 'Color', + 'displayCond' => 'USER:T3SBS\\T3sbootstrap\\UserFunction\\TcaMatcher->isDropdownMenu', + 'exclude' => 1, + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', + 'config' => [ + 'type' => 'input', + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], + ], + ], + 'tx_t3sbootstrap_navigationactivecolor' => [ + 'label' => 'Active Color', + 'displayCond' => 'USER:T3SBS\\T3sbootstrap\\UserFunction\\TcaMatcher->isDropdownMenu', + 'exclude' => 1, + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', + 'config' => [ + 'type' => 'input', + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], + ], + ], + 'tx_t3sbootstrap_navigationhover' => [ + 'label' => 'Hover Color', + 'displayCond' => 'USER:T3SBS\\T3sbootstrap\\UserFunction\\TcaMatcher->isDropdownMenu', + 'exclude' => 1, + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', + 'config' => [ + 'type' => 'input', + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], + ], + ], + 'tx_t3sbootstrap_navigationbgcolor' => [ + 'label' => 'Background Active & Hover Color', + 'displayCond' => 'USER:T3SBS\\T3sbootstrap\\UserFunction\\TcaMatcher->isDropdownMenu', + 'exclude' => 1, + 'description' => 'Hex color codes, RGB or CSS variables e.g. var(--primary)', + 'config' => [ + 'type' => 'input', + 'size' => 20, + 'eval' => 'trim', + 'valuePicker' => [ + 'items' => [ + ['var(--primary)', 'var(--primary)'], + ['var(--secondary)', 'var(--secondary)'], + ['var(--success)', 'var(--success)'], + ['var(--danger)', 'var(--danger)'], + ['var(--warning)', 'var(--warning)'], + ['var(--info)', 'var(--info)'] + ], + ], ], ] - - ]; \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages',$tempPagesColumns); @@ -150,6 +252,28 @@ \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette('pages', 'layout','--linebreak--,tx_t3sbootstrap_linkToTop','after:tx_t3sbootstrap_container'); \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette('pages', 'layout','--linebreak--,tx_t3sbootstrap_megamenu','after:tx_t3sbootstrap_linkToTop'); +if (array_key_exists('navigationColor', $extconf) && $extconf['navigationColor'] === '1') { + # add palette Navigation Colors + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes( + 'pages', + '--palette--; Navigation Colors for dropdown items;navColors', + '', + 'after:title' + ); + + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( + 'pages', 'navColors','--linebreak--,tx_t3sbootstrap_navigationcolor','after:tx_t3sbootstrap_subtitlecolor' + ); + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( + 'pages', 'navColors','--linebreak--,tx_t3sbootstrap_navigationactivecolor','after:tx_t3sbootstrap_navigationcolor' + ); + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( + 'pages', 'navColors','--linebreak--,tx_t3sbootstrap_navigationhover','after:tx_t3sbootstrap_navigationactivecolor' + ); + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( + 'pages', 'navColors','--linebreak--,tx_t3sbootstrap_navigationbgcolor','after:tx_t3sbootstrap_navigationhover' + ); +} if (array_key_exists('fontawesome', $extconf) && $extconf['fontawesome'] === '1') { @@ -223,3 +347,8 @@ 'Configuration/TSConfig/Registered/Header.tsconfig', 'Remove CType header' ); +\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerPageTSConfigFile( + 't3sbootstrap', + 'Configuration/TSConfig/Registered/Callouts.tsconfig', + 'Add BS-Callouts options in Layout field' +); diff --git a/Configuration/TCA/Overrides/sys_file_reference.php b/Configuration/TCA/Overrides/sys_file_reference.php index b3390b8a..3a924515 100644 --- a/Configuration/TCA/Overrides/sys_file_reference.php +++ b/Configuration/TCA/Overrides/sys_file_reference.php @@ -13,7 +13,7 @@ 'label' => 'Extra Class - figure-tag', 'config' => [ 'type' => 'input', - 'size' => 20, + 'size' => 40, 'eval' => 'trim', 'valuePicker' => [ 'items' => [ @@ -24,6 +24,12 @@ [ 'mr-3 (margin-right)', 'mr-3', ], [ 'mx-3 (margin-left and -right)', 'mx-3', ], [ 'my-3 (margin-top and -bottom)', 'my-3', ], + [ 'Hover zoom (basic)', 'img-hover-zoom', ], + [ 'Hover zoom (rotate)', 'img-hover-zoom--zoom-n-rotate', ], + [ 'Hover zoom (slowmo)', 'img-hover-zoom--slowmo', ], + [ 'Hover zoom (brightness)', 'img-hover-zoom--brightness', ], + [ 'Hover zoom (blurzoom)', 'img-hover-zoom--blur', ], + [ 'Hover zoom (colorize)', 'img-hover-zoom--colorize', ] ], ], ], @@ -33,7 +39,7 @@ 'label' => 'Extra Class - img-tag', 'config' => [ 'type' => 'input', - 'size' => 20, + 'size' => 40, 'eval' => 'trim', 'valuePicker' => [ 'items' => [ diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 2e47d912..c3a8c29b 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -40,7 +40,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-2_col.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem'] = ' --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, @@ -77,7 +76,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-3_col.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['three_columns']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -98,7 +96,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-4_col.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['four_columns']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -121,7 +118,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-4_col.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['six_columns']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -141,7 +137,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-card-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['card_wrapper']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -161,7 +156,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/bars.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['button_group']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -180,7 +174,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-card-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['autoLayout_row']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -199,7 +192,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-background_wrapper.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['background_wrapper']['showitem'] = ' --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, @@ -245,7 +237,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-parallax_wrapper.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['parallax_wrapper']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['background_wrapper']['showitem']; @@ -264,7 +255,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-card-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['container']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -283,7 +273,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-carousel-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['carousel_container']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -302,7 +291,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-accordion-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Blue.html') ); $GLOBALS['TCA']['tt_content']['types']['collapsible_container']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -321,7 +309,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-accordion-element.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['collapsible_accordion']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['background_wrapper']['showitem']; @@ -340,7 +327,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-modal.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Blue.html') ); $GLOBALS['TCA']['tt_content']['types']['modal']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -359,7 +345,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-tab-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Blue.html') ); $GLOBALS['TCA']['tt_content']['types']['tabs_container']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -378,7 +363,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-tab-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Green.html') ); $GLOBALS['TCA']['tt_content']['types']['tabs_tab']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -397,7 +381,6 @@ ) ) ->setIcon('EXT:t3sbootstrap/Resources/Public/Icons/Register/ge-accordion-container.svg') - ->setBackendTemplate('EXT:t3sbootstrap/Resources/Private/Backend/Templates/Container/Red.html') ); $GLOBALS['TCA']['tt_content']['types']['listGroup_wrapper']['showitem'] = $GLOBALS['TCA']['tt_content']['types']['two_columns']['showitem']; @@ -526,7 +509,10 @@ ['text-warning', 'text-warning'], ['text-info', 'text-info'], ['text-black', 'text-black'], - ['text-white', 'text-white'] + ['text-white', 'text-white'], + ['text-uppercase', 'text-uppercase'], + ['One line left and right', 'h-line-1'], + ['Two lines left and right', 'h-line-2'] ], ], ], @@ -875,6 +861,19 @@ 'default' => '' ] ], + 'tx_t3sbootstrap_image_orig' => [ + 'exclude' => 1, + 'label' => 'Use Original Image', + 'displayCond' => 'USER:T3SBS\T3sbootstrap\UserFunction\TcaMatcher->ratio_'.$extconf['origimage'], + 'config' => [ + 'type' => 'check', + 'items' => [ + '1' => [ + '0' => 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.enabled' + ] + ] + ] + ], 'tx_t3sbootstrap_animateCss' => [ 'exclude' => 1, 'l10n_display' => 'hideDiff', @@ -1219,6 +1218,12 @@ 'tx_t3sbootstrap_image_ratio', 'after:tx_t3sbootstrap_bordercolor' ); +\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( + 'tt_content', + 'mediaAdjustments', + 'tx_t3sbootstrap_image_orig', + 'before:tx_t3sbootstrap_image_ratio' +); \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette( 'tt_content', @@ -1228,7 +1233,6 @@ ); - # add palette bootstrap etc \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes( 'tt_content', @@ -1254,13 +1258,15 @@ '', 'after:layout' ); -# add palette animate -\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes( - 'tt_content', - '--palette--;Animation;animate', - '', - 'after:layout' -); +# add palette animate if EXT:content_animations is not loaded +if ( !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('content_animations') ) { + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes( + 'tt_content', + '--palette--;Animation;animate', + '', + 'after:layout' + ); +} $GLOBALS['TCA']['tt_content']['palettes']['bsHeaderExtra'] = [ 'showitem' => 'tx_t3sbootstrap_header_display, tx_t3sbootstrap_header_position, --linebreak--, @@ -1284,7 +1290,7 @@ 'showitem' => 'tx_t3sbootstrap_extra_class, --linebreak--, tx_t3sbootstrap_container, --linebreak--, tx_t3sbootstrap_flexform' -]; +]; } $GLOBALS['TCA']['tt_content']['palettes']['bootstrapColor'] = [ @@ -1311,3 +1317,17 @@ $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['t3sbootstrap_pi1'] = 'recursive,select_key,pages'; + +if ( $extconf['preview'] ) { + /*************** + * Show preview of tt_content elements in page module + */ + $GLOBALS['TCA']['tt_content']['ctrl']['previewRenderer'] = T3SBS\T3sbootstrap\Backend\Preview\DefaultPreviewRenderer::class; + $containers = ['two_columns', 'three_columns', 'four_columns', 'six_columns', 'card_wrapper', 'button_group', 'autoLayout_row', + 'background_wrapper','parallax_wrapper',' container', 'carousel_container', 'collapsible_container', 'collapsible_accordion', + 'modal', 'tabs_container', 'tabs_tab', 'listGroup_wrapper']; + foreach ($containers as $container) { + $GLOBALS['TCA']['tt_content']['types'][trim($container)]['previewRenderer'] = T3SBS\T3sbootstrap\Backend\Preview\T3sbPreviewRenderer::class; + } +} + diff --git a/Configuration/TCA/tx_t3sbootstrap_domain_model_config.php b/Configuration/TCA/tx_t3sbootstrap_domain_model_config.php index d10636b4..57d63018 100644 --- a/Configuration/TCA/tx_t3sbootstrap_domain_model_config.php +++ b/Configuration/TCA/tx_t3sbootstrap_domain_model_config.php @@ -711,6 +711,7 @@ ['bg-warning [warning]', 'warning'], ['bg-info [info]', 'info'], ['bg-white [white]', 'white'], + ['bg-transparent [transparent]', 'transparent'], ['bg-color [color]', 'color'], ] ] @@ -725,6 +726,22 @@ 'type' => 'input' ] ], + 'navbar_transparent' => [ + 'exclude' => false, + 'label' => 'Transparent Navbar', + 'accordion_id' => 3, + 'accordion_sub' => '3-3', + 'info' => 'Placement must be "fixed-top"', + 'config' => [ + 'type' => 'check', + 'items' => [ + '1' => [ + '0' => 'create a transparent navbar which changes its style on scroll' + ] + ] + ] + ], + 'navbar_container' => [ 'exclude' => false, 'label' => 'Container', @@ -876,6 +893,20 @@ ] ] ], + 'navbar_animatedtoggler' => [ + 'exclude' => false, + 'accordion_id' => 3, + 'accordion_sub' => '3-6', + 'label' => 'Animated Toggler', + 'config' => [ + 'type' => 'check', + 'items' => [ + '1' => [ + '0' => 'Doing it with plain HTML and pure CSS - does not work with "Offcanvas"' + ] + ] + ] + ], 'navbar_breakpoint' => [ 'exclude' => false, 'label' => 'Breakpoint', diff --git a/Configuration/TSConfig/CKEditor.tsconfig b/Configuration/TSConfig/CKEditor.tsconfig index 6a0d5af8..b47c502a 100644 --- a/Configuration/TSConfig/CKEditor.tsconfig +++ b/Configuration/TSConfig/CKEditor.tsconfig @@ -74,7 +74,7 @@ RTE { telephone.properties { class.default = } - properties.class.allowedClasses = phone-link, external-link, internal-link, email-link, download-link, btn, btn btn-primary, btn btn-secondary, btn btn-success, btn btn-danger, btn btn-warning, btn btn-info, btn btn-light, btn btn-dark, js-scroll-trigger + properties.class.allowedClasses = phone-link, external-link, internal-link, email-link, download-link, btn, btn btn-primary, btn btn-secondary, btn btn-success, btn btn-danger, btn btn-warning, btn btn-info, btn btn-light, btn btn-dark, js-scroll-trigger, text-primary, text-secondary, text-success, text-danger, text-warning, text-info, text-light bg-dark, text-dark, text-muted, text-white bg-dark, stretched-link queryParametersSelector.enabled = 0 } diff --git a/Configuration/TSConfig/NewContentElements.tsconfig b/Configuration/TSConfig/NewContentElements.tsconfig index 246ae8b5..0cd27136 100644 --- a/Configuration/TSConfig/NewContentElements.tsconfig +++ b/Configuration/TSConfig/NewContentElements.tsconfig @@ -23,25 +23,25 @@ mod.wizards { tt_content_defValues.CType = t3sbs_card } t3sbscarousel { - iconIdentifier = bs-carousel + iconIdentifier = content-carousel-image title = BS Carousel description = A slideshow component for cycling through elements—images or slides of text—like a carousel. tt_content_defValues.CType = t3sbs_carousel } t3sbutton { - iconIdentifier = bs-button + iconIdentifier = content-media title = BS Button description = Bootstrap includes several predefined button styles, each serving its own semantic purpose. tt_content_defValues.CType = t3sbs_button } t3sbsfluidtemplate { - iconIdentifier = bs-fluidtemplate + iconIdentifier = module-templates title = LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:t3sbs_fluidtemplate.title description = LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:t3sbs_fluidtemplate.description tt_content_defValues.CType = t3sbs_fluidtemplate } t3sbsgallery { - iconIdentifier = bs-gallery + iconIdentifier = apps-filetree-folder-media title = LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:t3sbsgallery.title description = LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:t3sbsgallery.description tt_content_defValues.CType = t3sbs_gallery diff --git a/Configuration/TSConfig/Registered/Callouts.tsconfig b/Configuration/TSConfig/Registered/Callouts.tsconfig new file mode 100644 index 00000000..c3c0a429 --- /dev/null +++ b/Configuration/TSConfig/Registered/Callouts.tsconfig @@ -0,0 +1,31 @@ +TCEFORM.tt_content { + layout { + addItems { + 94 = ------ T3SB ------ + 95 = Callout primary + 96 = Callout info + 97 = Callout success + 98 = Callout warning + 99 = Callout danger + 100 = Callout secondary + } + altLabels { + 94 = ------ T3SB ------ + 95 = Callout primary + 96 = Callout info + 97 = Callout success + 98 = Callout warning + 99 = Callout danger + 100 = Callout secondary + } + classes { + 94 = + 95 = bs-callout bs-callout-primary + 96 = bs-callout bs-callout-info + 97 = bs-callout bs-callout-success + 98 = bs-callout bs-callout-warning + 99 = bs-callout bs-callout-danger + 100 = bs-callout bs-callout-secondary + } + } +} \ No newline at end of file diff --git a/Configuration/TypoScript/Page/Template.typoscript b/Configuration/TypoScript/Page/Template.typoscript index 7fad288c..500168fa 100644 --- a/Configuration/TypoScript/Page/Template.typoscript +++ b/Configuration/TypoScript/Page/Template.typoscript @@ -40,6 +40,7 @@ page { backToTopClass = {$bootstrap.backToTopClass} backToTopForAllPages = {$bootstrap.backToTopForAllPages} gtm = {$bootstrap.gtm} + bgMediaQueries = {$bootstrap.image.bgMediaQueries} navbar { image.defaultPath = {$bootstrap.navbar.image.defaultPath} image.width = {$bootstrap.navbar.image.width} @@ -88,11 +89,13 @@ page { navbarImage = {$bootstrap.config.navbarImage} navbarColor = {$bootstrap.config.navbarColor} navbarBackground = {$bootstrap.config.navbarBackground} + navbarTransparent = {$bootstrap.config.navbarTransparent} navbarContainer = {$bootstrap.config.navbarContainer} navbarPlacement = {$bootstrap.config.navbarPlacement} navbarAlignment = {$bootstrap.config.navbarAlignment} navbarClass = {$bootstrap.config.navbarClass} navbarToggler = {$bootstrap.config.navbarToggler} + navbarAnimatedtoggler = {$bootstrap.config.navbarAnimatedtoggler} navbarBreakpoint = {$bootstrap.config.navbarBreakpoint} navbarOffcanvas = {$bootstrap.config.navbarOffcanvas} navbarHeight = {$bootstrap.config.navbarHeight} diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript index 045af30c..fe8959c6 100644 --- a/Configuration/TypoScript/constants.typoscript +++ b/Configuration/TypoScript/constants.typoscript @@ -32,8 +32,8 @@ bootstrap.cdn { popperjs = 1.16.1 # cat=bootstrap-cdn/b-version/12; type=small; label=Fontawesome: fontawesome = 5.15.1 - # cat=bootstrap-cdn/b-version/20; type=small; label=jQuery library: jQuery 3.5.0 won't work with Bootstrap 4.4.1. Dropdowns and collapse don't work. Reverted to jQuery 3.4.1 to make it work. - jquery = 3.5.1 + # cat=bootstrap-cdn/b-version/20; type=small; label=jQuery library: Downgrade to version 3.5.1 if you have any problems with this version. + jquery = 3.6.0 # cat=bootstrap-cdn/b-version/22; type=small; label=jQuery Easing: jqueryEasing = 1.4.1 # cat=bootstrap-cdn/b-version/25; type=int+; label=Cookieconsent: set to 3 only to get v3.x (latest) @@ -100,12 +100,14 @@ bootstrap.image { maxWidthToast = 20 # cat=bootstrap-image/a-image/70; type=boolean; label=Disable auto row: the default "Gallery row width in % = auto" is set to "none" if activated. disableAutoRow = 0 - # cat=bootstrap-image/b-image/10; type=small; label=Additional Image Sizes for Desktop min-width 1200px: comma-separated list of either image widths specified in pixels or pixel density descriptors, e. g. "2x". + # cat=bootstrap-image/b-image/10; type=small; label=Additional Image Sizes for Desktop min-width 1200px: comma-separated list of either image widths specified in pixels. srcsetDesktop = 125, 255, 385, 576, 768, 992, 1200, 1440, 1920, 2650 - # cat=bootstrap-image/b-image/20; type=small; label=Additional Image Sizes for Tablet min-width 576px: comma-separated list of either image widths specified in pixels or pixel density descriptors, e. g. "2x". + # cat=bootstrap-image/b-image/20; type=small; label=Additional Image Sizes for Tablet min-width 576px: comma-separated list of either image widths specified in pixels. srcsetTablet = 125, 255, 385, 576, 768, 992, 1200 - # cat=bootstrap-image/b-image/30; type=small; label=Additional Image Sizes for Mobile max-width 575px: comma-separated list of either image widths specified in pixels or pixel density descriptors, e. g. "2x". + # cat=bootstrap-image/b-image/30; type=small; label=Additional Image Sizes for Mobile max-width 575px: comma-separated list of either image widths specified in pixels. srcsetMobile = 60, 100, 200, 385, 575 + # cat=bootstrap-image/b-image/35; type=small; label=Additional Image Sizes for Background-Image: comma-separated list of either image widths specified in pixels. + bgMediaQueries = 2560, 1920, 1200, 992, 768, 576 # cat=bootstrap-image/c-image/010; type=int+; label=Threshold for Lazy load: if "lazyLoad" is activated in the EM config, the distance out of the viewport, expressed in pixel, before which to start loading the images. lazyLoadThreshold = 0 # cat=bootstrap-image/c-image/020; type=boolean; label=Lazy load for images in the BG-Wrapper: not the BG-image diff --git a/Resources/Private/Backend/Layouts/Default.html b/Resources/Private/Backend/Layouts/Default.html index 37bc39f9..329bed5a 100644 --- a/Resources/Private/Backend/Layouts/Default.html +++ b/Resources/Private/Backend/Layouts/Default.html @@ -1,8 +1,14 @@
- + + + + + + +
diff --git a/Resources/Private/Backend/Templates/Container/Blue.html b/Resources/Private/Backend/Templates/Container/Blue.html deleted file mode 100644 index 2679785c..00000000 --- a/Resources/Private/Backend/Templates/Container/Blue.html +++ /dev/null @@ -1,7 +0,0 @@ - -{tx_container_grid} - diff --git a/Resources/Private/Backend/Templates/Container/Green.html b/Resources/Private/Backend/Templates/Container/Green.html deleted file mode 100644 index 2679785c..00000000 --- a/Resources/Private/Backend/Templates/Container/Green.html +++ /dev/null @@ -1,7 +0,0 @@ - -{tx_container_grid} - diff --git a/Resources/Private/Backend/Templates/Container/Red.html b/Resources/Private/Backend/Templates/Container/Red.html deleted file mode 100644 index 2679785c..00000000 --- a/Resources/Private/Backend/Templates/Container/Red.html +++ /dev/null @@ -1,7 +0,0 @@ - -{tx_container_grid} - diff --git a/Resources/Private/Layouts/Content/Button.html b/Resources/Private/Layouts/Content/Button.html index 016ca04b..dc718984 100644 --- a/Resources/Private/Layouts/Content/Button.html +++ b/Resources/Private/Layouts/Content/Button.html @@ -53,7 +53,7 @@ Lightbox - same in News/Detail.html - + Baguette Box diff --git a/Resources/Private/Layouts/Content/Default.html b/Resources/Private/Layouts/Content/Default.html index b99e7f4d..5bc647ec 100644 --- a/Resources/Private/Layouts/Content/Default.html +++ b/Resources/Private/Layouts/Content/Default.html @@ -110,7 +110,7 @@
-
+
f:format.raw()}')}> diff --git a/Resources/Private/Layouts/Content/ListgroupWrapper.html b/Resources/Private/Layouts/Content/ListgroupWrapper.html index 3fe14ead..eb9cae36 100644 --- a/Resources/Private/Layouts/Content/ListgroupWrapper.html +++ b/Resources/Private/Layouts/Content/ListgroupWrapper.html @@ -53,7 +53,7 @@ Lightbox - same in News/Detail.html - + Baguette Box diff --git a/Resources/Private/Partials/Content/Header/All.html b/Resources/Private/Partials/Content/Header/All.html index 68dcf76b..67870381 100644 --- a/Resources/Private/Partials/Content/Header/All.html +++ b/Resources/Private/Partials/Content/Header/All.html @@ -1,4 +1,7 @@ + + + @@ -40,3 +43,19 @@ dateformat: settings.dateformat }" /> + + + +{f:if(condition: '{data.header_layout}',then: 'h{data.header_layout}', else: 'h{header.default}')} + +header.header-{data.uid}.h-line-1{overflow:hidden;}header.header-{data.uid}.h-line-1 {hlayout} {display: inline-block;position: relative;}header.header-{data.uid}.h-line-1 {hlayout}::before,header.header-{data.uid}.h-line-1 {hlayout}::after {content: "";position: absolute;border-top: 1px solid {header.hColorVar};top: 50%;width: 2000px;}header.header-{data.uid}.h-line-1 {hlayout}::before {margin-right: 15px;right: 100%;}header.header-{data.uid}.h-line-1 {hlayout}::after {margin-left: 15px;left: 100%;} + + + + +{f:if(condition: '{data.header_layout}',then: 'h{data.header_layout}', else: 'h{header.default}')} + +header.header-{data.uid}.h-line-2 {overflow:hidden;line-height: 0.5;}header.header-{data.uid}.h-line-2 {hlayout} {display: inline-block;position: relative;}header.header-{data.uid}.h-line-2 {hlayout}:before,header.header-{data.uid}.h-line-2 {hlayout}:after {content: "";position: absolute;height: 5px;border-bottom: 1px solid {header.hColorVar};border-top: 1px solid {header.hColorVar};top: 47%;width: 2000px;}header.header-{data.uid}.h-line-2 {hlayout}:before {right: 100%;margin-right: 15px;}header.header-{data.uid}.h-line-2 {hlayout}:after {left: 100%;margin-left: 15px;} + + + diff --git a/Resources/Private/Partials/Content/Media/Carousel.html b/Resources/Private/Partials/Content/Media/Carousel.html index add25c9b..4746a078 100644 --- a/Resources/Private/Partials/Content/Media/Carousel.html +++ b/Resources/Private/Partials/Content/Media/Carousel.html @@ -68,11 +68,18 @@
{media.title -> f:format.html()}
- + + + + + + + + diff --git a/Resources/Private/Partials/Content/Media/Rendering/Image.html b/Resources/Private/Partials/Content/Media/Rendering/Image.html index ca13348f..9ea4000e 100644 --- a/Resources/Private/Partials/Content/Media/Rendering/Image.html +++ b/Resources/Private/Partials/Content/Media/Rendering/Image.html @@ -1,36 +1,47 @@ - + - + - - + + + + + + + + + diff --git a/Resources/Private/Partials/Content/Media/Type/Image.html b/Resources/Private/Partials/Content/Media/Type/Image.html index 4f41a434..4559b815 100644 --- a/Resources/Private/Partials/Content/Media/Type/Image.html +++ b/Resources/Private/Partials/Content/Media/Type/Image.html @@ -109,4 +109,4 @@ $(this).parent().parent().prev().removeClass("d-none"); });
- \ No newline at end of file + diff --git a/Resources/Private/Partials/Page/Navbar/Assets.html b/Resources/Private/Partials/Page/Navbar/Assets.html index 1e2b4fa2..8b714902 100644 --- a/Resources/Private/Partials/Page/Navbar/Assets.html +++ b/Resources/Private/Partials/Page/Navbar/Assets.html @@ -2,10 +2,10 @@ xmlns:t3sb="http://typo3.org/ns/T3SBS/T3sbootstrap/ViewHelpers" data-namespace-typo3-fluid="true"> - + - + @@ -198,4 +198,44 @@ }); + + +{config.navbar.navColorCSS} + + + + + + // Navbar transparent - Navbar/Assets.html + if ( $(window).width() > {settings.navbar.{navbarBreakpoint}} ) { + $(window).on('scroll', function () { + if ( $(window).scrollTop() > 60 ) { + $('.navbar').css('background-color', '{config.navbar.colorschemes}'); + $('.navbar').css('transition', 'background-color 0.5s ease'); + $('.navbar').css('-webkit-transition', 'background-color 0.5s ease'); + $('.navbar').css('-moz-transition', 'background-color 0.5s ease'); + + // change navbar color + $('.navbar').removeClass('navbar-light'); + $('.navbar').addClass('navbar-dark'); + + } else { + $('.navbar').css('background-color', 'var(--transparent)'); + $('.navbar').css('transition', 'background-color 0.5s ease'); + $('.navbar').css('-webkit-transition', 'background-color 0.5s ease'); + $('.navbar').css('-moz-transition', 'background-color 0.5s ease'); + + // change navbar color + $('.navbar').removeClass('navbar-dark'); + $('.navbar').addClass('navbar-light'); + + } + }); + } else { + $('.navbar').css('background-color', '{config.navbar.colorschemes}'); + } + + + + diff --git a/Resources/Private/Partials/Page/Navbar/Navbar.html b/Resources/Private/Partials/Page/Navbar/Navbar.html index 52cb769c..8a2e1d0f 100644 --- a/Resources/Private/Partials/Page/Navbar/Navbar.html +++ b/Resources/Private/Partials/Page/Navbar/Navbar.html @@ -72,12 +72,12 @@
-