summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2007-07-11 23:36:24 +0200
committerAndreas Gohr <andi@splitbrain.org>2007-07-11 23:36:24 +0200
commit4ab889ea63838db0bbb33dd0d316eac03ab69cf2 (patch)
treea65c09a7a415718463a1ed3bdbd82dc3f5ce7081
parent8fe3bb00af38a1790e3c2b30eb655fec12e19653 (diff)
downloadrpg-4ab889ea63838db0bbb33dd0d316eac03ab69cf2.tar.gz
rpg-4ab889ea63838db0bbb33dd0d316eac03ab69cf2.tar.bz2
improved feed creation
The feed now can export diff views (unified and HTML) as well as full HTML page content. Some things might be broken. Everybody please test it! darcs-hash:20070711213624-7ad00-49359417127fdbd6e31374738509110271b6b351.gz
-rw-r--r--conf/dokuwiki.php6
-rw-r--r--feed.php246
-rw-r--r--inc/feedcreator.class.php7
-rw-r--r--inc/parser/xhtml.php8
-rw-r--r--lib/plugins/config/lang/en/lang.php16
-rw-r--r--lib/plugins/config/settings/config.metadata.php3
6 files changed, 194 insertions, 92 deletions
diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php
index 71a61f733..c041d0bee 100644
--- a/conf/dokuwiki.php
+++ b/conf/dokuwiki.php
@@ -103,11 +103,17 @@ $conf['rss_type'] = 'rss1'; //type of RSS feed to provide, by defau
// 'rss1' - RSS 1.0
// 'rss2' - RSS 2.0
// 'atom' - Atom 0.3
+ // 'atom1' - Atom 1.0
$conf['rss_linkto'] = 'diff'; //what page RSS entries link to:
// 'diff' - page showing revision differences
// 'page' - the revised page itself
// 'rev' - page showing all revisions
// 'current' - most recent revision of page
+$conf['rss_content'] = 'abstract'; // what to put in the items by deafult?
+ // 'abstract' - plain text, first paragraph or so
+ // 'diff' - plain text unified diff wrapped in <pre> tags
+ // 'htmldiff' - diff as HTML table
+ // 'html' - the full page rendered in XHTML
$conf['rss_update'] = 5*60; //Update the RSS feed every n minutes (defaults to 5 minutes)
$conf['recent_days'] = 7; //How many days of recent changes to keep. (days)
$conf['rss_show_summary'] = 1; //Add revision summary to title? 0|1
diff --git a/feed.php b/feed.php
index f63d7c498..7df3a0ff7 100644
--- a/feed.php
+++ b/feed.php
@@ -18,42 +18,12 @@
//close session
session_write_close();
-
- $num = $_REQUEST['num'];
- $type = $_REQUEST['type'];
- $mode = $_REQUEST['mode'];
- $minor = $_REQUEST['minor'];
- $ns = $_REQUEST['ns'];
- $ltype = $_REQUEST['linkto'];
-
- if($type == '')
- $type = $conf['rss_type'];
-
- switch ($type){
- case 'rss':
- $type = 'RSS0.91';
- $mime = 'text/xml';
- break;
- case 'rss2':
- $type = 'RSS2.0';
- $mime = 'text/xml';
- break;
- case 'atom':
- $type = 'ATOM0.3';
- $mime = 'application/xml';
- break;
- case 'atom1':
- $type = 'ATOM1.0';
- $mime = 'application/atom+xml';
- break;
- default:
- $type = 'RSS1.0';
- $mime = 'application/xml';
- }
+ // get params
+ $opt = rss_parseOptions();
// the feed is dynamic - we need a cache for each combo
// (but most people just use the default feed so it's still effective)
- $cache = getCacheName($num.$type.$mode.$ns.$ltype.$_SERVER['REMOTE_USER'],'.feed');
+ $cache = getCacheName(array_values($opt).$_SERVER['REMOTE_USER'],'.feed');
$cmod = @filemtime($cache); // 0 if not exists
if ($cmod && (@filemtime(DOKU_CONF.'local.php')>$cmod || @filemtime(DOKU_CONF.'dokuwiki.php')>$cmod)) {
// ignore cache if feed prefs may have changed
@@ -76,7 +46,7 @@
// create new feed
$rss = new DokuWikiFeedCreator();
- $rss->title = $conf['title'].(($ns) ? ' '.$ns : '');
+ $rss->title = $conf['title'].(($opt['namespace']) ? ' '.$opt['namespace'] : '');
$rss->link = DOKU_URL;
$rss->syndicationURL = DOKU_URL.'feed.php';
$rss->cssStyleSheet = DOKU_URL.'lib/exe/css.php?s=feed';
@@ -87,13 +57,13 @@
$image->link = DOKU_URL;
$rss->image = $image;
- if($mode == 'list'){
+ if($opt['feed_mode'] == 'list'){
rssListNamespace($rss,$ns);
}else{
- rssRecentChanges($rss,$num,$ltype,$ns,$minor);
+ rssRecentChanges($rss,$opt);
}
- $feed = $rss->createFeed($type,'utf-8');
+ $feed = $rss->createFeed($opt['feed_type'],'utf-8');
// save cachefile
io_saveFile($cache,$feed);
@@ -104,67 +74,159 @@
// ---------------------------------------------------------------- //
/**
- * Add recent changed pages to a feed object
+ * Get URL parameters and config options and return a initialized option array
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function rssRecentChanges(&$rss,$num,$ltype,$ns,$minor){
+function rss_parseOptions(){
global $conf;
- global $auth;
- if(!$num) $num = $conf['recent'];
- $guardmail = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
-
-
- $flags = RECENTS_SKIP_DELETED;
- if(!$minor) $flags += RECENTS_SKIP_MINORS;
+ $opt['items'] = (int) $_REQUEST['num'];
+ $opt['feed_type'] = $_REQUEST['type'];
+ $opt['feed_mode'] = $_REQUEST['mode'];
+ $opt['show_minor'] = $_REQUEST['minor'];
+ $opt['namespace'] = $_REQUEST['ns'];
+ $opt['link_to'] = $_REQUEST['linkto'];
+ $opt['item_content'] = $_REQUEST['content'];
+
+ if($opt['feed_type'] == '') $opt['feed_type'] = $conf['rss_type'];
+ if($opt['item_content'] == '') $opt['item_content'] = $conf['rss_content'];
+ if(!$opt['items']) $opt['items'] = $conf['recent'];
+ $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
+
+ switch ($opt['feed_type']){
+ case 'rss':
+ $opt['feed_type'] = 'RSS0.91';
+ $opt['mime_type'] = 'text/xml';
+ break;
+ case 'rss2':
+ $opt['feed_type'] = 'RSS2.0';
+ $opt['mime_type'] = 'text/xml';
+ break;
+ case 'atom':
+ $opt['feed_type'] = 'ATOM0.3';
+ $opt['mime_type'] = 'application/xml';
+ break;
+ case 'atom1':
+ $opt['feed_type'] = 'ATOM1.0';
+ $opt['mime_type'] = 'application/atom+xml';
+ break;
+ default:
+ $opt['feed_type'] = 'RSS1.0';
+ $opt['mime_type'] = 'application/xml';
+ }
+ return $opt;
+}
- $recents = getRecents(0,$num,$ns,$flags);
+/**
+ * Add recent changed pages to a feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param object $rss - the FeedCreator Object
+ * @param array $data - the items to add
+ * @param array $opt - the feed options
+ */
+function rss_buildItems(&$rss,&$data,$opt){
+ global $conf;
+ global $lang;
- foreach($recents as $recent){
+ foreach($data as $ditem){
$item = new FeedItem();
- $meta = p_get_metadata($recent['id']);
+ $id = $ditem['id'];
+ $meta = p_get_metadata($id);
+
+ // add date
+ if($ditem['date']){
+ $date = $ditem['date'];
+ }elseif($meta['date']['modified']){
+ $date = $meta['date']['modified'];
+ }else{
+ $date = @filemtime(wikiFN($id));
+ }
+ if($date) $item->date = date('r',$date);
+ // add title
if($conf['useheading'] && $meta['title']){
$item->title = $meta['title'];
}else{
- $item->title = $recent['id'];
+ $item->title = $ditem['id'];
}
- if($conf['rss_show_summary'] && !empty($recent['sum'])){
- $item->title .= ' - '.strip_tags($recent['sum']);
+ if($conf['rss_show_summary'] && !empty($ditem['sum'])){
+ $item->title .= ' - '.strip_tags($ditem['sum']);
}
- if(empty($ltype)) $ltype = $conf['rss_linkto'];
-
- switch ($ltype){
+ // add item link
+ switch ($opt['link_to']){
case 'page':
- $item->link = wl($recent['id'],'rev='.$recent['date'],true,'&');
+ $item->link = wl($id,'rev='.$date,true,'&');
break;
case 'rev':
- $item->link = wl($recent['id'],'do=revisions&rev='.$recent['date'],true,'&');
+ $item->link = wl($id,'do=revisions&rev='.$date,true,'&');
break;
case 'current':
- $item->link = wl($recent['id'], '', true,'&');
+ $item->link = wl($id, '', true,'&');
break;
case 'diff':
default:
- $item->link = wl($recent['id'],'rev='.$recent['date'].'&do=diff',true,'&');
+ $item->link = wl($id,'rev='.$date.'&do=diff',true,'&');
+ }
+
+ // add item content
+ switch ($opt['item_content']){
+ case 'diff':
+ case 'htmldiff':
+ require_once(DOKU_INC.'inc/DifferenceEngine.php');
+ $revs = getRevisions($id, 0, 1);
+ $rev = $revs[0];
+
+ if($rev){
+ $df = new Diff(explode("\n",htmlspecialchars(rawWiki($id,$rev))),
+ explode("\n",htmlspecialchars(rawWiki($id,''))));
+ }else{
+ $df = new Diff(array(''),
+ explode("\n",htmlspecialchars(rawWiki($id,''))));
+ }
+
+ if($opt['item_content'] == 'htmldiff'){
+ $tdf = new TableDiffFormatter();
+ $content = '<table>';
+ $content .= '<tr><th colspan="2" width="50%">'.$rev.'</th>';
+ $content .= '<th colspan="2" width="50%">'.$lang['current'].'</th></tr>';
+ $content .= $tdf->format($df);
+ $content .= '</table>';
+ }else{
+ $udf = new UnifiedDiffFormatter();
+ $content = "<pre>\n".$udf->format($df)."\n</pre>";
+ }
+ break;
+ case 'html':
+ $content = p_wiki_xhtml($id,$date,false);
+ // no TOC in feeds
+ $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s','',$content);
+
+ // make URLs work when canonical is not set, regexp instead of rerendering!
+ if(!$conf['canonical']){
+ $base = preg_quote(DOKU_REL,'/');
+ $content = preg_replace('/(<a href|<img src)="('.$base.')/s','$1="'.DOKU_URL,$content);
+ }
+
+ break;
+ case 'abstract':
+ default:
+ $content = $meta['description']['abstract'];
}
+ $item->description = $content; //FIXME a plugin hook here could be senseful
- $item->description = $meta['description']['abstract'];
- $item->date = date('r',$recent['date']);
- $cat = getNS($recent['id']);
- if($cat) $item->category = $cat;
- // FIXME should the user be pulled from metadata as well?
+ // add user
+ # FIXME should the user be pulled from metadata as well?
$user = null;
- $user = @$recent['user']; // the @ spares time repeating lookup
+ $user = @$ditem['user']; // the @ spares time repeating lookup
$item->author = '';
-
if($user && $conf['useacl'] && $auth){
$userInfo = $auth->getUserData($user);
$item->author = $userInfo['name'];
- if($guardmail) {
+ if($opt['guardmail']) {
//cannot obfuscate because some RSS readers may check validity
$item->authorEmail = $user.'@'.$recent['ip'];
}else{
@@ -177,44 +239,58 @@ function rssRecentChanges(&$rss,$num,$ltype,$ns,$minor){
}else{
$item->authorEmail = 'anonymous@'.$recent['ip'];
}
+
+ // add category
+ if($meta['subject']){
+ $item->category = $meta['subject'];
+ }else{
+ $cat = getNS($id);
+ if($cat) $item->category = $cat;
+ }
+
+ // finally add the item to the feed object
$rss->addItem($item);
}
}
+
+/**
+ * Add recent changed pages to a feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function rssRecentChanges(&$rss,$opt){
+ global $conf;
+ global $auth;
+
+ $flags = RECENTS_SKIP_DELETED;
+ if(!$opt['show_minor']) $flags += RECENTS_SKIP_MINORS;
+
+ $recents = getRecents(0,$opt['items'],$opt['namespace'],$flags);
+
+ rss_buildItems($rss,$recents,$opt);
+}
+
/**
* Add all pages of a namespace to a feedobject
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-function rssListNamespace(&$rss,$ns){
+function rssListNamespace(&$rss,$opt){
require_once(DOKU_INC.'inc/search.php');
global $conf;
- $ns=':'.cleanID($ns);
+ $ns=':'.cleanID($opt['namespace']);
$ns=str_replace(':','/',$ns);
$data = array();
sort($data);
search($data,$conf['datadir'],'search_list','',$ns);
- foreach($data as $row){
- $item = new FeedItem();
- $id = $row['id'];
- $date = filemtime(wikiFN($id));
- $meta = p_get_metadata($id);
+ rss_buildItems($rss,$data,$opt);
+}
- if($conf['useheading'] && $meta['title']){
- $item->title = $meta['title'];
- }else{
- $item->title = $id;
- }
- $item->link = wl($id,'rev='.$date,true,'&');
- $item->description = $meta['description']['abstract'];
- $item->date = date('r',$date);
- $rss->addItem($item);
- }
-}
//Setup VIM: ex: et ts=4 enc=utf-8 :
?>
diff --git a/inc/feedcreator.class.php b/inc/feedcreator.class.php
index bbe3220e1..76d2580a5 100644
--- a/inc/feedcreator.class.php
+++ b/inc/feedcreator.class.php
@@ -916,7 +916,12 @@ class RSSCreator091 extends FeedCreator {
$feed.= " <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
}
if ($this->category!="") {
- $feed.= " <category>".htmlspecialchars($this->category)."</category>\n";
+ // Changed for DokuWiki: multiple categories are possible
+ if(is_array($this->category)) foreach($this->category as $cat){
+ $feed.= " <category>".htmlspecialchars($cat)."</category>\n";
+ }else{
+ $feed.= " <category>".htmlspecialchars($this->category)."</category>\n";
+ }
}
if ($this->docs!="") {
$feed.= " <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."</docs>\n";
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
index 3a1eef3e7..2c1061c69 100644
--- a/inc/parser/xhtml.php
+++ b/inc/parser/xhtml.php
@@ -101,13 +101,15 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
if(count($toc) < 3) return '';
global $lang;
- $out = '<div class="toc">'.DOKU_LF;
+ $out = '<!-- TOC START -->'.DOKU_LF;
+ $out .= '<div class="toc">'.DOKU_LF;
$out .= '<div class="tocheader toctoggle" id="toc__header">';
$out .= $lang['toc'];
$out .= '</div>'.DOKU_LF;
$out .= '<div id="toc__inside">'.DOKU_LF;
$out .= html_buildlist($toc,'toc',array(__CLASS__,'_tocitem'));
$out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
+ $out .= '<!-- TOC END -->'.DOKU_LF;
return $out;
}
@@ -928,6 +930,10 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$ret .= '<img src="'.ml($src,array('w'=>$width,'h'=>$height,'cache'=>$cache)).'"';
$ret .= ' class="media'.$align.'"';
+ // make left/right alignment for no-CSS view work (feeds)
+ if($align == 'right') $ret .= ' align="right"';
+ if($align == 'left') $ret .= ' align="left"';
+
if (!is_null($title)) {
$ret .= ' title="'.$this->_xmlEntities($title).'"';
$ret .= ' alt="'.$this->_xmlEntities($title).'"';
diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php
index 932a00b05..e0b9a95af 100644
--- a/lib/plugins/config/lang/en/lang.php
+++ b/lib/plugins/config/lang/en/lang.php
@@ -128,6 +128,7 @@ $lang['broken_iua'] = 'Is the ignore_user_abort function broken on your system?
$lang['rss_type'] = 'XML feed type';
$lang['rss_linkto'] = 'XML feed links to';
+$lang['rss_content'] = 'What to display in the XML feed items?';
$lang['rss_update'] = 'XML feed update interval (sec)';
$lang['recent_days'] = 'How many recent changes to keep (days)';
$lang['rss_show_summary'] = 'XML feed show summary in title';
@@ -175,10 +176,17 @@ $lang['gdlib_o_1'] = 'Version 1.x';
$lang['gdlib_o_2'] = 'Autodetection';
/* rss_type options */
-$lang['rss_type_o_rss'] = 'RSS 0.91';
-$lang['rss_type_o_rss1'] = 'RSS 1.0';
-$lang['rss_type_o_rss2'] = 'RSS 2.0';
-$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+
+/* rss_content options */
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatted diff table';
+$lang['rss_content_o_html'] = 'Full HTML page content';
/* rss_linkto options */
$lang['rss_linkto_o_diff'] = 'difference view';
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
index 9c3d16e1c..f8e2c35ce 100644
--- a/lib/plugins/config/settings/config.metadata.php
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -164,8 +164,9 @@ $meta['hidepages'] = array('string');
$meta['send404'] = array('onoff');
$meta['compression'] = array('multichoice','_choices' => array('0','gz','bz2'));
$meta['sitemap'] = array('numeric');
-$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom'));
+$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom','atom1'));
$meta['rss_linkto'] = array('multichoice','_choices' => array('diff','page','rev','current'));
+$meta['rss_content'] = array('multichoice','_choices' => array('abstract','diff','htmldiff','html'));
$meta['rss_update'] = array('numeric');
$meta['recent_days'] = array('numeric');
$meta['rss_show_summary'] = array('onoff');