diff --git a/core/includes/common.inc b/core/includes/common.inc index a566bc5..d115bea 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3375,6 +3375,13 @@ function drupal_pre_render_link($element) { $element['#options']['attributes'] += $element['#attributes']; } + // Merge the provided attributes on top of the default attributes + // provided by the element definition. + if (isset($element['#default_attributes'])) { + $element['#options'] += array('attributes' => array()); + $element['#options']['attributes'] = NestedArray::mergeDeep($element['#default_attributes'], $element['#options']['attributes']); + } + // This #pre_render callback can be invoked from inside or outside of a Form // API context, and depending on that, a HTML ID may be already set in // different locations. #options should have precedence over Form API's #id. diff --git a/core/includes/theme.inc b/core/includes/theme.inc index f98aadd..7198664 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1847,18 +1847,6 @@ function template_preprocess_feed_icon(&$variables) { } /** - * Returns HTML for a "more" link, like those used in blocks. - * - * @param $variables - * An associative array containing: - * - url: The URL of the main page. - * - title: A descriptive verb for the link, like 'Read more'. - */ -function theme_more_link($variables) { - return ''; -} - -/** * Returns HTML for an indentation div; used for drag and drop tables. * * @param $variables @@ -2614,9 +2602,6 @@ function drupal_common_theme() { 'variables' => array('url' => NULL, 'title' => NULL), 'template' => 'feed-icon', ), - 'more_link' => array( - 'variables' => array('url' => NULL, 'title' => NULL) - ), 'progress_bar' => array( 'variables' => array('label' => NULL, 'percent' => NULL, 'message' => NULL), 'template' => 'progress-bar', diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php index 767639e..78a8652 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/Block/AggregatorFeedBlock.php @@ -133,9 +133,9 @@ public function build() { if ($feed = $this->storageController->load($this->configuration['feed'])) { $result = $this->connection->queryRange("SELECT * FROM {aggregator_item} WHERE fid = :fid ORDER BY timestamp DESC, iid DESC", 0, $this->configuration['block_count'], array(':fid' => $feed->id())); $more_link = array( - '#theme' => 'more_link', - '#url' => 'aggregator/sources/' . $feed->id(), - '#title' => t("View this feed's recent news."), + '#type' => 'more_link', + '#href' => 'aggregator/sources/' . $feed->id(), + '#attributes' => array('title' => t("View this feed's recent news.")), ); $read_more = drupal_render($more_link); $items = array(); diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index a7e4b9e..3d2ae99 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -582,7 +582,11 @@ function forum_block_view_pre_render($elements) { $result = $elements['#query']->execute(); if ($node_title_list = node_title_list($result)) { $elements['forum_list'] = $node_title_list; - $elements['forum_more'] = array('#theme' => 'more_link', '#url' => 'forum', '#title' => t('Read the latest forum topics.')); + $elements['forum_more'] = array( + '#type' => 'more_link', + '#href' => 'forum', + '#attributes' => array('title' => t('Read the latest forum topics.')), + ); } return $elements; } diff --git a/core/modules/system/css/system.theme.css b/core/modules/system/css/system.theme.css index 9a0153d..a256f30 100644 --- a/core/modules/system/css/system.theme.css +++ b/core/modules/system/css/system.theme.css @@ -119,7 +119,7 @@ abbr.form-required, abbr.tabledrag-changed, abbr.ajax-changed { } /** - * Markup generated by theme_more_link(). + * Markup generated by #type 'link'. */ .more-link { text-align: right; /* LTR */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php index 9ba4bf4..22e88a0 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php @@ -113,4 +113,50 @@ function testHtmlTag() { $this->assertElements($elements); } + /** + * Tests system #type 'more_link'. + */ + function testMoreLink() { + $elements = array( + // Test more_link anchor tag generation without class attributes to test default. + array( + 'name' => "#type 'more_link' anchor tag generation without extra classes", + 'value' => array( + '#type' => 'more_link', + '#href' => 'admin/content', + ), + 'expected' => '//a[@href="/admin/content" and @class="more-link" and text()="More"]', + ), + // Test more_link anchor tag generation with title change. + array( + 'name' => "#type 'more_link' anchor tag generation with different link text", + 'value' => array( + '#type' => 'more_link', + '#href' => '', + '#title' => 'More Titles', + ), + 'expected' => '//a[@href="/" and @class="more-link" and text()="More Titles"]', + ), + // Test more_link anchor tag generation without class attributes to test additional classes. + array( + 'name' => "#type 'more_link' anchor tag generation with extra classes", + 'value' => array( + '#type' => 'more_link', + '#href' => 'admin/content', + '#attributes' => array( + 'title' => 'description', + 'class' => array('drupal', 'test'), + ), + ), + 'expected' => '//a[@href="/admin/content" and @title="description" and contains(@class, "more-link") and contains(@class, "drupal") and contains(@class, "test") and text()="More"]', + ), + ); + + foreach($elements as $element) { + $xml = new \SimpleXMLElement(drupal_render($element['value'])); + $result = $xml->xpath($element['expected']); + $this->assertTrue($result, '"' . $element['name'] . '" input rendered correctly by drupal_render().'); + } + } + } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 1657f9f..35a41ca 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -545,6 +545,11 @@ function system_element_info() { $types['link'] = array( '#pre_render' => array('drupal_pre_render_link'), ); + // A "more" link, like those used in blocks. + $types['more_link'] = $types['link'] + array( + '#title' => t('More'), + '#default_attributes' => array('class' => array('more-link')), + ); $types['fieldset'] = array( '#value' => NULL, '#process' => array('form_process_group', 'ajax_process_form'), diff --git a/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/EventSubscriber/ThemeTestSubscriber.php index 2e5417d..e2bddaa 100644 --- a/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/EventSubscriber/ThemeTestSubscriber.php +++ b/core/modules/system/tests/modules/theme_test/lib/Drupal/theme_test/EventSubscriber/ThemeTestSubscriber.php @@ -42,7 +42,7 @@ public function onRequest(GetResponseEvent $event) { // theme_test_request_listener_page_callback() to test that even when the // theme system is initialized this early, it is still capable of // returning output and theming the page as a whole. - $GLOBALS['theme_test_output'] = theme('more_link', array('url' => 'user', 'title' => 'Themed output generated in a KernelEvents::REQUEST listener')); + $GLOBALS['theme_test_output'] = theme('theme_test_foo', array('foo' => 'Themed output generated in a KernelEvents::REQUEST listener')); } }