diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-88648-DefineTwitterCardTypeInPageProperties.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-88648-DefineTwitterCardTypeInPageProperties.rst new file mode 100644 index 0000000000000000000000000000000000000000..83535e946aefb79374ca876ec5f151f2ba0d42c5 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-88648-DefineTwitterCardTypeInPageProperties.rst @@ -0,0 +1,34 @@ +.. include:: ../../Includes.txt + +========================================================== +Feature: #88648 - Set Twitter Card Type in page properties +========================================================== + +See :issue:`88648` + +Description +=========== + +It is now possible to select the type of Twitter Card to be shown when a page is shared +on Twitter. This option will render the `twitter:card` meta tag in frontend. + +Impact +====== + +If you manually changed the value of the `twitter:card` by for example TypoScript and you +want to override the value of the page properties, you have to use the replace option to +override this value from the page properties. + +Example: + +.. code-block:: typoscript + + page { + meta { + twitter:card = summary_large_image + twitter:card.replace = 1 + } + } + + +.. index:: ext:seo diff --git a/typo3/sysext/seo/Classes/MetaTag/MetaTagGenerator.php b/typo3/sysext/seo/Classes/MetaTag/MetaTagGenerator.php index df664188e74d050aeff8a7586e0215f4c045c6c4..63e23a1388f3b8b07c0f2e5355376314a7005e30 100644 --- a/typo3/sysext/seo/Classes/MetaTag/MetaTagGenerator.php +++ b/typo3/sysext/seo/Classes/MetaTag/MetaTagGenerator.php @@ -79,12 +79,8 @@ class MetaTagGenerator } } - /* - * Set type of twitter card to summary. This value can be overridden by TypoScript or the MetaTag API by - * using the replace option. In v10 this will be a page property - */ $manager = $metaTagManagerRegistry->getManagerForProperty('twitter:card'); - $manager->addProperty('twitter:card', 'summary'); + $manager->addProperty('twitter:card', $params['page']['twitter_card'] ?: 'summary'); if (!empty($params['page']['twitter_title'])) { $manager = $metaTagManagerRegistry->getManagerForProperty('twitter:title'); diff --git a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php index 1674d600e5c9062c85d6d19b84bf159192b03f04..613cb216b9cf3c6cf41a3b52cb48090321a2327b 100644 --- a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php +++ b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php @@ -56,7 +56,7 @@ $tca = [ ], 'twittercards' => [ 'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.palettes.twittercards', - 'showitem' => 'twitter_title, --linebreak--, twitter_description, --linebreak--, twitter_image', + 'showitem' => 'twitter_title, --linebreak--, twitter_description, --linebreak--, twitter_image, --linebreak--, twitter_card', ], ], 'columns' => [ @@ -269,6 +269,19 @@ $tca = [ $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] ) ], + 'twitter_card' => [ + 'exclude' => true, + 'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.twitter_card', + 'config' => [ + 'type' => 'select', + 'renderType' => 'selectSingle', + 'default' => 'summary', + 'items' => [ + ['LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.twitter_card.summary', 'summary'], + ['LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.twitter_card.summary_large_image', 'summary_large_image'], + ] + ] + ], ], ]; diff --git a/typo3/sysext/seo/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/seo/Resources/Private/Language/locallang_tca.xlf index b3c04d5ab0cf733ce0ce2f63244e5f4191a6c406..5aba8489154bf35b4b4c2beb2b5ae611e701b13b 100644 --- a/typo3/sysext/seo/Resources/Private/Language/locallang_tca.xlf +++ b/typo3/sysext/seo/Resources/Private/Language/locallang_tca.xlf @@ -52,6 +52,15 @@ <trans-unit id="pages.twitter_image"> <source>Image</source> </trans-unit> + <trans-unit id="pages.twitter_card"> + <source>Type of card to show</source> + </trans-unit> + <trans-unit id="pages.twitter_card.summary"> + <source>Summary Card</source> + </trans-unit> + <trans-unit id="pages.twitter_card.summary_large_image"> + <source>Summary Card with a large image</source> + </trans-unit> <trans-unit id="pages.palettes.canonical"> <source>Canonical</source> </trans-unit> diff --git a/typo3/sysext/seo/Tests/Functional/Fixtures/Scenarios/pages_with_seo_meta.xml b/typo3/sysext/seo/Tests/Functional/Fixtures/Scenarios/pages_with_seo_meta.xml new file mode 100644 index 0000000000000000000000000000000000000000..0fd314429f2a1903be3d7dcfa7cea604c92ba2a7 --- /dev/null +++ b/typo3/sysext/seo/Tests/Functional/Fixtures/Scenarios/pages_with_seo_meta.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<dataset> + <pages> + <uid>1</uid> + <pid>0</pid> + <title>Page with twitter_card</title> + <twitter_card>summary</twitter_card> + <deleted>0</deleted> + </pages> + <pages> + <uid>2</uid> + <pid>1</pid> + <title>Page with twitter_card and typoscript</title> + <twitter_card>summary</twitter_card> + <deleted>0</deleted> + </pages> + <pages> + <uid>3</uid> + <pid>1</pid> + <title>Page with twitter_card and typoscript with replace</title> + <twitter_card>summary</twitter_card> + <deleted>0</deleted> + </pages> +</dataset> diff --git a/typo3/sysext/seo/Tests/Functional/Fixtures/page1.typoscript b/typo3/sysext/seo/Tests/Functional/Fixtures/page1.typoscript new file mode 100644 index 0000000000000000000000000000000000000000..e9ee8fdd20c53a86f767d0d9ede92b412c2b20bf --- /dev/null +++ b/typo3/sysext/seo/Tests/Functional/Fixtures/page1.typoscript @@ -0,0 +1,5 @@ +page = PAGE +page { + meta { + } +} diff --git a/typo3/sysext/seo/Tests/Functional/Fixtures/page2.typoscript b/typo3/sysext/seo/Tests/Functional/Fixtures/page2.typoscript new file mode 100644 index 0000000000000000000000000000000000000000..c45b50c6efadab26b3684234297e82c51f223743 --- /dev/null +++ b/typo3/sysext/seo/Tests/Functional/Fixtures/page2.typoscript @@ -0,0 +1,6 @@ +page = PAGE +page { + meta { + twitter:card = summary_large_image + } +} diff --git a/typo3/sysext/seo/Tests/Functional/Fixtures/page3.typoscript b/typo3/sysext/seo/Tests/Functional/Fixtures/page3.typoscript new file mode 100644 index 0000000000000000000000000000000000000000..4c423301c731424c62ebadeba049ca2a5b4b9d52 --- /dev/null +++ b/typo3/sysext/seo/Tests/Functional/Fixtures/page3.typoscript @@ -0,0 +1,7 @@ +page = PAGE +page { + meta { + twitter:card = summary_large_image + twitter:card.replace = 1 + } +} diff --git a/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4503b640a707f0121bbf9d830aa84d1048fa2733 --- /dev/null +++ b/typo3/sysext/seo/Tests/Functional/MetaTag/MetaTagTest.php @@ -0,0 +1,88 @@ +<?php +declare(strict_types = 1); +namespace TYPO3\CMS\Seo\Tests\Functional\MetaTag; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase; +use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; + +/** + * Functional test for the DataHandler + */ +class MetaTagTest extends AbstractTestCase +{ + protected function setUp(): void + { + $this->coreExtensionsToLoad[] = 'seo'; + + parent::setUp(); + $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/seo/Tests/Functional/Fixtures/Scenarios/pages_with_seo_meta.xml'); + + $this->writeSiteConfiguration( + 'website-local', + $this->buildSiteConfiguration(1, 'http://localhost/'), + [ + $this->buildDefaultLanguageConfiguration('EN', '/') + ] + ); + } + + public function ensureMetaDataAreCorrectDataProvider(): array + { + return [ + 'page with twitter_card in page properties' => [ + 1, + [ + ['type' => 'name' , 'tag' => 'twitter:card', 'content' => 'summary'], + ] + ], + 'page with twitter_card in page properties and in typoscript' => [ + 2, + [ + ['type' => 'name' , 'tag' => 'twitter:card', 'content' => 'summary'], + ] + ], + 'page with twitter_card in page properties and in typoscript with replace' => [ + 3, + [ + ['type' => 'name' , 'tag' => 'twitter:card', 'content' => 'summary_large_image'], + ] + ], + ]; + } + + /** + * @test + * @dataProvider ensureMetaDataAreCorrectDataProvider + * @param int $pageId + * @param array $expectedMetaTags + */ + public function ensureMetaDataAreCorrect(int $pageId, array $expectedMetaTags): void + { + $this->setUpFrontendRootPage(1, ['typo3/sysext/seo/Tests/Functional/Fixtures/page' . $pageId . '.typoscript']); + + // First hit to create a cached version + $uncachedResponse = $this->executeFrontendRequest( + (new InternalRequest('http://localhost/'))->withQueryParameters([ + 'id' => $pageId, + ]) + ); + $body = (string)$uncachedResponse->getBody(); + + foreach ($expectedMetaTags as $expectedMetaTag) { + $this->assertStringContainsString('<meta ' . $expectedMetaTag['type'] . '="' . $expectedMetaTag['tag'] . '" content="' . $expectedMetaTag['content'] . '" />', $body); + } + } +} diff --git a/typo3/sysext/seo/ext_tables.sql b/typo3/sysext/seo/ext_tables.sql index 557454515fc51959d5a65d98d178da46b4e264eb..c4c7b4751ec52b2a8725609409dad0d05fd6b73b 100644 --- a/typo3/sysext/seo/ext_tables.sql +++ b/typo3/sysext/seo/ext_tables.sql @@ -11,6 +11,7 @@ CREATE TABLE pages ( twitter_title varchar(255) DEFAULT '' NOT NULL, twitter_description text, twitter_image int(11) unsigned DEFAULT '0' NOT NULL, + twitter_card varchar(255) DEFAULT '' NOT NULL, canonical_link varchar(2048) DEFAULT '' NOT NULL, sitemap_priority decimal(1,1) DEFAULT '0.5' NOT NULL, sitemap_changefreq varchar(10) DEFAULT '' NOT NULL,