aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2013-07-21 13:51:35 -0400
committerJoey Hess <joey@kitenet.net>2013-07-21 13:51:35 -0400
commit4c88a4d9d8fb62e8e4bea068a2546059bd1fa306 (patch)
tree8e2512a7df7fe530083dca2203b08eb4c6d2e111
parent7d938559cb9994211d2917491c503f729d220abb (diff)
parent5c0a18e75a5bf9d6ce9da3a1a525117fe9ee8e47 (diff)
downloadikiwiki-4c88a4d9d8fb62e8e4bea068a2546059bd1fa306.tar
ikiwiki-4c88a4d9d8fb62e8e4bea068a2546059bd1fa306.tar.gz
Merge remote-tracking branch 'schmonz/fancypodcast'
-rw-r--r--IkiWiki/Plugin/aggregate.pm4
-rw-r--r--IkiWiki/Plugin/inline.pm55
-rw-r--r--IkiWiki/Plugin/meta.pm16
-rw-r--r--doc/features.mdwn8
-rw-r--r--doc/ikiwiki/directive/inline.mdwn3
-rw-r--r--doc/ikiwiki/directive/meta.mdwn5
-rw-r--r--doc/style.css3
-rwxr-xr-xt/podcast.t233
-rw-r--r--t/tinypodcast/attempted_multiple_enclosures.mdwn4
-rw-r--r--t/tinypodcast/fancy.mdwn1
-rw-r--r--t/tinypodcast/piano.mp3bin0 -> 80991 bytes
-rw-r--r--t/tinypodcast/pianopost.mdwn3
-rw-r--r--t/tinypodcast/scroll.3gpbin0 -> 21590 bytes
-rw-r--r--t/tinypodcast/simple.mdwn1
-rw-r--r--t/tinypodcast/simplepost.mdwn1
-rw-r--r--t/tinypodcast/walter.oggbin0 -> 28714 bytes
-rw-r--r--templates/aggregatepost.tmpl4
-rw-r--r--templates/atomitem.tmpl5
-rw-r--r--templates/inlinepage.tmpl6
-rw-r--r--templates/page.tmpl6
-rw-r--r--templates/rssitem.tmpl13
-rw-r--r--templates/rsspage.tmpl5
-rw-r--r--themes/actiontabs/style.css2
-rw-r--r--themes/blueview/style.css6
-rw-r--r--themes/goldtype/style.css8
-rw-r--r--themes/monochrome/style.css8
26 files changed, 356 insertions, 44 deletions
diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm
index 89da5c453..be6e8d476 100644
--- a/IkiWiki/Plugin/aggregate.pm
+++ b/IkiWiki/Plugin/aggregate.pm
@@ -593,6 +593,7 @@ sub aggregate (@) {
feed => $feed,
copyright => $f->copyright,
title => defined $entry->title ? decode_entities($entry->title) : "untitled",
+ author => defined $entry->author ? decode_entities($entry->author) : "",
link => $entry->link,
content => (defined $c && defined $c->body) ? $c->body : "",
guid => defined $entry->id ? $entry->id : time."_".$feed->{name},
@@ -690,6 +691,9 @@ sub write_page ($$$$$) {
}
$template->param(title => $params{title})
if defined $params{title} && length($params{title});
+ $template->param(author => $params{author})
+ if defined $params{author} && length($params{author}
+ && $params{author} ne $feed->{name});
$template->param(content => wikiescape(htmlabs($params{content},
defined $params{base} ? $params{base} : $feed->{feedurl})));
$template->param(name => $feed->{name});
diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
index 8eb033951..455ac3ad5 100644
--- a/IkiWiki/Plugin/inline.pm
+++ b/IkiWiki/Plugin/inline.pm
@@ -611,6 +611,26 @@ sub absolute_urls ($$) {
return $ret;
}
+sub genenclosure {
+ my $itemtemplate=shift;
+ my $url=shift;
+ my $file=shift;
+
+ return unless $itemtemplate->query(name => "enclosure");
+
+ my $size=(srcfile_stat($file))[8];
+ my $mime="unknown";
+ eval q{use File::MimeInfo};
+ if (! $@) {
+ $mime = mimetype($file);
+ }
+ $itemtemplate->param(
+ enclosure => $url,
+ type => $mime,
+ length => $size,
+ );
+}
+
sub genfeed ($$$$$@) {
my $feedtype=shift;
my $feedurl=shift;
@@ -627,6 +647,7 @@ sub genfeed ($$$$$@) {
foreach my $p (@pages) {
my $u=URI->new(encode_utf8(urlto($p, "", 1)));
my $pcontent = absolute_urls(get_inline_content($p, $page), $url);
+ my $fancy_enclosure_seen = 0;
$itemtemplate->param(
title => pagetitle(basename($p)),
@@ -648,32 +669,23 @@ sub genfeed ($$$$$@) {
$itemtemplate->param(mdate_822 => date_822($pagestate{$p}{meta}{updated}));
$itemtemplate->param(mdate_3339 => date_3339($pagestate{$p}{meta}{updated}));
}
- }
- if ($itemtemplate->query(name => "enclosure")) {
- my $file=$pagesources{$p};
- my $type=pagetype($file);
- if (defined $type) {
- $itemtemplate->param(content => $pcontent);
- }
- else {
- my $size=(srcfile_stat($file))[8];
- my $mime="unknown";
- eval q{use File::MimeInfo};
- if (! $@) {
- $mime = mimetype($file);
- }
- $itemtemplate->param(
- enclosure => $u,
- type => $mime,
- length => $size,
- );
+ if (exists $pagestate{$p}{meta}{enclosure}) {
+ my $absurl = $pagestate{$p}{meta}{enclosure};
+ my $file = $pagestate{$p}{meta}{enclosurefile};
+ genenclosure($itemtemplate, $absurl, $file);
+ $fancy_enclosure_seen = 1;
}
}
- else {
- $itemtemplate->param(content => $pcontent);
+
+ my $file=$pagesources{$p};
+ unless ($fancy_enclosure_seen || defined(pagetype($file))) {
+ genenclosure($itemtemplate, $u, $file);
+ $itemtemplate->param(simplepodcast => 1);
}
+ $itemtemplate->param(content => $pcontent);
+
run_hooks(pagetemplate => sub {
shift->(page => $p, destpage => $page,
template => $itemtemplate);
@@ -694,6 +706,7 @@ sub genfeed ($$$$$@) {
feeddesc => $feeddesc,
guid => $guid,
feeddate => date_3339($lasttime),
+ feeddate_822 => date_822($lasttime),
feedurl => $feedurl,
);
run_hooks(pagetemplate => sub {
diff --git a/IkiWiki/Plugin/meta.pm b/IkiWiki/Plugin/meta.pm
index 7ea70b5d1..e7b96bdf1 100644
--- a/IkiWiki/Plugin/meta.pm
+++ b/IkiWiki/Plugin/meta.pm
@@ -121,6 +121,18 @@ sub preprocess (@) {
add_link($page, $value);
return "";
}
+ elsif ($key eq 'enclosure') {
+ my $link=bestlink($page, $value);
+ if (! length $link) {
+ error gettext("enclosure not found")
+ }
+ add_depends($page, $link, deptype("presence"));
+
+ $value=urlto($link, $page, 1);
+ $pagestate{$page}{meta}{enclosure}=$value;
+ $pagestate{$page}{meta}{enclosurefile}=$link;
+ # fallthrough
+ }
elsif ($key eq 'author') {
$pagestate{$page}{meta}{author}=$value;
if (exists $params{sortas}) {
@@ -318,6 +330,10 @@ sub pagetemplate (@) {
$template->param(title_overridden => 1);
}
+ if (exists $pagestate{$page}{meta}{enclosure}) {
+ $template->param(enclosure => HTML::Entities::encode_entities(IkiWiki::urlabs($pagestate{$page}{meta}{enclosure}, $config{url})));
+ }
+
foreach my $field (qw{authorurl}) {
eval q{use HTML::Entities};
$template->param($field => HTML::Entities::encode_entities($pagestate{$page}{meta}{$field}))
diff --git a/doc/features.mdwn b/doc/features.mdwn
index 66f7ecb73..5bbe5ef21 100644
--- a/doc/features.mdwn
+++ b/doc/features.mdwn
@@ -64,9 +64,11 @@ Ikiwiki can also [[plugins/aggregate]] external blogs, feeding them into
the wiki. This can be used to create a Planet type site that aggregates
interesting feeds.
-You can also mix blogging with podcasting by dropping audio files where
-they will be picked up like blog posts. This will work for any files that
-you would care to syndicate.
+You can also mix blogging with podcasting. Simply drop media files
+where they will be picked up like blog posts. For fuller-featured
+podcast feeds, enclose media files in blog posts using [[plugins/meta]].
+Either way, this will work for any files that you would care to
+syndicate.
## Valid html and [[css]]
diff --git a/doc/ikiwiki/directive/inline.mdwn b/doc/ikiwiki/directive/inline.mdwn
index a9c241afc..c0d4e035b 100644
--- a/doc/ikiwiki/directive/inline.mdwn
+++ b/doc/ikiwiki/directive/inline.mdwn
@@ -11,7 +11,8 @@ Any pages that match the specified [[PageSpec]] (in the example, any
[[SubPage]] of "blog") will be part of the blog, and the newest 10
of them will appear in the page. Note that if files that are not pages
match the [[PageSpec]], they will be included in the feed using RSS
-enclosures, which is useful for podcasting.
+enclosures, which is useful for simple podcasting; for fuller-featured
+podcast feeds, enclose media files in blog posts using [[meta]].
The optional `rootpage` parameter tells the wiki that new posts to this
blog should default to being [[SubPages|SubPage]] of "blog", and enables a
diff --git a/doc/ikiwiki/directive/meta.mdwn b/doc/ikiwiki/directive/meta.mdwn
index 984f68540..fbbffa575 100644
--- a/doc/ikiwiki/directive/meta.mdwn
+++ b/doc/ikiwiki/directive/meta.mdwn
@@ -136,6 +136,11 @@ Supported fields:
[[!iki plugins/htmlscrubber desc=htmlscrubber]] plugin is enabled, since it can be used to
insert unsafe content.
+* enclosure
+
+ Specifies a link to a file to be rendered as an "enclosure" in
+ RSS/Atom feeds (and a plain old link in HTML). Useful for podcasting.
+
* redir
Causes the page to redirect to another page in the wiki.
diff --git a/doc/style.css b/doc/style.css
index b52c72b6b..067a3bf7a 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -58,7 +58,8 @@ nav {
border-bottom: 1px solid #000;
}
-.inlinecontent {
+.inlinecontent,
+.inlineenclosure {
margin-top: .4em;
}
diff --git a/t/podcast.t b/t/podcast.t
new file mode 100755
index 000000000..1052aea70
--- /dev/null
+++ b/t/podcast.t
@@ -0,0 +1,233 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+BEGIN {
+ eval q{use XML::Feed; use HTML::Parser; use HTML::LinkExtor};
+ if ($@) {
+ eval q{use Test::More skip_all =>
+ "XML::Feed and/or HTML::Parser not available"};
+ }
+ else {
+ eval q{use Test::More tests => 136};
+ }
+}
+
+use Cwd;
+use File::Basename;
+
+my $tmp = 't/tmp';
+my $statedir = 't/tinypodcast/.ikiwiki';
+
+sub podcast {
+ my $podcast_style = shift;
+
+ my $baseurl = 'http://example.com';
+ my @command = (qw(./ikiwiki.out -plugin inline -rss -atom));
+ push @command, qw(-underlaydir=underlays/basewiki);
+ push @command, qw(-set underlaydirbase=underlays -templatedir=templates);
+ push @command, "-url=$baseurl", qw(t/tinypodcast), "$tmp/out";
+
+ ok(! system("mkdir $tmp"),
+ q{setup});
+ ok(! system(@command),
+ q{build});
+
+ my %media_types = (
+ 'simplepost' => undef,
+ 'piano.mp3' => 'audio/mpeg',
+ 'scroll.3gp' => 'video/3gpp',
+ 'walter.ogg' => 'video/x-theora+ogg',
+ );
+
+ for my $format (qw(atom rss)) {
+ my $feed = XML::Feed->parse("$tmp/out/$podcast_style/index.$format");
+
+ is($feed->title, $podcast_style,
+ qq{$format feed title});
+ is($feed->link, "$baseurl/$podcast_style/",
+ qq{$format feed link});
+ is($feed->description, 'wiki',
+ qq{$format feed description});
+ if ('atom' eq $format) {
+ is($feed->author, $feed->description,
+ qq{$format feed author});
+ is($feed->id, $feed->link,
+ qq{$format feed id});
+ is($feed->generator, "ikiwiki",
+ qq{$format feed generator});
+ }
+
+ for my $entry ($feed->entries) {
+ my $title = $entry->title;
+ my $url = $entry->id;
+ my $body = $entry->content->body;
+ my $enclosure = $entry->enclosure;
+
+ is($entry->link, $url, qq{$format $title link});
+ isnt($entry->issued, undef,
+ qq{$format $title issued date});
+ isnt($entry->modified, undef,
+ qq{$format $title modified date});
+
+ if (defined $media_types{$title}) {
+ is($url, "$baseurl/$title",
+ qq{$format $title id});
+ is($body, undef,
+ qq{$format $title no body text});
+ is($enclosure->url, $url,
+ qq{$format $title enclosure url});
+ is($enclosure->type, $media_types{$title},
+ qq{$format $title enclosure type});
+ cmp_ok($enclosure->length, '>', 0,
+ qq{$format $title enclosure length});
+ }
+ else {
+ # XXX hack hack hack
+ my $expected_id = "$baseurl/$title/";
+ $expected_id =~ s/\ /_/g;
+
+ is($url, $expected_id,
+ qq{$format $title id});
+ isnt($body, undef,
+ qq{$format $title body text});
+
+ if ('fancy' eq $podcast_style) {
+ isnt($enclosure, undef,
+ qq{$format $title enclosure});
+ my $filename = basename($enclosure->url);
+ is($enclosure->type, $media_types{$filename},
+ qq{$format $title enclosure type});
+ cmp_ok($enclosure->length, '>', 0,
+ qq{$format $title enclosure length});
+ }
+ else {
+ is($enclosure, undef,
+ qq{$format $title no enclosure});
+ }
+ }
+ }
+ }
+
+ ok(! system("rm -rf $tmp $statedir"), q{teardown});
+}
+
+sub single_page_html {
+ my @command = (qw(./ikiwiki.out));
+ push @command, qw(-underlaydir=underlays/basewiki);
+ push @command, qw(-set underlaydirbase=underlays -templatedir=templates);
+ push @command, qw(t/tinypodcast), "$tmp/out";
+
+ ok(! system("mkdir $tmp"),
+ q{setup});
+ ok(! system(@command),
+ q{build});
+
+ my $html = "$tmp/out/pianopost/index.html";
+ like(_extract_html_content($html, 'content'), qr/has content and/m,
+ q{html body text});
+ like(_extract_html_content($html, 'enclosure'), qr/Download/m,
+ q{html enclosure});
+ my ($href) = _extract_html_links($html, 'piano');
+ is($href, '/piano.mp3',
+ q{html enclosure sans -url is site-absolute});
+
+ $html = "$tmp/out/attempted_multiple_enclosures/index.html";
+ like(_extract_html_content($html, 'content'), qr/has content and/m,
+ q{html body text});
+ like(_extract_html_content($html, 'enclosure'), qr/Download/m,
+ q{html enclosure});
+ ($href) = _extract_html_links($html, 'walter');
+ is($href, '/walter.ogg',
+ q{html enclosure sans -url is site-absolute});
+
+ my $baseurl = 'http://example.com';
+ ok(! system(@command, "-url=$baseurl", q{--rebuild}));
+
+ $html = "$tmp/out/pianopost/index.html";
+ ($href) = _extract_html_links($html, 'piano');
+ is($href, "$baseurl/piano.mp3",
+ q{html enclosure with -url is fully absolute});
+
+ $html = "$tmp/out/attempted_multiple_enclosures/index.html";
+ ($href) = _extract_html_links($html, 'walter');
+ is($href, "$baseurl/walter.ogg",
+ q{html enclosure with -url is fully absolute});
+
+ ok(! system("rm -rf $tmp $statedir"), q{teardown});
+}
+
+sub inlined_pages_html {
+ my @command = (qw(./ikiwiki.out -plugin inline));
+ push @command, qw(-underlaydir=underlays/basewiki);
+ push @command, qw(-set underlaydirbase=underlays -templatedir=templates);
+ push @command, qw(t/tinypodcast), "$tmp/out";
+
+ ok(! system("mkdir $tmp"),
+ q{setup});
+ ok(! system(@command),
+ q{build});
+
+ my $html = "$tmp/out/fancy/index.html";
+ my $contents = _extract_html_content($html, 'content');
+ like($contents, qr/has content and an/m,
+ q{html body text from pianopost});
+ like($contents, qr/has content and only one/m,
+ q{html body text from attempted_multiple_enclosures});
+ my $enclosures = _extract_html_content($html, 'inlineenclosure');
+ like($enclosures, qr/Download/m,
+ q{html enclosure});
+ my ($href) = _extract_html_links($html, 'piano.mp3');
+ is($href, '/piano.mp3',
+ q{html enclosure from pianopost sans -url});
+ ($href) = _extract_html_links($html, 'walter.ogg');
+ is($href, '/walter.ogg',
+ q{html enclosure from attempted_multiple_enclosures sans -url});
+
+ ok(! system("rm -rf $tmp $statedir"), q{teardown});
+}
+
+sub _extract_html_content {
+ my ($file, $desired_id, $desired_tag) = @_;
+ $desired_tag = 'div' unless defined $desired_tag;
+
+ my $p = HTML::Parser->new(api_version => 3);
+ my $content = '';
+
+ $p->handler(start => sub {
+ my ($tag, $self, $attr) = @_;
+ return if $tag ne $desired_tag;
+ return unless exists $attr->{id} && $attr->{id} eq $desired_id;
+
+ $self->handler(text => sub {
+ my ($dtext) = @_;
+ $content .= $dtext;
+ }, "dtext");
+ }, "tagname,self,attr");
+
+ $p->parse_file($file) || die $!;
+
+ return $content;
+}
+
+sub _extract_html_links {
+ my ($file, $desired_value) = @_;
+
+ my @hrefs = ();
+
+ my $p = HTML::LinkExtor->new(sub {
+ my ($tag, %attr) = @_;
+ return if $tag ne 'a';
+ return unless $attr{href} =~ qr/$desired_value/;
+ push(@hrefs, values %attr);
+ }, getcwd() . '/' . $file);
+
+ $p->parse_file($file);
+
+ return @hrefs;
+}
+
+podcast('simple');
+single_page_html();
+inlined_pages_html();
+podcast('fancy');
diff --git a/t/tinypodcast/attempted_multiple_enclosures.mdwn b/t/tinypodcast/attempted_multiple_enclosures.mdwn
new file mode 100644
index 000000000..ea7bae8d0
--- /dev/null
+++ b/t/tinypodcast/attempted_multiple_enclosures.mdwn
@@ -0,0 +1,4 @@
+[[!meta enclosure="piano.mp3" enclosure="scroll.3gp"]]
+[[!meta enclosure="walter.ogg"]]
+
+this article has content _and_ only one enclosure!
diff --git a/t/tinypodcast/fancy.mdwn b/t/tinypodcast/fancy.mdwn
new file mode 100644
index 000000000..290f4c2fd
--- /dev/null
+++ b/t/tinypodcast/fancy.mdwn
@@ -0,0 +1 @@
+[[!inline pages="pianopost or attempted_multiple_enclosures"]]
diff --git a/t/tinypodcast/piano.mp3 b/t/tinypodcast/piano.mp3
new file mode 100644
index 000000000..3d6b6625a
--- /dev/null
+++ b/t/tinypodcast/piano.mp3
Binary files differ
diff --git a/t/tinypodcast/pianopost.mdwn b/t/tinypodcast/pianopost.mdwn
new file mode 100644
index 000000000..b02f8dee0
--- /dev/null
+++ b/t/tinypodcast/pianopost.mdwn
@@ -0,0 +1,3 @@
+[[!meta enclosure="piano.mp3"]]
+
+this article has content _and_ an enclosure!
diff --git a/t/tinypodcast/scroll.3gp b/t/tinypodcast/scroll.3gp
new file mode 100644
index 000000000..61e69e9da
--- /dev/null
+++ b/t/tinypodcast/scroll.3gp
Binary files differ
diff --git a/t/tinypodcast/simple.mdwn b/t/tinypodcast/simple.mdwn
new file mode 100644
index 000000000..052369780
--- /dev/null
+++ b/t/tinypodcast/simple.mdwn
@@ -0,0 +1 @@
+[[!inline pages="simplepost or *.3gp or *.mov or *.mp3 or *.ogg"]]
diff --git a/t/tinypodcast/simplepost.mdwn b/t/tinypodcast/simplepost.mdwn
new file mode 100644
index 000000000..d28ddb524
--- /dev/null
+++ b/t/tinypodcast/simplepost.mdwn
@@ -0,0 +1 @@
+this article has content but no enclosure
diff --git a/t/tinypodcast/walter.ogg b/t/tinypodcast/walter.ogg
new file mode 100644
index 000000000..3eee48cd6
--- /dev/null
+++ b/t/tinypodcast/walter.ogg
Binary files differ
diff --git a/templates/aggregatepost.tmpl b/templates/aggregatepost.tmpl
index 4e89efe32..a89ccfcdf 100644
--- a/templates/aggregatepost.tmpl
+++ b/templates/aggregatepost.tmpl
@@ -11,5 +11,9 @@
<TMPL_IF COPYRIGHT>
[[!meta copyright="<TMPL_VAR COPYRIGHT ESCAPE=HTML>"]]
</TMPL_IF>
+<TMPL_IF AUTHOR>
+[[!meta author="<TMPL_VAR NAME ESCAPE=HTML>: <TMPL_VAR AUTHOR ESCAPE=HTML>"]]
+<TMPL_ELSE>
[[!meta author="<TMPL_VAR NAME ESCAPE=HTML>"]]
+</TMPL_IF>
[[!meta authorurl="<TMPL_VAR URL ESCAPE=HTML>"]]
diff --git a/templates/atomitem.tmpl b/templates/atomitem.tmpl
index 4ed17bc62..9b056e0f4 100644
--- a/templates/atomitem.tmpl
+++ b/templates/atomitem.tmpl
@@ -34,11 +34,12 @@
<published><TMPL_VAR CDATE_3339></published>
<TMPL_IF ENCLOSURE>
<link rel="enclosure" type="<TMPL_VAR TYPE>" href="<TMPL_VAR ENCLOSURE>" length="<TMPL_VAR LENGTH>" />
-<TMPL_ELSE>
+</TMPL_IF>
+<TMPL_UNLESS SIMPLEPODCAST>
<content type="html" xml:lang="en">
<TMPL_VAR CONTENT ESCAPE=HTML>
</content>
-</TMPL_IF>
+</TMPL_UNLESS>
<TMPL_IF COMMENTSURL>
<link rel="comments" href="<TMPL_VAR COMMENTSURL>" type="text/html" />
</TMPL_IF>
diff --git a/templates/inlinepage.tmpl b/templates/inlinepage.tmpl
index b0b53d041..37d7e48c1 100644
--- a/templates/inlinepage.tmpl
+++ b/templates/inlinepage.tmpl
@@ -23,6 +23,12 @@
<TMPL_VAR CONTENT>
<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+<TMPL_IF ENCLOSURE>
+<TMPL_IF HTML5><section id="inlineenclosure"><TMPL_ELSE><div id="inlineenclosure"></TMPL_IF>
+<a href="<TMPL_VAR ENCLOSURE>">Download</a>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
<TMPL_IF HTML5><footer class="inlinefooter"><TMPL_ELSE><div class="inlinefooter"></TMPL_IF>
<span class="pagedate">
diff --git a/templates/page.tmpl b/templates/page.tmpl
index 6353c7596..c886b22d8 100644
--- a/templates/page.tmpl
+++ b/templates/page.tmpl
@@ -138,6 +138,12 @@
<TMPL_VAR CONTENT>
<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+<TMPL_IF ENCLOSURE>
+<TMPL_IF HTML5><section id="enclosure"><TMPL_ELSE><div id="enclosure"></TMPL_IF>
+<a href="<TMPL_VAR ENCLOSURE>">Download</a>
+<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
+</TMPL_IF>
+
<TMPL_UNLESS DYNAMIC>
<TMPL_IF COMMENTS>
<TMPL_IF HTML5><section id="comments"><TMPL_ELSE><div id="comments"></TMPL_IF>
diff --git a/templates/rssitem.tmpl b/templates/rssitem.tmpl
index 831daa871..bb03ca5bc 100644
--- a/templates/rssitem.tmpl
+++ b/templates/rssitem.tmpl
@@ -1,16 +1,14 @@
<item>
-<TMPL_IF AUTHOR>
- <title><TMPL_VAR AUTHOR ESCAPE=HTML>: <TMPL_VAR TITLE></title>
- <dcterms:creator><TMPL_VAR AUTHOR ESCAPE=HTML></dcterms:creator>
-<TMPL_ELSE>
<title><TMPL_VAR TITLE></title>
-</TMPL_IF>
<TMPL_IF GUID>
<guid isPermaLink="false"><TMPL_VAR GUID></guid>
<TMPL_ELSE>
<guid isPermaLink="false"><TMPL_VAR URL></guid>
</TMPL_IF>
<link><TMPL_VAR PERMALINK></link>
+<TMPL_IF AUTHOR>
+ <dc:creator><TMPL_VAR AUTHOR ESCAPE=HTML></dc:creator>
+</TMPL_IF>
<TMPL_IF CATEGORIES>
<TMPL_LOOP CATEGORIES>
<category><TMPL_VAR CATEGORY></category>
@@ -20,9 +18,10 @@
<dcterms:modified><TMPL_VAR MDATE_3339></dcterms:modified>
<TMPL_IF ENCLOSURE>
<enclosure url="<TMPL_VAR ENCLOSURE>" type="<TMPL_VAR TYPE>" length="<TMPL_VAR LENGTH>" />
-<TMPL_ELSE>
- <description><TMPL_VAR CONTENT ESCAPE=HTML></description>
</TMPL_IF>
+<TMPL_UNLESS SIMPLEPODCAST>
+ <description><TMPL_VAR CONTENT ESCAPE=HTML></description>
+</TMPL_UNLESS>
<TMPL_IF COMMENTSURL>
<comments><TMPL_VAR COMMENTSURL></comments>
</TMPL_IF>
diff --git a/templates/rsspage.tmpl b/templates/rsspage.tmpl
index e54094aaa..45265f265 100644
--- a/templates/rsspage.tmpl
+++ b/templates/rsspage.tmpl
@@ -5,7 +5,12 @@
<channel>
<title><TMPL_VAR TITLE></title>
<link><TMPL_VAR PAGEURL></link>
+<TMPL_IF COPYRIGHT>
+<copyright><TMPL_VAR COPYRIGHT ESCAPE=HTML></copyright>
+</TMPL_IF>
<description><TMPL_VAR FEEDDESC ESCAPE=HTML></description>
+<generator>ikiwiki</generator>
+<pubDate><TMPL_VAR FEEDDATE_822></pubDate>
<TMPL_VAR CONTENT>
</channel>
</rss>
diff --git a/themes/actiontabs/style.css b/themes/actiontabs/style.css
index f6cb5c04e..d4afc0915 100644
--- a/themes/actiontabs/style.css
+++ b/themes/actiontabs/style.css
@@ -76,7 +76,7 @@ body {
padding: 2px;
}
-#content, #comments, #footer {
+#content, #enclosure, #comments, #footer {
margin: 1em 2em;
}
diff --git a/themes/blueview/style.css b/themes/blueview/style.css
index 40a940f26..af1434574 100644
--- a/themes/blueview/style.css
+++ b/themes/blueview/style.css
@@ -143,7 +143,7 @@ p,fieldset,table,pre {
* Copyright (C) 2010 Bernd Zeimetz
* Licensed under same license as ikiwiki: GPL v2 or later */
-.page, .pageheader, .sidebar, #content, #comments, .inlinepage, .recentchanges, .pageheader .actions ul, #pagebody {
+.page, .pageheader, .sidebar, #content, #enclosure, #comments, .inlinepage, .recentchanges, .pageheader .actions ul, #pagebody {
border: none;
}
@@ -223,7 +223,7 @@ body {
clear: none;
}
-#content a, #comments a, .sidebar a {
+#content a, #enclosure a, #comments a, .sidebar a {
color: #315485;
text-decoration: none;
font-weight: bold;
@@ -271,7 +271,7 @@ body {
.pageheader .header span a, .pageheader .actions ul li a, .pageheader .header .parentlinks a {
color #315485;
}
- #content, #comments, #pagebody {
+ #content, #enclosure, #comments, #pagebody {
margin-right: 0;
*margin-right: 0;
border-right: none;
diff --git a/themes/goldtype/style.css b/themes/goldtype/style.css
index 9c217c746..b0e29dfad 100644
--- a/themes/goldtype/style.css
+++ b/themes/goldtype/style.css
@@ -14,10 +14,12 @@ html, body {
background-color: #f2d98d;
}
-#content a:hover, #comments a:hover, .sidebar a:hover,
-#content a:visited:hover, #comments a:visited:hover, .sidebar a:visited:hover {
+#content a:hover, #enclosure a:hover, #comments a:hover, .sidebar a:hover,
+#content a:visited:hover, #enclosure a:visited:hover, #comments a:visited:hover,
+.sidebar a:visited:hover {
color: red;
}
-#content a:visited, #comments a:visited, .sidebar a:visited {
+#content a:visited, #enclosure a:visited, #comments a:visited,
+.sidebar a:visited {
color: #37485e;
}
diff --git a/themes/monochrome/style.css b/themes/monochrome/style.css
index 41a3a4441..bd3fdf593 100644
--- a/themes/monochrome/style.css
+++ b/themes/monochrome/style.css
@@ -36,12 +36,16 @@ body {
* thanks to <http://www.kryogenix.org/days/2002/08/30/external>
*/
#content a[href^="http:"]:after,
-#content a[href^="https:"]:after {
+#content a[href^="https:"]:after,
+#enclosure a[href^="http:"]:after,
+#enclosure a[href^="https:"]:after {
content: "↗";
}
/* you will want to replicate this for your own domain in local.css */
#content a[href^="http://localhost"]:after,
-#content a[href^="http://ikiwiki.info"]:after {
+#content a[href^="http://ikiwiki.info"]:after,
+#enclosure a[href^="http://localhost"]:after,
+#enclosure a[href^="http://ikiwiki.info"]:after {
content: none;
}