]> sipb.mit.edu Git - ikiwiki.git/commitdiff
Merge commit 'fae59b07b02dbcaba892e96ff86f3f800e6ef54a' into sipb
authorAnders Kaseorg <andersk@mit.edu>
Fri, 31 Jan 2014 05:58:10 +0000 (00:58 -0500)
committerAnders Kaseorg <andersk@mit.edu>
Fri, 31 Jan 2014 05:58:10 +0000 (00:58 -0500)
Conflicts:
templates/page.tmpl

90 files changed:
IkiWiki/CGI.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/httpauth.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/mdwn.pm
IkiWiki/Plugin/meta.pm
IkiWiki/Plugin/parentlinks.pm
IkiWiki/Plugin/toc.pm
IkiWiki/UserInfo.pm
IkiWiki/Wrapper.pm
Makefile.PL
README.SIPB [new file with mode: 0644]
TODO.SIPB [new file with mode: 0644]
debian/changelog
doc/bugs/capitalized_attachment_names.mdwn [new file with mode: 0644]
doc/favicon.ico
doc/features.mdwn
doc/forum/How_do_I_enable_OpenID__63__.mdwn [new file with mode: 0644]
doc/forum/Ikiwiki_themes_for_mobile_devices__63__.mdwn [new file with mode: 0644]
doc/forum/Refresh_or_recreate_style.css__63__.mdwn [new file with mode: 0644]
doc/forum/Refresh_or_recreate_style.css__63__/comment_1_3274be931d0b543c7f7cf641810817aa._comment [new file with mode: 0644]
doc/forum/google_openid_broken__63__.mdwn
doc/git.mdwn
doc/ikiwiki/directive/inline.mdwn
doc/ikiwiki/directive/meta.mdwn
doc/ikiwiki/directive/tag/discussion.mdwn [new file with mode: 0644]
doc/ikiwikiusers.mdwn
doc/news/openid.mdwn
doc/news/version_3.20120725.mdwn [deleted file]
doc/news/version_3.20130504.mdwn [new file with mode: 0644]
doc/plugins/contrib/livefyre.mdwn [new file with mode: 0644]
doc/plugins/contrib/mediawiki/discussion.mdwn
doc/plugins/contrib/proxies.mdwn
doc/plugins/type/auth.mdwn
doc/plugins/type/bundle.mdwn
doc/plugins/type/chrome.mdwn
doc/plugins/type/comments.mdwn
doc/plugins/type/core.mdwn
doc/plugins/type/date.mdwn
doc/plugins/type/format.mdwn
doc/plugins/type/fun.mdwn
doc/plugins/type/html.mdwn
doc/plugins/type/link.mdwn
doc/plugins/type/meta.mdwn
doc/plugins/type/slow.mdwn
doc/plugins/type/special-purpose.mdwn
doc/plugins/type/tags.mdwn
doc/plugins/type/web.mdwn
doc/plugins/type/widget.mdwn
doc/sandbox.mdwn
doc/style.css
doc/test.mdwn [deleted file]
doc/tips/DreamHost.mdwn
doc/tips/importing_posts_from_wordpress/ikiwiki-wordpress-import.mdwn
doc/tips/mailman_subscription_form.mdwn [new file with mode: 0644]
doc/todo/BTS_integration.mdwn
doc/todo/Fenced_code_blocks___40__from_GitHub_Flavored_Markdown__41__.mdwn [new file with mode: 0644]
doc/todo/Separate_OpenIDs_and_usernames.mdwn
doc/todo/assumes_system_perl.mdwn
doc/todo/calendar_with___34__create__34___links.mdwn [new file with mode: 0644]
doc/todo/calendar_with___34__create__34___links/incomplete_patch.pl [new file with mode: 0644]
doc/todo/fancypodcast.mdwn
doc/todo/toc-with-human-readable-anchors.mdwn [new file with mode: 0644]
doc/todo/translation_links.mdwn [new file with mode: 0644]
doc/translation/discussion.mdwn
doc/users/schmonz.mdwn
doc/wishlist/watched_pages.mdwn [new file with mode: 0644]
ikiwiki.spec
po/Makefile
po/ikiwiki.pot
t/map.t
t/podcast.t [new file with mode: 0755]
t/tinypodcast/attempted_multiple_enclosures.mdwn [new file with mode: 0644]
t/tinypodcast/fancy.mdwn [new file with mode: 0644]
t/tinypodcast/piano.mp3 [new file with mode: 0644]
t/tinypodcast/pianopost.mdwn [new file with mode: 0644]
t/tinypodcast/scroll.3gp [new file with mode: 0644]
t/tinypodcast/simple.mdwn [new file with mode: 0644]
t/tinypodcast/simplepost.mdwn [new file with mode: 0644]
t/tinypodcast/walter.ogg [new file with mode: 0644]
templates/atomitem.tmpl
templates/editpage.tmpl
templates/inlinepage.tmpl
templates/page.tmpl
templates/rssitem.tmpl
templates/rsspage.tmpl
themes/actiontabs/style.css
themes/blueview/style.css
themes/goldtype/style.css
themes/monochrome/style.css

index 5baa6c1798ef02e1f45680daa032da17674fafb0..5ea1080342a5514e2114e4a78af3ba04b0ef26fb 100644 (file)
@@ -159,7 +159,9 @@ sub cgi_signin ($$;$) {
                template => {type => 'div'},
                stylesheet => 1,
        );
-       my $buttons=["Login"];
+       # MITLOGIN: These should be restored when logins are allowed again.
+       #my $buttons=["Login"];
+       my $buttons=[];
        
        $form->field(name => "do", type => "hidden", value => "signin",
                force => 1);
@@ -258,13 +260,16 @@ sub cgi_prefs ($$) {
                force => 1);
        $form->field(name => "sid", type => "hidden", value => $session->id,
                force => 1);
-       $form->field(name => "email", size => 50, fieldset => "preferences");
+            #$form->field(name => "email", size => 50, fieldset => "preferences");
+       $form->field(name => "realname", size => 50, fieldset => "preferences");
        
        my $user_name=$session->param("name");
 
        if (! $form->submitted) {
-               $form->field(name => "email", force => 1,
-                       value => userinfo_get($user_name, "email"));
+            #$form->field(name => "email", force => 1,
+            #value => userinfo_get($user_name, "email"));
+               $form->field(name => "realname", force => 1,
+                       value => userinfo_get($user_name, "realname"));
        }
        
        if ($form->submitted eq 'Logout') {
@@ -281,7 +286,10 @@ sub cgi_prefs ($$) {
                        userinfo_set($user_name, 'email', $form->field('email')) ||
                                error("failed to set email");
                }
-
+               if (defined $form->field('realname')) {
+                       userinfo_set($user_name, 'realname', $form->field('realname')) ||
+                               error("failed to set realname");
+                }
                $form->text(gettext("Preferences saved."));
        }
        
index 3879abeae5b20e05d4f9c2990c270c6943982b65..bf6cfd9a136b66ad6bec1a25044ed539e3377388 100644 (file)
@@ -4,6 +4,7 @@ package IkiWiki::Plugin::git;
 use warnings;
 use strict;
 use IkiWiki;
+use IkiWiki::UserInfo;
 use Encode;
 use URI::Escape q{uri_escape_utf8};
 use open qw{:utf8 :std};
@@ -532,7 +533,8 @@ sub rcs_commit_helper (@) {
                }
                if (defined $u) {
                        $u=encode_utf8($u);
-                       $ENV{GIT_AUTHOR_NAME}=$u;
+                       # MITLOGIN This algorithm could be improved
+                       $ENV{GIT_AUTHOR_NAME}=IkiWiki::userinfo_get($u, "realname");
                }
                if (defined $params{session}->param("nickname")) {
                        $u=encode_utf8($params{session}->param("nickname"));
@@ -540,7 +542,7 @@ sub rcs_commit_helper (@) {
                        $u=~s/[^-_0-9[:alnum:]]+//g;
                }
                if (defined $u) {
-                       $ENV{GIT_AUTHOR_EMAIL}="$u\@web";
+                       $ENV{GIT_AUTHOR_EMAIL}="$u\@mit.edu";
                }
        }
 
index 76d574b2a899df7e77cb71f2a4f27ee078e76b43..7028130eefe8b62a0659588ec94d1fedc028eae8 100644 (file)
@@ -5,6 +5,7 @@ package IkiWiki::Plugin::httpauth;
 use warnings;
 use strict;
 use IkiWiki 3.00;
+use Data::Dumper;
 
 sub import {
        hook(type => "checkconfig", id => "httpauth", call => \&checkconfig);
@@ -67,7 +68,14 @@ sub auth ($$) {
        my $session=shift;
 
        if (defined $cgi->remote_user()) {
-               $session->param("name", $cgi->remote_user());
+               my $user = $cgi->remote_user();
+               $session->param("name", $user);
+               eval IkiWiki::possibly_foolish_untaint($ENV{SSL_CLIENT_S_DN_CN});
+               my $realname = IkiWiki::userinfo_get($user, "realname");
+               if ((!defined $realname || $realname eq "") &&
+                   defined $ENV{SSL_CLIENT_S_DN_CN}) {
+               IkiWiki::userinfo_set($user, "realname", $ENV{SSL_CLIENT_S_DN_CN});
+               }
        }
 }
 
index 8eb033951a365ce2ada82394c94c8e903ae858df..e313eb7755313ea051b14f43310168fb5750dd0e 100644 (file)
@@ -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,27 @@ 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};
+
+                               # XXX better way to compute relative to srcdir?
+                               my $file = $absurl;
+                               $file =~ s|^$config{url}/||;
+
+                               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 +710,7 @@ sub genfeed ($$$$$@) {
                feeddesc => $feeddesc,
                guid => $guid,
                feeddate => date_3339($lasttime),
+               feeddate_822 => date_822($lasttime),
                feedurl => $feedurl,
        );
        run_hooks(pagetemplate => sub {
index 430194bffdcc6444f34036709d9dc3767187af85..b7ed2c5081df90f447a2bcb3cf3187b10c263d71 100644 (file)
@@ -78,7 +78,7 @@ sub htmlize (@) {
                }
                if (! defined $markdown_sub) {
                        eval q{use Text::Markdown};
-                       if (! $@) {
+                       if (1) {#! $@) {  # Text::Markdown throws this but works.  Shrug.
                                if (Text::Markdown->can('markdown')) {
                                        $markdown_sub=\&Text::Markdown::markdown;
                                }
index 421f1dc86a83d33ac823f9989ad9e42c6dea12c9..794f6d861dbfb8bb5ca9fc452ae089055768b432 100644 (file)
@@ -107,12 +107,12 @@ sub preprocess (@) {
                # fallthrough
        }
        elsif ($key eq 'license') {
-               push @{$metaheaders{$page}}, '<link rel="license" href="#page_license" />';
+               push @{$metaheaders{$page}}, '<link rel="license" href="#pagelicense" />';
                $pagestate{$page}{meta}{license}=$value;
                return "";
        }
        elsif ($key eq 'copyright') {
-               push @{$metaheaders{$page}}, '<link rel="copyright" href="#page_copyright" />';
+               push @{$metaheaders{$page}}, '<link rel="copyright" href="#pagecopyright" />';
                $pagestate{$page}{meta}{copyright}=$value;
                return "";
        }
@@ -121,6 +121,17 @@ 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;
+               # fallthrough
+       }
        elsif ($key eq 'author') {
                $pagestate{$page}{meta}{author}=$value;
                if (exists $params{sortas}) {
@@ -318,6 +329,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}))
index 9f16dd08296a5743084fc390ddde362e3a6a5fe9..ef08118b4557ecd8a7b819c6a0bd0dffcc938af1 100644 (file)
@@ -41,10 +41,17 @@ sub parentlinks ($) {
 
        my @pagepath=(split("/", $page));
        my $pagedepth=@pagepath;
+
+       # The last element in @pagepath is the page itself, so punt that
+       # (These are /parent/ links, after all.)
+       pop @pagepath;
+
        foreach my $dir (@pagepath) {
                next if $dir eq 'index';
                $depth=$i;
                $height=($pagedepth - $depth);
+               $path.="/".$dir;
+               $title=pagetitle($dir);
                push @ret, {
                        url => urlto(bestlink($page, $path), $page),
                        page => $title,
@@ -53,8 +60,6 @@ sub parentlinks ($) {
                        "depth_$depth" => 1,
                        "height_$height" => 1,
                };
-               $path.="/".$dir;
-               $title=pagetitle($dir);
                $i++;
        }
        return @ret;
index ac07b9af6b860f0e5a36909197b4d98d0388fa41..1e888a82d0222a5814bdfe0aa86f75dc4a94c2f8 100644 (file)
@@ -29,6 +29,7 @@ sub preprocess (@) {
 
        if ($params{page} eq $params{destpage}) {
                $params{levels}=1 unless exists $params{levels};
+               $params{startlevel}=2 unless exists $params{startlevel};
 
                # It's too early to generate the toc here, so just record the
                # info.
index 0bf100a959c934d23c8f73ac1f0962f856732a35..31f20c51736ad930908676c0e694ddacfceb3cac 100644 (file)
@@ -36,8 +36,17 @@ sub userinfo_get ($$) {
        if (! defined $userinfo ||
            ! exists $userinfo->{$user} || ! ref $userinfo->{$user} ||
             ! exists $userinfo->{$user}->{$field}) {
+               if ($field eq "realname" && defined $ENV{SSL_CLIENT_S_DN_CN}) {
+                       userinfo_set($user, "realname", $ENV{SSL_CLIENT_S_DN_CN});
+                       return $ENV{SSL_CLIENT_S_DN_CN};
+               }
                return "";
        }
+       if ($field eq "realname" && $userinfo->{$user}->{$field} eq "" &&
+           defined $ENV{SSL_CLIENT_S_DN_CN}) {
+               userinfo_set($user, "realname", $ENV{SSL_CLIENT_S_DN_CN});
+               return $ENV{SSL_CLIENT_S_DN_CN};
+       }
        return $userinfo->{$user}->{$field};
 }
 
index 84b4b5a2f298f23bac5d5e223fb4144a7ebd72f1..38a9cdbec82dad0c6caeb873d0e5d28933c55606 100644 (file)
@@ -49,7 +49,7 @@ sub gen_wrapper () {
        my @envsave;
        push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
                       CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
-                      HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS
+                      HTTP_COOKIE REMOTE_USER HTTPS SSL_CLIENT_S_DN_CN REDIRECT_STATUS
                       HTTP_HOST SERVER_PORT HTTPS HTTP_ACCEPT
                       REDIRECT_URL} if $config{cgi};
        my $envsave="";
@@ -267,7 +267,6 @@ EOF
                #translators: The parameter is a C filename.
                error(sprintf(gettext("failed to compile %s"), "$wrapper.c"));
        }
-       unlink("$wrapper.c");
        if (defined $config{wrappergroup}) {
                my $gid=(getgrnam($config{wrappergroup}))[2];
                if (! defined $gid) {
index ef29a950c777b8e3c7b74821790a1b184be28c3b..f1df8bcd3f2dbfa463e3e182c4a295f5b547ff7d 100755 (executable)
@@ -96,7 +96,7 @@ underlay_install:
                install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$theme; \
                for file in $$theme/*; do \
                        if echo "$$file" | grep -q style.css; then \
-                               (cat doc/style.css; cat $$theme/base.css 2>/dev/null; cat $$file) >> $(DESTDIR)$(PREFIX)/share/ikiwiki/$$theme/style.css; \
+                               (cat doc/style.css; cat $$theme/base.css 2>/dev/null; cat $$file) > $(DESTDIR)$(PREFIX)/share/ikiwiki/$$theme/style.css; \
                        elif echo "$$file" | grep -q base.css; then \
                                :; \
                        elif [ -f "$$file" ]; then \
diff --git a/README.SIPB b/README.SIPB
new file mode 100644 (file)
index 0000000..c88f193
--- /dev/null
@@ -0,0 +1,56 @@
+README for SIPB maintainers
+
+Basic instructions on scripts of interest. Also,
+How this repository is set up, and how to keep IkiWiki up to date.
+
+
+Setup:
+
+There are three branches of interest: remotes/origin/master, master
+and sipb.  remotes/origin/master is the remote branch we are tracking;
+all upstream changes show up in this branch when we `git fetch`.
+
+master is our "awaiting upstream approval" branch, based off of
+remotes/origin/master. Any patches in this branch should be immediately
+suitable for submission to IkiWiki maintainers/. Ideally, this branch
+should be equivalent to remotes/origin/master.
+
+sipb is our live branch. It contains all of the ugly hacks and custom
+modifications that we needed to make our website run. Ideally, this
+branch is equivalent to master. Don't expect it to be without a lot
+of rearchitecting and upstream cooperation.
+
+
+Keeping up to date:
+
+XXX: This is what we'd do in our original clone of upstream.
+  How do we do this now that we have our own internal repo to clone?
+
+This two-tiered setup means that you will need to rebase twice in order
+to propagate changes; possibly once if master == origin/master. Your
+commands will look like this:
+
+$ git checkout master
+$ git pull --rebase
+$ git checkout sipb
+$ git rebase master
+
+TODO: Make a script that does this.
+
+
+Scripts:
+
+The source repository has a hook that automatically deploys changes when
+you push to it.  If bad things happen, however, there are two scripts of
+interest:
+
+~/bin/reinstall-ikiwiki
+    This script runs make and make install, reinstalling the source files to
+    make it live.
+
+~/bin/update-ikiwiki
+    This script recompiles the website from its source directory
+    ikiwiki/src into the live wiki directory web_scripts/wiki.
+
+Normally, these don't need to be run.
+
diff --git a/TODO.SIPB b/TODO.SIPB
new file mode 100644 (file)
index 0000000..1208f15
--- /dev/null
+++ b/TODO.SIPB
@@ -0,0 +1,12 @@
+Todo list
+
+* Presently, we only allow certificate'ed logins to edit the wiki. Eventually,
+  we will want to allow for some passworded users. When this happens, several
+  considerations must be taken:
+
+  * Unless user accounts are made on a case-by-case basis manually by
+    SIPB members (which should definitely be considered), there must be
+    anti-spam measures in the registration process.
+
+  * Certain files had hacks added to them. They are marked by MITLOGIN
+
index 1657ffcb608c53c51be26462ee05569ac8b4cfaa..e6d39fa27b17169b53abd6e19a58b1be69c2c00b 100644 (file)
@@ -1,12 +1,23 @@
-ikiwiki (3.20130213) UNRELEASED; urgency=low
+ikiwiki (3.20130505) UNRELEASED; urgency=low
+
+  * Fix test suite to not fail when XML::Twig is not installed.
+    Closes: #707436
+
+ -- Joey Hess <joeyh@debian.org>  Thu, 09 May 2013 10:47:18 -0400
+
+ikiwiki (3.20130504) unstable; urgency=low
 
   * Allow dots in directive parameter names. (tango)
   * Add missing plugin section, and deal with missing sections with a warning.
   * Detect plugins with a broken getsetup and warn.
   * map: Correct reversion introduced in version 3.20110225 that could
     generate invalid html. (smcv)
+  * Makefile.PL: overwrite theme style.css instead of appending
+    (Thanks, Mikko Rapeli)
+  * meta: Fix anchors used to link to the page's license and copyright.
+    Closes: #706437
 
- -- Joey Hess <joeyh@debian.org>  Fri, 15 Feb 2013 17:23:12 -0400
+ -- Joey Hess <joeyh@debian.org>  Sat, 04 May 2013 23:47:21 -0400
 
 ikiwiki (3.20130212) unstable; urgency=low
 
diff --git a/doc/bugs/capitalized_attachment_names.mdwn b/doc/bugs/capitalized_attachment_names.mdwn
new file mode 100644 (file)
index 0000000..b10781b
--- /dev/null
@@ -0,0 +1,14 @@
+Given an uploaded image via: \[\[!img NAME.svg alt="image"\]\]
+
+Viewing the generated page shows the following error:
+
+"\[\[!img Error: failed to read name.svg: Exception 420: no decode delegate for this image format `/home/user/path/name.svg' @ error/svg.c/ReadSVGImage/2815\]\]"
+
+The caps in the image title were somehow converted to small letters and then the image is saved as a directory.  Very puzzling.  
+I get the same error when image names are small letters.
+
+The error also occurs with png images.  
+
+How do I fix this?
+
+Later investigation ... I got around the problem by creating the mark-up in a new directory.  However, if I try to create a new directory with the same name as the directory containing the problem code, the problem re-emerges -- the old directory is apparently not overwritten.  Perhaps this is an issue with the git storage.    
index b55eba2800de9d41d9288bc084cde8ff649f8414..5adc83a647a79a061e05faaff12f7e330567336b 100644 (file)
Binary files a/doc/favicon.ico and b/doc/favicon.ico differ
index 66f7ecb7381383ac9b326779682643501e8dcd0e..5bbe5ef2190685c98a0c8a7b5d5f2d5553343a6e 100644 (file)
@@ -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/forum/How_do_I_enable_OpenID__63__.mdwn b/doc/forum/How_do_I_enable_OpenID__63__.mdwn
new file mode 100644 (file)
index 0000000..a4e1a45
--- /dev/null
@@ -0,0 +1 @@
+I'm trying to set up a new ikiwiki based blog and I want commentors to be able to log in with OpenID.  To enable OpenID I installed Net::OpenID::Consumer, and enabled the openid plugin in my blog.setup file and ran the ikiwiki --setup command.  Despite doing that I still only see the username and password in the login screen.  What am I missing?
diff --git a/doc/forum/Ikiwiki_themes_for_mobile_devices__63__.mdwn b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__.mdwn
new file mode 100644 (file)
index 0000000..dc1b31c
--- /dev/null
@@ -0,0 +1,7 @@
+Has anyone else created ikiwiki themes for mobile devices like phones and tablets?
+
+I've been using Blueview theme for a few years and finally tried to adapt the theme for my phone.
+My local.css is [here](http://mcfrisk.kapsi.fi/local.css), and my hobby web page full of images and videos [here](http://mcfrisk.kapsi.fi/skiing/).
+
+Previously I also had problems like wasted screen space, big minimum width and images not scaled down to the CSS element. Those got fixed as well.
+Would be nice if others could test that and maybe share their setups.
diff --git a/doc/forum/Refresh_or_recreate_style.css__63__.mdwn b/doc/forum/Refresh_or_recreate_style.css__63__.mdwn
new file mode 100644 (file)
index 0000000..262b0e3
--- /dev/null
@@ -0,0 +1,40 @@
+I was trying to use plain blueview theme but that's not what I see in the installed style.css:
+
+    ~/src/ikiwiki/themes/blueview$ grep bzed style.css
+    /*    bzed theme for ikiwiki
+    ~/src/ikiwiki/themes/blueview$ wc -l style.css
+    281 style.css
+    $ grep bzed ~/www/style.css
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    $ wc -l ~/www/style.css
+    7913
+
+I have installed ikiwiki to my home directory on the shared server and it seems the big css file is there too:
+
+    $ grep bzed ~/bin/share/ikiwiki/themes/blueview/style.css 
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    /*    bzed theme for ikiwiki
+    $ wc -l ~/bin/share/ikiwiki/themes/blueview/style.css 
+    7913
+
+Is the style.css really supposed to be that big?
+If not, how to create it from scratch?
+
+Reason why I'm debugging the css is that I'd like to make it better on small handset screens, like drop all margins, inline or hide sidebar etc. Chromium shows that the processed css is quite a mess.
diff --git a/doc/forum/Refresh_or_recreate_style.css__63__/comment_1_3274be931d0b543c7f7cf641810817aa._comment b/doc/forum/Refresh_or_recreate_style.css__63__/comment_1_3274be931d0b543c7f7cf641810817aa._comment
new file mode 100644 (file)
index 0000000..608dca0
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://mcfrisk.myopenid.com/"
+ nickname="mikko.rapeli"
+ subject="bug/feature in Makefile.PL"
+ date="2013-03-30T11:53:41Z"
+ content="""
+Theme style.css files were appended when installing in Makefile.PL. IMO overwriting the destination files is more correct. Sent a patch to Joey.
+"""]]
index 96ba2d79145adbc9c2fdcaba05201a380b57ce6c..d25d8fe4cc3d29d29fa7176a9ee833a58f2e1e17 100644 (file)
@@ -4,6 +4,9 @@ directly to sign into ikiwiki. Just use, for example,
 
 > This seems to work fine if you use the profile directly as an OpenID.  It doesn't seem to work with delegation.  From that I can see, this is a deliberate decision by Google for security reasons.  See the response [here](http://groups.google.com/group/google-federated-login-api/browse_thread/thread/825067789537568c/23451a68c8b8b057?show_docid=23451a68c8b8b057). -- [[Will]]
 
+### adding the GMail OpenID as an admin is unhandy
+Adding the non-human-friendly OpenID from Gmail as an admin for ikiwiki (if you haven't set up a profile with a readabe URL) is unhandy; first, you need to discover the URL, for example, by making a web edit with it (like me [here](http://source.ikiwiki.branchable.com/?p=source.git;a=search;s=https://www.google.com/accounts/o8/id%3Fid%3DAItOawl3JW_Ow4xMqj98Ig1vwGx_AnjUSsgwE8E;st=author)), and then copy the URL to ikiwiki.setup. --Ivan Z.
+
 ## historical discussion
 
 when I login via to this wiki (or ours) via Google's OpenID, I get this error:
index 25a360efdcef2c28218f0389c3bb8df6fe80ab1a..b743f6175e9c28db46165f5c710076af4b13fc93 100644 (file)
@@ -76,6 +76,7 @@ think about merging them. This is recommended. :-)
 * [[ttw]] `git://github.com/ttw/ikiwiki.git`
 * [[anarcat]] `git://src.anarcat.ath.cx/ikiwiki`
 * anderbubble `git://civilfritz.net/ikiwiki.git`
+* frioux `git://github.com/frioux/ikiwiki`
 
 ## branches
 
index a9c241afc1859951975961347af6c490dbc292d4..c0d4e035b2a1bc2cde5bd0b079471f49d56e25e4 100644 (file)
@@ -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
index 984f685402f28993eb7b1a11a761c3430eacd910..fbbffa575b5b858ced971313d8b38dd997bb2a18 100644 (file)
@@ -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/ikiwiki/directive/tag/discussion.mdwn b/doc/ikiwiki/directive/tag/discussion.mdwn
new file mode 100644 (file)
index 0000000..23352eb
--- /dev/null
@@ -0,0 +1,13 @@
+# Tags in HTML pages
+
+http://rhombus-tech.net is an ikiwiki site where the hardware development is expanding: there are now four hardware projects each of which has its own news page.  For convenience (putting in images for example), the pages have to use HTML not markdown or any other non-HTML format.
+
+However as there are quite a lot of them it would make sense to have an overview page saying "news reports", and that page to be auto-generated because every individual news page is tagged.
+
+... except the news pages are written in HTML, not any markup language into which a tag can be placed.
+
+question: what is the directive which allows an HTML page to have embedded within it a markup "tag"?
+
+> You can use the tag directive in `.html` pages, just like in `.mdwn` pages. This is if you're using
+> the default html plugin. If you instead use the rawhtml plugin, ikiwiki just copies your html files
+> and directives in them won't work. --[[Joey]]
index 3098145582c3c84b5ccf1600d9b849963caa5648..6b657c8ff8d1bed83f9d405881e822ddbb51f9d8 100644 (file)
@@ -87,6 +87,7 @@ Projects & Organizations
 * [The Open TV White Space Project](http://opentvws.org)
 * [The RS-232 Club](http://rs232club.org)
 * [FusionInventory project](http://www.fusioninventory.org)
+* FabLab Deventer i.o.
 
 Personal sites and blogs
 ========================
@@ -189,4 +190,4 @@ Personal sites and blogs
 * [[Martín Ferrari's homepage|http://tincho.org/]] and [[blog|http://blog.tincho.org/]]
 * [WikiAtoBR](http://wiki.hi.ato.br) Open, free and annoymous wiki. No need for account registering and login. It is Brazilian so it is in Portuguese.
 * [Manifesto](http://manifesto.hi.ato.br) Open, free and annoymous blog. No need for account registering and login. It is Brazilian so it is in Portuguese.
-
+ * [Z is for Zombies](http://blog.zouish.org/) — personal blog/site of Francesca Ciceri
index b13e821468844ed5a09de160c6748fa33a659f38..8f04c5e90496b499c8d830b87102c937924e7c15 100644 (file)
@@ -10,4 +10,4 @@ log back in, try out the OpenID signup process if you don't already have an
 OpenID, and see how OpenID works for you. And let me know your feelings about
 making such a switch. --[[Joey]]
 
-[[!poll 69 "Accept only OpenID for logins" 21 "Accept only password logins" 44 "Accept both"]]
+[[!poll 70 "Accept only OpenID for logins" 21 "Accept only password logins" 46 "Accept both"]]
diff --git a/doc/news/version_3.20120725.mdwn b/doc/news/version_3.20120725.mdwn
deleted file mode 100644 (file)
index 08e2c77..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-ikiwiki 3.20120725 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * recentchangesdiff: When diffurl is not set, provide inline diffs
-     in the recentchanges page, with visibility toggleable via javascript.
-     Thanks, Antoine Beaupré
-   * Split CFLAGS into words when building wrapper. Closes: #[682237](http://bugs.debian.org/682237)
-   * osm: Avoid calling urlto before generated files are registered.
-     Thanks, Philippe Gauthier and Antoine Beaupré
-   * osm: Add osm\_openlayers\_url configuration setting.
-     Thanks, Genevieve
-   * osm: osm\_layers can be used to configured the layers displayed on the map.
-     Thanks, Antoine Beaupré
-   * comments: Remove ipv6 address specific code."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20130504.mdwn b/doc/news/version_3.20130504.mdwn
new file mode 100644 (file)
index 0000000..18baf01
--- /dev/null
@@ -0,0 +1,11 @@
+ikiwiki 3.20130504 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Allow dots in directive parameter names. (tango)
+   * Add missing plugin section, and deal with missing sections with a warning.
+   * Detect plugins with a broken getsetup and warn.
+   * map: Correct reversion introduced in version 3.20110225 that could
+     generate invalid html. (smcv)
+   * Makefile.PL: overwrite theme style.css instead of appending
+     (Thanks, Mikko Rapeli)
+   * meta: Fix anchors used to link to the page's license and copyright.
+     Closes: #[706437](http://bugs.debian.org/706437)"""]]
\ No newline at end of file
diff --git a/doc/plugins/contrib/livefyre.mdwn b/doc/plugins/contrib/livefyre.mdwn
new file mode 100644 (file)
index 0000000..d4a62c0
--- /dev/null
@@ -0,0 +1,14 @@
+[[!template id=plugin name=livefyre core=0 author="[[cmauch]]"]]
+[[!tag  type/special-purpose]]
+
+[LiveFyre](http://www.livefyre.com) is a third party comment and discussion system similar in some ways to Disqus or IntenseDebate.  All three services use javascript to attach comments to your site without the need to use a native commenting system.  
+
+This plugin is designed to replace the commenting system in IkiWiki entirely.  It embeds LiveFyre comments on your ikiwiki blog or posts.  It is was originally based on the [Disqus Plugin](https://code.google.com/p/ikiwiki-plugin-disqus/).  After a few days of noticing odd page title names on the livefyre moderation interface, I updated the script to make use of JSON.  I made extensive use of the [integration guide](https://github.com/Livefyre/livefyre-docs/wiki/StreamHub-Integration-Guide) to get it all running.
+
+It's loud and messy and slow, but kind of neat too.
+
+Requires the [[!cpan JSON]], [[!cpan JSON::WebToken]], and [[!cpan Digest::MD5]] perl modules to be available. 
+
+You can grab the source [here](https://bitbucket.org/cmauch/ikiwiki/src/master/IkiWiki/Plugin/livefyre.pm)
+
+See the POD documention in the module for installation and configuration instructions.
index 5066d9de54be523707f91aaa8f7ca8ee34eb876e..c288d9bd182a59a18818cfef06368f60531267b0 100644 (file)
@@ -3,3 +3,7 @@ Anyone know a safe place where this plugin can be found? -- mjr at phonecoop.coo
 > I ended up doing a backassward way of doing it, as described at the [convert discussion page](http://ikiwiki.info/tips/convert_mediawiki_to_ikiwiki/discussion/). -[[simonraven]]
 
 >> I've mirrored it at <http://alcopop.org/~jon/mediawiki.pm>. -- [[Jon]]
+
+---
+
+Something that gives me better results is to edit the source of the [[wikitext]] plugin, and change all occurences of Text::WikiFormat to Text::MediawikiFormat. (This of course depends on ''libtext-mediawikiformat-perl'' instead of ''libtext-wikiformat-perl'' -- [[gi1242]]
index dc53adf2955d6916663691d79f4b0a62e09794a5..7f8f5faaf1a6fd98117a42196f040d49703c3553 100644 (file)
@@ -1,6 +1,6 @@
 [[!template id=plugin name=proxies author="[[schmonz]]"]]
 [[!template id=gitbranch branch=schmonz/proxies author="[[schmonz]]"]]
-[[!tag type/format]]
+[[!tag type/web]]
 
 This plugin enables ikiwiki to open outbound connections (such as
 found in [[plugins/aggregate]], [[plugins/openid]], and [[plugins/pinger]])
index 400a5bccad9b143822ab3d52368eb09308600ff3..6a1f2d12c64653682965b4466b90174501575cbd 100644 (file)
@@ -1,2 +1,4 @@
 These plugins add different authentication methods for logging in to the
 wiki and control what pages users can edit.
+
+[[!map pages="plugins/* and tagged(.)"]]
index 0bf049ece72d6c40a9b699c1a1d993851a34ec21..980dbbe5776053b50f38ca2df5cec957777e45e8 100644 (file)
@@ -1 +1,3 @@
 These plugins enable whole bundles of other plugins.
+
+[[!map pages="plugins/* and tagged(.)"]]
index a1c6d07283c66623e2c533b349c5375f47cdae20..73a6e58985b80d6ede15b96c3678952608a0d6cf 100644 (file)
@@ -1 +1,3 @@
 These plugins affect the look and feel of the overall wiki.
+
+[[!map pages="plugins/* and tagged(.)"]]
index 6eaa2c25a0b875598549dd27c6c6883e11037fb0..1e4dd7278fc2c42bbb011bde399cebfdc48f0c30 100644 (file)
@@ -1 +1,3 @@
 These plugins relate to [[plugins/comments]].
+
+[[!map pages="plugins/* and tagged(.)"]]
index 71d93c4a6763dea439fd19230504d6079876c73d..2646996ba2fc744adb0f76ead8a86ed063349e8c 100644 (file)
@@ -1 +1,3 @@
 These plugins provide core functionality and are enabled by default.
+
+[[!map pages="plugins/* and tagged(.)"]]
index eae1226dad02b4df9c999b55188717eb42fa314f..b95a7ecd3c05668aec9d323ef65bb3503c298d91 100644 (file)
@@ -1 +1,3 @@
 These plugins control how ikiwiki displays dates.
+
+[[!map pages="plugins/* and tagged(.)"]]
index a60d725d8d1696d832f576ad5c8638912dba3e75..8a100f963a387dcaecd6b6b32c40ee65f6b74b60 100644 (file)
@@ -1 +1,3 @@
 These plugins provide ways to format text on wiki pages.
+
+[[!map pages="plugins/* and tagged(.)"]]
index 4d97c8e6641aa6adac4aec3ea2e7dde3d67cd2a1..ad9e9c2e66c89463fe005b77f6d08a6225eef151 100644 (file)
@@ -1 +1,3 @@
 These plugins are just for fun.
+
+[[!map pages="plugins/* and tagged(.)"]]
index 290208f92312906a0eac02fb463111d7ed2fd89c..94e13b621e6150d0ec6a30dd8a026b73decdd893 100644 (file)
@@ -1 +1,3 @@
 These plugins generate or process html.
+
+[[!map pages="plugins/* and tagged(.)"]]
index c10863fac250d39c4271b3729c73d31b7c304ec1..fce27ae9c6f0c0a0f9a9c065f3d99b9828cb1e8f 100644 (file)
@@ -1 +1,3 @@
 These plugins deal with [[WikiLinks|ikiwiki/WikiLink]].
+
+[[!map pages="plugins/* and tagged(.)"]]
index cae30cad17512e0926c1790a53a4268c66c8f9a1..7a339747e93b89b98f7fddbb1dea2cf8e60f6170 100644 (file)
@@ -1 +1,3 @@
 These plugins deal in meta-information about the wiki.
+
+[[!map pages="plugins/* and tagged(.)"]]
index c0e72158527356b5979ec60f23243b50261cd28c..5907d26f96f75e423392c03080eaac3bb9a37565 100644 (file)
@@ -1,3 +1,5 @@
 These plugins can cause wiki rendering to be significantly slowed down,
 due to things like needing to run an external program for every page
 rendered.
+
+[[!map pages="plugins/* and tagged(.)"]]
index b6ed045313cb89acc1f0df6f2eaae39f84bc36ae..7aeb8be9ce6d71567e900943b88369b101b8508b 100644 (file)
@@ -1 +1,3 @@
 Special-purpose plugins.
+
+[[!map pages="plugins/* and tagged(.)"]]
index bb74066f8f2f0300f4bed9d1f8c8b36bffec807f..78daebd53180781fcd057b93c80c9ce35dcb0a1a 100644 (file)
@@ -1 +1,3 @@
 These plugins support tagging.
+
+[[!map pages="plugins/* and tagged(.)"]]
index b60e26a29f5d6f8246012442f88a5613747ddee5..6ebd6cd373930588e6819ea7e3fd691d0b977e78 100644 (file)
@@ -1 +1,3 @@
 These plugins enhance the web interface.
+
+[[!map pages="plugins/* and tagged(.)"]]
index 875829d0bcdb048f0e0b749f8b8c728ff402e010..496b7da2465d3a94fb93ae36857eb3d1d2532918 100644 (file)
@@ -1,2 +1,4 @@
 These plugins allow inserting various things into pages via a
 [[ikiwiki/directive]].
+
+[[!map pages="plugins/* and tagged(.)"]]
index c7c91e4fbef56d27a3a932960de1fd31c73ecc62..3ecd588439bca77d499ed24269638712615b3db5 100644 (file)
@@ -13,6 +13,10 @@ hello world
 >>> to three levels
 >
 > Back to the first level.
+>
+> added a line in level 1
+> and another
+
 
 Numbered list 
 
@@ -69,6 +73,7 @@ test _this_ out.
 
 _italic_
 
+test ms
 
 opopopo
 ----
index 424d438167dd9ee5272ec55971f261515a4d95ff..81b6a0a284832e5d61b6673e1fb1c76dae776a81 100644 (file)
@@ -58,7 +58,8 @@ nav {
        border-bottom: 1px solid #000;
 }
 
-.inlinecontent {
+.inlinecontent,
+.inlineenclosure {
        margin-top: .4em;
 }
 
diff --git a/doc/test.mdwn b/doc/test.mdwn
deleted file mode 100644 (file)
index 8ae0569..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# Test
index 070638e3e41a947f5717f92f26365459cd673bb9..338bca78239e33500f38bf0209150b941796eb63 100644 (file)
@@ -176,6 +176,7 @@ Then you'll have to add a few variables to your path [referenced by your compile
 
     export C_INCLUDE_PATH=YOUR_INSTALL_PATH_HERE/include/
     export LIBRARY_PATH=YOUR_INSTALL_PATH_HERE/lib/
+    export LD_LIBRARY_PATH=YOUR_INSTALL_PATH_HERE/lib/
 
 Then you should be able to install the module, and it'll be faster.
 
index 0c0527f2ce8e84a7d4aff0e1f9a85fb875ad64f5..a59d4b5ad48595418d915b12382370f82a3b3064 100644 (file)
@@ -1,9 +1,244 @@
 [[!meta title="ikiwiki-wordpress-import"]]
 
+I converted the script to Perl.  The new version gets your name and email automatically from your git config, converts the body of your posts to markdown, and also imports comments.  More importantly it works with the latest wordpress, which the python version does not.  Note that it's still not 100% perfect and I intend to make a few modifications still, but they will require access to the mysql database and that may render the script useless to some users.
+
+-----
+[[!format perl '''
+#!/usr/bin/env perl
+
+use 5.16.1;
+use warnings;
+
+use XML::Simple;
+use DateTime::Format::Strptime;
+use HTML::WikiConverter;
+use LWP::UserAgent;
+use Try::Tiny;
+use Digest::MD5 'md5_hex';
+
+die "usage: $0 import_file subdir [branch] | git-fast-import"
+   unless @ARGV == 2 or @ARGV == 3;
+
+chomp(my $name = qx(git config --get user.name));
+chomp(my $email = qx(git config --get user.email));
+
+my ($file, $subdir, $branch) = @ARGV;
+
+my %events;
+
+POST:
+for my $x (grep $_->{'wp:status'} eq 'publish', @{XMLin($file)->{channel}{item}}) {
+   state $date_parser = DateTime::Format::Strptime->new(
+      pattern => '%F %T',
+      time_zone => 'UTC',
+   );
+
+   my $stub = $x =~ m<([^/]+)\/$>
+      ? $1
+      : lc($x->{title} =~ s/\W/-/gr =~ s/-$//r)
+   ;
+
+   my $guid = $x->{guid}{content} || $x->{link};
+   utf8::encode($x->{title});
+   my $msg = qq($x->{title}\n\nfrom WordPress [$guid]);
+   my $timestamp = $date_parser
+      ->parse_datetime($x->{'wp:post_date_gmt'})
+      ->epoch;
+
+   my $c = $x->{category};
+   $c = [$c] if ref $c && ref $c ne 'ARRAY';
+
+   my $content =
+      sprintf(qq([[!meta title="%s"]]\n), $x->{title} =~ s/"/\\"/gr) .
+      convert_content($x->{'content:encoded'}) . "\n\n" .
+      join("\n",
+         map '[[!tag ' . s/ /-/r . ']]',
+         keys %{
+            +{
+               map { $_ => 1 }
+               grep $_ ne 'uncategorized',
+               map $_->{nicename},
+               @$c
+            }
+         }
+      );
+
+   $events{$timestamp} = join "\n",
+      "commit refs/heads/$branch",
+      "committer $name <$email> $timestamp +0000",
+      'data <<8675309',
+      $msg,
+      '8675309',
+      "M 644 inline $subdir/$stub.mdwn",
+      'data <<8675309',
+      $content,
+      '8675309'
+   ;
+
+   get_comments($x->{link}, "$subdir/$stub")
+      if $x->{'wp:post_type'} eq 'post'
+}
+
+sub get_comments {
+   my ($url, $dir) = @_;
+
+   state $ua = LWP::UserAgent->new;
+
+   my $content = $ua->get("$url/feed")->decoded_content;
+   my $first;
+   my $bail;
+   my $decoded =
+      try { XMLin($content, ForceArray => ['item']) }
+      catch { $bail = 1 };
+
+   return if $bail;
+
+   COMMENT:
+   for my $x (@{$decoded->{channel}{item}}) {
+      my $date = $x->{pubDate};
+      $date =~ s/^\S+\s//;
+      $date =~ s/\s\S+$//;
+
+      #ghetto
+      $date =~ s/Jan/01/;
+      $date =~ s/Feb/02/;
+      $date =~ s/Mar/03/;
+      $date =~ s/Apr/04/;
+      $date =~ s/May/05/;
+      $date =~ s/Jun/06/;
+      $date =~ s/Jul/07/;
+      $date =~ s/Aug/08/;
+      $date =~ s/Sep/09/;
+      $date =~ s/Oct/10/;
+      $date =~ s/Nov/11/;
+      $date =~ s/Dec/12/;
+
+      state $date_parser = DateTime::Format::Strptime->new(
+         pattern => '%d %m %Y %T',
+         time_zone => 'UTC',
+      );
+
+      my $datetime = $date_parser
+         ->parse_datetime($date);
+
+      my $timestamp = $datetime->epoch;
+      my $formatted_date = "$timestamp";
+
+      my $msg = 'Added a comment';
+      my $content = convert_content($x->{'content:encoded'});
+      utf8::encode($x->{'dc:creator'});
+
+      $events{$timestamp} = join "\n",
+         "commit refs/heads/$branch",
+         # still need to get email address
+         "committer $x->{'dc:creator'} <$x->{'dc:creator'}> $timestamp +0000",
+         'data <<8675309',
+         $msg,
+         '8675309',
+         "M 644 inline " . unique_comment_location($dir, $content),
+         'data <<8675309',
+
+      <<"COMMENT",
+[[!comment format=mdwn
+ username="$x->{'dc:creator'}"
+ date="$formatted_date"
+ content="""
+$content
+"""]]
+COMMENT
+      '8675309'
+      ;
+   }
+}
+
+say $events{$_} for sort keys %events;
+
+sub convert_content {
+   my $body = shift;
+
+   utf8::encode($body);
+
+   state $converter = HTML::WikiConverter->new(
+      dialect              => 'Markdown',
+      link_style           => 'inline',
+      unordered_list_style => 'dash',
+      image_style          => 'inline',
+      image_tag_fallback   => 0,
+   );
+
+   # I know I know you can't parse XML with regular expressions.  Go find a real
+   # parser and send me a patch
+   my $in_code = 0;
+
+   my $start_code = qr(<pre[^>]*>);
+   # (?:) is a no op but keeps ikiwiki from breaking my script
+   my $end_code = qr(</p(?:)re>);
+
+   $body =~ s(&#(?:8217|039);)(')g;
+   $body =~ s(&(?:quot|#822[01]);)(")g;
+   $body =~ s(&lt;)(<)g;
+   $body =~ s(&gt;)(>)g;
+   $body =~ s(&amp;)(&)g;
+   $body =~ s(&#8230;)(...)g;
+   $body =~ s(&#821[12];)(-)g;
+   $body =~ s(&#8216;)(')g;
+   $body =~ s(&#8242;)(')g;
+   $body =~ s(&infin;)(∞)g;
+   $body =~ s(&nbsp;)()g;
+   $body =~ s(<code[^>]*>)(<p(?:)re>)g;
+   $body =~ s(</c(?:)ode>)(</p(?:)re>)g;
+
+   my @tokens =
+      map {; split qr[(?=<p(?:)re>)] }
+      map {; split qr[</p(?:)re>\K] }
+      split /\n\n/,
+      $body;
+
+   my @new_tokens;
+   for my $t (@tokens) {
+      if (
+         ($in_code && $t !~ $end_code) ||
+         ($t =~ $start_code && $t =~ $end_code)
+      ) {
+         # do nothing
+      } elsif ($t =~ $start_code) {
+         $in_code = 1;
+      } elsif ($t =~ $end_code) {
+         $in_code = 0;
+      } else {
+         die "$t !!! '$1'" if $t =~ m/&([^;\s]+);/ && $1 !~ /[lg]t/;
+
+         $t = "<p>$t</p>"
+      }
+      push @new_tokens, $t
+   }
+
+   $converter->html2wiki(join "\n\n", @new_tokens)
+}
+
+sub unique_comment_location {
+   my ($dir, $content) = @_;
+
+   utf8::encode($content);
+   my $md5 = md5_hex($content);
+
+   my $location;
+   my $i = 0;
+   do {
+      $i++;
+      $location = "$dir/comment_${i}_$md5._comment";
+   } while -e $location;
+
+   return $location
+}
+
+''']]
+-----
+
 I modified the script a bit so categories and tags would actually show up in the output file.
 
 -----
-<pre>
+[[!format '''
 #!/usr/bin/env python
 
 """
@@ -110,7 +345,7 @@ if __name__ == "__main__":
     else:
         main(*sys.argv[1:])
 
-</pre>
+''']]
 -----
 
 I have another version of the script, which uses the `timestamp` from the script, and inserts that as a \[[!meta date="foodate"]]. I'm posting it here just in case I happen to be doing something to the httpd.
@@ -118,7 +353,7 @@ I have another version of the script, which uses the `timestamp` from the script
 (Hopefully I've escaped everything properly; if I missed something, check the source.)
 
 -----
-<pre>
+[[!format '''
 #!/usr/bin/env python
 
 """
@@ -223,7 +458,7 @@ if __name__ == "__main__":
     else:
         main(*sys.argv[1:])
 
-</pre>
+''']]
 -----
 
 
diff --git a/doc/tips/mailman_subscription_form.mdwn b/doc/tips/mailman_subscription_form.mdwn
new file mode 100644 (file)
index 0000000..3e9ed07
--- /dev/null
@@ -0,0 +1,10 @@
+One can think about implementing "[[Mailman integration]]" or something, but I find that rather overdoing it. Mailman is simple enough that you can add a clean subscription form to your ikiwiki site in seconds, just add:
+
+~~~~
+<form action="https://listes.example.com/cgi-bin/mailman/subscribe/listname" method="POST">
+Email: <input name="email" />
+<input type="submit" value="Subscribe" />
+</form>
+~~~~
+
+To your site and voilà, you are done! No more scary mailman subscription form! (Thanks to [[bgm]] for that trick!) --[[anarcat]]
index b504698c495131cef5f594a4e60ad0ede279ccc2..6355867099fc133ad8e884ff09573432142818bc 100644 (file)
@@ -4,7 +4,7 @@ This seems somewhat difficult, as ikiwiki would need to maintain a cache of the
 
 --[[JoshTriplett]]
 
-[scmbug](http://www.mkgnu.net/?q=scmbug) might help here. --[[JoshTriplett]]
+[scmbug](http://www.mkgnu.net/scmbug) might help here. --[[JoshTriplett]]
 
 [[!tag soc]]
 
diff --git a/doc/todo/Fenced_code_blocks___40__from_GitHub_Flavored_Markdown__41__.mdwn b/doc/todo/Fenced_code_blocks___40__from_GitHub_Flavored_Markdown__41__.mdwn
new file mode 100644 (file)
index 0000000..24552b2
--- /dev/null
@@ -0,0 +1,44 @@
+GitHub's flavor of markdown adds fenced code blocks, delimited by triple-backquotes, like this:
+
+    ```
+    code
+    more code
+    ```
+
+That syntax proves quite a bit more convenient in many cases, because it doesn't require modifying every line of the code block to add indentation.  Please consider adding optional support for this in ikiwiki.  Please also consider turning it on by default for new wikis, though not for existing wikis since it could *potentially* break backward compatibility with existing content.
+
+> I don't think that's an official markdown feature, although it might be available
+> as an extension in some markdown library or other -- possibly one of the ones
+> supported by ikiwiki.
+> 
+> However, aside from compatability, ikiwiki already provides a way to do it that does not
+> require indenting the code: The [[ikiwiki/directive/format]] directive. Which has the benefit of
+> also telling it what kind of code it is, so it can syntax highlight it. Example:
+
+[[!format haskell """
+main :: IO ()
+main = forever $
+  putStrLn "hello, world!"
+"""]]
+
+> --[[Joey]]
+
+> > It is not a standard feature (as much as Markdown is [[standardized|Track_Markdown_Standardisation_Efforts]]...) But it does allow for [syntax hilightning](https://help.github.com/articles/github-flavored-markdown) too, just tag the language name after the backticks. It *seems* that Discount supports github-style backtick format (as well as Pandoc `~~~~` format) but doesn't allow the keyword argument.
+> > 
+> > I strongly support this feature. --[[anarcat]]
+> > 
+> > In fact, it turns out that it already works here!
+> >
+> > ~~~~
+> > this is a pandoc-style fenced in code block
+> > this is another line
+> > ~~~~
+> > 
+> > github-style backticks, however, do not add a wrapping `<pre>` block for some reason:
+> >
+> > ```
+> > this is a github-style fenced in code block
+> > this is another line
+> > ```
+> >
+> > ... maybe a bug in Discount... --[[anarcat]]
index a4940220adef0fabdbc10175f27c5bfe5e198df9..b7ff82282ed04078907ef889a14538004c6b6cd5 100644 (file)
@@ -13,6 +13,8 @@ A slightly more complex next step would be to request sreg from the provider and
 > implemented as a badly-done wart on the side of their regular login
 > system.
 > 
+> > If there are user profiles on the site with non-empty information associated with them (including permissions, reputation), then it would make more sense to be able to access your user profile with alternative OpenIDs (in case one of the provider goes down), as on <http://stackoverflow.com>. In ikiwiki, there might be no such special information associated with users (or you can think of something like this?), except for the admin rights. But fortunately, several OpenIDs can be set up for admins in ikwiki. (Only if it comes to [the OpenIDs provided by Gmail][forum/google openid broken?], then it turns out to be unhandy to write the ID into the configuration file as a second admin ID.)--Ivan Z.
+> 
 > The openid plugin now attempts to get an email and a username, and stores
 > them in the session database for later use (ie, when the user edits a
 > page).
index a0405472b64110f0e6ee210d4b92384964a105ce..63ffccf0d8d41abf24df21adf78d0a3463af74bd 100644 (file)
@@ -13,4 +13,8 @@ The installed bin/ikiwiki file also refers to /usr/bin/perl rather than the perl
 > yours, but do not plan to work on it myself, since I do not use systems
 > where /usr/bin/perl is not a sane default. --[[Joey]]
 
+> > I've implemented a change that should fix this.  For what it's worth this is a
+> > life saver on shared hosting where building your own perl is super effective.
+> > --frioux ([code here](https://github.com/frioux/ikiwiki/tree/use-env-perl))
+
 [[wishlist]]
diff --git a/doc/todo/calendar_with___34__create__34___links.mdwn b/doc/todo/calendar_with___34__create__34___links.mdwn
new file mode 100644 (file)
index 0000000..9fe6c43
--- /dev/null
@@ -0,0 +1,10 @@
+the [[ikiwiki/directive/calendar]] directive is well usable without ikiwiki-calendar (eg for articles about meetings), but in such situations, it might be useful to have page creating links at the days.
+
+a [[!taglink patch]] to address this [[!taglink wishlist]] item is [[attached|incomplete_patch.pl]].
+
+from the new documentation (also in the patch):
+
+> * `newpageformat` - In month mode, if no articles match the query, the value of
+>   `newpageformat` will be used to strformat the date in question. A good value
+>   is `newpageformat="meetings/%Y-%m-%d"`. It might be a good idea to have
+>   `\[[!meta date="<TMPL_VAR name>"]]` in the edittemplate of `meetings/*`
diff --git a/doc/todo/calendar_with___34__create__34___links/incomplete_patch.pl b/doc/todo/calendar_with___34__create__34___links/incomplete_patch.pl
new file mode 100644 (file)
index 0000000..dc67988
--- /dev/null
@@ -0,0 +1,36 @@
+diff --git a/IkiWiki/Plugin/calendar.pm b/IkiWiki/Plugin/calendar.pm
+index d443198..0436eda 100644
+--- a/IkiWiki/Plugin/calendar.pm
++++ b/IkiWiki/Plugin/calendar.pm
+@@ -238,7 +238,16 @@ EOF
+                       else {
+                               $tag='month-calendar-day-nolink';
+                       }
+-                      $calendar.=qq{\t\t<td class="$tag $downame{$wday}">$day</td>\n};
++                      if ($params{newpageformat}) {
++                              $calendar.=qq{\t\t<td class="$tag $downame{$wday}">};
++                              $calendar.=htmllink($params{page}, $params{destpage},
++                                      strftime_utf8($params{newpageformat}, 0, 0, 0, $day, $params{month} - 1, $params{year} - 1900),
++                                      noimageinline => 1,
++                                      linktext => $day);
++                              $calendar.=qq{</td>\n};
++                      } else {
++                              $calendar.=qq{\t\t<td class="$tag $downame{$wday}">$day</td>\n};
++                      }
+               }
+       }
+diff --git a/doc/ikiwiki/directive/calendar.mdwn b/doc/ikiwiki/directive/calendar.mdwn
+index cb40f88..7b7fa85 100644
+--- a/doc/ikiwiki/directive/calendar.mdwn
++++ b/doc/ikiwiki/directive/calendar.mdwn
+@@ -56,5 +56,9 @@ An example crontab:
+   and so on. Defaults to 0, which is Sunday.
+ * `months_per_row` - In the year calendar, number of months to place in
+   each row. Defaults to 3.
++* `newpageformat` - In month mode, if no articles match the query, the value of
++  `newpageformat` will be used to strformat the date in question. A good value
++  is `newpageformat="meetings/%Y-%m-%d"`. It might be a good idea to have
++  `\[[!meta date="<TMPL_VAR name>"]]` in the edittemplate of `meetings/*`.
+ [[!meta robots="noindex, follow"]]
index 8ce3dd3e7cace45eb7dc8573099c4dddd22ac67b..ccf08eeaf904fddf8518d481412b7ddeb2ff1760 100644 (file)
@@ -5,6 +5,38 @@ also have lots more metadata.
 
 [[!toc]]
 
+## Status
+
+[[!template id=gitbranch branch=schmonz/fancypodcast author="[[schmonz]]"]]
+[[!tag patch]]
+
+In summary, the branch preserves ikiwiki's existing podcast behavior,
+adds more featureful behavior, and has been tested to work well in
+some common podcatchers. I believe it is ready for review and
+possible integration, and I'd like to get feedback to that effect
+(or to the contrary) before making further enhancements. I know
+[[joey]]'s the final arbiter here, but I'd appreciate any qualified,
+critical eyes ([[smcv]]?) raking over my diffs. --[[schmonz]]
+
+## Features
+
+[[!table data="""
+Feature            |iTunes RSS|iTunes Atom|Downcast RSS|Downcast Atom
+Feed image         |{X}       |{X}        |{X}         |{X}
+Feed title         |(./)      |(./)       |(./)        |(./)
+Feed publisher     |{X}       |{X}        |{X}         |{X}
+Feed "category"    |{X}       |{X}        |{X}         |{X}
+Feed date          |(./)      |(./)       |(./)        |(./)
+Feed description   |(./)      |(./)       |(./)        |{X}
+Episode image      |{X}       |{X}        |{X}         |{X}
+Episode title      |(./)      |(./)       |(./)        |(./)
+Episode date       |(./)      |(./)       |(./)        |(./)
+Episode duration   |{X}       |{X}        |{X}         |{X}
+Episode author     |{X}       |{X}        |{X}         |{X}
+Episode description|(./)      |(./)       |(./)        |{X}
+Episode enclosure  |(./)      |(./)       |(./)        |(./)
+"""]]
+
 ## Design
 
 7. For each fancy podcast episode, write a blog post containing
@@ -18,9 +50,6 @@ also have lots more metadata.
 
 ## Implementation
 
-[[!template id=gitbranch branch=schmonz/fancypodcast author="[[schmonz]]"]]
-[[!tag patch]]
-
 ### Completed
 
 * Cover the existing simple podcast behavior with tests.
@@ -42,34 +71,113 @@ also have lots more metadata.
 * Verify that the feeds validate.
 * Subscribe to a fancy feed in some common podcatchers and verify
   display details against a reference podcast.
-
-### Status
-
-[[!table data="""
-Feature            |iTunes RSS|iTunes Atom|Downcast RSS|Downcast Atom
-Feed image         |{X}       |{X}        |{X}         |{X}
-Feed title         |(./)      |(./)       |(./)        |(./)
-Feed publisher     |{X}       |{X}        |{X}         |{X}
-Feed "category"    |{X}       |{X}        |{X}         |{X}
-Feed date          |(./)      |(./)       |(./)        |(./)
-Feed description   |(./)      |(./)       |(./)        |{X}
-Episode image      |{X}       |{X}        |{X}         |{X}
-Episode title      |(./)      |(./)       |(./)        |(./)
-Episode date       |(./)      |(./)       |(./)        |(./)
-Episode duration   |{X}       |{X}        |{X}         |{X}
-Episode author     |{X}       |{X}        |{X}         |{X}
-Episode description|(./)      |(./)       |(./)        |{X}
-Episode enclosure  |(./)      |(./)       |(./)        |(./)
-"""]]
+* Verify smooth transitions for two common use cases (see testing
+  details below).
 
 ### Must-have (for [[schmonz]], anyway)
 
-* Think carefully about...
-    * UTF-8.
-    * Whether [[tips/howto avoid flooding aggregators]] suffices for
-      migrating a fancy podcast into ikiwiki.
+* Think carefully about UTF-8.
 * Verify that _all_ the tests pass (not just my new ones).
 
+## Migration
+
+### Upgrading within ikiwiki: from simple to fancy
+
+#### My test podcast
+
+For this test, I chose a podcast that tries to work around ikiwiki's
+current limitations by issuing two separate `inline`s:
+
+* One with `feedonly=yes` that includes `.mdwn`, `.pdf`, and `.mp3`
+* One with `feeds=no` that includes only `.mdwn` (and makes a trail)
+
+This has the following effects:
+
+* Browser: sees just the articles (each of which has a manually
+  created link to its corresponding media file)
+* Feedreader: sees all the articles and media in one flat stream
+* Podcatcher: sees just the media (sans articles)
+
+I want instead to write one `inline` with these effects:
+
+* Browser: sees just the articles (each of which automatically links
+  to its enclosure)
+* Feedreader: sees just the articles (each of which specifies its
+  enclosure)
+* Podcatcher: sees just the enclosures (each of which has an enclosing
+  article, rendered as the media's "description")
+
+#### Upgrade steps
+
+7. Set up a non-production copy of the podcast.
+    7. Visually diff RSS and Atom feeds against production.
+    7. Subscribe to the copy (both feeds) in `r2e`, iTunes, Downcast.
+7. Apply fancypodcast patch to the installed ikiwiki:
+    7. `cd ~/Documents/trees/ikiwiki && git checkout fancypodcast`
+    7. `git diff --no-prefix master > ~/Documents/trees/localpatches/www/ikiwiki/fancypodcast.diff`
+    7. `cd ~/Documents/trees/pkgsrc-current/www/ikiwiki && make deinstall && make install clean`
+7. Verify that simple podcasts are unaffected:
+    7. Rerun `ikiwiki --setup`.
+    7. `diff -uB simple-before.rss simple-after.rss`
+        * A few new elements and attributes, as expected.
+    7. `diff -uB simple-before.atom simple-after.atom`
+        * No change.
+7. Remove the feed-only `inline` and enable feeds on the remaining one.
+7. Convert articles' manual download links to `\[[!meta enclosure=""]]`.
+7. I want existing and future podcatchers to get my new fancy
+   episodes, and I know my podcast isn't in any planets, so I'm
+   going to skip [[tips/howto avoid flooding aggregators]].
+7. Rerun `ikiwiki --setup`.
+7. Verify browser shows the same stuff.
+7. `diff -uB simple-after.rss fancy-after.rss   # and atom`
+    * MP3s and PDFs are no longer naked enclosures, but belong to
+      articles as they should.
+    * Articles have updated modification times, as they should.
+7. `r2e run` (both RSS and Atom)
+    * Nothing new with the default `trust-guid = True` (otherwise
+      would expect updated articles).
+7. iTunes "Update Podcast" (both RSS and Atom)
+    * Added one episode per article, with article text as the episode
+      description.
+    * Kept old naked-enclosure episodes around.
+7. Downcast refresh (RSS):
+    * Added one episode per article, with article text as the episode
+      description.
+    * Kept old naked-enclosure episodes around.
+7. Downcast refresh (Atom):
+    * Added one episode per article, with no episode description
+      (expected, see feature table).
+    * Kept old naked-enclosure episodes around.
+
+Different tradeoffs are possible. These seem okay to me.
+
+### Importing into ikiwiki: fancy (from another CMS)
+
+#### My test podcast
+
+For this test, I chose a podcast currently being published with
+Textpattern and tru_podcast, because I'd strongly prefer to publish
+it with ikiwiki instead.
+
+#### Upgrade steps
+
+7. Set up a non-production copy of the podcast.
+    7. Visually diff RSS and Atom feeds against production.
+    7. Subscribe to the copy (both feeds) in `r2e`, iTunes, Downcast.
+7. With a fancypodcast-enabled ikiwiki installed:
+    7. Copy content from Textpattern to ikiwiki:
+        7. Match article paths to preserve `/YYYY/MM/DD/post-title` permalinks.
+        7. Match enclosure paths (or redirect) to preserve Textpattern's URLs.
+        7. Match titles, post dates, and guids with `\[[!meta]]`.
+           7. Match feed paths with permanent redirects from `/atom/` to
+           `/index.atom` (and same for RSS).
+        7. `\[[!inline]]` the articles.
+    7. Rerun `ikiwiki --setup`.
+7. Stop Textpattern, start ikiwiki.
+7. Verify that podcatchers see the feeds and don't redownload anything.
+7. Naively add two new blog posts, one with an enclosure.
+7. Verify that podcatchers download the new enclosures.
+
 -----
 
 ## Future improvements
@@ -104,6 +212,8 @@ Episode enclosure  |(./)      |(./)       |(./)        |(./)
 
 ### Other ideas
 
+* Don't render template text (e.g., "Use this template to insert a
+  note into a page") in feeds.
 * Optionally specify the enclosure's:
     * MIME type, in case `File::MimeInfo` guesses wrong.
     * Duration, in case `ffprobe` guesses wrong.
diff --git a/doc/todo/toc-with-human-readable-anchors.mdwn b/doc/todo/toc-with-human-readable-anchors.mdwn
new file mode 100644 (file)
index 0000000..0f358f4
--- /dev/null
@@ -0,0 +1,7 @@
+The [[/plugins/toc]] plugin is very useful but it creates anchors with names such as #index1h3
+
+In #ikiwiki today, another user and I were in agreement that an option for human readable anchors would be preferable.
+
+> +1 - i would love to see that happen too. Here's a patch I wrote a while back for similar functionality in moinmoin: https://svn.koumbit.net/koumbit/trunk/patches/moinmoin/nice_headings.patch -- [[anarcat]]
+
+[[!tag wishlist]]
diff --git a/doc/todo/translation_links.mdwn b/doc/todo/translation_links.mdwn
new file mode 100644 (file)
index 0000000..63e8d10
--- /dev/null
@@ -0,0 +1,46 @@
+This is an offshoot of [[this rant|translation/discussion/#index3h1]].
+
+Basically, while I can appreciate the [[plugins/po]] plugin for more or less "static" site, or more organised wikis, for certain wikis, it's way too overhead.
+
+## Stories
+
+The following stories should be answered by that plugin:
+
+ 1. a user browses the wiki, finds that the page is translated in another language and clicks on the language to see that page translated
+ 2. a user browses the wiki and gets automatically the right language
+ 3. an editor creates a wiki page, and it gets assigned a language
+ 4. a translator sees that page and translates it to another language, and that page is linked with the first one, both ways (in that stories 1 and 2 can work)
+ 5. (optional) a translator can see the list of pages needing translation and translate pages
+ 6. (optional) an editor changes a wiki page, the translated page is marked as "dirty" (ie. needing translation)
+
+## Fundamental constraints
+
+This issue is about creating a "wikipedia-like" translation structure where:
+
+ 1. there's no "master language"
+ 2. there's a loose connexion between pages
+ 3. not all pages are necessarily translated, nor is it a goal
+
+Those are fundamental constraints that should be required by that plugin. It doesn't mean that the plugin cannot be used otherwise, but that's all it needs to respect to fulfill the requirements here.
+
+## Optional constraints
+
+There can be more constraints that we may want to impose or not, which will make things more or less complicated:
+
+ 4. the page URLs need to be translatable - it would make [[!wikipedia Content_negotiation]] fail, so it would require the CGI for story 2. it would also make it harder to create the connexion between pages, as metadata would be needed in each page
+ 5. the language must not be visible in the URL - same as #4
+ 6. translation system must also be usable from the commandline/git repository - #5 and #6 would be basically impossible to implement there
+
+## Basic spec
+
+ 1. a hook that looks for foo.la.mdwn pages, where la is a language code (defined where..?), and that lists available translations - 
+    this is where most of the work needs to happen. we can probably reuse the builtin template stuff that got injected with the [[plugins/po]] plugin was imported, to start with
+ 2. instructions on how to setup [[!wikipedia Content_negotiation]] so that the above works out of the box - just documentation
+ 3. a button to create such translations - that would be through the [[pageactions hook|plugins/write/#index15h3]]
+ 4. a default language setting? - that's obviously the getsetup hook
+ 5. a set of language code settings? - same
+ 6. content-negotiation - the po module has good code for that
+
+## Authors
+
+ * [[anarcat]]
index 61606e3d0d067f4daf5fbf7db09cbf7cf12ec73d..b274317cd34dc17d93a1b8b834fabb98aa99e642 100644 (file)
@@ -117,3 +117,5 @@ Obviously, this is a lot more work, diverging in a different direction than the
 Also, the thing with the above is that if functionalities 1 and 2 (mapping and page flipping) is stripped out of the po plugin and made reusable, functionalities 3 and 4 can be made optional and a wiki is still translatable, giving the user the responsability of tracking the translations...
 
 So basically, what I think should happen is to have ikiwiki be able to use the .po plugin without .po files - just allow for pages to be linked together. Detect foo.fr.mdwn when parsing foo.mdwn and create links to it would already be a huge start... -- [[anarcat]]
+
+> I have a hopefully clearer spec for a plugin called [[todo/translation_links]]. -- [[anarcat]]
index 10ca6e6ebe1cbb1bf16ab25fe44ede99be302f99..84dca19485a67d31fcdbf5f8df407b9eebc44782 100644 (file)
@@ -1,10 +1,20 @@
-[Amitai Schlair](http://www.schmonz.com/) finds himself using ikiwiki
-for all sorts of things. His attempts at contributing:
+[Amitai Schlair](http://www.schmonz.com/) uses ikiwiki
+for all sorts of things:
+
+* a undergraduate group's university-provided-static-hosted site
+  (with [[plugins/rsync]] and a [WIND
+  authentication](http://www.columbia.edu/acis/rad/authmethods/wind/)
+  plugin)
+* a major open-source project's wiki (with the [[rcs/cvs]] plugin)
+* team documentation and project planning at work: product and
+  sprint backlogs, burndown charts, release plans/procedures/announcements,
+  aggregating feeds of shared interest, etc. (with the
+  [[plugins/contrib/dynamiccookies]] and [[plugins/contrib/proxies]]
+  plugins)
+* personal to-do and scratch space
+
+ikiwiki contributions:
 
 [[!map
 pages="!*/Discussion and ((link(users/schmonz) and plugins/*) or rcs/cvs or todo/fancypodcast)"
 ]]
-
-He's also written a plugin for [WIND
-authentication](http://www.columbia.edu/acis/rad/authmethods/wind/), which
-may or may not be of general utility.
diff --git a/doc/wishlist/watched_pages.mdwn b/doc/wishlist/watched_pages.mdwn
new file mode 100644 (file)
index 0000000..d943571
--- /dev/null
@@ -0,0 +1 @@
+Is there a way to mark pages I edit as "watched"? A way of doing this through git would be acceptable too. Right now I link to my homepage on every page I comment on, but this doesn't tell me if the pages were updated... --[[anarcat]]
index 7caaca7178dfbb1cc65defe74976742581d41384..7e9dbf0f66a3a1bc073e62e1c821298338fa7794 100644 (file)
@@ -1,5 +1,5 @@
 Name:           ikiwiki
-Version: 3.20130212
+Version: 3.20130504
 Release:        1%{?dist}
 Summary:        A wiki compiler
 
index 5ec4a157c6ddbb0fdfcdea3d117730b3cb2ea266..961763d058b42b9b65dd66967d4cc71ec3b8899c 100644 (file)
@@ -5,29 +5,16 @@ POTFILES=$(sort $(shell find ../IkiWiki -type f -name \*.pm)) \
 POFILES=$(wildcard *.po)
 MOFILES=$(POFILES:.po=.mo)
 
-# Translated underlays can only be generated if po4a is available.
-TRANSLATED_UNDERLAYS=$(shell if perl -e 'use Locale::Po4a::Common' 2>/dev/null; then echo ../underlays/locale; fi)
-
-all: ikiwiki.pot mo $(TRANSLATED_UNDERLAYS)
+all: ikiwiki.pot mo
 
 mo: $(MOFILES)
 
 install: all
-       # Normal mo files for program translation.
        for file in $(MOFILES); do \
                lang=`echo $$file | sed 's/\.mo//'`; \
                install -d $(DESTDIR)$(PREFIX)/share/locale/$$lang/LC_MESSAGES/; \
                install -m 0644 $$file $(DESTDIR)$(PREFIX)/share/locale/$$lang/LC_MESSAGES/ikiwiki.mo; \
        done
-       
-       # Underlay translation via po files that go in special per-language
-       # underlays.
-       for file in `cd underlays && find . -type f -name \*.po`; do \
-               lang=`echo $$file | sed -e 's/.po$$//' -e 's/.*\\.//'`; \
-               dir=`dirname "$(DESTDIR)$(PREFIX)/share/ikiwiki/po/$$lang/$$file"`; \
-               install -d $$dir; \
-               install -m 0644 underlays/$$file $$dir; \
-       done
 
 ikiwiki.pot: $(POTFILES)
        @if perl -e '($$ver)=`xgettext -V | head -n 1`=~/.*\s+([0-9]+\.[0-9]+)/; die "gettext $$ver too old, not updating the pot file\n" if $$ver < 0.16'; then \
@@ -36,9 +23,7 @@ ikiwiki.pot: $(POTFILES)
        fi
 
 clean:
-       rm -f $(MOFILES) messages messages.mo *_stamp
-       rm -rf html underlays/.ikiwiki $(TRANSLATED_UNDERLAYS)
-       find underlays -name \*.mdwn -or -name \*.pot | xargs rm -f
+       rm -f $(MOFILES) messages messages.mo
 
 %.mo: %.po
        @if ! msgfmt -o $@ $<; then echo "unable to run msgfmt"; fi
@@ -64,34 +49,3 @@ check:
                printf "$$lang: "; \
                msgfmt -o /dev/null -c -v --statistics $$lang.po;\
        done
-
-underlays_copy_stamp:
-       # copy all the files we want to translate into a srcdir
-       for file in `cd ..; find underlays -follow -name \*.mdwn`; do \
-               install -d $$(dirname $$file); \
-               cp -aL ../$$file $$file 2>/dev/null || \
-               install -m 644 ../$$file $$file; \
-       done
-       install -d underlays/directives/ikiwiki/directive
-       for file in `cd ..; find doc/ikiwiki/directive/ -maxdepth 1 -type f`; do \
-               cp -a ../$$file underlays/directives/ikiwiki/directive ||  \
-               install -m 644 ../$$file underlays/directives/ikiwiki/directive; \
-       done
-       install -d underlays/empty
-       touch $@
-
-underlays: ../ikiwiki.out underlays_copy_stamp
-       ../ikiwiki.out -libdir .. -setup underlay.setup -refresh
-
-../ikiwiki.out: ../Makefile
-       make -C .. ikiwiki.out
-
-../Makefile: ../Makefile.PL
-       cd .. && ./Makefile.PL
-
-$(TRANSLATED_UNDERLAYS): po2wiki_stamp
-po2wiki_stamp: po2wiki underlays_copy_stamp
-       PERL5LIB=.. ./po2wiki underlay.setup
-       touch $@
-
-.PHONY: underlays
index 8d739f95bbbc014e4eb82b7b28d15334d2efe0b3..d7f2926a38f6bd3eb928868f1ff9a739c40bbe88 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-02-12 21:50-0400\n"
+"POT-Creation-Date: 2013-05-04 23:52-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/t/map.t b/t/map.t
index 7f3df61f7c9068f8ea28aeac6d929f685530ba4a..5d4713d6fc9604d91018280c253911082d75c212 100755 (executable)
--- a/t/map.t
+++ b/t/map.t
@@ -3,9 +3,16 @@ package IkiWiki;
 
 use warnings;
 use strict;
-use XML::Twig;
 use Test::More;
 
+BEGIN {
+        unless (eval { require XML::Twig }) {
+                eval q{
+                        use Test::More skip_all => "XML::Twig is not available"
+                }
+        }
+}
+
 BEGIN { use_ok("IkiWiki"); }
 BEGIN { use_ok("IkiWiki::Render"); }
 BEGIN { use_ok("IkiWiki::Plugin::map"); }
diff --git a/t/podcast.t b/t/podcast.t
new file mode 100755 (executable)
index 0000000..a00545b
--- /dev/null
@@ -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/this episode/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/this episode/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/this episode/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 (file)
index 0000000..ea7bae8
--- /dev/null
@@ -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 (file)
index 0000000..290f4c2
--- /dev/null
@@ -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 (file)
index 0000000..3d6b662
Binary files /dev/null and b/t/tinypodcast/piano.mp3 differ
diff --git a/t/tinypodcast/pianopost.mdwn b/t/tinypodcast/pianopost.mdwn
new file mode 100644 (file)
index 0000000..b02f8de
--- /dev/null
@@ -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 (file)
index 0000000..61e69e9
Binary files /dev/null and b/t/tinypodcast/scroll.3gp differ
diff --git a/t/tinypodcast/simple.mdwn b/t/tinypodcast/simple.mdwn
new file mode 100644 (file)
index 0000000..0523697
--- /dev/null
@@ -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 (file)
index 0000000..d28ddb5
--- /dev/null
@@ -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 (file)
index 0000000..3eee48c
Binary files /dev/null and b/t/tinypodcast/walter.ogg differ
index 4ed17bc62070756b16e2dc1c6de3d10d0058de5e..9b056e0f455c06a06144d4c73922184441c1d3a6 100644 (file)
        <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>
index 4736c95d0a8197d32d37f72fd7ab27ae48788553..e94ccce96fcfc2a15d67eca736fc49b6092b97e2 100644 (file)
@@ -69,6 +69,15 @@ $(function () { $('#fileupload').fileupload(); }); // initialize upload widget
 </div> 
 </div>
 </TMPL_IF>
+<div class="license">
+    <p>By submitting content to this wiki, you agree to release your work under
+    the dual license of</p>
+    <ul>
+      <li>the Creative Commons Attribution-Share Alike license, and</li>
+      <li>the GNU Free Documentation License, with no Invariant Sections, no
+         Front-Cover Texts, and no Back-Cover-Texts.</li>
+    </ul>
+</div>
 <TMPL_VAR FORM-END>
 <TMPL_VAR WMD_PREVIEW>
 <TMPL_IF NAME="PAGE_PREVIEW">
index b0b53d0416db76d2dc24bb606c5e86755dee93ef..2e80a51ccad0e93fd7e5e51bfb7a79b16e1fa0a5 100644 (file)
 <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 this episode</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">
index 6353c75969154bc14f10895c48b342a43e763a23..9ec65205862a2db28cf479b17e388a24a8e9dcec 100644 (file)
@@ -1,8 +1,8 @@
 <TMPL_IF HTML5><!DOCTYPE html>
-<html>
+<html lang="en">
 <TMPL_ELSE><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 </TMPL_IF>
 <head>
 <TMPL_IF DYNAMIC>
 </TMPL_IF>
 <TMPL_IF HTML5><meta charset="utf-8" /><TMPL_ELSE><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></TMPL_IF>
 <title><TMPL_VAR TITLE></title>
-<TMPL_IF FAVICON>
-<link rel="icon" href="<TMPL_VAR BASEURL><TMPL_VAR FAVICON>" type="image/x-icon" />
-</TMPL_IF>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL>style.css" type="text/css" />
-<TMPL_IF LOCAL_CSS>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL><TMPL_VAR LOCAL_CSS>" type="text/css" />
-<TMPL_ELSE>
-<link rel="stylesheet" href="<TMPL_VAR BASEURL>local.css" type="text/css" />
-</TMPL_IF>
-
-<TMPL_UNLESS DYNAMIC>
+<meta http-equiv="Content-Style-Type" content="text/css" />
+<meta name="robots" content="all" />
+<meta name="author" content="SIPB" />
+<meta name="description" content="MIT Student Information Processing Board" /> 
+<meta name="keywords" content="SIPB, MIT, hackers" />
+<link rel="stylesheet" type="text/css" href="<TMPL_VAR BASEURL>style.css" />
 <TMPL_IF EDITURL>
 <link rel="alternate" type="application/x-wiki" title="Edit this page" href="<TMPL_VAR EDITURL>" />
 </TMPL_IF>
 <link rel="next" href="<TMPL_VAR NEXTURL>" title="<TMPL_VAR NEXTTITLE>" />
 </TMPL_IF>
 </TMPL_LOOP>
-</TMPL_UNLESS>
 
 </head>
 <body>
 
-<TMPL_IF HTML5><article class="page"><TMPL_ELSE><div class="page"></TMPL_IF>
+<div id="content-block">
 
-<TMPL_IF HTML5><section class="pageheader"><TMPL_ELSE><div class="pageheader"></TMPL_IF>
-<TMPL_IF HTML5><header class="header"><TMPL_ELSE><div class="header"></TMPL_IF>
-<span>
-<span class="parentlinks">
+<div id="logo">
+<a href="<TMPL_VAR BASEURL>./"><img src="<TMPL_VAR BASEURL>images/grumpyfuzzball_half.png" alt="grumpy fuzzball" /></a>
+<a href="<TMPL_VAR BASEURL>./"><img src="<TMPL_VAR BASEURL>images/SIPBlogo.png" alt="MIT Student Information Processing Board" id="sipb-logo" /></a>
+<div id="hidden-title"><h1>SIPB: MIT Student Information Processing Board</h1></div>
+</div>
+
+<ul id="navigation">
+<li class="first-navbox">
+<a href="<TMPL_VAR BASEURL>projects/"><span>Projects</span></a>
+</li>
+<li class="second-navbox">
+<a href="<TMPL_VAR BASEURL>doc/"><span>Docs</span></a>
+</li>
+<li class="third-navbox">
+<a href="<TMPL_VAR BASEURL>office/"><span>Office</span></a>
+</li>
+<li class="fourth-navbox">
+<a href="<TMPL_VAR BASEURL>join/"><span>Join</span></a>
+</li>
+</ul>
+
+<h1><TMPL_VAR TITLE></h1>
+
+<TMPL_IF PARENTLINKS>
+<div id="breadcrumbs">
+<ul>
 <TMPL_LOOP PARENTLINKS>
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/ 
+<li><a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>&#187;</li>
 </TMPL_LOOP>
-</span>
-<span class="title">
-<TMPL_VAR TITLE>
-<TMPL_IF ISTRANSLATION>
-&nbsp;(<TMPL_VAR PERCENTTRANSLATED>%)
-</TMPL_IF>
-</span>
-</span>
-<TMPL_UNLESS DYNAMIC>
-<TMPL_IF SEARCHFORM>
-<TMPL_VAR SEARCHFORM>
-</TMPL_IF>
-</TMPL_UNLESS>
-<TMPL_IF HTML5></header><TMPL_ELSE></div></TMPL_IF>
+</ul>
+<br style="clear:both;" />
+</div>
+</TMPL_IF>
+
+<div id="featured-block" class="<TMPL_UNLESS PARENTLINKS>is-top</TMPL_UNLESS>">
+<TMPL_VAR CONTENT>
+</div>
+
+<div id="prefooter"></div>
+
+</div>
+
+<div id="footer">
 
 <TMPL_IF HAVE_ACTIONS>
 <TMPL_IF HTML5><nav class="actions"><TMPL_ELSE><div class="actions"></TMPL_IF>
 <TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
 </TMPL_IF>
 
-<TMPL_IF OTHERLANGUAGES>
-<TMPL_IF HTML5><nav id="otherlanguages"><TMPL_ELSE><div id="otherlanguages"></TMPL_IF>
-<ul>
-<TMPL_LOOP OTHERLANGUAGES>
-<li>
-<a href="<TMPL_VAR URL>"><TMPL_VAR LANGUAGE></a>
-<TMPL_IF MASTER>
-(master)
-<TMPL_ELSE>
-&nbsp;(<TMPL_VAR PERCENT>%)
-</TMPL_IF>
-</li>
-</TMPL_LOOP>
-</ul>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<TMPL_UNLESS DYNAMIC>
-<TMPL_VAR TRAILS>
-</TMPL_UNLESS>
+<p>&copy; 2009 Student Information Processing Board</p>
+<p>Unless otherwise specified, all content on this wiki is released under a dual license of the Creative Commons Attribution-Share Alike license, and the GNU Free Documentation License, with no Invariant Sections, no Front-Cover Texts, and no Back-Cover-Texts.<br />
+ This follows the SIPB Documentation Licensing Recommendation.</p>
 
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-
-<TMPL_UNLESS DYNAMIC>
-<TMPL_IF SIDEBAR>
-<TMPL_IF HTML5><aside class="sidebar"><TMPL_ELSE><div class="sidebar"></TMPL_IF>
-<TMPL_VAR SIDEBAR>
-<TMPL_IF HTML5></aside><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-</TMPL_UNLESS>
-
-<div id="pagebody">
-
-<TMPL_IF HTML5><section id="content"><TMPL_ELSE><div id="content"></TMPL_IF>
-<TMPL_VAR CONTENT>
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-
-<TMPL_UNLESS DYNAMIC>
-<TMPL_IF COMMENTS>
-<TMPL_IF HTML5><section id="comments"><TMPL_ELSE><div id="comments"></TMPL_IF>
-<TMPL_VAR COMMENTS>
-<TMPL_IF ADDCOMMENTURL>
-<div class="addcomment">
-<a href="<TMPL_VAR ADDCOMMENTURL>">Add a comment</a>
 </div>
-<TMPL_ELSE>
-<div class="addcomment">Comments on this page are closed.</div>
-</TMPL_IF>
-<TMPL_IF HTML5></section><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-</TMPL_UNLESS>
-
-</div>
-
-<TMPL_IF HTML5><footer id="footer" class="pagefooter"><TMPL_ELSE><div id="footer" class="pagefooter"></TMPL_IF>
-<TMPL_UNLESS DYNAMIC>
-<TMPL_IF HTML5><nav id="pageinfo"><TMPL_ELSE><div id="pageinfo"></TMPL_IF>
-
-<TMPL_VAR TRAILS>
-
-<TMPL_IF TAGS>
-<TMPL_IF HTML5><nav class="tags"><TMPL_ELSE><div class="tags"></TMPL_IF>
-Tags:
-<TMPL_LOOP TAGS>
-<TMPL_VAR LINK>
-</TMPL_LOOP>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<TMPL_IF BACKLINKS>
-<TMPL_IF HTML5><nav id="backlinks"><TMPL_ELSE><div id="backlinks"></TMPL_IF>
-Links:
-<TMPL_LOOP BACKLINKS>
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
-</TMPL_LOOP>
-<TMPL_IF MORE_BACKLINKS>
-<span class="popup">...
-<span class="balloon">
-<TMPL_LOOP MORE_BACKLINKS>
-<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
-</TMPL_LOOP>
-</span>
-</span>
-</TMPL_IF>
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-</TMPL_IF>
-
-<TMPL_IF COPYRIGHT>
-<div class="pagecopyright">
-<a name="pagecopyright"></a>
-<TMPL_VAR COPYRIGHT>
-</div>
-</TMPL_IF>
-
-<TMPL_IF LICENSE>
-<div class="pagelicense">
-<a name="pagelicense"></a>
-License: <TMPL_VAR LICENSE>
-</div>
-</TMPL_IF>
-
-<div class="pagedate">
-Last edited <TMPL_VAR MTIME>
-<!-- Created <TMPL_VAR CTIME> -->
-</div>
-
-<TMPL_IF HTML5></nav><TMPL_ELSE></div></TMPL_IF>
-<TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
-</TMPL_UNLESS>
-<!-- from <TMPL_VAR WIKINAME> -->
-<TMPL_IF HTML5></footer><TMPL_ELSE></div></TMPL_IF>
 
-<TMPL_IF HTML5></article><TMPL_ELSE></div></TMPL_IF>
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+try {
+var pageTracker = _gat._getTracker("UA-15235584-1");
+pageTracker._trackPageview();
+} catch(err) {}</script>
 
 </body>
 </html>
index 831daa871d11369b7b5c532014fbfab2b478c550..9acefb5d3aab81ac182b2b83e38b7658d458c693 100644 (file)
@@ -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>
+       <dcterms:creator><TMPL_VAR AUTHOR ESCAPE=HTML></dcterms:creator>
+</TMPL_IF>
 <TMPL_IF CATEGORIES>
 <TMPL_LOOP CATEGORIES>
        <category><TMPL_VAR CATEGORY></category>
        <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>
index e54094aaa2f1ddbc7e7b1cde73827eca9ad7da89..fec6775c242fc83adb3e6d02ccacb43c7f47b86e 100644 (file)
@@ -1,11 +1,18 @@
 <?xml version="1.0"?>
 <rss version="2.0"
+     xmlns:atom="http://www.w3.org/2005/Atom"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      xmlns:dcterms="http://purl.org/dc/terms/" >
 <channel>
 <title><TMPL_VAR TITLE></title>
 <link><TMPL_VAR PAGEURL></link>
+<atom:link href="<TMPL_VAR FEEDURL>" rel="self" type="application/rss+xml" />
+<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>
index f6cb5c04e1e0e011641464d54fcb718297c7eae6..d4afc0915b86a44ce2ad20d5d9e574e17abae945 100644 (file)
@@ -76,7 +76,7 @@ body {
        padding: 2px;
 }
 
-#content, #comments, #footer {
+#content, #enclosure, #comments, #footer {
        margin: 1em 2em;
 }
 
index 40a940f265a94f77be5191b124bbb321f3080b45..af1434574b537259e4bbf77fee8780788fe18856 100644 (file)
@@ -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;
index 9c217c746a065c48ccb080efc263419a375c5bd4..b0e29dfad6e6f7cfdc2849c2a16f214b66a74faa 100644 (file)
@@ -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;
 }
index 41a3a4441f7ce219ccf6c4ef752088e07f5c9002..bd3fdf5939c5a7754f7c08b1885ad8301e7b825e 100644 (file)
@@ -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;
 }