? .completion.db ? drnr.tmproj ? files ? mw.patch ? sites/all/modules ? sites/default/files ? themes/garland/mw.patch Index: includes/theme.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/theme.inc,v retrieving revision 1.455 diff -u -F^f -p -r1.455 theme.inc --- includes/theme.inc 7 Dec 2008 09:32:58 -0000 1.455 +++ includes/theme.inc 7 Dec 2008 15:47:34 -0000 @@ -1978,29 +1978,29 @@ function template_preprocess_page(&$vari */ function template_preprocess_node(&$variables) { $node = $variables['node']; - if (module_exists('taxonomy')) { - $variables['taxonomy'] = taxonomy_link('taxonomy terms', $node); - } - else { - $variables['taxonomy'] = array(); - } - - if ($variables['teaser'] && $node->teaser) { - $variables['content'] = $node->teaser; - } - elseif (isset($node->body)) { - $variables['content'] = $node->body; - } - else { - $variables['content'] = ''; - } $variables['date'] = format_date($node->created); - $variables['links'] = !empty($node->links) ? theme('links', $node->links, array('class' => 'links inline')) : ''; $variables['name'] = theme('username', $node); $variables['node_url'] = url('node/' . $node->nid); - $variables['terms'] = theme('links', $variables['taxonomy'], array('class' => 'links inline')); $variables['title'] = check_plain($node->title); + + if ($node->build_mode == NODE_BUILD_PREVIEW) { + unset($node->content['links']); + } + + // Render taxonomy links separately. + $variables['terms'] = !empty($node->taxonomy) ? drupal_render($node->content['links']['terms']) : ''; + + // Render all remaining node links. + $variables['links'] = !empty($node->content['links']) ? drupal_render($node->content['links']) : ''; + + // Render the rest of the node into $content. + if (!empty($node->content['teaser'])) { + $variables['content'] = drupal_render($node->content['teaser']); + } + else { + $variables['content'] = drupal_render($node->content); + } // Flatten the node object's member fields. $variables = array_merge((array)$node, $variables); Index: modules/blog/blog.module =================================================================== RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v retrieving revision 1.312 diff -u -F^f -p -r1.312 blog.module --- modules/blog/blog.module 1 Nov 2008 18:23:12 -0000 1.312 +++ modules/blog/blog.module 7 Dec 2008 15:47:34 -0000 @@ -94,22 +94,22 @@ function blog_view($node, $teaser = FALS } /** - * Implementation of hook_link(). + * Implementation of hook_nodeapi_view. */ -function blog_link($type, $node = NULL, $teaser = FALSE) { - $links = array(); - - if ($type == 'node' && $node->type == 'blog') { +function blog_nodeapi_view($node, $teaser = FALSE) { + if ($node->type == 'blog') { if (arg(0) != 'blog' || arg(1) != $node->uid) { $links['blog_usernames_blog'] = array( 'title' => t("!username's blog", array('!username' => $node->name)), 'href' => "blog/$node->uid", 'attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' => $node->name))), ); + $node->content['links']['blog'] = array( + '#type' => 'node_links', + '#value' => $links, + ); } } - - return $links; } /** Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.476 diff -u -F^f -p -r1.476 book.module --- modules/book/book.module 5 Dec 2008 22:18:44 -0000 1.476 +++ modules/book/book.module 7 Dec 2008 15:47:34 -0000 @@ -61,12 +61,12 @@ function book_perm() { } /** - * Implementation of hook_link(). + * Inject links into $node as needed. */ -function book_link($type, $node = NULL, $teaser = FALSE) { +function book_nodeapi_view_link($node, $teaser) { $links = array(); - - if ($type == 'node' && isset($node->book)) { + + if (isset($node->book['depth'])) { if (!$teaser) { $child_type = variable_get('book_child_type', 'book'); if ((user_access('add content to books') || user_access('administer book outlines')) && node_access('create', $child_type) && $node->status == 1 && $node->book['depth'] < MENU_MAX_DEPTH) { @@ -87,7 +87,12 @@ function book_link($type, $node = NULL, } } - return $links; + if (!empty($links)) { + $node->content['links']['book'] = array( + '#type' => 'node_links', + '#value' => $links, + ); + } } /** @@ -732,6 +737,8 @@ function book_nodeapi_view(&$node, $teas } } } + + book_nodeapi_view_link($node, $teaser, $page); } /** Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.669 diff -u -F^f -p -r1.669 comment.module --- modules/comment/comment.module 5 Dec 2008 22:18:44 -0000 1.669 +++ modules/comment/comment.module 7 Dec 2008 15:47:35 -0000 @@ -412,16 +412,16 @@ function theme_comment_block() { } /** - * Implementation of hook_link(). + * An implementation of hook_nodeapi_view(). */ -function comment_link($type, $node = NULL, $teaser = FALSE) { +function comment_nodeapi_view($node, $teaser, $page) { $links = array(); - if ($type == 'node' && $node->comment) { + if ($node->comment) { if ($teaser) { // Main page: display the number of comments that have been posted. if (user_access('access comments')) { - if ($node->comment_count) { + if (!empty($node->comment_count)) { $links['comment_comments'] = array( 'title' => format_plural($node->comment_count, '1 comment', '@count comments'), 'href' => "node/$node->nid", @@ -476,17 +476,16 @@ function comment_link($type, $node = NUL } } } - } - - if ($type == 'comment') { - $links = comment_links($node, $teaser); - } + + if (isset($links['comment_forbidden'])) { + $links['comment_forbidden']['html'] = TRUE; + } - if (isset($links['comment_forbidden'])) { - $links['comment_forbidden']['html'] = TRUE; + $node->content['links']['comment'] = array( + '#type' => 'node_links', + '#value' => $links, + ); } - - return $links; } /** @@ -864,6 +863,14 @@ function comment_save($edit) { } } +// An implementation of hook_link(). +function comment_link($type, $object, $teaser) { + if ($type == 'comment') { + $links = comment_links($object, FALSE); + return $links; + } +} + /** * Build command links for a comment (e.g.\ edit, reply, delete) with respect to the current user's access permissions. * @@ -1005,7 +1012,7 @@ function comment_render($node, $cid = 0) $mode = _comment_get_display_setting('mode', $node); $comments_per_page = _comment_get_display_setting('comments_per_page', $node); - if ($cid && is_numeric($cid)) { + if (!empty($node->cid)) { // Single comment view. $query = db_select('comment', 'c'); $query->fields('c', array('cid', 'nid', 'pid', 'comment', 'subject', 'format', 'timestamp', 'name', 'mail', 'homepage', 'status') ); Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1001 diff -u -F^f -p -r1.1001 node.module --- modules/node/node.module 5 Dec 2008 22:18:45 -0000 1.1001 +++ modules/node/node.module 7 Dec 2008 15:47:35 -0000 @@ -138,6 +138,9 @@ function node_theme() { 'node_admin_overview' => array( 'arguments' => array('name' => NULL, 'type' => NULL), ), + 'node_links' => array( + 'arguments' => array('element' => NULL), + ), ); } @@ -1134,31 +1137,11 @@ function node_delete($nid) { * @return * An HTML representation of the themed node. */ -function node_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) { +function node_view($node, $teaser = FALSE, $page = FALSE) { $node = (object)$node; $node = node_build_content($node, $teaser, $page); - if ($links) { - $node->links = module_invoke_all('link', 'node', $node, $teaser); - drupal_alter('link', $node->links, $node); - } - - // Set the proper node part, then unset unused $node part so that a bad - // theme can not open a security hole. - $content = drupal_render($node->content); - if ($teaser) { - $node->teaser = $content; - unset($node->body); - } - else { - $node->body = $content; - unset($node->teaser); - } - - // Allow modules to modify the fully-built node. - node_invoke_nodeapi($node, 'alter', $teaser, $page); - return theme('node', $node, $teaser, $page); } @@ -1221,6 +1204,9 @@ function node_build_content($node, $teas // Allow modules to make their own additions to the node. node_invoke_nodeapi($node, 'view', $teaser, $page); + + // Allow modules to modify the structured node. + drupal_alter('node_view', $node, $teaser, $page); return $node; } @@ -1232,6 +1218,7 @@ function node_show($node, $cid, $message if ($message) { drupal_set_title(t('Revision of %title from %date', array('%title' => $node->title, '%date' => format_date($node->revision_timestamp))), PASS_THROUGH); } + $output = node_view($node, FALSE, TRUE); if (function_exists('comment_render') && $node->comment) { @@ -3000,3 +2987,27 @@ function node_list_permissions($type) { return $perms; } + +/** + * Implementation of hook_elements(). + */ +function node_elements() { + $type['node_links'] = array(); + + return $type; +} + +/** + * Format a set of node links. + * + * @param $element + * An associative array containing the properties of the element. + * Properties used: value + * @return + * A themed HTML string representing the links. + * + * @ingroup themeable + */ +function theme_node_links($element) { + return theme('links', $element['#value'], array('class' => 'links inline')); +} \ No newline at end of file Index: modules/node/node.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v retrieving revision 1.46 diff -u -F^f -p -r1.46 node.pages.inc --- modules/node/node.pages.inc 3 Dec 2008 16:32:22 -0000 1.46 +++ modules/node/node.pages.inc 7 Dec 2008 15:47:35 -0000 @@ -415,12 +415,12 @@ function theme_node_preview($node) { if ($preview_trimmed_version) { drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication. You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split.')); $output .= '

' . t('Preview trimmed version') . '

'; - $output .= node_view(clone $node, 1, FALSE, 0); + $output .= node_view(clone $node, 1, FALSE); $output .= '

' . t('Preview full version') . '

'; - $output .= node_view($node, 0, FALSE, 0); + $output .= node_view($node, 0, FALSE); } else { - $output .= node_view($node, 0, FALSE, 0); + $output .= node_view($node, 0, FALSE); } $output .= "\n"; Index: modules/statistics/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v retrieving revision 1.287 diff -u -F^f -p -r1.287 statistics.module --- modules/statistics/statistics.module 2 Dec 2008 21:24:34 -0000 1.287 +++ modules/statistics/statistics.module 7 Dec 2008 15:47:35 -0000 @@ -96,20 +96,23 @@ function statistics_perm() { } /** - * Implementation of hook_link(). + * Implementation of hook_nodeapi_view(). */ -function statistics_link($type, $node = NULL, $teaser = FALSE) { +function statistics_nodeapi_view($node, $teaser, $page) { global $id; $links = array(); - if ($type != 'comment' && user_access('view post access counter')) { + if (user_access('view post access counter')) { $statistics = statistics_get($node->nid); if ($statistics) { $links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads'); } } - - return $links; + + $node->content['links']['statistics'] = array( + '#type' => 'node_links', + '#value' => $links, + ); } /** @@ -244,9 +247,8 @@ function statistics_get($nid) { if ($nid > 0) { // Retrieve an array with both totalcount and daycount. $statistics = db_fetch_array(db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = %d', $nid)); + return $statistics; } - - return $statistics; } /** Index: modules/system/system.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v retrieving revision 1.2 diff -u -F^f -p -r1.2 system.api.php --- modules/system/system.api.php 3 Dec 2008 16:32:22 -0000 1.2 +++ modules/system/system.api.php 7 Dec 2008 15:47:35 -0000 @@ -322,7 +322,7 @@ function hook_image_toolkits() { * Define internal Drupal links. * * This hook enables modules to add links to many parts of Drupal. Links - * may be added in nodes or in the navigation block, for example. + * may be added in the navigation block, for example. * * The returned array should be a keyed array of link entries. Each link can * be in one of two formats. @@ -345,11 +345,10 @@ function hook_image_toolkits() { * An identifier declaring what kind of link is being requested. * Possible values: * - comment: Links to be placed below a comment being viewed. - * - node: Links to be placed below a node being viewed. * @param $object - * A node object or a comment object according to the $type. + * A comment object. * @param $teaser - * In case of node link: a 0/1 flag depending on whether the node is + * A 0/1 flag depending on whether the node is * displayed with its teaser or its full form. * @return * An array of the requested links. @@ -358,46 +357,16 @@ function hook_image_toolkits() { function hook_link($type, $object, $teaser = FALSE) { $links = array(); - if ($type == 'node' && isset($object->parent)) { - if (!$teaser) { - if (book_access('create', $object)) { - $links['book_add_child'] = array( - 'title' => t('add child page'), - 'href' => "node/add/book/parent/$object->nid", - ); - } - if (user_access('see printer-friendly version')) { - $links['book_printer'] = array( - 'title' => t('printer-friendly version'), - 'href' => 'book/export/html/' . $object->nid, - 'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.')) - ); - } - } - } - - $links['sample_link'] = array( - 'title' => t('go somewhere'), - 'href' => 'node/add', - 'query' => 'foo=bar', - 'fragment' => 'anchorname', - 'attributes' => array('title' => t('go to another page')), - ); - - // Example of a link that's not an anchor - if ($type == 'video') { - if (variable_get('video_playcounter', 1) && user_access('view play counter')) { - $links['play_counter'] = array( - 'title' => format_plural($object->play_counter, '1 play', '@count plays'), - ); - } + if ($type == 'comment') { + $links = comment_links($object, FALSE); + return $links; } return $links; } /** - * Perform alterations before links on a node are rendered. One popular use of + * Perform alterations before links on a comment are rendered. One popular use of * this hook is to add/delete links from other modules. * * @param $links Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.445 diff -u -F^f -p -r1.445 taxonomy.module --- modules/taxonomy/taxonomy.module 5 Dec 2008 22:18:46 -0000 1.445 +++ modules/taxonomy/taxonomy.module 7 Dec 2008 15:47:36 -0000 @@ -39,57 +39,45 @@ function taxonomy_theme() { } /** - * Implementation of hook_link(). - * - * This hook is extended with $type = 'taxonomy terms' to allow themes to - * print lists of terms associated with a node. Themes can print taxonomy - * links with: - * - * if (module_exists('taxonomy')) { - * $terms = taxonomy_link('taxonomy terms', $node); - * print theme('links', $terms); - * } - */ -function taxonomy_link($type, $node = NULL) { - if ($type == 'taxonomy terms' && $node != NULL) { - $links = array(); - // If previewing, the terms must be converted to objects first. - if (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW) { - $node->taxonomy = taxonomy_preview_terms($node); - } - if (!empty($node->taxonomy)) { - foreach ($node->taxonomy as $term) { - // During preview the free tagging terms are in an array unlike the - // other terms which are objects. So we have to check if a $term - // is an object or not. - if (is_object($term)) { - $links['taxonomy_term_' . $term->tid] = array( - 'title' => $term->name, - 'href' => taxonomy_term_path($term), - 'attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description)) - ); - } - // Previewing free tagging terms; we don't link them because the - // term-page might not exist yet. - else { - foreach ($term as $free_typed) { - $typed_terms = drupal_explode_tags($free_typed); - foreach ($typed_terms as $typed_term) { - $links['taxonomy_preview_term_' . $typed_term] = array( - 'title' => $typed_term, - ); - } + * An implementation of hook_nodeapi_view(). + */ +function taxonomy_nodeapi_view($node) { + $links = array(); + // If previewing, the terms must be converted to objects first. + if (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW) { + $node->taxonomy = taxonomy_preview_terms($node); + } + if (!empty($node->taxonomy)) { + foreach ($node->taxonomy as $term) { + // During preview the free tagging terms are in an array unlike the + // other terms which are objects. So we have to check if a $term + // is an object or not. + if (is_object($term)) { + $links['taxonomy_term_' . $term->tid] = array( + 'title' => $term->name, + 'href' => taxonomy_term_path($term), + 'attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description)) + ); + } + // Previewing free tagging terms; we don't link them because the + // term-page might not exist yet. + else { + foreach ($term as $free_typed) { + $typed_terms = drupal_explode_tags($free_typed); + foreach ($typed_terms as $typed_term) { + $links['taxonomy_preview_term_' . $typed_term] = array( + 'title' => $typed_term, + ); } } } } - - // We call this hook again because some modules and themes - // call taxonomy_link('taxonomy terms') directly. - drupal_alter('link', $links, $node); - - return $links; } + + $node->content['links']['terms'] = array( + '#type' => 'node_links', + '#value' => $links + ); } /** Index: modules/translation/translation.module =================================================================== RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v retrieving revision 1.34 diff -u -F^f -p -r1.34 translation.module --- modules/translation/translation.module 11 Nov 2008 16:49:38 -0000 1.34 +++ modules/translation/translation.module 7 Dec 2008 15:47:36 -0000 @@ -158,14 +158,13 @@ function translation_form_alter(&$form, } /** - * Implementation of hook_link(). + * Implementation of hook_nodeapi_view(). * * Display translation links with native language names, if this node * is part of a translation set. */ -function translation_link($type, $node = NULL, $teaser = FALSE) { - $links = array(); - if ($type == 'node' && ($node->tnid) && $translations = translation_node_get_translations($node->tnid)) { +function translation_nodeapi_view(&$node, $teaser = FALSE) { + if (isset($node->tnid) && $translations = translation_node_get_translations($node->tnid)) { // Do not show link to the same node. unset($translations[$node->language]); $languages = language_list(); @@ -177,10 +176,13 @@ function translation_link($type, $node = 'language' => $language, 'attributes' => array('title' => $translations[$langcode]->title, 'class' => 'translation-link') ); + $node->content['links']['translation'] = array( + '#type' => 'node_links', + '#value' => $links, + ); } } } - return $links; } /** Index: modules/upload/upload.module =================================================================== RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v retrieving revision 1.219 diff -u -F^f -p -r1.219 upload.module --- modules/upload/upload.module 5 Dec 2008 22:18:46 -0000 1.219 +++ modules/upload/upload.module 7 Dec 2008 15:47:36 -0000 @@ -56,13 +56,13 @@ function upload_perm() { } /** - * Implementation of hook_link(). + * Inject links into $node for attachments. */ -function upload_link($type, $node = NULL, $teaser = FALSE) { +function upload_nodeapi_links($node, $teaser) { $links = array(); // Display a link with the number of attachments - if ($teaser && $type == 'node' && isset($node->files) && user_access('view uploaded files')) { + if ($teaser && isset($node->files) && user_access('view uploaded files')) { $num_files = 0; foreach ($node->files as $file) { if ($file->list) { @@ -76,10 +76,12 @@ function upload_link($type, $node = NULL 'attributes' => array('title' => t('Read full article to view attachments.')), 'fragment' => 'attachments' ); + $node->content['links']['upload_attachments'] = array( + '#type' => 'node_links', + '#value' => $links, + ); } } - - return $links; } /** @@ -323,6 +325,8 @@ function upload_nodeapi_view(&$node, $te ); } } + + upload_nodeapi_links($node, $teaser); } } Index: modules/upload/upload.test =================================================================== RCS file: /cvs/drupal/drupal/modules/upload/upload.test,v retrieving revision 1.8 diff -u -F^f -p -r1.8 upload.test --- modules/upload/upload.test 25 Nov 2008 13:14:29 -0000 1.8 +++ modules/upload/upload.test 7 Dec 2008 15:47:36 -0000 @@ -44,12 +44,17 @@ class UploadTestCase extends DrupalWebTe $this->uploadFile($node, $files[0]); $this->uploadFile($node, $files[1]); - // Check to see that uploaded file is listed and actually accessible. + // Check to see that uploaded file is listed in detail page and actually accessible. $this->assertText(basename($files[0]), basename($files[0]) . ' found on node.'); $this->assertText(basename($files[1]), basename($files[1]) . ' found on node.'); $this->checkUploadedFile(basename($files[0])); $this->checkUploadedFile(basename($files[1])); + + // Assure that the attachment link appears on teaser view and has correct count. + $node = node_load($node->nid); + $teaser = node_view($node, TRUE); + $this->assertTrue(strpos($teaser, format_plural(2, '1 attachment', '@count attachments')), 'Attachments link found on node teaser.'); // Fetch db record and use fid to rename and delete file. $upload = db_fetch_object(db_query('SELECT fid, description FROM {upload} WHERE nid = %d', array($node->nid))); Index: themes/chameleon/chameleon.theme =================================================================== RCS file: /cvs/drupal/drupal/themes/chameleon/chameleon.theme,v retrieving revision 1.81 diff -u -F^f -p -r1.81 chameleon.theme --- themes/chameleon/chameleon.theme 24 Nov 2008 15:27:12 -0000 1.81 +++ themes/chameleon/chameleon.theme 7 Dec 2008 15:47:36 -0000 @@ -133,21 +133,23 @@ function chameleon_node($node, $teaser = $output .= " \n"; - $submitted['node_submitted'] = theme_get_setting("toggle_node_info_$node->type") ? array( - 'title' => t("By !author at @date", array('!author' => theme('username', $node), '@date' => format_date($node->created, 'small'))), - 'html' => TRUE) : array(); - - $terms = array(); - if (module_exists('taxonomy')) { - $terms = taxonomy_link("taxonomy terms", $node); + $submitted = ''; + if (theme_get_setting("toggle_node_info_$node->type")) { + $submitted = t("By !author at @date", array('!author' => theme('username', $node), '@date' => format_date($node->created, 'small'))); } - $links = array_merge($submitted, $terms); - if (isset($node->links)) { - $links = array_merge($links, $node->links); + $terms = ''; + if ($node->taxonomy) { + $terms = drupal_render($node->content['links']['taxonomy']); + } + + $links = ''; + if ($node->content['links']) { + $links = drupal_render($node->content['links']); } - if (count($links)) { - $output .= '\n"; + + if (!empty($terms) || !empty($links)) { + $output .= '\n"; } $output .= "\n"; @@ -160,7 +162,7 @@ function chameleon_comment($comment, $no 'title' => t('By !author at @date', array('!author' => theme('username', $comment), '@date' => format_date($comment->timestamp, 'small'))), 'html' => TRUE); - $output = "
\n"; + $output = "
status . "\">\n"; $output .= "

" . l($comment->subject, $_GET['q'], array('fragment' => "comment-$comment->cid")) . "

\n"; $output .= "
" . $comment->comment; if (!empty($signature)) {