diff --git a/CHANGELOG.md b/CHANGELOG.md index 4797d07..6136a1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Types of changes Security in case of vulnerabilities. ) +## [1.1.0](https://github.com/pdir/contao-seo-plugin/tree/1.1.0) - 2025-03-21 + +- [Added] Show or hide the content of your website based on multiple conditions + ## [1.0.3](https://github.com/pdir/contao-seo-plugin/tree/1.0.3) - 2024-11-09 - [Fixed] do not use global namespace in OutputFrontendTemplateListener diff --git a/README.md b/README.md index 19a20d3..e21df40 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,13 @@ We help website owners and editorial teams to get more traffic from search engin helps users to optimize their content and make it easy to find for both users and search engines. With the Contao SEO plugin, you have the most important on-page factors directly in view. -### Current range of functions of version 1.0.0 +### Current range of functions of version 1.1.0 - SEO analysis of 8 typical on-page problems - IndexNow function for all known providers [indexnow.org](https://www.indexnow.org/faq) - Possibility to activate a 404 error log - Monitoring of alias changes (experimental, must be activated in user profile) - Display existing URL redirects in the alias view +- Show or hide the content of your website based on multiple conditions ### An outlook on further functions - At least 30 additional tests for on-page recommendations @@ -47,6 +48,9 @@ Display existing URL redirects in the alias view ![404 error log](_docs/screenshots/404-error-log.png) 404 error log +![404 error log](_docs/screenshots/conditional_content.png) +Conditional content + ## German Wir helfen Website-Betreibern und Redaktionsteams, mehr Traffic von Suchmaschinen wie Google zu erhalten. Das Contao SEO @@ -59,6 +63,7 @@ Mit dem Contao SEO Plugin hast du die wichtigsten OnPage Faktoren direkt im Blic - Möglichkeit, ein 404-Fehlerprotokoll zu aktivieren - Überwachung von Alias-Änderungen (experimentell, muss im Benutzerprofil aktiviert werden) - Anzeige bestehender URL-Weiterleitungen in der Alias-Ansicht +- Zeige oder verberge den Inhalt deiner Website auf der Grundlage mehrerer Bedingungen ### Ein Ausblick auf weitere Funktionen - Mindestens 30 weitere Tests für Onpage Empfehlungen diff --git a/config/services.yaml b/config/services.yaml index 55149c2..88f00d2 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -24,3 +24,9 @@ services: Pdir\ContaoSeoPlugin\EventListener\OutputFrontendTemplateListener: public: true + + Pdir\ContaoSeoPlugin\EventListener\IsVisibleElementListener: + public: true + arguments: + - '@request_stack' + - '@contao.routing.scope_matcher' diff --git a/contao/dca/tl_article.php b/contao/dca/tl_article.php new file mode 100644 index 0000000..2b3b535 --- /dev/null +++ b/contao/dca/tl_article.php @@ -0,0 +1,27 @@ + true, + 'inputType' => 'checkbox', + 'eval' => ['submitOnChange' => true, 'tl_class' => 'clr'], + 'sql' => "char(1) NOT NULL default ''", +]; + +$GLOBALS['TL_DCA']['tl_article']['fields']['contaoSeoEntityCondition'] = [ + 'exclude' => true, + 'inputType' => 'textarea', + 'eval' => ['mandatory' => true, 'useRawRequestData' => true, 'style' => 'height:40px', 'tl_class' => 'clr'], + 'sql' => 'text NULL', +]; + +foreach($GLOBALS['TL_DCA']['tl_article']['palettes'] as $key=>$value) { + if ($key == '__selector__') { + continue; + } + $GLOBALS['TL_DCA']['tl_article']['palettes'][$key] .= ',contaoSeoIsConditionalEntity'; +} diff --git a/contao/dca/tl_content.php b/contao/dca/tl_content.php new file mode 100644 index 0000000..d4e7712 --- /dev/null +++ b/contao/dca/tl_content.php @@ -0,0 +1,27 @@ + true, + 'inputType' => 'checkbox', + 'eval' => ['submitOnChange' => true, 'tl_class' => 'clr'], + 'sql' => "char(1) NOT NULL default ''", +]; + +$GLOBALS['TL_DCA']['tl_content']['fields']['contaoSeoEntityCondition'] = [ + 'exclude' => true, + 'inputType' => 'textarea', + 'eval' => ['mandatory' => true, 'useRawRequestData' => true, 'style' => 'height:40px', 'tl_class' => 'clr'], + 'sql' => 'text NULL', +]; + +foreach($GLOBALS['TL_DCA']['tl_content']['palettes'] as $key=>$value) { + if ($key == '__selector__') { + continue; + } + $GLOBALS['TL_DCA']['tl_content']['palettes'][$key] .= ',contaoSeoIsConditionalEntity'; +} diff --git a/contao/dca/tl_module.php b/contao/dca/tl_module.php new file mode 100644 index 0000000..1a763cb --- /dev/null +++ b/contao/dca/tl_module.php @@ -0,0 +1,27 @@ + true, + 'inputType' => 'checkbox', + 'eval' => ['submitOnChange' => true, 'tl_class' => 'clr'], + 'sql' => "char(1) NOT NULL default ''", +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['contaoSeoEntityCondition'] = [ + 'exclude' => true, + 'inputType' => 'textarea', + 'eval' => ['mandatory' => true, 'useRawRequestData' => true, 'style' => 'height:40px', 'tl_class' => 'clr'], + 'sql' => 'text NULL', +]; + +foreach($GLOBALS['TL_DCA']['tl_module']['palettes'] as $key=>$value) { + if ($key == '__selector__') { + continue; + } + $GLOBALS['TL_DCA']['tl_module']['palettes'][$key] .= ',contaoSeoIsConditionalEntity'; +} diff --git a/contao/languages/de/default.php b/contao/languages/de/default.php index bbf33d4..8132b8e 100644 --- a/contao/languages/de/default.php +++ b/contao/languages/de/default.php @@ -9,3 +9,5 @@ $GLOBALS['TL_LANG']['tl_page']['rewriteStatusActive'] = 'Aktiv'; $GLOBALS['TL_LANG']['tl_page']['rewriteStatusInactive'] = 'Inaktiv'; $GLOBALS['TL_LANG']['tl_page']['rewriteListNoItems'] = 'Es wurden keine Weiterleitungen gefunden.'; + +$GLOBALS['TL_LANG']['MSC']['contaoSeoActiveCondition'] = 'Es ist mindestens eine Bedingung aktiv.'; diff --git a/contao/languages/de/tl_article.php b/contao/languages/de/tl_article.php new file mode 100644 index 0000000..be83eaa --- /dev/null +++ b/contao/languages/de/tl_article.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') oder für Arrays in_array(\'en\', languages)']; diff --git a/contao/languages/de/tl_content.php b/contao/languages/de/tl_content.php new file mode 100644 index 0000000..12f7d3a --- /dev/null +++ b/contao/languages/de/tl_content.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') oder für Arrays in_array(\'en\', languages)']; diff --git a/contao/languages/de/tl_module.php b/contao/languages/de/tl_module.php new file mode 100644 index 0000000..fb078ca --- /dev/null +++ b/contao/languages/de/tl_module.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') oder für Arrays in_array(\'en\', languages)']; diff --git a/contao/languages/en/default.php b/contao/languages/en/default.php index f46627f..11edbca 100644 --- a/contao/languages/en/default.php +++ b/contao/languages/en/default.php @@ -9,3 +9,5 @@ $GLOBALS['TL_LANG']['tl_page']['rewriteStatusActive'] = 'Active'; $GLOBALS['TL_LANG']['tl_page']['rewriteStatusInactive'] = 'Inactive'; $GLOBALS['TL_LANG']['tl_page']['rewriteListNoItems'] = 'No redirects were found.'; + +$GLOBALS['TL_LANG']['MSC']['contaoSeoActiveCondition'] = 'At least one condition is active.'; diff --git a/contao/languages/en/tl_article.php b/contao/languages/en/tl_article.php new file mode 100644 index 0000000..a393c44 --- /dev/null +++ b/contao/languages/en/tl_article.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') or for arrays in_array(\'en\', languages).']; diff --git a/contao/languages/en/tl_content.php b/contao/languages/en/tl_content.php new file mode 100644 index 0000000..d040072 --- /dev/null +++ b/contao/languages/en/tl_content.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') or for arrays in_array(\'en\', languages).']; diff --git a/contao/languages/en/tl_module.php b/contao/languages/en/tl_module.php new file mode 100644 index 0000000..9c36712 --- /dev/null +++ b/contao/languages/en/tl_module.php @@ -0,0 +1,6 @@ +(foo == \'de\' && bar == \'test\') or for arrays in_array(\'en\', languages).']; diff --git a/src/EventListener/DataContainer/EntityConditionSaveListener.php b/src/EventListener/DataContainer/EntityConditionSaveListener.php new file mode 100644 index 0000000..5e41f9c --- /dev/null +++ b/src/EventListener/DataContainer/EntityConditionSaveListener.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Pdir\ContaoSeoPlugin\EventListener\DataContainer; + +use Contao\BackendUser; +use Contao\CoreBundle\DependencyInjection\Attribute\AsCallback; +use Contao\DataContainer; +use Contao\PageModel; + +#[AsCallback(table: 'tl_article', target: 'fields.contaoSeoEntityCondition.save')] +#[AsCallback(table: 'tl_content', target: 'fields.contaoSeoEntityCondition.save')] +#[AsCallback(table: 'tl_module', target: 'fields.contaoSeoEntityCondition.save')] +class EntityConditionSaveListener +{ + public function __invoke($value, DataContainer $dc) + { + if (empty($value)) { + return $value; + } + + // Return the processed value + return $value; + } + + private function validateCondition($code) + { + // Only safe characters (letters, numbers, operators and spaces) are allowed + if (preg_match('/^[a-zA-Z0-9+\-*/%\(\)\s]+$/', $code)) { + return true; + } + + return false; + } +} diff --git a/src/EventListener/IsVisibleElementListener.php b/src/EventListener/IsVisibleElementListener.php new file mode 100644 index 0000000..e9b81cb --- /dev/null +++ b/src/EventListener/IsVisibleElementListener.php @@ -0,0 +1,49 @@ +requestStack = $requestStack; + $this->scopeMatcher = $scopeMatcher; + } + public function __invoke(Model $element, bool $isVisible): bool + { + // Is back end request + if (!($request = $this->requestStack->getCurrentRequest()) || $this->scopeMatcher->isBackendRequest($request)) { + + // Check if condition is active + if ($element->contaoSeoIsConditionalEntity && trim($element->contaoSeoEntityCondition) !== '') { + $element->text = '⚠( ' .$element->contaoSeoEntityCondition.' )'.$element->text; + } + + return $isVisible; + } + + # $expressionLanguage = new ExpressionLanguage(); + # var_dump($expressionLanguage->evaluate($element->contaoSeoEntityCondition)); + + // Check if this element can be shown + if ($element->contaoSeoIsConditionalEntity && null !== $element->contaoSeoEntityCondition && trim($element->contaoSeoEntityCondition) !== '') { + return eval('return '.$element->contaoSeoEntityCondition.';'); + } + + // Otherwise we don't want to change the visibility state + return $isVisible; + } +}