views_rss.module

Tracking 5.x-1.x branch
  1. drupal
    1. 5 contributions/views/views_rss.module

Functions & methods

NameDescription
theme_views_rss_feedplugin that actually displays an RSS feed
views_handler_arg_rss_feedhandler for our own RSS argument; mimics the feed selector
views_rss_views_argumentsWhile we support the global selector, some might want to allow ONLY RSS feeds so we support a stingy selector too
views_rss_views_feed_argumentfeed argument hook that will convert us to RSS or display an icon. the 4th argument isn't part of the hook, but we use it to differentiate when called as a hook or when called manually from views_rss_views_post_view
views_rss_views_post_viewpost view for our own op -- mimics the feed selector
views_rss_views_style_pluginsProvide views plugins for the feed types we support.

File

View source
  1. <?php
  2. /**
  3. * Provide views plugins for the feed types we support.
  4. */
  5. function views_rss_views_style_plugins() {
  6. return array(
  7. 'views_rss' => array(
  8. 'name' => t('Views RSS: RSS feed'),
  9. 'theme' => 'views_rss_feed',
  10. 'needs_table_header' => TRUE,
  11. 'needs_fields' => TRUE,
  12. 'even_empty' => TRUE,
  13. ),
  14. );
  15. }
  16. /**
  17. * While we support the global selector, some might want to allow
  18. * ONLY RSS feeds so we support a stingy selector too
  19. */
  20. function views_rss_views_arguments() {
  21. $arguments = array(
  22. 'rss_feed' => array(
  23. 'name' => t('RSS: RSS Feed Selector'),
  24. 'handler' => 'views_handler_arg_rss_feed',
  25. 'option' => 'string',
  26. 'help' => t('This argument specifies a specific RSS feed selector; it will only select RSS feeds, unlike the built-in selector which can select pluggable feeds. You may enter the title the feed will advertise in the title field here, and the description of the feed in the option field here.'),
  27. ),
  28. );
  29. return $arguments;
  30. }
  31. /**
  32. * handler for our own RSS argument; mimics the feed selector
  33. */
  34. function views_handler_arg_rss_feed($op, &$query, $argtype, $arg = '') {
  35. switch($op) {
  36. case 'summary':
  37. case 'sort':
  38. case 'link':
  39. case 'title':
  40. break;
  41. case 'filter':
  42. // This is a clone of the default selector, but it just invokes ours
  43. // rather than calling all of them.
  44. views_rss_views_feed_argument('argument', $GLOBALS['current_view'], $arg, $argtype);
  45. }
  46. }
  47. /**
  48. * post view for our own op -- mimics the feed selector
  49. */
  50. function views_rss_views_post_view($view, $items, $output) {
  51. foreach ($view->argument as $id => $argument) {
  52. if ($argument['type'] == 'rss_feed') {
  53. $feed = $id;
  54. break;
  55. }
  56. }
  57. if ($feed !== NULL) {
  58. return views_rss_views_feed_argument('post_view', $view, 'rss_feed');
  59. }
  60. }
  61. /**
  62. * feed argument hook that will convert us to RSS or display an icon.
  63. * the 4th argument isn't part of the hook, but we use it to differentiate
  64. * when called as a hook or when called manually from views_rss_views_post_view
  65. */
  66. function views_rss_views_feed_argument($op, &$view, $arg, $argdata = NULL) {
  67. if ($op == 'argument' && $arg == 'feed') {
  68. $view->page_type = 'views_rss';
  69. if ($argdata['options']) {
  70. $view->description = $argdata['options'];
  71. }
  72. // reset the 'real url' to the URL without the feed argument.
  73. $view_args = array();
  74. $max = count($view->args);
  75. foreach ($view->args as $id => $view_arg) {
  76. ++$count;
  77. if ($view_arg == $arg && $view->argument[$id]['id'] == $argdata['id']) {
  78. if ($count != $max) {
  79. $view_args[] = $argdata['wildcard'];
  80. }
  81. }
  82. else {
  83. $view_args[] = $view_arg;
  84. }
  85. }
  86. $view->feed_url = views_get_url($view, $view_args);
  87. }
  88. else if ($op == 'post_view' && $view->build_type != 'block') {
  89. $args = views_post_view_make_args($view, $arg, 'feed');
  90. $url = views_get_url($view, $args);
  91. $title = views_get_title($view, 'page', $args);
  92. if ($view->used_filters) {
  93. $filters = drupal_query_string_encode($view->used_filters);
  94. }
  95. drupal_add_feed(url($url, $filters), $title);
  96. }
  97. }
  98. /**
  99. * plugin that actually displays an RSS feed
  100. */
  101. function theme_views_rss_feed($view, $nodes, $type) {
  102. if ($type == 'block') {
  103. return;
  104. }
  105. global $base_url;
  106. $channel = array(
  107. // a check_plain isn't required on these because format_rss_channel
  108. // already does this.
  109. 'title' => views_get_title($view, 'page'),
  110. 'link' => url($view->feed_url ? $view->feed_url : $view->real_url, NULL, NULL, true),
  111. 'description' => $view->description,
  112. );
  113. $item_length = variable_get('feed_item_length', 'teaser');
  114. $namespaces = array('xmlns:dc="http://purl.org/dc/elements/1.1/"');
  115. // Except for the original being a while and this being a foreach, this is
  116. // completely cut & pasted from node.module.
  117. foreach ($nodes as $node) {
  118. // Load the specified node:
  119. $item = node_load($node->nid);
  120. $link = url("node/$node->nid", NULL, NULL, 1);
  121. if ($item_length != 'title') {
  122. $teaser = ($item_length == 'teaser') ? TRUE : FALSE;
  123. // Filter and prepare node teaser
  124. if (node_hook($item, 'view')) {
  125. node_invoke($item, 'view', $teaser, FALSE);
  126. }
  127. else {
  128. $item = node_prepare($item, $teaser);
  129. }
  130. // Allow modules to change $node->teaser before viewing.
  131. node_invoke_nodeapi($item, 'view', $teaser, FALSE);
  132. }
  133. // Allow modules to add additional item fields
  134. $extra = node_invoke_nodeapi($item, 'rss item');
  135. $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' => date('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))));
  136. foreach ($extra as $element) {
  137. if ($element['namespace']) {
  138. $namespaces = array_merge($namespaces, $element['namespace']);
  139. }
  140. }
  141. // Prepare the item description
  142. switch ($item_length) {
  143. case 'fulltext':
  144. $item_text = $item->body;
  145. break;
  146. case 'teaser':
  147. $item_text = $item->teaser;
  148. if ($item->readmore) {
  149. $item_text .= '<p>'. l(t('read more'), 'node/'. $item->nid, NULL, NULL, NULL, TRUE) .'</p>';
  150. }
  151. break;
  152. case 'title':
  153. $item_text = '';
  154. break;
  155. }
  156. $items .= format_rss_item($item->title, $link, $item_text, $extra);
  157. }
  158. $channel_defaults = array(
  159. 'version' => '2.0',
  160. 'title' => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
  161. 'link' => $base_url,
  162. 'description' => variable_get('site_mission', ''),
  163. 'language' => $GLOBALS['locale'],
  164. );
  165. $channel = array_merge($channel_defaults, $channel);
  166. $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
  167. $output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\" ". implode(' ', $namespaces) .">\n";
  168. $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
  169. $output .= "</rss>\n";
  170. drupal_set_header('Content-Type: text/xml; charset=utf-8');
  171. print $output;
  172. module_invoke_all('exit');
  173. exit;
  174. }