diff --git a/core/modules/system/src/Tests/Theme/FunctionsTest.php b/core/modules/system/src/Tests/Theme/FunctionsTest.php index 5e31422..e64f10e 100644 --- a/core/modules/system/src/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php @@ -290,6 +290,127 @@ function testLinks() { } /** + * Tests links.html.twig. + */ + function testIndexedKeyedLinks() { + // Turn off the query for the + // \Drupal\Core\Utility\LinkGeneratorInterface::generate() method to compare + // the active link correctly. + $original_query = \Drupal::request()->query->all(); + \Drupal::request()->query->replace([]); + // Verify that empty variables produce no output. + $variables = []; + $expected = ''; + $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback generates no output.'); + + $variables = []; + $variables['heading'] = 'Some title'; + $expected = ''; + $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.'); + + // Verify that a list of links is properly rendered. + $variables = []; + $variables['attributes'] = ['id' => 'somelinks']; + $variables['links'] = array( + array( + 'title' => 'A ', + 'url' => Url::fromUri('base:a/link'), + ), + array( + 'title' => 'Plain "text"', + ), + array( + 'title' => SafeMarkup::format('@text', array('@text' => 'potentially unsafe text that be escaped')), + ), + array( + 'title' => 'Front page', + 'url' => Url::fromRoute(''), + ), + array( + 'title' => 'Test route', + 'url' => Url::fromRoute('router_test.1'), + ), + array( + 'title' => 'Query test route', + 'url' => Url::fromRoute('router_test.1'), + 'query' => array( + 'key' => 'value', + ) + ), + ); + + $expected_links = ''; + $expected_links .= ''; + + // Verify that passing a string as heading works. + $variables['heading'] = 'Links heading'; + $expected_heading = '

Links heading

'; + $expected = $expected_heading . $expected_links; + $this->assertThemeOutput('links', $variables, $expected); + + // Restore the original request's query. + \Drupal::request()->query->replace($original_query); + + // Verify that passing an array as heading works (core support). + $variables['heading'] = [ + 'text' => 'Links heading', + 'level' => 'h3', + 'attributes' => ['class' => ['heading']], + ]; + $expected_heading = '

Links heading

'; + $expected = $expected_heading . $expected_links; + $this->assertThemeOutput('links', $variables, $expected); + + // Verify that passing attributes for the heading works. + $variables['heading'] = ['text' => 'Links heading', 'level' => 'h3', 'attributes' => ['id' => 'heading']]; + $expected_heading = '

Links heading

'; + $expected = $expected_heading . $expected_links; + $this->assertThemeOutput('links', $variables, $expected); + + // Verify that passing attributes for the links work. + $variables['links'][1]['attributes'] = [ + 'class' => ['a/class'], + ]; + $expected_links = ''; + $expected_links .= ''; + $expected = $expected_heading . $expected_links; + $this->assertThemeOutput('links', $variables, $expected); + + // Verify the data- attributes for setting the "active" class on links. + \Drupal::currentUser()->setAccount(new UserSession(array('uid' => 1))); + $variables['set_active_class'] = TRUE; + $expected_links = ''; + $expected_links .= ''; + $expected = $expected_heading . $expected_links; + $this->assertThemeOutput('links', $variables, $expected); + } + + /** * Test the use of drupal_pre_render_links() on a nested array of links. */ function testDrupalPreRenderLinks() { diff --git a/core/themes/stable/stable.theme b/core/themes/stable/stable.theme index dac7d7c..aafe570 100644 --- a/core/themes/stable/stable.theme +++ b/core/themes/stable/stable.theme @@ -1,13 +1,17 @@ $value) { if (!is_numeric($key)) { - $variables['links'][$key]['attributes']['class'][] = $key; + $class = Html::getClass($key); + $variables['links'][$key]['attributes']->addClass($class); } } }