diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php index d698604b15bf9bfc6716b3fabb7ee6259a5a7e39..2dc416f4bd7b19a8a9b55c0b35efc58c851ac539 100644 --- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php @@ -436,7 +436,15 @@ protected function processHtmlHeadLink(array $html_head_link) { '#attributes' => $attributes, ]; $href = $attributes['href']; - $attached['html_head'][] = [$element, 'html_head_link:' . $attributes['rel'] . ':' . $href]; + $rel = $attributes['rel']; + + // Allow multiple hreflang tags to use the same href. + if (isset($attributes['hreflang'])) { + $attached['html_head'][] = [$element, 'html_head_link:' . $rel . ':' . $attributes['hreflang'] . ':' . $href]; + } + else { + $attached['html_head'][] = [$element, 'html_head_link:' . $rel . ':' . $href]; + } if ($should_add_header) { // Also add a HTTP header "Link:". diff --git a/core/modules/system/tests/modules/render_attached_test/src/Controller/RenderAttachedTestController.php b/core/modules/system/tests/modules/render_attached_test/src/Controller/RenderAttachedTestController.php index 1bbf8ebe65db07d8b133cdd3e0f268d702b60a86..955e3daa221de4d3d6c948c67325d115125ad094 100644 --- a/core/modules/system/tests/modules/render_attached_test/src/Controller/RenderAttachedTestController.php +++ b/core/modules/system/tests/modules/render_attached_test/src/Controller/RenderAttachedTestController.php @@ -80,6 +80,7 @@ public function htmlHeaderLink() { $render['#attached']['html_head_link'][] = [['href' => '/foo?bar=<baz>&baz=false', 'rel' => 'alternate'], TRUE]; $render['#attached']['html_head_link'][] = [['href' => '/not-added-to-http-headers', 'rel' => 'alternate'], FALSE]; $render['#attached']['html_head_link'][] = [['href' => '/foo/bar', 'hreflang' => 'nl', 'rel' => 'alternate'], TRUE]; + $render['#attached']['html_head_link'][] = [['href' => '/foo/bar', 'hreflang' => 'de', 'rel' => 'alternate'], TRUE]; return $render; } diff --git a/core/modules/system/tests/src/Functional/Render/HtmlResponseAttachmentsTest.php b/core/modules/system/tests/src/Functional/Render/HtmlResponseAttachmentsTest.php index f07424b455e31f0410a28c61bc95cd9452c5c9b4..9921fe04a9001f34fc563a55c56a0fad39514630 100644 --- a/core/modules/system/tests/src/Functional/Render/HtmlResponseAttachmentsTest.php +++ b/core/modules/system/tests/src/Functional/Render/HtmlResponseAttachmentsTest.php @@ -65,8 +65,13 @@ public function testAttachments() { $expected_link_headers = [ '</foo?bar=<baz>&baz=false>; rel="alternate"', '</foo/bar>; hreflang="nl"; rel="alternate"', + '</foo/bar>; hreflang="de"; rel="alternate"', ]; $this->assertEquals($expected_link_headers, $this->getSession()->getResponseHeaders()['Link']); + + // Check that duplicate alternate URLs with different hreflangs are allowed. + $test_link = $this->xpath('//head/link[@rel="alternate"][@href="/foo/bar"]'); + $this->assertEquals(2, count($test_link), 'Duplicate alternate URLs are allowed.'); } /**