Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.358 diff -u -p -r1.358 menu.inc --- includes/menu.inc 1 Nov 2009 23:02:13 -0000 1.358 +++ includes/menu.inc 4 Nov 2009 03:41:38 -0000 @@ -1796,16 +1796,26 @@ function menu_local_tasks($level = 0) { * If the path "node/123" is passed to this function, then it will return the * links for 'edit' and 'report-as-spam'. * + * @param $module + * The name of the implementing module. This is used to prefix the key for + * each contextual link, which is transformed into a CSS class during + * rendering by theme_links(). For example, if $module is 'block' and the + * retrieved local task path argument is 'edit', then the resulting CSS class + * will be 'block-edit'. * @param $path - * The menu router path of the object to retrieve local tasks for, for example - * "node/123" or "admin/structure/menu/manage/[menu_name]". + * The static menu router path of the object to retrieve local tasks for, for + * example 'node' or 'admin/structure/block/manage'. + * @param $args + * A list of of dynamic path arguments to append to $path to form the fully- + * qualified menu router path, for example array(123) for a certain node or + * array('system', 'navigation') for a certain block. * * @return * A list of menu router items that are local tasks for the passed in path. * * @see system_preprocess() */ -function menu_contextual_links($parent_path, $args) { +function menu_contextual_links($module, $parent_path, $args) { static $path_empty = array(); $links = array(); @@ -1851,12 +1861,9 @@ function menu_contextual_links($parent_p if (!$item['access']) { continue; } - // All contextual links are keyed by the actual "task" path argument. The - // menu system does not allow for two local tasks with the same name, and - // since the key is also used as CSS class for the link item, which may be - // styled as icon, it wouldn't make sense to display the same icon for - // different tasks. - $links[$key] = $item; + // All contextual links are keyed by the actual "task" path argument, + // prefixed with the name of implementing module. + $links[$module . '-' . $key] = $item; } // Allow modules to alter contextual links. Index: includes/update.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/update.inc,v retrieving revision 1.18 diff -u -p -r1.18 update.inc --- includes/update.inc 24 Oct 2009 23:19:21 -0000 1.18 +++ includes/update.inc 4 Nov 2009 03:41:38 -0000 @@ -140,6 +140,8 @@ function update_fix_d7_requirements() { 'not null' => TRUE, 'default' => 0, )); + db_drop_index('menu_router', 'tab_parent'); + db_add_index('menu_router', 'tab_parent', array(array('tab_parent', 64), 'weight', 'title')); db_add_field('menu_router', 'theme_callback', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '')); db_add_field('menu_router', 'theme_arguments', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '')); Index: modules/block/block.module =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.module,v retrieving revision 1.394 diff -u -p -r1.394 block.module --- modules/block/block.module 23 Oct 2009 22:24:11 -0000 1.394 +++ modules/block/block.module 4 Nov 2009 03:41:38 -0000 @@ -283,7 +283,7 @@ function _block_get_renderable_array($li // Add contextual links for this block; skipping the system main block. if ($key != 'system_main') { - $build[$key]['#contextual_links']['block'] = menu_contextual_links('admin/structure/block/manage', array($block->module, $block->delta)); + $build[$key]['#contextual_links']['block'] = array('admin/structure/block/manage', array($block->module, $block->delta)); } $build[$key] += array( Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.522 diff -u -p -r1.522 book.module --- modules/book/book.module 3 Nov 2009 06:47:22 -0000 1.522 +++ modules/book/book.module 4 Nov 2009 05:47:42 -0000 @@ -1087,8 +1087,10 @@ function book_export_traverse($tree, $vi * The HTML generated for the given node. */ function book_node_export(stdClass $node, $children = '') { - node_build_content($node, 'print'); - $node->rendered = drupal_render($node->content); + $build = node_build($node, 'print'); + unset($build['#theme']); + unset($build['#theme_wrappers']); + $node->rendered = drupal_render($build); return theme('book_node_export_html', array('node' => $node, 'children' => $children)); } Index: modules/comment/comment.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.api.php,v retrieving revision 1.12 diff -u -p -r1.12 comment.api.php --- modules/comment/comment.api.php 10 Oct 2009 13:37:09 -0000 1.12 +++ modules/comment/comment.api.php 4 Nov 2009 03:41:38 -0000 @@ -73,6 +73,34 @@ function hook_comment_view($comment) { } /** + * The comment was built, the module may modify the structured content. + * + * This hook is called after the content has been assembled in a structured array + * and may be used for doing processing which requires that the complete comment + * content structure has been built. + * + * If the module wishes to act on the rendered HTML of the comment rather than the + * structured content array, it may use this hook to add a #post_render callback. + * Alternatively, it could also implement hook_preprocess_comment(). See + * drupal_render() and theme() documentation respectively for details. + * + * @param $build + * A renderable array representing the comment. + * + * @see comment_build() + */ +function hook_comment_build_alter($build) { + // Check for the existence of a field added by another module. + if ($build['#build_mode'] == 'full' && isset($build['an_additional_field'])) { + // Change its weight. + $build['an_additional_field']['#weight'] = -10; + } + + // Add a #post_render callback to act on the rendered HTML of the comment. + $build['#post_render'][] = 'my_module_comment_post_render'; +} + +/** * The comment is being published by the moderator. * * @param $comment Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.800 diff -u -p -r1.800 comment.module --- modules/comment/comment.module 3 Nov 2009 06:47:22 -0000 1.800 +++ modules/comment/comment.module 4 Nov 2009 03:41:38 -0000 @@ -794,8 +794,6 @@ function comment_build($comment, stdClas '#node' => $node, '#build_mode' => $build_mode, ); - // Add contextual links for this comment. - $build['#contextual_links']['comment'] = menu_contextual_links('comment', array($comment->cid)); $prefix = ''; $is_threaded = isset($comment->divs) && variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED) == COMMENT_MODE_THREADED; @@ -819,6 +817,9 @@ function comment_build($comment, stdClas $build['#suffix'] = str_repeat('', $comment->divs_final); } + // Allow modules to modify the structured comment. + drupal_alter('comment_build', $build); + return $build; } @@ -857,9 +858,6 @@ function comment_build_content($comment, // Allow modules to make their own additions to the comment. module_invoke_all('comment_view', $comment, $build_mode); - - // Allow modules to modify the structured comment. - drupal_alter('comment_build', $comment, $build_mode); } /** Index: modules/menu/menu.module =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v retrieving revision 1.214 diff -u -p -r1.214 menu.module --- modules/menu/menu.module 1 Nov 2009 12:11:10 -0000 1.214 +++ modules/menu/menu.module 4 Nov 2009 03:41:38 -0000 @@ -427,7 +427,7 @@ function menu_block_view($delta = '') { $data['content'] = menu_tree($delta); // Add contextual links for this block. if (!empty($data['content'])) { - $data['content']['#contextual_links']['menu'] = menu_contextual_links('admin/structure/menu/manage', array($delta)); + $data['content']['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($delta)); } return $data; } @@ -440,7 +440,7 @@ function menu_block_view_alter(&$data, $ if ($block->module == 'system' && !empty($data['content'])) { $system_menus = menu_list_system_menus(); if (isset($system_menus[$block->delta])) { - $data['content']['#contextual_links']['menu'] = menu_contextual_links('admin/structure/menu/manage', array($block->delta)); + $data['content']['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($block->delta)); } } } Index: modules/node/node.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.api.php,v retrieving revision 1.42 diff -u -p -r1.42 node.api.php --- modules/node/node.api.php 1 Nov 2009 12:11:10 -0000 1.42 +++ modules/node/node.api.php 4 Nov 2009 03:41:38 -0000 @@ -542,7 +542,7 @@ function hook_node_view(stdClass $node, /** * The node content was built, the module may modify the structured content. * - * This hook is called after the content has been assembled in $node->content + * This hook is called after the content has been assembled in a structured array * and may be used for doing processing which requires that the complete node * content structure has been built. * @@ -551,20 +551,19 @@ function hook_node_view(stdClass $node, * Alternatively, it could also implement hook_preprocess_node(). See * drupal_render() and theme() documentation respectively for details. * - * @param $node - * The node the action is being performed on. - * @param $build_mode - * The $build_mode parameter from node_build(). + * @param $build + * A renderable array representing the node content. + * + * @see node_build() */ -function hook_node_build_alter(stdClass $node, $build_mode) { - // Check for the existence of a field added by another module. - if (isset($node->content['an_additional_field'])) { +function hook_node_build_alter($build) { + if ($build['#build_mode'] == 'full' && isset($build['an_additional_field'])) { // Change its weight. - $node->content['an_additional_field']['#weight'] = -10; + $build['an_additional_field']['#weight'] = -10; } // Add a #post_render callback to act on the rendered HTML of the node. - $node->content['#post_render'][] = 'my_module_node_post_render'; + $build['#post_render'][] = 'my_module_node_post_render'; } /** Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1161 diff -u -p -r1.1161 node.module --- modules/node/node.module 3 Nov 2009 06:47:22 -0000 1.1161 +++ modules/node/node.module 4 Nov 2009 06:07:15 -0000 @@ -1148,7 +1148,10 @@ function node_build($node, $build_mode = '#build_mode' => $build_mode, ); // Add contextual links for this node. - $build['#contextual_links']['node'] = menu_contextual_links('node', array($node->nid)); + $build['#contextual_links']['node'] = array('node', array($node->nid)); + + // Allow modules to modify the structured node. + drupal_alter('node_build', $build); return $build; } @@ -1210,9 +1213,6 @@ function node_build_content(stdClass $no // Allow modules to make their own additions to the node. module_invoke_all('node_view', $node, $build_mode); - - // Allow modules to modify the structured node. - drupal_alter('node_build', $node, $build_mode); } /** @@ -1544,8 +1544,10 @@ function node_search_execute($keys = NUL foreach ($find as $item) { // Render the node. $node = node_load($item->sid); - node_build_content($node, 'search_result'); - $node->rendered = drupal_render($node->content); + $build = node_build($node, 'search_result'); + unset($build['#theme']); + unset($build['#theme_wrappers']); + $node->rendered = drupal_render($build); // Fetch comments for snippet. $node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node); @@ -2033,16 +2035,18 @@ function node_feed($nids = FALSE, $chann // The node gets built and modules add to or modify $node->rss_elements // and $node->rss_namespaces. - node_build_content($node, 'rss'); + $build = node_build($node, 'rss'); + unset($build['#theme']); + unset($build['#theme_wrappers']); if (!empty($node->rss_namespaces)) { $namespaces = array_merge($namespaces, $node->rss_namespaces); } - if ($item_length != 'title' && !empty($node->content)) { + if ($item_length != 'title') { // We render node contents and force links to be last. - $links = drupal_render($node->content['links']); - $item_text .= drupal_render($node->content) . $links; + $build['links']['#weight'] = 1000; + $item_text .= drupal_render($build); } $items .= format_rss_item($node->title[FIELD_LANGUAGE_NONE][0]['value'], $node->link, $item_text, $node->rss_elements); @@ -2186,8 +2190,10 @@ function _node_index_node(stdClass $node variable_set('node_cron_last', $node->changed); // Render the node. - node_build_content($node, 'search_index'); - $node->rendered = drupal_render($node->content); + $build = node_build($node, 'search_index'); + unset($build['#theme']); + unset($build['#theme_wrappers']); + $node->rendered = drupal_render($build); $text = '