4 * Mini blog-style filter for globbing contents of another directory
5 * and inserting summaries into a main page.
6 * @note This filter should be run before other "cosmetic" filters, as
7 * it makes major changes to page content and may pull data from
8 * sources that have not been processed yet.
10 class XHTMLCompiler_DOMFilter_News
extends XHTMLCompiler_DOMFilter_NewsBase
12 protected $name = 'News';
13 protected $prefix = 'news';
14 protected $xcAttr = array('news');
15 public function process(DOMDocument
$dom, $page, $manager) {
16 // Remove the semaphore xc:news attribute, and assign to $page
19 if ($this->confiscateAttr($dom->documentElement
, 'xc', 'news')) {
21 $page->attr
['news'] = true;
24 $containers = $this->query("//html:div[@news:source]");
25 foreach ($containers as $container) {
27 $this->generateNews($container, $dom, $page, $manager);
29 if ($dep) $manager->addDependency(__FILE__
);
34 * Generates a particular news container.
36 public function generateNews($container, DOMDocument
$dom, $page, $manager) {
39 $source = $this->confiscateAttr($container, $this->ns
, 'source');
40 $source = $page->normalizePath($source);
41 $limit = $this->confiscateAttr($container, $this->ns
, 'limit');
42 if (!$limit) $limit = 5;
43 $header = $this->confiscateAttr($container, $this->ns
, 'header');
44 if (!$header) $header = 'h2';
45 $idPrefix = $this->confiscateAttr($container, $this->ns
, 'idPrefix');
46 if (!$idPrefix) $idPrefix = '';
47 $increase = $header[1] - 1; // amount increase sub-headings
49 // Recursively glob for source files
50 // :TODO: add DI for this
52 $result = $fs->globr($source, '*.xhtml');
53 // This doesn't work if there is more than one entry in a day
57 $xc = XHTMLCompiler
::getInstance();
58 $manager = $xc->getFilterManager();
60 for ($i = $d = 0, $c = count($result); $i < $c && $d != $limit; $i++
) {
63 // :TODO: Add support for nested directories. Also need to modify
64 // generateId when that happens.
65 $base = basename($entry);
66 if (strlen($base) < 4 ||
!ctype_digit(substr($base, 0, 4))) {
70 $entryFile = new XHTMLCompiler_Page($entry);
71 // This DOM has IDs setup, but no other processing setup.
72 $subdom = $manager->parse($entryFile->getSource(), $entryFile);
74 $entryNode = $dom->createElement('div');
75 $entryNode->setAttribute('class', 'item');
77 // Generate ID for this entry. The format is
78 // year-month-date-lc-title-with-dashes
79 $entryNode->setAttribute('id', $idPrefix . $this->generateId($entryFile->getPathStem()));
82 $node = $subdom->getElementsByTagName('h1')->item(0);
83 $h1 = $dom->importNode($node, true);
84 $hx = $dom->createElement($header);
85 $hx->setAttribute('class', 'title');
86 foreach ($h1->childNodes
as $h1node) $hx->appendChild($h1node);
87 $entryNode->appendChild($hx);
89 // Possible place for factoring out. Also, we can also add
90 // a timezone to be more like ours.
91 $dateTime = $entryFile->getCreatedTime();
93 $entryNode->appendChild($this->makeDateNode($dom, $dateTime));
97 // :WARNING: This code apparently leaves behind an
98 // xmlns statement, although we're not quite sure why.
99 $node = $subdom->getElementById('short-content');
100 $permText = 'Read more...';
102 $node = $subdom->getElementById('content');
103 $permText = 'Permalink';
105 $node = $dom->importNode($node, true);
106 $this->confiscateAttr($node, 'id');
107 $node->setAttribute('class', 'body');
108 $entryNode->appendChild($node);
111 $permalink = $dom->createElement('div');
112 $permalink->setAttribute('class', 'permalink');
113 $a = $dom->createElement('a');
114 $a->setAttribute('href', $entryFile->getAbsolutePath());
115 $a->appendChild($dom->createTextNode($permText));
116 $permalink->appendChild($a);
117 $entryNode->appendChild($permalink);
119 $container->appendChild($entryNode);
121 $manager->addDependency($entry);
123 // increment one successful
129 * Generates an ID based on the filename of a blog entry
131 public function generateId($entry) {
132 $parts = array_slice(explode('/', $entry), -2);
133 // A very specific format: year/monthday-entry-name, like 2008/0131-foobar
134 // Arbitrary folders before that is ok.
135 $entry = 'entry-' . $parts[0] .
136 '-' . substr($parts[1], 0, 2) .
137 '-' . substr($parts[1], 2, 2) .
138 '-' . substr($parts[1], 5);