Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1220 diff -u -p -r1.1220 common.inc --- includes/common.inc 15 Sep 2010 04:34:26 -0000 1.1220 +++ includes/common.inc 15 Sep 2010 15:56:17 -0000 @@ -4943,6 +4943,25 @@ function drupal_pre_render_conditional_c } /** + * Pre-render function for rendering groupable elements together. + */ +function drupal_pre_render_groups($elements) { + // Go through each element, and ensure that when it is rendered, by default + // it will not have its own group wrapper. This allows the elements to be + // properly displayed together as a single group, assuming the functions they + // are themed with support this concept. Note that we only support altering + // one level of nesting in this array; any elements located deeper down will + // not be affected by this function. + foreach (element_children($elements) as $group) { + if (!isset($elements[$group]['#wrap_elements']) && empty($elements[$group]['#printed'])) { + $elements[$group]['#wrap_elements'] = FALSE; + } + } + + return $elements; +} + +/** * #pre_render callback to render a link into #markup. * * Doing so during pre_render gives modules a chance to alter the link parts. @@ -5803,7 +5822,10 @@ function drupal_common_theme() { 'variables' => array('text' => NULL, 'path' => NULL, 'options' => array()), ), 'links' => array( - 'variables' => array('links' => NULL, 'attributes' => array('class' => array('links')), 'heading' => array()), + 'variables' => array('links' => NULL, 'attributes' => array('class' => array('links')), 'heading' => array(), 'children' => NULL, 'wrap_elements' => TRUE), + ), + 'grouped_element' => array( + 'render element' => 'element', ), 'image' => array( // HTML 4 and XHTML 1.0 always require an alt attribute. The HTML 5 draft Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.611 diff -u -p -r1.611 theme.inc --- includes/theme.inc 14 Sep 2010 21:42:05 -0000 1.611 +++ includes/theme.inc 15 Sep 2010 15:56:17 -0000 @@ -1395,17 +1395,32 @@ function theme_link($variables) { * screen-reader and keyboard only users to navigate to or skip the links. * See http://juicystudio.com/article/screen-readers-display-none.php * and http://www.w3.org/TR/WCAG-TECHS/H42.html for more information. + * - children: An optional string representing the rendered HTML of any + * children to append to the end of the list of links. + * - wrap_elements: A boolean indicating whether the provided links should be + * wrapped so as to form a complete group. For example, in the default + * implementation, in which the links are themed as an unordered list, + * setting 'wrap_elements' to FALSE causes the concatenated
  • elements + * to be displayed, but without being wrapped in '; } @@ -1473,6 +1496,24 @@ function theme_links($variables) { } /** + * Returns HTML for an element whose children represent groups. + * + * @param $variables + * An associative array containing: + * - element: An associative array containing the properties of the element. + * Properties used: #theme_callback + */ +function theme_grouped_element($variables) { + $element = $variables['element']; + + // First render any children, to pass along to the theme function. + $element['#children'] = drupal_render_children($element); + + // Now return the themed result. + return theme($element['#theme_callback'], $element); +} + +/** * Returns HTML for an image. * * @param $variables Index: modules/blog/blog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v retrieving revision 1.360 diff -u -p -r1.360 blog.module --- modules/blog/blog.module 30 Aug 2010 05:58:46 -0000 1.360 +++ modules/blog/blog.module 15 Sep 2010 15:56:17 -0000 @@ -80,11 +80,16 @@ function blog_view($node, $view_mode) { function blog_node_view($node, $view_mode) { if ($view_mode != 'rss') { if ($node->type == 'blog' && (arg(0) != 'blog' || arg(1) != $node->uid)) { - $node->content['links']['#links']['blog_usernames_blog'] = array( + $links['blog_usernames_blog'] = array( 'title' => t("!username's blog", array('!username' => format_username($node))), 'href' => "blog/$node->uid", 'attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' => format_username($node)))), ); + $node->content['links']['blog'] = array( + '#theme' => 'links__node__blog', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } } Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.552 diff -u -p -r1.552 book.module --- modules/book/book.module 9 Sep 2010 23:01:48 -0000 1.552 +++ modules/book/book.module 15 Sep 2010 15:56:17 -0000 @@ -112,7 +112,11 @@ function book_node_view_link($node, $vie } if (!empty($links)) { - $node->content['links']['#links'] = array_merge($node->content['links']['#links'], $links); + $node->content['links']['book'] = array( + '#theme' => 'links__node__book', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.898 diff -u -p -r1.898 comment.module --- modules/comment/comment.module 13 Sep 2010 05:52:18 -0000 1.898 +++ modules/comment/comment.module 15 Sep 2010 15:56:18 -0000 @@ -682,7 +682,11 @@ function comment_node_view($node, $view_ $links['comment_forbidden']['html'] = TRUE; } - $node->content['links']['#links'] = array_merge($node->content['links']['#links'], $links); + $node->content['links']['comment'] = array( + '#theme' => 'links__node__comment', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); // Only append comments when we are building a node on its own node detail // page. We compare $node and $page_node to ensure that comments are not Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1298 diff -u -p -r1.1298 node.module --- modules/node/node.module 11 Sep 2010 06:03:11 -0000 1.1298 +++ modules/node/node.module 15 Sep 2010 15:56:18 -0000 @@ -1286,6 +1286,13 @@ function node_build_content($node, $view entity_prepare_view('node', array($node->nid => $node)); $node->content += field_attach_view('node', $node, $view_mode); + // Prepare an array to hold the groups of links. + $node->content['links'] = array( + '#type' => 'grouped_element', + '#theme_callback' => 'links__node', + '#attributes' => array('class' => array('links', 'inline')), + ); + // Always display a read more link on teasers because we have no way // to know when a teaser view is different than a full view. $links = array(); @@ -1296,8 +1303,8 @@ function node_build_content($node, $view 'attributes' => array('rel' => 'tag', 'title' => strip_tags($node->title)) ); } - $node->content['links'] = array( - '#theme' => 'links__node', + $node->content['links']['node'] = array( + '#theme' => 'links__node__node', '#links' => $links, '#attributes' => array('class' => array('links', 'inline')), ); Index: modules/rdf/rdf.module =================================================================== RCS file: /cvs/drupal/drupal/modules/rdf/rdf.module,v retrieving revision 1.45 diff -u -p -r1.45 rdf.module --- modules/rdf/rdf.module 9 Sep 2010 20:22:00 -0000 1.45 +++ modules/rdf/rdf.module 15 Sep 2010 15:56:18 -0000 @@ -500,7 +500,7 @@ function rdf_preprocess_node(&$variables // Adds RDFa markup annotating the number of comments a node has. if (isset($variables['node']->comment_count) && !empty($variables['node']->rdf_mapping['comment_count']['predicates'])) { // Annotates the 'x comments' link in teaser view. - if (isset($variables['content']['links']['#links']['comment-comments'])) { + if (isset($variables['content']['links']['comment']['#links']['comment-comments'])) { $comment_count_attributes['property'] = $variables['node']->rdf_mapping['comment_count']['predicates']; $comment_count_attributes['content'] = $variables['node']->comment_count; $comment_count_attributes['datatype'] = $variables['node']->rdf_mapping['comment_count']['datatype']; @@ -510,7 +510,7 @@ function rdf_preprocess_node(&$variables // we set an empty rel attribute which triggers rule number 5. See // http://www.w3.org/TR/rdfa-syntax/#sec_5.5. $comment_count_attributes['rel'] = ''; - $variables['content']['links']['#links']['comment-comments']['attributes'] += $comment_count_attributes; + $variables['content']['links']['comment']['#links']['comment-comments']['attributes'] += $comment_count_attributes; } // In full node view, the number of comments is not displayed by // node.tpl.php so it is expressed in RDFa in the tag. Index: modules/statistics/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v retrieving revision 1.338 diff -u -p -r1.338 statistics.module --- modules/statistics/statistics.module 30 Aug 2010 05:58:46 -0000 1.338 +++ modules/statistics/statistics.module 15 Sep 2010 15:56:18 -0000 @@ -114,12 +114,19 @@ function statistics_permission() { */ function statistics_node_view($node, $view_mode) { if ($view_mode != 'rss') { + $links = array(); if (user_access('view post access counter')) { $statistics = statistics_get($node->nid); if ($statistics) { - $node->content['links']['#links']['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads'); + $links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads'); } } + + $node->content['links']['statistics'] = array( + '#theme' => 'links__node__statistics', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.960 diff -u -p -r1.960 system.module --- modules/system/system.module 11 Sep 2010 06:03:12 -0000 1.960 +++ modules/system/system.module 15 Sep 2010 15:56:19 -0000 @@ -484,6 +484,12 @@ function system_element_info() { '#theme' => 'hidden', ); + // Miscellaneous elements. + $types['grouped_element'] = array( + '#pre_render' => array('drupal_pre_render_groups'), + '#theme' => 'grouped_element', + ); + return $types; } Index: modules/translation/translation.module =================================================================== RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v retrieving revision 1.84 diff -u -p -r1.84 translation.module --- modules/translation/translation.module 9 Sep 2010 23:01:48 -0000 1.84 +++ modules/translation/translation.module 15 Sep 2010 15:56:19 -0000 @@ -188,7 +188,11 @@ function translation_node_view($node, $v $links = $links->links; // Do not show link to the same node. unset($links[$node->language]); - $node->content['links']['#links'] = array_merge($node->content['links']['#links'], $links); + $node->content['links']['translation'] = array( + '#theme' => 'links__node__translation', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } }