Commit 361bb8c3 authored by Benni Mack's avatar Benni Mack
Browse files

[BUGFIX] Use "pages.target" properly for Pages with External URL

The database field "pages.target" allows to define
a custom target attribute for links in menus of external
URLs.

Before this was (wrongly) built in HMENU but applied
after Typolink worked. This option belongs to the
actual link building when building links to external URLs
where $conf[extTarget] is evaluated.

In addition, HMENU tests now also evaluate "target"
for regular pages as well.

Resolves: #96470
Releases: main, 11.5
Change-Id: I3919b6b13666565687e8ff56dcfc867c871837e2
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72866


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 502b7bea
......@@ -22,7 +22,6 @@ use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\LanguageAspect;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\Type\Bitmask\PageTranslationVisibility;
......@@ -1225,12 +1224,8 @@ abstract class AbstractMenuContentObject
// Mount points:
$MP_params = $MP_var ? '&MP=' . rawurlencode($MP_var) : '';
}
// Setting main target:
if ($altTarget) {
$mainTarget = $altTarget;
} else {
$mainTarget = (string)$this->parent_cObj->stdWrapValue('target', $this->mconf ?? []);
}
// Setting main target
$mainTarget = $altTarget ?: (string)$this->parent_cObj->stdWrapValue('target', $this->mconf ?? []);
// Creating link:
$addParams = ($this->mconf['addParams'] ?? '') . $MP_params;
if (($this->mconf['collapse'] ?? false) && $this->isActive($this->menuArr[$key] ?? [], $this->getMPvar($key))) {
......@@ -1240,12 +1235,6 @@ abstract class AbstractMenuContentObject
$addParams .= ($this->I['val']['additionalParams'] ?? '');
$LD = $this->menuTypoLink($this->menuArr[$key], $mainTarget, $addParams, $typeOverride, $overrideId);
}
// Override default target configuration if the DB field "pages.target" = $this->menuArr[$key]['target'] is filled
// but do not set this for type email or external URLs
if (($this->menuArr[$key]['target'] ?? false) && !in_array($LD['type'], [LinkService::TYPE_EMAIL, LinkService::TYPE_URL], true)) {
$LD['target'] = $this->menuArr[$key]['target'];
}
// Overriding URL / Target if set to do so:
if ($this->menuArr[$key]['_OVERRIDE_HREF'] ?? false) {
$LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF'];
......
......@@ -215,6 +215,10 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
if ((int)$page['doktype'] === PageRepository::DOKTYPE_LINK) {
$conf['parameter'] = $page['url'];
unset($conf['parameter.']);
// Use "pages.target" as this is the requested field for external links as well
if (!isset($conf['extTarget'])) {
$conf['extTarget'] = (isset($page['target']) && trim($page['target'])) ? $page['target'] : $target;
}
$this->contentObjectRenderer->typoLink($linkText, $conf);
$target = $this->contentObjectRenderer->lastTypoLinkTarget;
$url = $this->contentObjectRenderer->lastTypoLinkUrl;
......
__variables:
- &pageStandard 0
- &pageExternalUrl 3
- &pageShortcut 4
- &pageMount 7
- &pageSpacer 199
......@@ -151,6 +152,8 @@ entities:
children:
- self: {id: 2121, title: 'About', slug: '/about-jane'}
- self: {id: 2700, title: 'Announcements & News', type: *pageMount, mount: 7100, slug: '/news'}
- self: {id: 2800, title: 'What is a blog on Wikipedia ', type: *pageExternalUrl, url: 'https://en.wikipedia.org/wiki/Blog', slug: '/what-is-a-blog', target: 'a_new_tab' }
- self: {id: 2900, title: 'What is Wikipedia in a separate window ', type: *pageExternalUrl, url: 'https://en.wikipedia.org/', slug: '/wikipedia' }
- self: {id: 2930, title: 'ACME Inc', type: *pageShortcut, shortcut: 1000, slug: '/acme'}
- self: {id: 3000, title: 'ACME Archive', root: true, slug: '/'}
languageVariants:
......@@ -172,7 +175,7 @@ entities:
children:
- self: {id: 7110, title: 'Markets', slug: '/common/markets'}
- self: {id: 7120, title: 'Products', slug: '/common/products'}
- self: {id: 7130, title: 'Partners', slug: '/common/partners'}
- self: {id: 7130, title: 'Partners', slug: '/common/partners', target: '_blank' }
- self: {id: 8000, title: 'Usual Collection Non-Root', root: true, slug: '/usual'}
children:
- self: {id: 8100, title: 'Announcements & News', type: *pageFolder, slug: '/usual/news-folder'}
......
......@@ -680,75 +680,88 @@ class SlugLinkGeneratorTest extends AbstractTestCase
'https://acme.us/',
1100,
[
['title' => 'EN: Welcome', 'link' => '/welcome'],
['title' => 'EN: Welcome', 'link' => '/welcome', 'target' => ''],
[
'title' => 'ZH-CN: Welcome Default',
// Symfony UrlGenerator, which is used for uri generation, rawurlencodes the url internally.
'link' => '/%E7%AE%80-bienvenue',
'target' => '',
],
[
'title' => 'EN: Features',
'link' => '/features',
'target' => '',
'children' => [
[
'title' => 'EN: Frontend Editing',
'link' => '/features/frontend-editing/',
'target' => '',
],
],
],
[
'title' => 'EN: Products',
'link' => 'https://products.acme.com/products',
'target' => '',
'children' => [
[
'title' => 'EN: Planets',
'link' => 'https://products.acme.com/products/planets',
'target' => '',
],
[
'title' => 'EN: Spaceships',
'link' => 'https://products.acme.com/products/spaceships',
'target' => '',
],
[
'title' => 'EN: Dark Matter',
'link' => 'https://products.acme.com/products/dark-matter',
'target' => '',
],
],
],
['title' => 'EN: ACME in your Region', 'link' => '/acme-in-your-region'],
['title' => 'EN: ACME in your Region', 'link' => '/acme-in-your-region', 'target' => ''],
[
'title' => 'Divider',
'link' => '/divider',
'target' => '',
'children' => [
[
'title' => 'EN: Subpage of Spacer',
'link' => '/divider/subpage-of-spacer',
'target' => '',
],
],
],
['title' => 'Internal', 'link' => '/my-acme'],
['title' => 'About us', 'link' => '/about'],
['title' => 'Internal', 'link' => '/my-acme', 'target' => ''],
['title' => 'About us', 'link' => '/about', 'target' => ''],
[
'title' => 'Announcements & News',
'link' => '/news',
'target' => '',
'children' => [
[
'title' => 'Markets',
'link' => '/news/common/markets',
'target' => '',
],
[
'title' => 'Products',
'link' => '/news/common/products',
'target' => '',
],
[
'title' => 'Partners',
'link' => '/news/common/partners',
'target' => '_blank',
],
],
],
['title' => 'That page is forbidden to you', 'link' => '/403'],
['title' => 'That page was not found', 'link' => '/404'],
['title' => 'Our Blog', 'link' => 'https://blog.acme.com/authors'],
['title' => 'Cross Site Shortcut', 'link' => 'https://blog.acme.com/authors'],
['title' => 'That page is forbidden to you', 'link' => '/403', 'target' => ''],
['title' => 'That page was not found', 'link' => '/404', 'target' => ''],
['title' => 'Our Blog', 'link' => 'https://blog.acme.com/authors', 'target' => ''],
['title' => 'Cross Site Shortcut', 'link' => 'https://blog.acme.com/authors', 'target' => ''],
],
],
'ACME Blog' => [
......@@ -758,14 +771,17 @@ class SlugLinkGeneratorTest extends AbstractTestCase
[
'title' => 'Authors',
'link' => '/authors',
'target' => '',
'children' => [
[
'title' => 'John Doe',
'link' => 'https://blog.acme.com/john/john',
'target' => '',
],
[
'title' => 'Jane Doe',
'link' => 'https://blog.acme.com/jane/jane',
'target' => '',
],
],
],
......@@ -773,22 +789,29 @@ class SlugLinkGeneratorTest extends AbstractTestCase
[
'title' => 'Announcements & News',
'link' => '/news',
'target' => '',
'children' => [
[
'title' => 'Markets',
'link' => '/news/common/markets',
'target' => '',
],
[
'title' => 'Products',
'link' => '/news/common/products',
'target' => '',
],
[
'title' => 'Partners',
'link' => '/news/common/partners',
'target' => '_blank',
],
],
],
['title' => 'ACME Inc', 'link' => 'https://acme.us/welcome'],
['title' => 'What is a blog on Wikipedia', 'link' => 'https://en.wikipedia.org/wiki/Blog', 'target' => 'a_new_tab'],
// target is empty because no fluid_styled_content typoscript with config.extTarget is active
['title' => 'What is Wikipedia in a separate window', 'link' => 'https://en.wikipedia.org/', 'target' => ''],
['title' => 'ACME Inc', 'link' => 'https://acme.us/welcome', 'target' => ''],
],
],
];
......@@ -819,7 +842,7 @@ class SlugLinkGeneratorTest extends AbstractTestCase
);
$json = json_decode((string)$response->getBody(), true);
$json = $this->filterMenu($json);
$json = $this->filterMenu($json, ['title', 'link', 'target']);
self::assertSame($expectation, $json);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment