[PATCH] News cleanup & hAtom support
[email protected] ("Hannes Magnusson")
| Newsgroups | php.webmaster |
|---|---|
| Message-ID | <[email protected]> |
Hi all Attached is a master & phpweb "news system" cleanup patch (gosh, what was I thinking) which should increase the readability, performance and scalability heckofalot. The patch also adds hAtom support for all news items. If there are no objections I'll commit it probably on Monday. -Hannes
news.patch.txt
(text/plain, 14.7 KB)
Index: master/scripts/pregen_news
===================================================================
RCS file: /repository/php-master-web/scripts/pregen_news,v
retrieving revision 1.2
diff -u -p -r1.2 pregen_news
--- master/scripts/pregen_news 29 Dec 2007 14:44:08 -0000 1.2
+++ master/scripts/pregen_news 29 Feb 2008 17:17:08 -0000
@@ -1,102 +1,151 @@
<?php /* vim: set noet ts=4 sw=4 ft=php: : */
+define("XMLNS_ATOM", "http://www.w3.org/2005/Atom");
+define("XMLNS_XHTML", "http://www.w3.org/1999/xhtml");
+define("XMLNS_PHP", "http://php.net/ns/news");
+
+function date_sort($a, $b) {
+ return $a["updated"] == $b["updated"] ? 0 : (strtotime($a["updated"]) > strtotime($b["updated"]) ? -1 : 1);
+}
+
$XML_OPTIONS = LIBXML_COMPACT | LIBXML_NOBLANKS | LIBXML_NOCDATA | LIBXML_NSCLEAN | LIBXML_XINCLUDE;
+
function pregen_atom($feed, $feedDest, $newsDest) {
- $dom = new DOMDocument("1.0", "UTF-8");
- $dom->formatOutput = true;
- $dom->preserveWhiteSpace = false;
- $options = $GLOBALS["XML_OPTIONS"];
-
- $y = date("Y");
- if (file_exists($feed .$y. ".xml")) {
- $dom->load($feed .$y. ".xml", $options);
- } elseif (file_exists($feed .(--$y). ".xml")) {
- $dom->load($feed .$y. ".xml");
- } else {
- trigger_error("Can't find news feed", E_USER_WARNING);
- return;
+ $entries = format_atom_feed($feed, $y = date("Y"));
+ uasort($entries, "date_sort");
+
+ $write = '<?php $NEWS_ENTRIES = ' . var_export($entries, 1) . ';';
+ file_put_contents($newsDest, $write);
+
+ do {
+ $filename = $feed . $y .".xml";
+ } while (!file_exists($filename));
+ copy($filename, $feedDest);
+}
+
+function format_atom_feed($feed, $year) {
+ static $frontpage = 0;
+ static $conf = 0;
+
+ // Lets only go back one year
+ if ($year < (date("Y")-1)) {
+ $frontpage = $conf = 100;
+ return array();
}
+ $filename = $feed . $year .".xml";
- $entrys = $dom->getElementsByTagNameNS("http://www.w3.org/2005/Atom", "entry");
- if(!$entrys || $entrys->length < 10) {
- $fragment = $dom->createDocumentFragment();
- $tmp = new DOMDocument("1.0", "UTF-8");
- $tmp->formatOutput = true;
- $tmp->preserveWhiteSpace = false;
-
- $tmp->load($feed .($y-1). ".xml", $options);
- $e = $tmp->getElementsByTagNameNS("http://www.w3.org/2005/Atom", "entry");
- foreach($e as $n) {
- $n->setAttribute("xmlns", "http://www.w3.org/2005/Atom");
- $n->setAttribute("xmlns:php", "http://php.net/ns/news");
- $fragment->appendXML($tmp->saveXML($n));
+ // January 1st...
+ if (!file_exists($filename)) {
+ return format_atom_feed($feed, --$year);
+ }
+
+ $r = new XMLReader;
+ $r->open($filename, "UTF-8");
+
+ $entries = array();
+ while($r->read()) {
+ if ($r->nodeType === XMLReader::ELEMENT && $r->name === "entry") {
+ $entries[] = $current = format_atom_entry($r);
+
+ // Count the frontpage & conference entries
+ foreach($current["category"] as $dog) {
+ if ($dog["term"] == "frontpage") {
+ ++$frontpage;
+ break;
+ } else {
+ ++$conf;
+ }
+ }
}
- $child = $dom->documentElement->appendChild($fragment);
- $child->removeAttributeNS("http://www.w3.org/1999/xhtml", "default");
}
- $dom->save($feedDest, $options);
- //$dom->normalizeDocument(); # For whatever reason this doesn't seem to work :(
- $dom->load($feedDest);
- $NEWS = array();
-
- foreach($entrys as $entry) {
- $fragment = "";
- $c = array();
- $contentNode = $entry->getElementsByTagName("content")->item(0)->firstChild;
-
- foreach($entry->getElementsByTagName("link") as $link) {
- if($link->getAttribute("rel") == "alternate") {
- $self = $link->getAttribute("href");
- $fragment = parse_url("http://php.net" . $self, PHP_URL_FRAGMENT);
+ // Make sure we have enough entries to display (shortly after new-year..)
+ if (min($frontpage, $conf) < 5) {
+ $entries = array_merge($entries, format_atom_feed($feed, --$year));
+ }
+
+ return $entries;
+}
+
+// {{{ Parse the entry into array(element => value)
+function format_atom_entry($r) {
+ $retval = array();
+
+ while($r->read()) {
+ if ($r->nodeType !== XMLReader::ELEMENT) {
+ if ($r->nodeType === XMLReader::END_ELEMENT && $r->name === "entry") {
+ return $retval;
+ }
+ continue;
+ }
+
+ $name = $r->localName;
+ if ($r->namespaceURI === XMLNS_ATOM) {
+ switch($name) {
+ case "title":
+ case "id":
+ case "published":
+ case "updated":
+ $retval[$name] = $r->readString();
+ $retval[$name] = $r->readString();
+ break;
+
+ case "link":
+ case "category":
+ $retval[$name][] = format_attributes($r);
+ break;
+
+ case "content":
+ if ($r->hasAttributes) {
+ switch($r->getAttribute("type")) {
+ case "html":
+ case "xhtml":
+ $retval[$name] = $r->readInnerXML();
+ break;
+
+ case "text":
+ $retval[$name] = $r->readString();
+ break;
+ }
+ } else {
+ $retval[$name] = $r->readString();
+ }
break;
}
- }
+ } elseif ($r->namespaceURI === XMLNS_PHP) {
+ switch($name) {
+ case "newsImage":
+ $retval[$name] = format_attributes($r);
+ $retval[$name]["content"] = $r->readString();
+ break;
- $dateNode = $entry->getElementsByTagName("published")->item(0)->firstChild;
- $date = date("d-M-Y", strtotime($dom->saveXML($dateNode, $options)));
- $dateSpanNode = $dom->createElement("span", "[$date]");
- $dateSpanNode->setAttribute("class", "newsdate");
-
- $contentNode->insertBefore($dateSpanNode, $contentNode->firstChild);
- $contentNode->removeAttributeNS("http://www.w3.org/1999/xhtml", "");
-
- $content = $dom->saveXML($contentNode, $options);
- $title = $dom->saveXML($entry->getElementsByTagName("title")->item(0)->firstChild, $options);
- $image = $entry->getElementsByTagNameNS("http://php.net/ns/news", "newsImage");
- if($image->length > 0) {
- $image = array(
- "link" => $image->item(0)->getAttribute("link"),
- "title" => $image->item(0)->getAttribute("title"),
- "image" => $image->item(0)->nodeValue,
- );
- } else {
- $image = false;
+ case "finalTeaserDate":
+ $retval[$name] = $r->readString();
+ break;
+ }
}
+ }
- $newsEntry = array(
- "fragment" => $fragment,
- "title" => $title,
- "content" => $content,
- "image" => $image,
- "date" => $date,
- );
- $categories = $entry->getElementsByTagName("category");
- for ($i=0; $i<$categories->length; $i++) {
- $c[] = $categories->item($i)->getAttribute("term");
- }
- if (in_array("cfp", $c) || in_array("conferences", $c)) {
- $NEWS["conferences"][] = $newsEntry;
- }
- if (in_array("frontpage", $c)) {
- $NEWS["frontpage"][] = $newsEntry;
- }
+ return $retval;
+} // }}}
+
+// {{{ Return all attrs for current element as an array(attr-name => attr-value)
+function format_attributes($r) {
+ $retval = array();
+
+ if (!$r->hasAttributes) {
+ return $retval;
}
- $write = '<?php $NEWS_ENTRIES = ' . var_export($NEWS, 1) . ';';
- file_put_contents($newsDest, $write);
-}
+ $r->moveToFirstAttribute();
+ do {
+ $retval[$r->localName] = $r->value;
+ } while($r->moveToNextAttribute());
+ $r->moveToElement();
+
+ return $retval;
+} // }}}
function legacy_rss($atom, $newsDest, $confDest) {
$sxe = new SimpleXMLElement($atom, $GLOBALS["XML_OPTIONS"], true);
Index: web/index.php
===================================================================
RCS file: /repository/phpweb/index.php,v
retrieving revision 1.905
diff -u -p -r1.905 index.php
--- web/index.php 25 Feb 2008 13:05:43 -0000 1.905
+++ web/index.php 29 Feb 2008 17:17:09 -0000
@@ -245,7 +245,7 @@ if (is_array($CONF_TEASER) && count($CON
/* Where the h*ll did all the news go?
* See archives/2007.xml
*/
-print_news($NEWS_ENTRIES["frontpage"]);
+print_news($NEWS_ENTRIES, "frontpage");
?>
<p class="center"><a href="/archive/index.php">News Archive</a></p>
Index: web/archive/2008.xml
===================================================================
RCS file: /repository/phpweb/archive/2008.xml,v
retrieving revision 1.11
diff -u -p -r1.11 2008.xml
--- web/archive/2008.xml 28 Feb 2008 23:02:42 -0000 1.11
+++ web/archive/2008.xml 29 Feb 2008 17:17:09 -0000
@@ -21,7 +21,7 @@
<php:finalTeaserDate>2008-05-24</php:finalTeaserDate>
<php:newsImage link="http://tek.phparch.com/" title="php|tek 2008: Chicago">phptek_2008.png</php:newsImage>
<content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml" class="description">
+ <div xmlns="http://www.w3.org/1999/xhtml">
<a href="http://tek.phparch.com/" class="url">php|tek 2008: Chicago</a>
<p>
The publishers of <a href="http://www.phparch.com/">php|architect Magazine</a> are proud to announce the php|tek 2008 conference in Chicago, Illinois, USA.
@@ -46,7 +46,7 @@ For the past two years, php|architect's
<php:finalTeaserDate>2008-03-16</php:finalTeaserDate>
<php:newsImage link="http://conf.phpquebec.com/en/conf2008/" title="PHP Québec conference 2008">conference_php_quebec.gif</php:newsImage>
<content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml" class="description">
+ <div xmlns="http://www.w3.org/1999/xhtml">
<a href="http://conf.phpquebec.com/">2008 PHP Quebec Conference & Job Fair</a>
<p>
The PHP Quebec team is pleased to present the sixth edition of the <a
@@ -78,7 +78,7 @@ visit the website: <a href="http://conf.
<php:newsImage xmlns="http://php.net/ns/news" link="http://www.phpconference.co.uk/" title="PHP London Conference 08">phplondon2008.png</php:newsImage>
<link href="http://www.phpconference.co.uk/" rel="via" type="text/html"/>
<content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml" class="description">
+ <div xmlns="http://www.w3.org/1999/xhtml">
<p><abbr class="dtstart" title="2008-02-29">February 29th</abbr> (Leap Year Day). phplondon.org announce their third
annual <a href="http://www.phpconference.co.uk" alt="phplondon.org community conference" class="url">community conference</a>
to be held at Inmarsat, Old Street, London.</p>
Index: web/archive/2008.php
===================================================================
RCS file: /repository/phpweb/archive/2008.php,v
retrieving revision 1.1
diff -u -p -r1.1 2008.php
--- web/archive/2008.php 29 Dec 2007 15:12:04 -0000 1.1
+++ web/archive/2008.php 29 Feb 2008 17:17:09 -0000
@@ -16,13 +16,8 @@ site_header("News Archive - 2008");
<hr />
<?php
-function date_sort($a, $b) {
- return $a["date"] == $b["date"] ? 0 : (strtotime($a["date"]) > strtotime($b["date"]) ? -1 : 1);
-}
-$news = array_merge($NEWS_ENTRIES["frontpage"], $NEWS_ENTRIES["conferences"]);
-uasort($news, "date_sort");
-print_news($news, 2008);
+print_news($NEWS_ENTRIES, array("conferences", "cfp", "frontpage"), 50);
/* %s/<a href="\(.*\)"><img src="\/images\/news\/\(.*\)" alt="\(.*\)" width.*><\/a>/<?php news_image("\1", "\2", "\3"); ?>/g */
site_footer();
Index: web/conferences/index.php
===================================================================
RCS file: /repository/phpweb/conferences/index.php,v
retrieving revision 1.23
diff -u -p -r1.23 index.php
--- web/conferences/index.php 25 Feb 2008 15:49:21 -0000 1.23
+++ web/conferences/index.php 29 Feb 2008 17:17:09 -0000
@@ -22,7 +22,7 @@ unset($RSIDEBAR_DATA);
site_header("PHP Conferences around the world", array("layout_workaround" => $layout_workaround, 'headtags' => '<link rel="alternate" type="application/atom+xml" title="PHP: Conference announcements" href="' . $MYSITE . 'feed.atom" />'));
-print_news($NEWS_ENTRIES["conferences"], false, true);
+print_news($NEWS_ENTRIES, array("conferences", "cfp"), 15);
site_footer(
array("atom" => "/feed.atom") // Add a link to the feed
Index: web/include/layout.inc
===================================================================
RCS file: /repository/phpweb/include/layout.inc,v
retrieving revision 1.277
diff -u -p -r1.277 layout.inc
--- web/include/layout.inc 25 Feb 2008 15:49:21 -0000 1.277
+++ web/include/layout.inc 29 Feb 2008 17:17:09 -0000
@@ -623,24 +623,60 @@ function news_archive_sidebar()
}
// Print news
-function print_news($news, $year = false, $event = false) {
+function print_news($news, $dog, $max = 5) {
+ $count = 0;
foreach($news as $item) {
- if ($year && $year != date("Y", strtotime($item["date"]))) {
+ $vevent = "";
+ $ok = false;
+
+ // Only print entries in the provided s/dog/cat/ egory
+ // If its a conference, use the hCalendar container
+ foreach($item["category"] as $category) {
+ if (in_array($category["term"], (array)$dog)) {
+ $ok = true;
+ ++$count;
+ }
+ if ($category["term"] === "conferences") {
+ $vevent = " vevent";
+ }
+ }
+ if ($count > $max) {
+ break;
+ }
+ if ($ok === false) {
continue;
}
+
$image = "";
- if($item["image"]) {
- $image = news_image($item["image"]["link"], $item["image"]["image"], $item["image"]["title"]);
+ if(isset($item["newsImage"])) {
+ $image = news_image($item["newsImage"]["link"], $item["newsImage"]["content"], $item["newsImage"]["title"]);
}
- $vevent = "";
- if ($event) {
- $vevent = " vevent";
+
+ //$id = parse_url($item["id"], PHP_URL_FRAGMENT); 5.1.2
+ $id = parse_url($item["id"]);
+ $id = $id["fragment"];
+
+ // Find the permlink
+ foreach($item["link"] as $link) {
+ if ($link["rel"] === "via") {
+ $permlink = $link["href"];
+ break;
+ }
+ }
+ if (!isset($permlink)) {
+ $permlink = "#" .$id;
}
+
+ $newsdate = date("d-M-Y", strtotime($item["updated"]));
+
echo <<< EOT
-<div class="newsItem$vevent">
- $image
- <a name="{$item["fragment"]}" id="{$item["fragment"]}"><h1 class="summary">{$item["title"]}</h1></a>
- {$item["content"]}
+<div class="newsItem hentry$vevent">
+ <div class="newsImage">$image</div>
+ <h1 class="summary entry-title"><a name="{$id}" id="{$id}" href="{$permlink}" rel="bookmark" class="bookmark">{$item["title"]}</a></h1>
+ [<abbr class="updated newsdate" title="{$item["updated"]}">{$newsdate}</abbr>]
+ <div class="entry-content description">
+ {$item["content"]}
+ </div>
</div>
<hr />
@@ -649,3 +685,4 @@ EOT;
}
}
/* vim: set et ts=4 sw=4 ft=php: : */
+
Index: web/styles/site.css
===================================================================
RCS file: /repository/phpweb/styles/site.css,v
retrieving revision 1.63
diff -u -p -r1.63 site.css
--- web/styles/site.css 5 Feb 2008 08:12:26 -0000 1.63
+++ web/styles/site.css 29 Feb 2008 17:17:09 -0000
@@ -160,10 +160,6 @@ hr {
color: #6666cc;
background-color: transparent;
}
-div.newsItem .newsdate {
- float:left;
- padding-right: 10px;
-}
div.indent {
margin-left: 50px;