diff options
-rw-r--r-- | modules/blog/blog.module | 4 | ||||
-rw-r--r-- | modules/book/book.module | 4 | ||||
-rw-r--r-- | modules/comment/comment.module | 21 | ||||
-rw-r--r-- | modules/node/node.api.php | 39 | ||||
-rw-r--r-- | modules/node/node.module | 76 | ||||
-rw-r--r-- | modules/node/node.test | 25 | ||||
-rw-r--r-- | modules/node/tests/node_test.module | 27 | ||||
-rw-r--r-- | modules/statistics/statistics.module | 24 | ||||
-rw-r--r-- | modules/taxonomy/taxonomy.module | 55 | ||||
-rw-r--r-- | modules/upload/upload.module | 96 |
10 files changed, 177 insertions, 194 deletions
diff --git a/modules/blog/blog.module b/modules/blog/blog.module index 884372f02..b5ac2cae9 100644 --- a/modules/blog/blog.module +++ b/modules/blog/blog.module @@ -97,8 +97,8 @@ function blog_view($node, $teaser) { * Implementation of hook_node_view. */ function blog_node_view($node, $teaser = FALSE) { - if ($node->type == 'blog') { - if (arg(0) != 'blog' || arg(1) != $node->uid) { + if ($node->build_mode != NODE_BUILD_RSS) { + if ($node->type == 'blog' && 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", diff --git a/modules/book/book.module b/modules/book/book.module index 888324bb9..815442677 100644 --- a/modules/book/book.module +++ b/modules/book/book.module @@ -715,7 +715,9 @@ function book_node_view($node, $teaser) { } } - book_node_view_link($node, $teaser); + if ($node->build_mode != NODE_BUILD_RSS) { + book_node_view_link($node, $teaser); + } } /** diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 22962b06f..0a59cde46 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -423,7 +423,14 @@ function comment_node_view($node, $teaser) { $links = array(); if ($node->comment) { - if ($teaser) { + if ($node->build_mode == NODE_BUILD_RSS) { + // Add a comments RSS element which is a URL to the comments of this node. + $node->rss_elements[] = array( + 'key' => 'comments', + 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE)) + ); + } + else if ($teaser) { // Main page: display the number of comments that have been posted. if (user_access('access comments')) { if (!empty($node->comment_count)) { @@ -731,18 +738,6 @@ function comment_node_search_result($node) { } /** - * Implementation of hook_node_rss_item(). - */ -function comment_node_rss_item($node) { - if ($node->comment != COMMENT_NODE_HIDDEN) { - return array(array('key' => 'comments', 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE)))); - } - else { - return array(); - } -} - -/** * Implementation of hook_user_cancel(). */ function comment_user_cancel($edit, $account, $method) { diff --git a/modules/node/node.api.php b/modules/node/node.api.php index 65446cad9..39da26ea4 100644 --- a/modules/node/node.api.php +++ b/modules/node/node.api.php @@ -287,28 +287,6 @@ function hook_node_prepare_translation($node) { } /** - * An RSS feed is being generated. - * - * The module can return properties to be added to the RSS item generated for - * this node. This hook should only be used to add XML elements to the RSS - * feed item itself. See comment_node_rss_item() and upload_node_rss_item() - * for examples. - * - * @param $node - * The node the action is being performed on. - * @return - * Extra information to be added to the RSS item. - */ -function hook_node_rss_item($node) { - if ($node->comment != COMMENT_NODE_HIDDEN) { - return array(array('key' => 'comments', 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE)))); - } - else { - return array(); - } -} - -/** * The node is being displayed as a search result. * * If you want to display extra information with the result, return it. @@ -401,9 +379,20 @@ function hook_node_validate($node, $form) { /** * The node content is being assembled before rendering. * - * The module may add elements $node->content prior to rendering. This hook - * will be called after hook_view(). The structure of $node->content is a renderable - * array as expected by drupal_render(). + * TODO D7 This needs work to clearly explain the different build modes. + * + * The module may add elements to $node->content prior to rendering. This hook + * will be called after hook_view(). The structure of $node->content is a + * renderable array as expected by drupal_render(). + * + * When $node->build_mode is NODE_BUILD_RSS modules can also add extra RSS + * elements and namespaces to $node->rss_elements and $node->rss_namespaces + * respectively for the RSS item generated for this node. For details on how + * this is used @see node_feed() + * + * @see taxonomy_node_view() + * @see upload_node_view() + * @see comment_node_view() * * @param $node * The node the action is being performed on. diff --git a/modules/node/node.module b/modules/node/node.module index 92a088871..b557a56cb 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -1950,70 +1950,38 @@ function node_feed($nids = FALSE, $channel = array()) { $item_length = variable_get('feed_item_length', 'teaser'); $namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'); + $teaser = ($item_length == 'teaser'); // Load all nodes to be rendered. $nodes = node_load_multiple($nids); $items = ''; - foreach ($nodes as $item) { - $item->build_mode = NODE_BUILD_RSS; - $item->link = url("node/$item->nid", array('absolute' => TRUE)); - - if ($item_length != 'title') { - $teaser = ($item_length == 'teaser'); - - // Filter and prepare node teaser - if (node_hook($item, 'view')) { - $item = node_invoke($item, 'view', $teaser, FALSE); - } - else { - $item = node_prepare($item, $teaser); - } - - // Allow modules to change $node->content before the node is rendered. - module_invoke_all('node_view', $item, $teaser); - - // Set the proper node property, then unset unused $node property so that a - // bad theme can not open a security hole. - $content = drupal_render($item->content); - if ($teaser) { - $item->teaser = $content; - unset($item->body); - } - else { - $item->body = $content; - unset($item->teaser); - } + foreach ($nodes as $node) { + $item_text = ''; + + $node->build_mode = NODE_BUILD_RSS; + $node->link = url("node/$node->nid", array('absolute' => TRUE)); + $node->rss_namespaces = array(); + $node->rss_elements = array( + array('key' => 'pubDate', 'value' => gmdate('r', $node->created)), + array('key' => 'dc:creator', 'value' => $node->name), + array('key' => 'guid', 'value' => $node->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false')) + ); - // Allow modules to modify the fully-built node. - module_invoke_all('node_alter', $item, $teaser, FALSE); - } + // The node gets built and modules add to or modify $node->rss_elements + // and $node->rss_namespaces. + $node = node_build_content($node, $teaser); - // Allow modules to add additional item fields and/or modify $item - $extra = module_invoke_all('node_rss_item', $item); - $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' => gmdate('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false')))); - foreach ($extra as $element) { - if (isset($element['namespace'])) { - $namespaces = array_merge($namespaces, $element['namespace']); - } + if (!empty($node->rss_namespaces)) { + $namespaces = array_merge($namespaces, $node->rss_namespaces); } - // Prepare the item description - switch ($item_length) { - case 'fulltext': - $item_text = $item->body; - break; - case 'teaser': - $item_text = $item->teaser; - if (!empty($item->readmore)) { - $item_text .= '<p>' . l(t('read more'), 'node/' . $item->nid, array('absolute' => TRUE, 'attributes' => array('target' => '_blank'))) . '</p>'; - } - break; - case 'title': - $item_text = ''; - break; + if ($item_length != 'title' && !empty($node->content)) { + // We render node contents and force links to be last. + $links = drupal_render($node->content['links']); + $item_text .= drupal_render($node->content) . $links; } - $items .= format_rss_item($item->title, $item->link, $item_text, $extra); + $items .= format_rss_item($node->title, $node->link, $item_text, $node->rss_elements); } $channel_defaults = array( diff --git a/modules/node/node.test b/modules/node/node.test index 022b0cf78..cf2cb4802 100644 --- a/modules/node/node.test +++ b/modules/node/node.test @@ -658,10 +658,29 @@ class NodeRSSContentTestCase extends DrupalWebTestCase { // Create a node. $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); - $test_text = t('Extra test data added to node !nid.', array('!nid' => $node->nid)); - $this->drupalGet('rss.xml'); - $this->assertText($test_text, t('Extra node content appears in RSS feed.')); + + // Check that content added in NODE_BUILD_RSS appear in RSS feed. + $rss_only_content = t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->nid)); + $this->assertText($rss_only_content, t('Node content designated for RSS appear in RSS feed.')); + + // Check that content added in build modes other than NODE_BUILD_RSS doesn't + // appear in RSS feed. + $non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->nid)); + $this->assertNoText($non_rss_content, t('Node content not designed for RSS doesn\'t appear in RSS feed.')); + + // Check that extra RSS elements and namespaces are added to RSS feed. + $test_element = array( + 'key' => 'testElement', + 'value' => t('Value of testElement RSS element for node !nid.', array('!nid' => $node->nid)), + ); + $test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"'; + $this->assertRaw(format_xml_elements(array($test_element)), t('Extra RSS elements appear in RSS feed.')); + $this->assertRaw($test_ns, t('Extra namespaces appear in RSS feed.')); + + // Check that content added in NODE_BUILD_RSS doesn't appear when viewing node. + $this->drupalGet("node/$node->nid"); + $this->assertNoText($rss_only_content, t('Node content designed for RSS doesn\'t appear when viewing node.')); } } diff --git a/modules/node/tests/node_test.module b/modules/node/tests/node_test.module index d42172b6b..1ad3227ff 100644 --- a/modules/node/tests/node_test.module +++ b/modules/node/tests/node_test.module @@ -8,11 +8,28 @@ */ /** - * When the module is enabled, text will be added to all nodes in all build modes. + * Implementation of hook_node_view(). */ function node_test_node_view($node, $teaser) { - $node->content['node_test_extra_field'] = array( - '#markup' => '<p>' . t('Extra test data added to node !nid.', array('!nid' => $node->nid)) . '</p>', - '#weight' => 10, - ); + if ($node->build_mode == NODE_BUILD_RSS) { + // Add RSS elements and namespaces when building the RSS feed. + $node->rss_elements[] = array( + 'key' => 'testElement', + 'value' => t('Value of testElement RSS element for node !nid.', array('!nid' => $node->nid)), + ); + $node->rss_namespaces['xmlns:drupaltest'] = 'http://example.com/test-namespace'; + + // Add content that should be displayed only in the RSS feed. + $node->content['extra_feed_content'] = array( + '#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->nid)) . '</p>', + '#weight' => 10, + ); + } + + if ($node->build_mode != NODE_BUILD_RSS) { + // Add content that should NOT be displayed in the RSS feed. + $node->content['extra_non_feed_content'] = array( + '#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->nid)) . '</p>', + ); + } } diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module index f2a5a24de..ad876b97b 100644 --- a/modules/statistics/statistics.module +++ b/modules/statistics/statistics.module @@ -104,20 +104,20 @@ function statistics_perm() { * Implementation of hook_node_view(). */ function statistics_node_view($node, $teaser) { - global $id; - $links = array(); - - 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'); + if ($node->build_mode != NODE_BUILD_RSS) { + $links = array(); + 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'); + } } - } - $node->content['links']['statistics'] = array( - '#type' => 'node_links', - '#value' => $links, - ); + $node->content['links']['statistics'] = array( + '#type' => 'node_links', + '#value' => $links, + ); + } } /** diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module index d38357013..07d970551 100644 --- a/modules/taxonomy/taxonomy.module +++ b/modules/taxonomy/taxonomy.module @@ -39,12 +39,28 @@ function taxonomy_theme() { * An implementation of hook_node_view(). */ function taxonomy_node_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)) { + return; } - if (!empty($node->taxonomy)) { + + if ($node->build_mode == NODE_BUILD_RSS) { + // Provide category information for RSS feeds. + foreach ($node->taxonomy as $term) { + $node->rss_elements[] = array( + 'key' => 'category', + 'value' => $term->name, + 'attributes' => array('domain' => url(taxonomy_term_path($term), array('absolute' => TRUE))), + ); + } + } + else { + $links = array(); + + // If previewing, the terms must be converted to objects first. + if ($node->build_mode == NODE_BUILD_PREVIEW) { + $node->taxonomy = taxonomy_preview_terms($node); + } + 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 @@ -69,13 +85,13 @@ function taxonomy_node_view($node) { } } } - } - $node->content['links']['terms'] = array( - '#type' => 'node_links', - '#value' => $links, - '#sorted' => TRUE, - ); + $node->content['links']['terms'] = array( + '#type' => 'node_links', + '#value' => $links, + '#sorted' => TRUE, + ); + } } /** @@ -1590,23 +1606,6 @@ function taxonomy_node_validate($node, $form) { } /** - * Implementation of hook_node_rss_item(). - * - * Provides category information for RSS feeds. - */ -function taxonomy_node_rss_item($node) { - $output = array(); - foreach ($node->taxonomy as $term) { - $output[] = array( - 'key' => 'category', - 'value' => $term->name, - 'attributes' => array('domain' => url(taxonomy_term_path($term), array('absolute' => TRUE))), - ); - } - return $output; -} - -/** * Implementation of hook_node_update_index(). */ function taxonomy_node_update_index($node) { diff --git a/modules/upload/upload.module b/modules/upload/upload.module index a4406b11e..e71099b27 100644 --- a/modules/upload/upload.module +++ b/modules/upload/upload.module @@ -62,26 +62,24 @@ function upload_node_links($node, $teaser) { $links = array(); // Display a link with the number of attachments - if ($teaser && isset($node->files) && user_access('view uploaded files')) { - $num_files = 0; - foreach ($node->files as $file) { - if ($file->list) { - $num_files++; - } - } - if ($num_files) { - $links['upload_attachments'] = array( - 'title' => format_plural($num_files, '1 attachment', '@count attachments'), - 'href' => "node/$node->nid", - 'attributes' => array('title' => t('Read full article to view attachments.')), - 'fragment' => 'attachments' - ); - $node->content['links']['upload_attachments'] = array( - '#type' => 'node_links', - '#value' => $links, - ); + $num_files = 0; + foreach ($node->files as $file) { + if ($file->list) { + $num_files++; } } + if ($num_files) { + $links['upload_attachments'] = array( + 'title' => format_plural($num_files, '1 attachment', '@count attachments'), + 'href' => "node/$node->nid", + 'attributes' => array('title' => t('Read full article to view attachments.')), + 'fragment' => 'attachments' + ); + $node->content['links']['upload_attachments'] = array( + '#type' => 'node_links', + '#value' => $links, + ); + } } /** @@ -341,20 +339,45 @@ function upload_node_load($nodes, $types) { * Implementation of hook_node_view(). */ function upload_node_view($node, $teaser) { - if (isset($node->files) && user_access('view uploaded files')) { - // Add the attachments list to node body with a heavy - // weight to ensure they're below other elements. + if (!isset($node->files)) { + return; + } + + if (user_access('view uploaded files') && $node->build_mode != NODE_BUILD_RSS) { if (count($node->files)) { if (!$teaser) { + // Add the attachments list to node body with a heavy weight to ensure + // they're below other elements. $node->content['files'] = array( '#files' => $node->files, '#theme' => 'upload_attachments', '#weight' => 50, ); } + else { + upload_node_links($node, $teaser); + } } + } - upload_node_links($node, $teaser); + if ($node->build_mode == NODE_BUILD_RSS) { + // Add the first file as an enclosure to the RSS item. RSS allows only one + // enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure + foreach ($node->files as $file) { + if ($file->list) { + break; + } + } + if ($file->list) { + $node->rss_elements[] = array( + 'key' => 'enclosure', + 'attributes' => array( + 'url' => file_create_url($file->filepath), + 'length' => $file->filesize, + 'type' => $file->filemime + ) + ); + } } } @@ -410,35 +433,6 @@ function upload_node_search_result($node) { } /** - * Implementation of hook_node_rss_item(). - */ -function upload_node_rss_item($node) { - if (is_array($node->files)) { - $files = array(); - foreach ($node->files as $file) { - if ($file->list) { - $files[] = $file; - } - } - if (count($files) > 0) { - // RSS only allows one enclosure per item - $file = array_shift($files); - return array( - array( - 'key' => 'enclosure', - 'attributes' => array( - 'url' => file_create_url($file->filepath), - 'length' => $file->filesize, - 'type' => $file->filemime - ) - ) - ); - } - } - return array(); -} - -/** * Displays file attachments in table * * @ingroup themeable |