4 * Generates an RSS feed from a specially designed HTML container indicated
7 class XHTMLCompiler_DOMFilter_RSSGenerator
extends XHTMLCompiler_DOMFilter
10 protected $name = 'RSSGenerator';
11 protected $prefix = 'rss';
13 // new namespace defines the following attributes:
14 // for - IDREF to an element where we are to get the RSS info from
16 public function process(DOMDocument
$dom, $page, $manager) {
18 // attempt to find declarations of the namespace
19 $nodes = $this->query(
20 "//attribute::*[namespace-uri() = '".$this->ns
."']"
22 if (!$nodes->length
) return;
23 $manager->addDependency(__FILE__
);
25 // grab the document's links to RSS feeds
26 // we require that the link have a href, a title and a type
27 // as well as an rss:for attribute specifying where to grab data
28 $links = $this->query('//html:link[@rss:for]');
30 foreach ($links as $link) {
31 $this->generateRSS($dom, $link, $page);
37 * Generates the RSS feed for a specific link in a document
38 * @param $link <link> DOMElement we're generating feed for
39 * @param $page Page we're generating for
41 protected function generateRSS($dom, $link, $page) {
43 // retrieve web-path of the page
44 $path = $page->getWebPath();
45 $xc = XHTMLCompiler
::getInstance();
47 // generate RSS template
48 $rss = new XHTMLCompiler_RSSFeed(
49 $link->getAttribute('title'),
51 $this->confiscateAttr($link, $this->ns
, 'description'),
52 $lang = $dom->documentElement
->getAttribute('xml:lang')
55 // retrieve data source
56 $id = $this->confiscateAttr($link, $this->ns
, 'for');
57 $data_source = $dom->getElementById($id);
59 // parse data source, add news items
60 foreach ($data_source->childNodes
as $src_item) {
61 if (! $src_item instanceof DOMElement
) continue;
62 if ($src_item->getAttribute('class') !== 'item') continue;
64 $title = $date = $body = '';
65 foreach ($src_item->childNodes
as $element) {
66 if (! $element instanceof DOMElement
) continue;
67 $var = $element->getAttribute('class');
69 if (($node = $element->childNodes
->item(0)) instanceof DOMElement
) {
70 // If we are using human readable dates but
71 // non-parseable machine dates, an abbr
72 // element should be inside the element with class="date"
73 // with a class atNNN where NNN is the Unix timestamp
75 $datetime = new DateTime('@' . substr($node->getAttribute('class'), 2));
76 $date = $datetime->format('r');
78 $date = $element->textContent
;
80 } elseif ($var == 'permalink') {
81 $permalink = $element->childNodes
->item(0)->getAttribute('href');
82 } elseif ($var == 'title' ||
$var == 'body') {
83 $
$var = $element->textContent
;
87 if (isset($permalink)) {
88 // assume that the permalink is an absolute path
89 if ($permalink[0] !== '/') {
90 trigger_error("Permalink for '$title' is not absolute");
93 $article_link = 'http://' . $xc->getConf('web_domain') . $permalink;
95 // determine the article link, based off anchors
96 $item_id = $src_item->getAttribute('id');
98 trigger_error("News item '$title' has no ID");
101 $article_link = $path . '#' . $item_id;
103 $rss->addItem($article_link, $title, $date, $body);
109 $page->normalizePath(
110 $link->getAttribute('href')