diff options
-rw-r--r-- | IkiWiki/Render.pm | 78 | ||||
-rw-r--r-- | doc/features.mdwn | 7 | ||||
-rw-r--r-- | doc/ikiwiki.setup | 2 | ||||
-rw-r--r-- | doc/usage.mdwn | 6 | ||||
-rwxr-xr-x | ikiwiki | 7 | ||||
-rw-r--r-- | templates/page.tmpl | 5 | ||||
-rw-r--r-- | templates/rsspage.tmpl | 21 |
7 files changed, 120 insertions, 6 deletions
diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index df24fd568..646e254a5 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -79,7 +79,13 @@ sub parentlinks ($) { #{{{ return @ret; } #}}} -sub finalize ($$$) { #{{{ +sub rsspage ($) { #{{{ + my $page=shift; + + return $page.".rss"; +} #}}} + +sub genpage ($$$) { #{{{ my $content=shift; my $page=shift; my $mtime=shift; @@ -102,6 +108,10 @@ sub finalize ($$$) { #{{{ $u=~s/\[\[file\]\]/$pagesources{$page}/g; $template->param(historyurl => $u); } + + if ($config{rss}) { + $template->param(rssurl => rsspage($page)); + } $template->param( title => $title, @@ -116,6 +126,59 @@ sub finalize ($$$) { #{{{ return $template->output; } #}}} +sub date_822 ($) { #{{{ + my $time=shift; + + eval q{use POSIX}; + return POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time)); +} #}}} + +sub absolute_urls ($$) { #{{{ + my $content=shift; + my $url=shift; + + $url=~s/[^\/]+$//; + + $content=~s{<a\s+href="([^"]+)"}{ + "<a href=\"$url$1\"" + }ieg; + $content=~s{<img\s+src="([^"]+)"}{ + "<img src=\"$url$1\"" + }ieg; + return $content; +} #}}} + +sub genrss ($$$) { #{{{ + my $content=shift; + my $page=shift; + my $mtime=shift; + + my $url="$config{url}/".htmlpage($page); + + my $template=HTML::Template->new(blind_cache => 1, + filename => "$config{templatedir}/rsspage.tmpl"); + + # Regular page gets a feed that is updated every time the + # page is changed, so the mtime is encoded in the guid. + my @items=( + { + itemtitle => pagetitle(basename($page)), + itemguid => "$url?mtime=$mtime", + itemurl => $url, + itempubdate => date_822($mtime), + itemcontent => absolute_urls($content, $url), # rss sucks + }, + ); + + $template->param( + title => pagetitle(basename($page)), + pageurl => $url, + items => \@items, + ); + + return $template->output; +} #}}} + sub check_overwrite ($$) { #{{{ # Important security check. Make sure to call this before saving # any files to the source directory. @@ -161,13 +224,20 @@ sub render ($) { #{{{ $content=linkify($content, $page); $content=htmlize($type, $content); - $content=finalize($content, $page, - mtime("$config{srcdir}/$file")); check_overwrite("$config{destdir}/".htmlpage($page), $page); - writefile("$config{destdir}/".htmlpage($page), $content); + writefile("$config{destdir}/".htmlpage($page), + genpage($content, $page, mtime("$config{srcdir}/$file"))); $oldpagemtime{$page}=time; $renderedfiles{$page}=htmlpage($page); + + # TODO: should really add this to renderedfiles and call + # check_overwrite, as above, but currently renderedfiles + # only supports listing one file per page. + if ($config{rss}) { + writefile("$config{destdir}/".rsspage($page), + genrss($content, $page, mtime("$config{srcdir}/$file"))); + } } else { $links{$file}=[]; diff --git a/doc/features.mdwn b/doc/features.mdwn index c20da504d..4699f3096 100644 --- a/doc/features.mdwn +++ b/doc/features.mdwn @@ -27,6 +27,13 @@ Currently implemented: and is quite smart about converting it to html. The only additional markup provided by ikiwiki aside from regular markdown is the [[WikiLink]]. +* [[RSS]] + + ikiwiki supports generating RSS (2.0) feed for individual pages. These + feeds can be subscribed to, to get an update when a page is changed. + + (Support for proper blogs is also planned.) + * support for other file types ikiwiki also supports files of any other type, including raw html, text, diff --git a/doc/ikiwiki.setup b/doc/ikiwiki.setup index 374093a5e..b81983080 100644 --- a/doc/ikiwiki.setup +++ b/doc/ikiwiki.setup @@ -44,4 +44,6 @@ use IkiWiki::Setup::Standard { # Can anonymous web users edit pages? #anonok => 1, + # Generate rss feeds for pages? + #rss => 1, } diff --git a/doc/usage.mdwn b/doc/usage.mdwn index b9744438b..02d01f49c 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -64,6 +64,12 @@ flags such as --verbose can be negated with --no-verbose. By default, anonymous users cannot edit the wiki. +* --rss, --norss + + If rss is set, along with every html page rendered by ikiwiki, an rss + page will also be rendered, to allow users to subscribe to a rss feed of + changes to that page. + * --cgi Enable [[CGI]] mode. In cgi mode ikiwiki runs as a cgi script, and supports editing pages, signing in, registration, and displaying [[RecentChanges]]. @@ -30,6 +30,7 @@ sub getconfig () { #{{{ historyurl => '', diffurl => '', anonok => 0, + rss => 0, rebuild => 0, wrapper => undef, wrappermode => undef, @@ -49,6 +50,7 @@ sub getconfig () { #{{{ "wrappermode=i" => \$config{wrappermode}, "svn!" => \$config{svn}, "anonok!" => \$config{anonok}, + "rss!" => \$config{rss}, "cgi!" => \$config{cgi}, "url=s" => \$config{url}, "cgiurl=s" => \$config{cgiurl}, @@ -85,7 +87,10 @@ sub getconfig () { #{{{ sub checkconfig () { #{{{ if ($config{cgi} && ! length $config{url}) { - error("Must specify url to wiki with --url when using --cgi"); + error("Must specify url to wiki with --url when using --cgi\n"); + } + if ($config{rss} && ! length $config{url}) { + error("Must specify url to wiki with --url when using --rss\n"); } $config{wikistatedir}="$config{srcdir}/.ikiwiki" diff --git a/templates/page.tmpl b/templates/page.tmpl index 1e484056e..5a7450af7 100644 --- a/templates/page.tmpl +++ b/templates/page.tmpl @@ -41,7 +41,10 @@ <p> <!-- from <TMPL_VAR NAME=WIKINAME> --> -last edited <TMPL_VAR NAME=MTIME> +Last edited <TMPL_VAR NAME=MTIME> +<TMPL_IF NAME="RSSURL"> +; <a type="application/rss+xml" href="<TMPL_VAR NAME=RSSURL>">RSS</a> +</TMPL_IF> </p> </body> diff --git a/templates/rsspage.tmpl b/templates/rsspage.tmpl new file mode 100644 index 000000000..cbfeb5471 --- /dev/null +++ b/templates/rsspage.tmpl @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<rss version="2.0"> + <channel> + <title><TMPL_VAR TITLE ESCAPE=HTML></title> + <link><TMPL_VAR PAGEURL></link> + <description><TMPL_VAR TITLE ESCAPE=HTML></description> + <TMPL_LOOP NAME="ITEMS"> + <item> + <title><TMPL_VAR ITEMTITLE ESCAPE=HTML></title> + <TMPL_IF NAME="ITEMGUID"> + <guid isPermaLink="false"><TMPL_VAR ITEMGUID></guid> + <TMPL_ELSE> + <guid><TMPL_VAR ITEMURL></guid> + </TMPL_IF> + <link><TMPL_VAR ITEMURL></link> + <pubDate><TMPL_VAR ITEMPUBDATE></pubDate> + <description><![CDATA[<TMPL_VAR ITEMCONTENT>]]></description> + </item> + </TMPL_LOOP> + </channel> +</rss> |