From 39eb3020586b9291b1116ad76ac21166627b45d1 Mon Sep 17 00:00:00 2001 From: Helmut Hackbarth Date: Sun, 14 Aug 2022 14:34:30 +0200 Subject: [PATCH] New release v5.2.0 --- Classes/Command/CdnToLocal.php | 79 ++++++- Classes/Command/CommandBase.php | 70 ++++++ Classes/Command/CustomScss.php | 199 ++++++++++++------ Classes/ContentElements/Menu.php | 1 - .../AbstractCompatibilityController.php | 3 +- Classes/Controller/AbstractController.php | 49 ++--- Classes/DataProcessing/ConfigProcessor.php | 1 + Classes/DataProcessing/GalleryProcessor.php | 31 +-- Classes/Domain/Model/Config.php | 28 +++ .../EventListener/AssetRenderer/IsInline.php | 93 ++++++-- Classes/Helper/ClassHelper.php | 1 - Classes/Helper/DefaultHelper.php | 2 - Classes/Layouts/FourColumns.php | 1 - Classes/Wrapper/CardWrapper.php | 1 + Classes/Wrapper/Modal.php | 3 + Classes/Wrapper/SwiperContainer.php | 5 + Configuration/FlexForms/Container/Modal.xml | 32 ++- .../FlexForms/Container/SwiperContainer.xml | 8 + .../tx_t3sbootstrap_domain_model_config.php | 14 ++ .../TypoScript/Lib/ContentElement.typoscript | 1 + .../TypoScript/Page/Configuration.typoscript | 1 + .../Page/IncludeBootstrapScss.typoscript | 1 + .../TypoScript/Page/IncludeCdn.typoscript | 5 - .../TypoScript/Page/IncludeDefault.typoscript | 28 +-- .../TypoScript/Page/IncludeLocal.typoscript | 16 -- .../TypoScript/Page/Template.typoscript | 1 + Configuration/TypoScript/constants.typoscript | 44 ++-- Configuration/TypoScript/setup.typoscript | 11 + .../Backend/Templates/Config/Dashboard.html | 81 ++++++- .../Backend/Templates/Config/List.html | 106 ++++++++-- .../Private/Partials/List/Body/Item.html | 4 +- .../Partials/Content/Header/Header.html | 2 +- .../Partials/Content/Swiper/Default.html | 39 ++-- .../Partials/Content/TextWithImage.html | 18 +- .../Private/Partials/FunctionAssets.html | 11 +- Resources/Private/Partials/Page/Assets.html | 6 +- .../Templates/Container/CardWrapper.html | 17 +- .../Private/Templates/Container/Modal.html | 2 +- Resources/Private/Templates/Content/Card.html | 2 +- .../Private/Templates/Content/Carousel.html | 12 ++ .../Content/MenuCategorizedPages.html | 2 +- .../Templates/Content/MenuSection.html | 7 +- Resources/Private/Templates/Main.html | 17 +- .../Fontawesome/webfonts/fa-brands-400.svg | 4 - .../Fontawesome/webfonts/fa-regular-400.svg | 4 - .../Fontawesome/webfonts/fa-solid-900.svg | 4 - Resources/Public/Icons/Extension.svg | 1 - Resources/Public/Icons/Register/bars.svg | 1 - Resources/Public/Icons/Register/bs-button.svg | 1 - ext_conf_template.txt | 4 +- ext_emconf.php | 2 +- ext_icon.svg | 1 - ext_localconf.php | 7 +- ext_tables.sql | 1 + 54 files changed, 783 insertions(+), 302 deletions(-) create mode 100644 Classes/Command/CommandBase.php diff --git a/Classes/Command/CdnToLocal.php b/Classes/Command/CdnToLocal.php index d9b3fd0a..bcbf52ea 100644 --- a/Classes/Command/CdnToLocal.php +++ b/Classes/Command/CdnToLocal.php @@ -18,10 +18,15 @@ * For the full copyright and license information, please read the * LICENSE file that was distributed with this source code. */ -class CdnToLocal extends Command +class CdnToLocal extends CommandBase { - protected $configurationManager; + const localZipFile = 'googlefont.zip'; + const localZipPath = 'fileadmin/T3SB/Resources/Public/CSS/googlefonts/'; + const zipFilePath = 'https://google-webfonts-helper.herokuapp.com/api/fonts/'; + const localGoogleFile = 'fileadmin/T3SB/Resources/Public/CSS/googlefonts.css'; + + protected $configurationManager; public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) { @@ -73,6 +78,17 @@ protected function execute(InputInterface $input, OutputInterface $output) $settings['cdn']['fontawesome'] = '5.15.4'; } + if ( !empty($settings['cdn']['googlefonts']) && empty($settings['cdn']['noZip']) ) { + self::getGoogleFonts($settings['cdn']['googlefonts']); + } else { + $localZipPath = GeneralUtility::getFileAbsFileName(self::localZipPath); + if ( is_dir($localZipPath) ) { + parent::rmDir($localZipPath); + } + $cssFile = GeneralUtility::getFileAbsFileName(self::localGoogleFile); + if (file_exists($cssFile)) unlink($cssFile); + } + foreach ($settings['cdn'] as $key=>$version) { if ($key == 'jquery') { @@ -264,6 +280,7 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } + private function writeCustomFile($customPath, $customFileName, $cdnPath, $extend=false ) { $customFile = $customPath.$customFileName; $customContent = GeneralUtility::getURL($cdnPath); @@ -285,4 +302,62 @@ private function writeCustomFile($customPath, $customFileName, $cdnPath, $extend } + private function getGoogleFonts($googleFonts) { + $localZipPath = GeneralUtility::getFileAbsFileName(self::localZipPath); + if ( is_dir($localZipPath) ) { + parent::rmDir($localZipPath); + } + mkdir($localZipPath, 0777, true); + $localZipFile = GeneralUtility::getFileAbsFileName(self::localZipPath.self::localZipFile); + $googleFontsArr = explode(',', $googleFonts); + $cFF = ''; + foreach ($googleFontsArr as $key=>$font) { + $fontFamily = trim($font); + $font = str_replace(' ', '-', trim($font)); + $zipFilename = strtolower($font).'?download=zip&subsets=latin&variants=regular'; + + $zipContent = GeneralUtility::getURL(self::zipFilePath . $zipFilename); + + if ($zipContent) { + GeneralUtility::writeFile($localZipFile, $zipContent); + $extractTo = $localZipPath; + $zip = new \ZipArchive; + if ($zip->open($localZipFile) === TRUE) { + $zip->extractTo($extractTo); + $zip->close(); + } else { + throw new \InvalidArgumentException('Sorry ZIP creation failed at this time!', 1655291667); + } + $zipFile = GeneralUtility::getFileAbsFileName($localZipFile); + if (file_exists($zipFile)) unlink($zipFile); + $googleFiles = scandir($localZipPath); + $css = ''; + foreach ($googleFiles as $googleFile) { + if ( str_ends_with($googleFile, 'woff') && $cFF != $fontFamily ) { + $googleFileArr[$key] = $googleFile; + $cFF = $fontFamily; + } + } + } else { + throw new \InvalidArgumentException('Check the spelling of the google fonts!', 1657464667); + } + } + + foreach ($googleFileArr as $key=>$googleFile) { +$css .= "@font-face {".LF." + font-family: '".trim($googleFontsArr[$key])."';".LF." + font-style: normal;".LF." + font-weight: 400;".LF." + src: local(''),".LF." + url('googlefonts/".$googleFile."') format('woff2'),".LF." + url('googlefonts/".$googleFile."') format('woff');".LF." +}".LF.LF; + } + $cssFile = GeneralUtility::getFileAbsFileName(self::localGoogleFile); + if (file_exists($cssFile)) unlink($cssFile); + GeneralUtility::writeFile($cssFile, $css); + } + + + } \ No newline at end of file diff --git a/Classes/Command/CommandBase.php b/Classes/Command/CommandBase.php new file mode 100644 index 00000000..d7cc5d45 --- /dev/null +++ b/Classes/Command/CommandBase.php @@ -0,0 +1,70 @@ +getQueryBuilderForTable('pages'); $result = $queryBuilder ->select('*') @@ -184,6 +195,7 @@ protected function execute(InputInterface $input, OutputInterface $output) private function writeCustomFile($customPath, $customFileName, $settings, $name) { $customFile = $customPath.$customFileName; + $keepVariables = (int)$settings['keepVariables']; if (file_exists($customFile)) { $copyFile = $customPath.'_'.time().'-'.$customFileName; @@ -226,85 +238,134 @@ private function deleteFilesFromDirectory($directory){ } - /** - * remove dirs - */ - private function rmDir(string $path) : int + public function getSccFiles($bootstrapVersion): void { - if (!is_dir ($path)) { - return -1; - } - $dir = @opendir ($path); - if (!$dir) { - return -2; + $localZipPath = GeneralUtility::getFileAbsFileName(self::localZipPath); + if ( is_dir($localZipPath) ) { + parent::rmDir($localZipPath); } - while ($entry = @readdir($dir)) { - if ($entry == '.' || $entry == '..') continue; - if (is_dir ($path.'/'.$entry)) { - $res = self::rmDir ($path.'/'.$entry); - if ($res == -1) { - @closedir ($dir); - return -2; - } else if ($res == -2) { - @closedir ($dir); - return -2; - } else if ($res == -3) { - @closedir ($dir); - return -3; - } else if ($res != 0) { - @closedir ($dir); - return -2; - } - } else if (is_file ($path.'/'.$entry) || is_link ($path.'/'.$entry)) { - $res = @unlink ($path.'/'.$entry); - if (!$res) { - @closedir ($dir); - return -2; - } + mkdir($localZipPath, 0777, true); + $localZipFile = GeneralUtility::getFileAbsFileName(self::localZipPath.self::localZipFile); + $zipFilename = 'v'.$bootstrapVersion.'.zip'; + $zipContent = GeneralUtility::getURL(self::zipFilePath . $zipFilename); + if ($zipContent) { + GeneralUtility::writeFile($localZipFile, $zipContent); + $extractTo = $localZipPath; + $zip = new \ZipArchive; + if ($zip->open($localZipFile) === TRUE) { + $zip->extractTo($extractTo); + $zip->close(); } else { - @closedir ($dir); - return -3; + throw new \InvalidArgumentException('Sorry ZIP creation failed at this time! Set the constant "bootstrap.cdn.noZip=1" and try again.', 1657464538); } + $renameFrom = GeneralUtility::getFileAbsFileName(self::localZipPath.'bootstrap-'.$bootstrapVersion.'/scss'); + $renameTo = GeneralUtility::getFileAbsFileName(self::localZipPath.'scss'); + if ( is_dir($renameFrom) ) { + rename($renameFrom, $renameTo); + } + parent::rmDir(GeneralUtility::getFileAbsFileName(self::localZipPath.'bootstrap-'.$bootstrapVersion)); + $zipFile = GeneralUtility::getFileAbsFileName(self::localZipPath.self::localZipFile); + if (file_exists($zipFile)) unlink($zipFile); + } else { + throw new \InvalidArgumentException('No content from GitHub archive!', 1657464783); } + } + - @closedir ($dir); - $res = @rmdir ($path); + public function getSccFilesNoZip($settings, $bootstrapVersion, $customPath): void + { + $gitURL = 'https://raw.githubusercontent.com/twbs/bootstrap/'; + $bootstrapPath = 'fileadmin/T3SB/Resources/Public/Contrib/Bootstrap/scss'; - if (!$res) { - return -2; + # get the Boostrap SCSS-Files + if ( $bootstrapVersion > '5.1.3') { + $scssList = '_accordion.scss, _alert.scss, _badge.scss, _breadcrumb.scss, _button-group.scss, _buttons.scss, _card.scss, _carousel.scss, _close.scss, _containers.scss, _dropdown.scss, _forms.scss, _functions.scss, _grid.scss, _helpers.scss, _images.scss, _list-group.scss, _maps.scss, _mixins.scss, _modal.scss, _nav.scss, _navbar.scss, _offcanvas.scss, _pagination.scss, _placeholders.scss, _popover.scss, _progress.scss, _reboot.scss, _root.scss, _spinners.scss, _tables.scss, _toasts.scss, _tooltip.scss, _transitions.scss, _type.scss, _utilities.scss, _variables.scss, bootstrap-grid.scss, bootstrap-reboot.scss, bootstrap-utilities.scss, bootstrap.scss'; + } else { + $scssList = '_accordion.scss, _alert.scss, _badge.scss, _breadcrumb.scss, _button-group.scss, _buttons.scss, _card.scss, _carousel.scss, _close.scss, _containers.scss, _dropdown.scss, _forms.scss, _functions.scss, _grid.scss, _helpers.scss, _images.scss, _list-group.scss, _mixins.scss, _modal.scss, _nav.scss, _navbar.scss, _offcanvas.scss, _pagination.scss, _placeholders.scss, _popover.scss, _progress.scss, _reboot.scss, _root.scss, _spinners.scss, _tables.scss, _toasts.scss, _tooltip.scss, _transitions.scss, _type.scss, _utilities.scss, _variables.scss, bootstrap-grid.scss, bootstrap-reboot.scss, bootstrap-utilities.scss, bootstrap.scss'; } - return 0; - } + $mixinsList = '_alert.scss, _backdrop.scss, _border-radius.scss, _box-shadow.scss, _breakpoints.scss, _buttons.scss, _caret.scss, _clearfix.scss, _color-scheme.scss, _container.scss, _deprecate.scss, _forms.scss, _gradients.scss, _grid.scss, _image.scss, _list-group.scss, _lists.scss, _pagination.scss, _reset-text.scss, _resize.scss, _table-variants.scss, _text-truncate.scss, _transition.scss, _utilities.scss, _visually-hidden.scss'; + $utilitiesList = '_api.scss'; - public function getSccFiles($bootstrapVersion): void - { - $localZipPath = GeneralUtility::getFileAbsFileName(self::localZipPath); - if ( is_dir($localZipPath) ) { - self::rmDir($localZipPath); + $formsList = '_floating-labels.scss, _form-check.scss, _form-control.scss, _form-range.scss, _form-select.scss, _form-text.scss, _input-group.scss, _labels.scss, _validation.scss'; + + $helpersList = '_clearfix.scss, _colored-links.scss, _position.scss, _ratio.scss, _stacks.scss, _stretched-link.scss, _text-truncation.scss, _visually-hidden.scss, _vr.scss'; + + foreach (explode(',', $scssList) as $scss ) { + $customFileName = trim($scss); + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/'.$customFileName; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); } - mkdir($localZipPath, 0777, true); - $localZipFile = GeneralUtility::getFileAbsFileName(self::localZipPath.self::localZipFile); - $zipFilename = 'v'.$bootstrapVersion.'.zip'; - $zipContent = GeneralUtility::getURL(self::zipFilePath . $zipFilename); - GeneralUtility::writeFile($localZipFile, $zipContent); - $extractTo = $localZipPath; - $zip = new \ZipArchive; - if ($zip->open($localZipFile) === TRUE) { - $zip->extractTo($extractTo); - $zip->close(); - } else { - throw new \InvalidArgumentException('Sorry ZIP creation failed at this time!', 1657464667); + + $customDir = $bootstrapPath.'/mixins/'; + $customPath = GeneralUtility::getFileAbsFileName($customDir); + + foreach (explode(',', $mixinsList) as $mixins ) { + $customFileName = trim($mixins); + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/mixins/'.$customFileName; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); + } + + $customDir = $bootstrapPath.'/utilities/'; + $customPath = GeneralUtility::getFileAbsFileName($customDir); + + foreach (explode(',', $utilitiesList) as $utils ) { + $customFileName = trim($utils); + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/utilities/'.$customFileName; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); } - $renameFrom = GeneralUtility::getFileAbsFileName(self::localZipPath.'bootstrap-'.$bootstrapVersion.'/scss'); - $renameTo = GeneralUtility::getFileAbsFileName(self::localZipPath.'scss'); - if ( is_dir($renameFrom) ) { - rename($renameFrom, $renameTo); + + $customDir = $bootstrapPath.'/forms/'; + $customPath = GeneralUtility::getFileAbsFileName($customDir); + + + foreach (explode(',', $formsList) as $forms ) { + $customFileName = trim($forms); + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/forms/'.$customFileName; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); } - self::rmDir(GeneralUtility::getFileAbsFileName(self::localZipPath.'bootstrap-'.$bootstrapVersion)); - $zipFile = GeneralUtility::getFileAbsFileName(self::localZipPath.self::localZipFile); - if (file_exists($zipFile)) unlink($zipFile); + + $customDir = $bootstrapPath.'/helpers/'; + $customPath = GeneralUtility::getFileAbsFileName($customDir); + + foreach (explode(',', $helpersList) as $helpers ) { + $customFileName = trim($helpers); + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/helpers/'.$customFileName; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); + } + + $customDir = $bootstrapPath.'/vendor/'; + $customPath = GeneralUtility::getFileAbsFileName($customDir); + + $customFileName = '_rfs.scss'; + $customFile = $customPath.$customFileName; + $cdnPath = $gitURL.'v'.trim($bootstrapVersion).'/scss/vendor/_rfs.scss'; + $customContent = GeneralUtility::getURL($cdnPath); + if (file_exists($customFile)) unlink($customFile); + if (!is_dir($customPath)) mkdir($customPath, 0777, true); + GeneralUtility::writeFile($customFile, $customContent); + } } diff --git a/Classes/ContentElements/Menu.php b/Classes/ContentElements/Menu.php index 4d2976f8..38a357f3 100644 --- a/Classes/ContentElements/Menu.php +++ b/Classes/ContentElements/Menu.php @@ -43,7 +43,6 @@ public function getProcessedData(array $processedData, array $flexconf, string $ $processedData['menupills'] = ''; } - return $processedData; } diff --git a/Classes/Controller/AbstractCompatibilityController.php b/Classes/Controller/AbstractCompatibilityController.php index debecf58..4849ec0b 100644 --- a/Classes/Controller/AbstractCompatibilityController.php +++ b/Classes/Controller/AbstractCompatibilityController.php @@ -60,6 +60,7 @@ public function listAction(bool $deleted = FALSE, bool $created = FALSE, bool $u $allConfig[$page['uid']]['confUid'] = $config->getUid(); $allConfig[$page['uid']]['title'] = $page['title']; $allConfig[$page['uid']]['uid'] = $page['uid']; + $assignedOptions['compress'] = $config->getCompress(); } } @@ -321,9 +322,9 @@ public function listAction(bool $deleted = FALSE, bool $created = FALSE, bool $u $allConfig[$page['uid']]['confUid'] = $config->getUid(); $allConfig[$page['uid']]['title'] = $page['title']; $allConfig[$page['uid']]['uid'] = $page['uid']; + $assignedOptions['compress'] = $config->getCompress(); } } - $assignedOptions['isSiteroot'] = TRUE; $assignedOptions['allConfig'] = $allConfig; } diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php index af79f535..04bc5fac 100644 --- a/Classes/Controller/AbstractController.php +++ b/Classes/Controller/AbstractController.php @@ -36,11 +36,11 @@ abstract class AbstractController extends ActionController protected $rootTemplates; protected $persistenceManager; - /** - * Init all actions. - */ - public function initializeAction() - { + /** + * Init all actions. + */ + public function initializeAction() + { $site = self::getCurrentSite(); $this->rootPageId = $site->getRootPageId(); $this->currentUid = (int) GeneralUtility::_GET('id'); @@ -64,9 +64,9 @@ public function initializeAction() 'TYPO3/CMS/T3sbootstrap/Bootstrap', 'function() { console.log("Loaded bootstrap.js by t3sbootstrap!"); }' ); - } - - + } + + /** * SCSS in the BE */ @@ -301,7 +301,7 @@ protected function writeConstants(): void $filecontent .= '[page["uid"] == '.$config->getPid().']'.PHP_EOL; } if ($config->getGeneralOverride()) { - $filecontent .= self::getConstants($config, TRUE); + $filecontent .= self::getConstants($config, TRUE); } else { $filecontent .= self::getConstants($config, FALSE); } @@ -447,7 +447,7 @@ protected function getUtilityColors(): array return $colorArr; } else { ksort($defaultUtilityColors); - return $defaultUtilityColors; + return $defaultUtilityColors; } } else { return []; @@ -466,46 +466,47 @@ protected function setDefaults(Config $newConfig): Config $newConfig->setPageTitlealign( 'center' ); $newConfig->setNavbarImage($defaultNavbarImagePath); $newConfig->setNavbarEnable( 'light' ); - $newConfig->setNavbarLevels( 4 ); + $newConfig->setNavbarLevels(4); $newConfig->setNavbarbrandAlignment( 'left' ); $newConfig->setNavbarColor( 'warning' ); $newConfig->setNavbarAlignment( 'left' ); $newConfig->setNavbarBrand( 'imgText' ); $newConfig->setNavbarContainer( 'inside' ); $newConfig->setNavbarClass(''); - $newConfig->setJumbotronEnable( 1 ); - $newConfig->setJumbotronSlide( 0 ); + $newConfig->setJumbotronEnable(1); + $newConfig->setJumbotronSlide(0); $newConfig->setJumbotronPosition( 'below' ); $newConfig->setJumbotronContainer( 'container' ); $newConfig->setJumbotronContainerposition( 'Inside' ); $newConfig->setJumbotronCarouselInterval(5000); $newConfig->setJumbotronCarouselPause(0); $newConfig->setJumbotronClass( 'p-5 mb-4 bg-light rounded-0' ); - $newConfig->setBreadcrumbEnable( 1 ); - $newConfig->setBreadcrumbCorner( 1 ); + $newConfig->setBreadcrumbEnable(1); + $newConfig->setBreadcrumbCorner(1); $newConfig->setBreadcrumbPosition( 'belowJum' ); $newConfig->setBreadcrumbContainer( 'container' ); - $newConfig->setSidebarLevels( 4 ); - $newConfig->setFooterEnable( 1 ); - $newConfig->setFooterSlide( 0 ); + $newConfig->setSidebarLevels(4); + $newConfig->setFooterEnable(1); + $newConfig->setFooterSlide(0); $newConfig->setFooterContainer( 'container' ); - $newConfig->setFooterSticky( 1 ); + $newConfig->setFooterSticky(1); $newConfig->setFooterContainerposition( 'inside' ); $newConfig->setFooterClass( 'bg-dark text-light py-4' ); $newConfig->setStickyFooterExtraPadding(100); - $newConfig->setCompress( 1 ); + $newConfig->setCompress(1); $newConfig->setDisablePrefixComment(1); $newConfig->setGlobalPaddingTop( 'pt-5' ); $newConfig->setLoadingSpinnerColor( 'primary' ); $newConfig->setLightboxSelection(1); $newConfig->setShrinkingNavPadding( '5' ); $newConfig->setSidebarMenuPosition( 'above' ); - $newConfig->setLangMenuWithFaIcon( 1 ); + $newConfig->setLangMenuWithFaIcon(1); $newConfig->setDateFormat( 'd.m.Y' ); $newConfig->setSubheaderColor( 'secondary' ); - $newConfig->setFaLinkIcons( 1 ); + $newConfig->setFaLinkIcons(1); $newConfig->setSectionmenuAnchorOffset(29); $newConfig->setSectionmenuScrollspyOffset(130); + $newConfig->setSectionmenuScrollspy(1); $newConfig->setNavbarLangFlags(1); return $newConfig; @@ -562,6 +563,6 @@ protected function getTreeList($id, $depth, $begin = 0, $permsClause = ''): stri return (string)$theList; } - - + + } \ No newline at end of file diff --git a/Classes/DataProcessing/ConfigProcessor.php b/Classes/DataProcessing/ConfigProcessor.php index b56d49a8..d9c70eb4 100644 --- a/Classes/DataProcessing/ConfigProcessor.php +++ b/Classes/DataProcessing/ConfigProcessor.php @@ -462,6 +462,7 @@ public function process(ContentObjectRenderer $cObj, array $contentObjectConfigu $topOffset = (int)$processedRecordVariables['sectionmenuAnchorOffset'] + (int)$processedRecordVariables['navbarHeight']; $processedData['config']['sidebar']['stickTopOffset'] = $topOffset ? $topOffset.'px' : 0; $processedData['config']['sidebar']['scrollspyOffset'] = $processedRecordVariables['sectionmenuScrollspyOffset']; + $processedData['config']['sidebar']['scrollspy'] = $processedRecordVariables['sectionmenuScrollspy']; } else { if (!empty($processedData['subNavigation']) && is_array($processedData['subNavigation'])) { $processedData['subNavigation'] = diff --git a/Classes/DataProcessing/GalleryProcessor.php b/Classes/DataProcessing/GalleryProcessor.php index a627bffb..e0b378f9 100644 --- a/Classes/DataProcessing/GalleryProcessor.php +++ b/Classes/DataProcessing/GalleryProcessor.php @@ -398,37 +398,10 @@ protected function determineMaximumGalleryWidth() $countChildren = self::countContentRecord($this->processedData['data']['tx_container_parent'], 'tt_content', 'tx_container_parent'); $this->galleryData['count']['columns'] = $countChildren; $this->rowWidth = 100; - $this->cardWrapper = $this->parentflexconf['card_wrapper']; - if ($this->parentflexconf['card_wrapper'] == 'deck' || $this->parentflexconf['card_wrapper'] == 'group' ) { - - $x = 0; - if ($countChildren) - $x = (int) floor(100 / $this->galleryData['count']['columns']); - - if ( $x == 100 ) { - $p = 100; - } elseif ( $x == 50 ) { - $p = 50; - } elseif ( $x == 33 ) { - $p = 33; - } elseif ( $x == 25 ) { - $p = 25; - } elseif ( $x == 20 ) { - $p = 20; - } elseif ( $x == 16 ) { - $p = 16; - } + $this->cardWrapper = $this->parentflexconf['card_wrapper']; - if ( $p != 25 ) { - // 1% = space between - $p = $p - 1; - $block = '.card-deck .card {-ms-flex: 0 0 '. $p .'%; flex: 0 0 '. $p .'%;}'; - if($block) - GeneralUtility::makeInstance(AssetCollector::class) - ->addInlineStyleSheet('cardwrapperinlinecss-'.$this->processedData['data']['tx_container_parent'], $block,[],['priority' => true]); - } - } elseif ($this->parentflexconf['card_wrapper'] == 'columns' ) { + if ($this->parentflexconf['card_wrapper'] == 'columns' ) { $this->galleryData['count']['columns'] = 4; diff --git a/Classes/Domain/Model/Config.php b/Classes/Domain/Model/Config.php index 4e4e06dd..48845415 100644 --- a/Classes/Domain/Model/Config.php +++ b/Classes/Domain/Model/Config.php @@ -816,6 +816,13 @@ class Config extends AbstractEntity */ protected $sectionmenuStickyTop = false; + /** + * sectionmenuScrollspy + * + * @var bool + */ + protected $sectionmenuScrollspy = false; + /** * backgroundImageEnable * @@ -3612,6 +3619,27 @@ public function setSectionmenuStickyTop($sectionmenuStickyTop) $this->sectionmenuStickyTop = $sectionmenuStickyTop; } + /** + * Returns the sectionmenuScrollspy + * + * @return bool $sectionmenuScrollspy + */ + public function getSectionmenuScrollspy() + { + return $this->sectionmenuScrollspy; + } + + /** + * Sets the sectionmenuScrollspy + * + * @param bool $sectionmenuScrollspy + * @return void + */ + public function setSectionmenuScrollspy($sectionmenuScrollspy) + { + $this->sectionmenuScrollspy = $sectionmenuScrollspy; + } + /** * Returns the backgroundImageEnable * diff --git a/Classes/EventListener/AssetRenderer/IsInline.php b/Classes/EventListener/AssetRenderer/IsInline.php index 6dc50a18..343f776f 100644 --- a/Classes/EventListener/AssetRenderer/IsInline.php +++ b/Classes/EventListener/AssetRenderer/IsInline.php @@ -42,25 +42,43 @@ public function __invoke(BeforeJavaScriptsRenderingEvent $event): void if ( $event->isPriority() == FALSE ) { // Java Scripts + $jsCode = ''; + $faCode = ''; if ( $t3sbconcatenate ) { - $jsCode = ''; foreach ( $event->getAssetCollector()->getJavaScripts() as $library => $jsFile ) { $jsCode .= '// *** T3SB identifier: '.$library.LF.LF; - if ( str_starts_with($jsFile['source'], 'http') ) { - $jsCode .= GeneralUtility::getURL($jsFile['source']).LF.LF; + if ( $library == 'fontawesome' ) { + if ( str_starts_with($jsFile['source'], 'http') ) { + $faCode .= GeneralUtility::getURL($jsFile['source']).LF.LF; + } else { + if ( GeneralUtility::getFileAbsFileName($jsFile['source']) != FALSE ) { + $faCode .= GeneralUtility::getURL(GeneralUtility::getFileAbsFileName($jsFile['source'])).LF.LF; + } + } } else { - if ( GeneralUtility::getFileAbsFileName($jsFile['source']) != FALSE ) { - $jsCode .= GeneralUtility::getURL(GeneralUtility::getFileAbsFileName($jsFile['source'])).LF.LF; + if ( str_starts_with($jsFile['source'], 'http') ) { + $jsCode .= GeneralUtility::getURL($jsFile['source']).LF.LF; + } else { + if ( GeneralUtility::getFileAbsFileName($jsFile['source']) != FALSE ) { + $jsCode .= GeneralUtility::getURL(GeneralUtility::getFileAbsFileName($jsFile['source'])).LF.LF; + } } } + $event->getAssetCollector()->removeJavaScript($library); } - if (!empty($jsCode)) { - // add Temp Java Scripts - $file = self::inline2TempFile($jsCode, 'js'); - if ($file) { - $event->getAssetCollector()->addJavaScript('t3sbootstrap', $file); - } + } + + if (!empty($jsCode) || !empty($faCode)) { + + if ( !empty($settings['t3sbminify']) && !empty($jsCode) ) { + $url = 'https://www.toptal.com/developers/javascript-minifier/api/raw'; + $jsCode = self::minifyData($url, $jsCode); + } + // add Temp Java Scripts + $file = self::inline2TempFile($faCode.$jsCode, 'js'); + if ($file) { + $event->getAssetCollector()->addJavaScript('t3sbootstrapjsinline', $file); } } } @@ -77,17 +95,17 @@ public function __invoke(BeforeJavaScriptsRenderingEvent $event): void foreach ($event->getAssetCollector()->getStyleSheets() as $library => $source) { $css .= LF.'/*** T3SB identifier: '.$library.' */'.LF; if (!empty($source['source'])) { - if ( str_starts_with($source['source'], 'http') ) { + if ( str_starts_with($source['source'], 'http') ) { $css .= GeneralUtility::getURL($source['source']).LF; } else { if ( GeneralUtility::getFileAbsFileName($source['source']) != FALSE ) { $css .= GeneralUtility::getURL(GeneralUtility::getFileAbsFileName($source['source'])).LF; - } + } } } $event->getAssetCollector()->removeStyleSheet($library); } - } + } // Inline Style Sheets foreach ($event->getAssetCollector()->getInlineStyleSheets() as $library => $source) { @@ -98,9 +116,15 @@ public function __invoke(BeforeJavaScriptsRenderingEvent $event): void // add Temp Style Sheet if (!empty($css)) { + + if (!empty($settings['t3sbminify'])) { + $url = 'https://www.toptal.com/developers/cssminifier/api/raw'; + $css = self::minifyData($url, $css); + } + $cssFile = self::inline2TempFile($css, 'css'); if ($cssFile) { - $event->getAssetCollector()->addStyleSheet('t3sbootstrap', $cssFile); + $event->getAssetCollector()->addStyleSheet('t3sbootstrapcss', $cssFile); } } @@ -118,8 +142,8 @@ public function __invoke(BeforeJavaScriptsRenderingEvent $event): void foreach ($assetJsInline as $library => $source) { if (str_ends_with($library, 'function')) { $function .= $source['source'] .LF.LF; - } elseif (str_starts_with($library, 'vanilla')) { - $js .= $source['source'] .LF; + } elseif (str_starts_with($library, 'vanilla')) { + $js .= $source['source'] .LF; } elseif ( str_starts_with($library, 'addheight-') ) { $addheight .= $source['source'] .LF.LF; } else { @@ -146,10 +170,15 @@ public function __invoke(BeforeJavaScriptsRenderingEvent $event): void $source .= LF."(function($){'use strict';".LF. $jquery .LF."})(jQuery);".LF; } + if ( !empty($settings['t3sbminify']) ) { + $url = 'https://www.toptal.com/developers/javascript-minifier/api/raw'; + $source = self::minifyData($url, $source); + } + if (!empty($source)) { $jsFile = self::inline2TempFile($source, 'js'); if ($jsFile) { - $event->getAssetCollector()->addJavaScript('t3sbootstrap', $jsFile); + $event->getAssetCollector()->addJavaScript('t3sbootstrapjs', $jsFile); } } } @@ -175,7 +204,7 @@ public static function inline2TempFile($str, $ext) break; } if ($script) { - $pathSite = Environment::getPublicPath() . '/'; + $pathSite = Environment::getPublicPath() . '/'; if (!@is_file($pathSite . $script)) { GeneralUtility::writeFile($pathSite . $script, $str); } @@ -183,4 +212,30 @@ public static function inline2TempFile($str, $ext) return $script; } + + public static function minifyData($url, $input) + { + // init the request, set various options, and send it + $ch = curl_init(); + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"], + CURLOPT_POSTFIELDS => http_build_query([ "input" => $input ]) + ]); + + $output = curl_exec($ch); + // finally, close the request + curl_close($ch); + + if ( str_starts_with($output, 'error') ) { + // input remains + $output = $input; + } + + return $output; + } + + } diff --git a/Classes/Helper/ClassHelper.php b/Classes/Helper/ClassHelper.php index 9b22bd82..4dd839b8 100644 --- a/Classes/Helper/ClassHelper.php +++ b/Classes/Helper/ClassHelper.php @@ -261,7 +261,6 @@ public function getHeaderClass(array $data): array } return $header; - } diff --git a/Classes/Helper/DefaultHelper.php b/Classes/Helper/DefaultHelper.php index d773ae09..8896cf15 100644 --- a/Classes/Helper/DefaultHelper.php +++ b/Classes/Helper/DefaultHelper.php @@ -135,8 +135,6 @@ public function getDefaults( if ( ($processedData['data']['tx_t3sbootstrap_header_celink'] && $processedData['data']['header_link']) || (!empty($flexconf['bgwlink']) && $processedData['data']['header_link']) ) { - - if ( $cType == 't3sbs_card' ) { if (!empty($flexconf['button']['enable'])) { $processedData['card']['button']['link'] = $processedData['data']['header_link']; diff --git a/Classes/Layouts/FourColumns.php b/Classes/Layouts/FourColumns.php index 47d93840..d2ad2428 100644 --- a/Classes/Layouts/FourColumns.php +++ b/Classes/Layouts/FourColumns.php @@ -24,7 +24,6 @@ public function getProcessedData(array $processedData, array $flexconf): array { $processedData = GeneralUtility::makeInstance(Gutters::class)->getGutters($processedData, $flexconf); $processedData = GeneralUtility::makeInstance(Grid::class)->getGrid($processedData, $flexconf); - $processedData['equalHeight'] = !empty($flexconf['equalHeight']) ? ' d-flex align-items-stretch' : ''; return $processedData; diff --git a/Classes/Wrapper/CardWrapper.php b/Classes/Wrapper/CardWrapper.php index 555ebf45..5647ade5 100644 --- a/Classes/Wrapper/CardWrapper.php +++ b/Classes/Wrapper/CardWrapper.php @@ -71,6 +71,7 @@ public function getProcessedData(array $processedData, array $flexconf): array $children[$key]['tx_t3sbootstrap_header_display'] = $child['tx_t3sbootstrap_header_display']; $children[$key]['tx_t3sbootstrap_header_class'] = $child['tx_t3sbootstrap_header_class']; $children[$key]['tx_t3sbootstrap_header_fontawesome'] = $child['tx_t3sbootstrap_header_fontawesome']; + $children[$key]['celink'] = $child['tx_t3sbootstrap_header_celink']; $children[$key]['settings'] = $flexFormService->convertFlexFormContentToArray($child['tx_t3sbootstrap_flexform']); } diff --git a/Classes/Wrapper/Modal.php b/Classes/Wrapper/Modal.php index 952f97e5..1a4aba26 100644 --- a/Classes/Wrapper/Modal.php +++ b/Classes/Wrapper/Modal.php @@ -42,6 +42,9 @@ public function getProcessedData(array $processedData, array $flexconf): array if ( $headerPosition == 'right' ) $headerPosition = 'end'; $processedData['class'] .= ' text-'.$headerPosition; } + if ($flexconf['whiteclosebutton']) { + $processedData['modal']['whiteclosebutton'] = TRUE; + } return $processedData; } diff --git a/Classes/Wrapper/SwiperContainer.php b/Classes/Wrapper/SwiperContainer.php index 2ebe78fd..2b548302 100644 --- a/Classes/Wrapper/SwiperContainer.php +++ b/Classes/Wrapper/SwiperContainer.php @@ -42,6 +42,11 @@ public function getProcessedData(array $processedData, array $flexconf): array $processedData['pagination'] = (int)$flexconf['pagination']; $processedData['autoplay'] = (int)$flexconf['autoplay']; $processedData['delay'] = !empty($flexconf['autoplay']) ? (int)$flexconf['delay'] : 99999999; + + +$processedData['origImage'] = $flexconf['origImage'] ?? ''; + + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); $queryBuilder = $connectionPool->getQueryBuilderForTable('tt_content'); $statement = $queryBuilder diff --git a/Configuration/FlexForms/Container/Modal.xml b/Configuration/FlexForms/Container/Modal.xml index 77d54289..21aa750a 100644 --- a/Configuration/FlexForms/Container/Modal.xml +++ b/Configuration/FlexForms/Container/Modal.xml @@ -75,14 +75,21 @@ select selectSingle - LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:default - default - LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:large - modal-lg - LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:small - modal-sm - Fullscreen - modal-fullscreen + + LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:default + default + + LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:small + modal-sm + + LLL:EXT:t3sbootstrap/Resources/Private/Language/locallang_be.xlf:large + modal-lg + + Extra large + modal-xl + + Fullscreen + modal-fullscreen default @@ -98,6 +105,15 @@ + + + + + check + 0 + + + -

-
+
@@ -185,12 +186,10 @@

Configuration

-

- -

+

Currently available utility colors:

@@ -203,8 +202,91 @@

Configuration

-

Set the following constant to disable the "Utility Colors":
+

Set the following constant to disable the "Utility Colors":
bootstrap.config.enableUtilityColors = 0

+ + + +
+
+ + +

WebP Support is enabled

+
+ +

WebP Support is disabled

+
+
+ + +

EM config: T3SB lazyLoad is enabled

+
+ +

EM config: T3SB lazyLoad is disabled

+
+
+ + +

EM config: T3SB concatenate is enabled

+
+ +

EM config: T3SB concatenate is disabled

+
+
+ + +

EM config: T3SB minify is enabled

+
+ +

EM config: T3SB minify is disabled

+
+
+ + +

BE Modul: T3SB compress is enabled

+
+ +

BE Modul: T3SB compress is disabled

+
+
+ + + + +

Konstanten-Editor: CDN is enabled

+
+ +

Konstanten-Editor: CDN is disabled

+
+
+ + +
+
+

Make sure you optimize Bootstrap by only @importing the components you need.

+ + + + + + + +
{label}{optimize}
+
+
+ +

Set the following constant to disable this hints:
+ bootstrap.config.enableInfo = 0

+
+
+ +
diff --git a/Resources/Private/Extensions/news/Resources/Private/Partials/List/Body/Item.html b/Resources/Private/Extensions/news/Resources/Private/Partials/List/Body/Item.html index cb682aa2..2face3b2 100644 --- a/Resources/Private/Extensions/news/Resources/Private/Partials/List/Body/Item.html +++ b/Resources/Private/Extensions/news/Resources/Private/Partials/List/Body/Item.html @@ -32,11 +32,11 @@

- {newsItem.title} + {newsItem.title -> f:format.raw()} - {newsItem.title} + {newsItem.title -> f:format.raw()}

diff --git a/Resources/Private/Partials/Content/Header/Header.html b/Resources/Private/Partials/Content/Header/Header.html index 75d1e69b..b75be5cb 100644 --- a/Resources/Private/Partials/Content/Header/Header.html +++ b/Resources/Private/Partials/Content/Header/Header.html @@ -55,7 +55,7 @@ - + {hFa -> f:format.raw()}{header -> f:format.raw()} diff --git a/Resources/Private/Partials/Content/Swiper/Default.html b/Resources/Private/Partials/Content/Swiper/Default.html index c86c2f08..77902c80 100644 --- a/Resources/Private/Partials/Content/Swiper/Default.html +++ b/Resources/Private/Partials/Content/Swiper/Default.html @@ -107,13 +107,13 @@ + arguments="{ratio: '{ratio}', file: '{swiperSlides.{card.uid}.0}', width: '{width}', swiper: 'true', origImage: '{origImage}'}" /> + arguments="{ratio: '{ratio}', file: '{swiperSlides.{card.uid}.0}', width: '{width}', swiper: 'true', origImage: '{origImage}'}" /> @@ -143,20 +143,27 @@
- + + + + + + + +
diff --git a/Resources/Private/Partials/Content/TextWithImage.html b/Resources/Private/Partials/Content/TextWithImage.html index c0d2a845..df68d209 100644 --- a/Resources/Private/Partials/Content/TextWithImage.html +++ b/Resources/Private/Partials/Content/TextWithImage.html @@ -10,7 +10,9 @@
- {data.bodytext -> f:format.html()} + + {data.bodytext -> f:format.html()} +
@@ -32,7 +34,9 @@
- {data.bodytext -> f:format.html()} + + {data.bodytext -> f:format.html()} +
@@ -53,7 +57,9 @@ + {data.bodytext -> f:format.html()} + Beside Text right or left @@ -98,13 +104,17 @@ -
{data.bodytext -> f:format.html()}
+ +
{data.bodytext -> f:format.html()}
+
-
{data.bodytext -> f:format.html()}
+ +
{data.bodytext -> f:format.html()}
+
diff --git a/Resources/Private/Partials/FunctionAssets.html b/Resources/Private/Partials/FunctionAssets.html index c80ab544..7ccbae26 100644 --- a/Resources/Private/Partials/FunctionAssets.html +++ b/Resources/Private/Partials/FunctionAssets.html @@ -73,8 +73,8 @@ - - + + // Magnifying glass icon - Main.html function t3sbMagnifying(img, viewportWidth, navbarBreakpointWidth) { var zoomOverlay = img.parentElement.parentElement.querySelectorAll('div.zoom-overlay'); @@ -104,11 +104,10 @@ } function t3sbHandleScroll() { - var scrollToTopBtn = document.querySelector('.back-to-top'); + var scrollToTopBtn = document.querySelector('.back-to-top'), + scrollTop = window.pageYOffset || document.documentElement.scrollTop; scrollToTopBtn.addEventListener('click', t3sbScrollIt); - const scrollableHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; - const RATIO = 0.2; - if ((document.documentElement.scrollTop / scrollableHeight ) > RATIO) { + if (scrollTop > 100) { scrollToTopBtn.classList.add('st-block'); scrollToTopBtn.classList.remove('st-none'); } else { diff --git a/Resources/Private/Partials/Page/Assets.html b/Resources/Private/Partials/Page/Assets.html index 282316b4..cf53d086 100644 --- a/Resources/Private/Partials/Page/Assets.html +++ b/Resources/Private/Partials/Page/Assets.html @@ -127,7 +127,6 @@ - Page/Section.html, Page/MenuSection.html @@ -136,7 +135,7 @@ document.body.setAttribute('data-bs-target', '#sectionmenu'); document.body.setAttribute('data-bs-offset', {settings.config.sectionmenuScrollspyOffset}); document.body.setAttribute('tabindex', '0'); - document.body.style.position = 'relative'; + //document.body.style.position = 'relative'; if (document.body.style.overflowY) { document.body.style.overflowY = 'unset'; } @@ -152,7 +151,8 @@ }); - + + window.onscroll = function() {stickyFunction()}; var sticky = sectionmenu.offsetTop; diff --git a/Resources/Private/Templates/Container/CardWrapper.html b/Resources/Private/Templates/Container/CardWrapper.html index d9d936ca..f16ba0cd 100644 --- a/Resources/Private/Templates/Container/CardWrapper.html +++ b/Resources/Private/Templates/Container/CardWrapper.html @@ -341,11 +341,11 @@

{card.backheader -> f:format.raw()}

- -

- {card.hFa -> f:format.raw()}{card.header -> f:format.raw()}

-
{card.subheader -> f:format.raw()}
- + +

+ {card.hFa -> f:format.raw()}{card.header -> f:format.raw()}

+
{card.subheader -> f:format.raw()}
+

@@ -363,7 +363,8 @@

- {card.hFa -> f:format.raw()}{card.header -> f:format.raw()} + {card.hFa -> f:format.raw()}{card.header -> f:format.raw()}

{card.subheader -> f:format.raw()}
@@ -371,14 +372,14 @@
{card.subheader -> f:format.raw()}

- + {card.hFa -> f:format.raw()}{card.header -> f:format.raw()}

- + {card.hFa -> f:format.raw()}{card.subheader -> f:format.raw()}

diff --git a/Resources/Private/Templates/Container/Modal.html b/Resources/Private/Templates/Container/Modal.html index f8aa2d93..7b2ca6fa 100644 --- a/Resources/Private/Templates/Container/Modal.html +++ b/Resources/Private/Templates/Container/Modal.html @@ -50,7 +50,7 @@