diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php index b8c05909bd1588ebe1871bf8ab8fc8eb18020814..ff01040f52a4dcd3f8a26f78a924d4cc15f55777 100644 --- a/core/lib/Drupal/Core/Template/Attribute.php +++ b/core/lib/Drupal/Core/Template/Attribute.php @@ -43,10 +43,11 @@ * htmlspecialchars() and the entire attribute string is marked safe for output. */ class Attribute implements \ArrayAccess, \IteratorAggregate, SafeStringInterface { + /** * Stores the attribute data. * - * @var array + * @var \Drupal\Core\Template\AttributeValueBase[] */ protected $storage = array(); @@ -261,6 +262,21 @@ public function __toString() { return $return; } + /** + * Returns all storage elements as an array. + * + * @return array + * An associative array of attributes. + */ + public function toArray() { + $return = []; + foreach ($this->storage as $name => $value) { + $return[$name] = $value->value(); + } + + return $return; + } + /** * Implements the magic __clone() method. */ diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 52a0b59b8f1514dfc26383657a04f6e14d314d26..482c8882b7c74435f7af1867aa92fc6ccef591af 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -260,17 +260,20 @@ public function getUrlFromPath($path, $options = array()) { * The link text for the anchor tag as a translated string. * @param \Drupal\Core\Url|string $url * The URL object or string used for the link. - * @param array $attributes - * An optional array of link attributes. + * @param array|\Drupal\Core\Template\Attribute $attributes + * An optional array or Attribute object of link attributes. * * @return array * A render array representing a link to the given URL. */ - public function getLink($text, $url, array $attributes = []) { + public function getLink($text, $url, $attributes = []) { if (!$url instanceof Url) { $url = Url::fromUri($url); } if ($attributes) { + if ($attributes instanceof Attribute) { + $attributes = $attributes->toArray(); + } if ($existing_attributes = $url->getOption('attributes')) { $attributes = array_merge($existing_attributes, $attributes); } diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php index 86b49e89d3acb98952707b100f9051252d2d5082..59af0147a0a49b4b4d6b876bf4ea844606b0cf0c 100644 --- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php +++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php @@ -85,6 +85,7 @@ public function testTwigLinkGenerator() { 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['absolute' => TRUE, 'attributes' => ['foo' => 'bar']])), 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['foo' => 'bar', 'id' => 'kitten']])), 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['id' => 'kitten']])), + 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['class' => ['llama', 'kitten', 'panda']]])), ]; // Verify that link() has the ability to bubble cacheability metadata: diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php index d49ebba438125730fb933e3acc4bba88c5d56d05..dce85a38bcd220ceb8825e295be0d7a30ee83b45 100644 --- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php +++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php @@ -7,6 +7,7 @@ namespace Drupal\twig_theme_test; +use Drupal\Core\Template\Attribute; use Drupal\Core\Url; /** @@ -53,11 +54,14 @@ public function urlGeneratorRender() { * Renders for testing link_generator functions in a Twig template. */ public function linkGeneratorRender() { - return array( + return [ '#theme' => 'twig_theme_test_link_generator', '#test_url' => new Url('user.register', [], ['absolute' => TRUE]), '#test_url_attribute' => new Url('user.register', [], ['attributes' => ['foo' => 'bar']]), - ); + // Explicitly creating an Attribute object to avoid false positives when + // testing Attribute object merging with the twig link() function. + '#attributes' => new Attribute(['class' => ['llama', 'kitten', 'panda']]), + ]; } /** diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig index 3fb846fa36ae35e1b9418db753addd499d66991f..8925705be1eea73c0ce725d5a9fc343ebb642d28 100644 --- a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig @@ -2,3 +2,4 @@
link via the linkgenerator: {{ link('register', test_url, {'foo': 'bar'}) }}
link via the linkgenerator: {{ link('register', test_url_attribute, {'id': 'kitten'}) }}
link via the linkgenerator: {{ link('register', 'route:user.register', {'id': 'kitten'}) }}
+
link via the linkgenerator: {{ link('register', 'route:user.register', attributes) }}
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module index d5e098ce0e1529068a7e139b2f34f01e6564d157..52c0ef48c98405a91d65be548b50edd44f886de1 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module @@ -43,7 +43,11 @@ function twig_theme_test_theme($existing, $type, $theme, $path) { 'template' => 'twig_theme_test.url_generator', ); $items['twig_theme_test_link_generator'] = array( - 'variables' => array('test_url' => NULL, 'test_url_attribute' => NULL), + 'variables' => [ + 'test_url' => NULL, + 'test_url_attribute' => NULL, + 'attributes' => [], + ], 'template' => 'twig_theme_test.link_generator', ); $items['twig_theme_test_url_to_string'] = array(