]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/commitdiff
Merge commit 'smcv/underlay'
authorJoey Hess <joey@gnu.kitenet.net>
Tue, 27 Jan 2009 01:13:15 +0000 (20:13 -0500)
committerJoey Hess <joey@gnu.kitenet.net>
Tue, 27 Jan 2009 01:13:15 +0000 (20:13 -0500)
36 files changed:
IkiWiki.pm
IkiWiki/Plugin/blogspam.pm
IkiWiki/Plugin/comments.pm
IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/img.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/meta.pm
IkiWiki/Plugin/remove.pm
IkiWiki/Setup/Automator.pm
debian/changelog
doc/bugs/cannot_reliably_use_meta_in_template.mdwn [new file with mode: 0644]
doc/contact.mdwn
doc/forum/chinese_character_problem.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/meta.mdwn
doc/ikiwiki/directive/pagestats/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/testpagespec/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/pagespec/discussion.mdwn
doc/ikiwikiusers.mdwn
doc/install/discussion.mdwn
doc/news/code_swarm.mdwn
doc/plugins/blogspam.mdwn
doc/plugins/comments.mdwn
doc/plugins/contrib/po.mdwn
doc/sandbox.mdwn
doc/style.css
doc/todo/avatar.mdwn [new file with mode: 0644]
doc/todo/need_global_renamepage_hook.mdwn
doc/todo/overriding_displayed_modification_time.mdwn [new file with mode: 0644]
doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn
doc/users/smcv.mdwn
doc/users/smcv/gallery.mdwn
doc/wikitemplates.mdwn
po/es.po
templates/comment.tmpl
templates/commentmoderation.tmpl [new file with mode: 0644]

index ca483a111693291adab7efbc720b2f8bdeda94c3..66fea4369b1326903f0bce26ed019a288e12788e 100644 (file)
@@ -174,7 +174,7 @@ sub getsetup () {
        verbose => {
                type => "boolean",
                example => 1,
-               description => "display verbose messages when building?",
+               description => "display verbose messages?",
                safe => 1,
                rebuild => 0,
        },
@@ -1729,7 +1729,7 @@ sub pagespec_translate ($) {
                                $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@_)";
                        }
                        else {
-                               $code.=' 0';
+                               $code.="IkiWiki::FailReason->new(".safequote(qq{unknown function in pagespec "$word"}).")";
                        }
                }
                else {
@@ -1738,7 +1738,7 @@ sub pagespec_translate ($) {
        }
 
        if (! length $code) {
-               $code=0;
+               $code="IkiWiki::FailReason->new('empty pagespec')";
        }
 
        no warnings;
index cc6e840f0ec6c8aa31f15e80312c472165a82165..cbd9859a533cf58dba27e1af20dc04368ab66e5e 100644 (file)
@@ -62,11 +62,11 @@ sub checkcontent (@) {
        }
 
        my $url=$defaulturl;
-       $url = $params{blogspam_server} if exists $params{blogspam_server};
+       $url = $config{blogspam_server} if exists $config{blogspam_server};
        my $client = RPC::XML::Client->new($url);
 
-       my @options = split(",", $params{blogspam_options})
-               if exists $params{blogspam_options};
+       my @options = split(",", $config{blogspam_options})
+               if exists $config{blogspam_options};
 
        # Allow short comments and whitespace-only edits, unless the user
        # has overridden min-words themselves.
@@ -83,7 +83,7 @@ sub checkcontent (@) {
        # and "buy".
        push @options, "exclude=stopwords";
 
-       my $res = $client->send_request('testComment', {
+       my %req=(
                ip => $ENV{REMOTE_ADDR},
                comment => $params{content},
                subject => defined $params{subject} ? $params{subject} : "",
@@ -92,17 +92,20 @@ sub checkcontent (@) {
                options => join(",", @options),
                site => $config{url},
                version => "ikiwiki ".$IkiWiki::version,
-       });
+       );
+       my $res = $client->send_request('testComment', \%req);
 
        if (! ref $res || ! defined $res->value) {
                debug("failed to get response from blogspam server ($url)");
                return undef;
        }
        elsif ($res->value =~ /^SPAM:(.*)/) {
+               eval q{use Data::Dumper};
+               debug("blogspam server reports ".$res->value.": ".Dumper(\%req));
                return gettext("Sorry, but that looks like spam to <a href=\"http://blogspam.net/\">blogspam</a>: ").$1;
        }
        elsif ($res->value ne 'OK') {
-               debug(gettext("blogspam server failure: ").$res->value);
+               debug("blogspam server failure: ".$res->value);
                return undef;
        }
        else {
index 833bedf25dcbad59a6f1dc3faed0f5c764b03db9..b2243ce4c85e3938483e4656746cf93d0b2f6821 100644 (file)
@@ -26,6 +26,7 @@ sub import {
        hook(type => "htmlize", id => "_comment", call => \&htmlize);
        hook(type => "pagetemplate", id => "comments", call => \&pagetemplate);
        hook(type => "cgi", id => "comments", call => \&linkcgi);
+       hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup);
        IkiWiki::loadplugin("inline");
 }
 
@@ -134,8 +135,8 @@ sub preprocess {
        }
 
        # no need to bother with htmlize if it's just HTML
-       $content = IkiWiki::htmlize($page, $params{destpage}, $format,
-               $content) if defined $format;
+       $content = IkiWiki::htmlize($page, $params{destpage}, $format, $content)
+               if defined $format;
 
        IkiWiki::run_hooks(sanitize => sub {
                $content = shift->(
@@ -263,13 +264,23 @@ sub linkcgi ($) {
        }
 }
 
-# Mostly cargo-culted from IkiWiki::plugin::editpage
 sub sessioncgi ($$) {
        my $cgi=shift;
        my $session=shift;
 
        my $do = $cgi->param('do');
-       return unless $do eq 'comment';
+       if ($do eq 'comment') {
+               editcomment($cgi, $session);
+       }
+       elsif ($do eq 'commentmoderation') {
+               commentmoderation($cgi, $session);
+       }
+}
+
+# Mostly cargo-culted from IkiWiki::plugin::editpage
+sub editcomment ($$) {
+       my $cgi=shift;
+       my $session=shift;
 
        IkiWiki::decode_cgi_utf8($cgi);
 
@@ -380,14 +391,7 @@ sub sessioncgi ($$) {
        IkiWiki::check_canedit($page, $cgi, $session);
        $postcomment=0;
 
-       # FIXME: rather a simplistic way to make the comments...
-       my $i = 0;
-       my $file;
-       my $location;
-       do {
-               $i++;
-               $location = "$page/$config{comments_pagename}$i";
-       } while (-e "$config{srcdir}/$location._comment");
+       my $location=unique_comment_location($page, $config{srcdir});
 
        my $content = "[[!_comment format=$type\n";
 
@@ -406,19 +410,19 @@ sub sessioncgi ($$) {
 
        if ($config{comments_allowauthor}) {
                my $author = $form->field('author');
-               if (length $author) {
+               if (defined $author && length $author) {
                        $author =~ s/"/&quot;/g;
                        $content .= " claimedauthor=\"$author\"\n";
                }
                my $url = $form->field('url');
-               if (length $url) {
+               if (defined $url && length $url) {
                        $url =~ s/"/&quot;/g;
                        $content .= " url=\"$url\"\n";
                }
        }
 
        my $subject = $form->field('subject');
-       if (length $subject) {
+       if (defined $subject && length $subject) {
                $subject =~ s/"/&quot;/g;
                $content .= " subject=\"$subject\"\n";
        }
@@ -438,29 +442,12 @@ sub sessioncgi ($$) {
        # - this means that if they do, rocks fall and everyone dies
 
        if ($form->submitted eq PREVIEW) {
-               my $preview = IkiWiki::htmlize($location, $page, '_comment',
-                               IkiWiki::linkify($location, $page,
-                                       IkiWiki::preprocess($location, $page,
-                                               IkiWiki::filter($location,
-                                                       $page, $content),
-                                               0, 1)));
+               my $preview=previewcomment($content, $location, $page, time);
                IkiWiki::run_hooks(format => sub {
-                               $preview = shift->(page => $page,
-                                       content => $preview);
-                       });
-
-               my $template = template("comment.tmpl");
-               $template->param(content => $preview);
-               $template->param(title => $form->field('subject'));
-               $template->param(ctime => displaytime(time));
-
-               IkiWiki::run_hooks(pagetemplate => sub {
-                       shift->(page => $location,
-                               destpage => $page,
-                               template => $template);
+                       $preview = shift->(page => $page,
+                               content => $preview);
                });
-
-               $form->tmpl_param(page_preview => $template->output);
+               $form->tmpl_param(page_preview => $preview);
        }
        else {
                $form->tmpl_param(page_preview => "");
@@ -470,21 +457,34 @@ sub sessioncgi ($$) {
                IkiWiki::checksessionexpiry($cgi, $session);
                
                $postcomment=1;
-               IkiWiki::check_content(content => $form->field('editcontent'),
+               my $ok=IkiWiki::check_content(content => $form->field('editcontent'),
                        subject => $form->field('subject'),
                        $config{comments_allowauthor} ? (
                                author => $form->field('author'),
                                url => $form->field('url'),
                        ) : (),
                        page => $location,
-                       cgi => $cgi, session => $session
+                       cgi => $cgi,
+                       session => $session,
+                       nonfatal => 1,
                );
                $postcomment=0;
-               
-               my $file = "$location._comment";
+
+               if (! $ok) {
+                       my $penddir=$config{wikistatedir}."/comments_pending";
+                       $location=unique_comment_location($page, $penddir);
+                       writefile("$location._comment", $penddir, $content);
+                       IkiWiki::printheader($session);
+                       print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
+                               "<p>".
+                               gettext("Your comment will be posted after moderator review"),
+                               "</p>");
+                       exit;
+               }
 
                # FIXME: could probably do some sort of graceful retry
                # on error? Would require significant unwinding though
+               my $file = "$location._comment";
                writefile($file, $config{srcdir}, $content);
 
                my $conflict;
@@ -529,6 +529,173 @@ sub sessioncgi ($$) {
        exit;
 }
 
+sub commentmoderation ($$) {
+       my $cgi=shift;
+       my $session=shift;
+
+       IkiWiki::needsignin($cgi, $session);
+       if (! IkiWiki::is_admin($session->param("name"))) {
+               error(gettext("you are not logged in as an admin"));
+       }
+
+       IkiWiki::decode_cgi_utf8($cgi);
+       
+       if (defined $cgi->param('sid')) {
+               IkiWiki::checksessionexpiry($cgi, $session);
+
+               my $rejectalldefer=$cgi->param('rejectalldefer');
+
+               my %vars=$cgi->Vars;
+               my $added=0;
+               foreach my $id (keys %vars) {
+                       if ($id =~ /(.*)\Q._comment\E$/) {
+                               my $action=$cgi->param($id);
+                               next if $action eq 'Defer' && ! $rejectalldefer;
+
+                               # Make sure that the id is of a legal
+                               # pending comment before untainting.
+                               my ($f)= $id =~ /$config{wiki_file_regexp}/;
+                               if (! defined $f || ! length $f ||
+                                   IkiWiki::file_pruned($f, $config{srcdir})) {
+                                       error("illegal file");
+                               }
+
+                               my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1));
+                               my $file="$config{wikistatedir}/comments_pending/".
+                                       IkiWiki::possibly_foolish_untaint($id);
+
+                               if ($action eq 'Accept') {
+                                       my $content=eval { readfile($file) };
+                                       next if $@; # file vanished since form was displayed
+                                       my $dest=unique_comment_location($page, $config{srcdir})."._comment";
+                                       writefile($dest, $config{srcdir}, $content);
+                                       if ($config{rcs} and $config{comments_commit}) {
+                                               IkiWiki::rcs_add($dest);
+                                       }
+                                       $added++;
+                               }
+
+                               # This removes empty subdirs, so the
+                               # .ikiwiki/comments_pending dir will
+                               # go away when all are moderated.
+                               require IkiWiki::Render;
+                               IkiWiki::prune($file);
+                       }
+               }
+
+               if ($added) {
+                       my $conflict;
+                       if ($config{rcs} and $config{comments_commit}) {
+                               my $message = gettext("Comment moderation");
+                               IkiWiki::disable_commit_hook();
+                               $conflict=IkiWiki::rcs_commit_staged($message,
+                                       $session->param('name'), $ENV{REMOTE_ADDR});
+                               IkiWiki::enable_commit_hook();
+                               IkiWiki::rcs_update();
+                       }
+               
+                       # Now we need a refresh
+                       require IkiWiki::Render;
+                       IkiWiki::refresh();
+                       IkiWiki::saveindex();
+               
+                       error($conflict) if defined $conflict;
+               }
+       }
+
+       my @comments=map {
+               my ($id, $ctime)=@{$_};
+               my $file="$config{wikistatedir}/comments_pending/$id";
+               my $content=readfile($file);
+               my $preview=previewcomment($content, $id,
+                       IkiWiki::dirname($_), $ctime);
+               {
+                       id => $id,
+                       view => $preview,
+               } 
+       } sort { $b->[1] <=> $a->[1] } comments_pending();
+
+       my $template=template("commentmoderation.tmpl");
+       $template->param(
+               sid => $session->id,
+               comments => \@comments,
+       );
+       IkiWiki::printheader($session);
+       my $out=$template->output;
+       IkiWiki::run_hooks(format => sub {
+               $out = shift->(page => "", content => $out);
+       });
+       print IkiWiki::misctemplate(gettext("comment moderation"), $out);
+       exit;
+}
+
+sub formbuilder_setup (@) {
+       my %params=@_;
+
+       my $form=$params{form};
+       if ($form->title eq "preferences") {
+               push @{$params{buttons}}, "Comment Moderation";
+               if ($form->submitted && $form->submitted eq "Comment Moderation") {
+                       commentmoderation($params{cgi}, $params{session});
+               }
+       }
+}
+
+sub comments_pending () {
+       my $dir="$config{wikistatedir}/comments_pending/";
+       return unless -d $dir;
+
+       my @ret;
+       eval q{use File::Find};
+       error($@) if $@;
+       find({
+               no_chdir => 1,
+               wanted => sub {
+                       $_=decode_utf8($_);
+                       if (IkiWiki::file_pruned($_, $dir)) {
+                               $File::Find::prune=1;
+                       }
+                       elsif (! -l $_ && ! -d _) {
+                               $File::Find::prune=0;
+                               my ($f)=/$config{wiki_file_regexp}/; # untaint
+                               if (defined $f && $f =~ /\Q._comment\E$/) {
+                                       my $ctime=(stat($f))[10];
+                                       $f=~s/^\Q$dir\E\/?//;
+                                        push @ret, [$f, $ctime];
+                               }
+                       }
+               }
+       }, $dir);
+
+       return @ret;
+}
+
+sub previewcomment ($$$) {
+       my $content=shift;
+       my $location=shift;
+       my $page=shift;
+       my $time=shift;
+
+       my $preview = IkiWiki::htmlize($location, $page, '_comment',
+                       IkiWiki::linkify($location, $page,
+                       IkiWiki::preprocess($location, $page,
+                       IkiWiki::filter($location, $page, $content), 0, 1)));
+
+       my $template = template("comment.tmpl");
+       $template->param(content => $preview);
+       $template->param(ctime => displaytime($time));
+
+       IkiWiki::run_hooks(pagetemplate => sub {
+               shift->(page => $location,
+                       destpage => $page,
+                       template => $template);
+       });
+
+       $template->param(have_actions => 0);
+
+       return $template->output;
+}
+
 sub commentsshown ($) {
        my $page=shift;
 
@@ -654,6 +821,20 @@ sub pagetemplate (@) {
        }
 }
 
+sub unique_comment_location ($) {
+       my $page=shift;
+       my $dir=shift;
+
+       my $location;
+       my $i = 0;
+       do {
+               $i++;
+               $location = "$page/$config{comments_pagename}$i";
+       } while (-e "$dir/$location._comment");
+
+       return $location;
+}
+
 package IkiWiki::PageSpec;
 
 sub match_postcomment ($$;@) {
index bba52e4fd322e8bbad5f63a13198ff5f491cdef5..c206d96a44f521200861271bd2256a03b49ccfa2 100644 (file)
@@ -105,11 +105,12 @@ sub check_content (@) {
                                $ok=1;
                        }
                        elsif (ref $ret eq 'CODE') {
-                               $ret->();
+                               $ret->() unless $params{nonfatal};
                                $ok=0;
                        }
                        elsif (defined $ret) {
-                               error($ret);
+                               error($ret) unless $params{nonfatal};
+                               $ok=0;
                        }
                }
 
index 3085a3b6711da7d9a2991837820664b108630569..042c69f5a043699ff275f4acb7433a9482a366c8 100644 (file)
@@ -139,6 +139,12 @@ sub safe_git (&@) {
        my @lines;
        while (<$OUT>) {
                chomp;
+               
+               # check for invalid utf-8, and toss it back to avoid crashes
+               if (! utf8::valid($_)) {
+                       $_=encode_utf8($_);
+               }
+
                push @lines, $_;
        }
 
index 5c580c03cec01a5c4529fefd9f207702e0306d58..d295b833b21b57ccfef5c5d985ae91281efb466b 100644 (file)
@@ -119,9 +119,9 @@ sub preprocess (@) {
        }
 
        my $imgtag='<img src="'.$imgurl.
-               '" alt="'.(exists $params{alt} ? $params{alt} : '').
                '" width="'.$im->Get("width").
                '" height="'.$im->Get("height").'"'.
+               (exists $params{alt} ? '" alt="'.$params{alt}.'"' : '').
                (exists $params{title} ? ' title="'.$params{title}.'"' : '').
                (exists $params{class} ? ' class="'.$params{class}.'"' : '').
                (exists $params{id} ? ' id="'.$params{id}.'"' : '').
index d8b5f8548251f4d04332fb0f7d9e0bbd555993af..2205ebffc48cda2f9ccd6fab71dec170765fa880 100644 (file)
@@ -519,9 +519,15 @@ sub genfeed ($$$$$@) {
                        mdate_3339 => date_3339($pagemtime{$p}),
                );
 
-               if (exists $pagestate{$p} &&
-                   exists $pagestate{$p}{meta}{guid}) {
-                       $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+               if (exists $pagestate{$p}) {
+                       if (exists $pagestate{$p}{meta}{guid}) {
+                               $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+                       }
+
+                       if (exists $pagestate{$p}{meta}{updated}) {
+                               $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")) {
index 15bb29b3fc8450e693fe4a3005f2f3925ab0f00b..4a22fed3057015156c27d9f8159e9f4b47e3a633 100644 (file)
@@ -128,6 +128,13 @@ sub preprocess (@) {
                        $IkiWiki::pagectime{$page}=$time if defined $time;
                }
        }
+       elsif ($key eq 'updated') {
+               eval q{use Date::Parse};
+               if (! $@) {
+                       my $time = str2time($value);
+                       $pagestate{$page}{meta}{updated}=$time if defined $time;
+               }
+       }
 
        if (! defined wantarray) {
                # avoid collecting duplicate data during scan pass
index 21989aff3ff1c812af0ca83f5d8ecd72046393aa..ee5784f2026db29ac4d48041f6cd355c2356bf1a 100644 (file)
@@ -218,7 +218,7 @@ sub sessioncgi ($$) {
                        }
                }
                else {
-                       IkiWiki::showform($form, $buttons, $session, $q);
+                       removal_confirm($q, $session, 0, $q->param("page"));
                }
 
                exit 0;
index b7798fcec09c287ae247bc12d6c9923ae8b3971d..42caf3039a9d79fc9686adc206b5b874eb2b3bdf 100644 (file)
@@ -9,12 +9,13 @@ use IkiWiki;
 use IkiWiki::UserInfo;
 use Term::ReadLine;
 use File::Path;
+use Encode;
 
 sub ask ($$) {
        my ($question, $default)=@_;
 
        my $r=Term::ReadLine->new("ikiwiki");
-       $r->readline($question." ", $default);
+       $r->readline(encode_utf8($question)." ", $default);
 }
 
 sub prettydir ($) {
index 013dc1884455e073ea4f95993cbd7f88d62844d6..7f72a672a0e63278040c75ed9a9659112f34a5e9 100644 (file)
@@ -1,3 +1,20 @@
+ikiwiki (3.03) UNRELEASED; urgency=low
+
+  * Avoid feeding decoded unicode to Term::ReadLine.
+    Closes: 512169
+  * blogspam: Log spam info on failure in debug mode.
+  * Remove nonstandard css. Closes: #512378
+  * blogspam: Fix use of blogspam_options and blogspam_server
+    config settings.
+  * comments: If comment content checks fail, store the comment
+    (in .ikiwiki/comments_pending) for moderator review.
+  * comments: Add a moderation web interface.
+  * git: Fix malformed utf8 recieved from git.
+  * meta: New "updated" metadata specifies a fake modification time for a
+    page, to be output into RSS and Atom feeds. (smcv)
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 18 Jan 2009 14:50:57 -0500
+
 ikiwiki (3.02) unstable; urgency=low
 
   * blogspam: New plugin, adding spam filtering for page editing / comment
diff --git a/doc/bugs/cannot_reliably_use_meta_in_template.mdwn b/doc/bugs/cannot_reliably_use_meta_in_template.mdwn
new file mode 100644 (file)
index 0000000..046f40a
--- /dev/null
@@ -0,0 +1,14 @@
+meta title cannot reliably be put inside a template used by the
+[[plugins/template]] plugin. Since meta title info is gathered in the scan
+pass, which does not look at the template a page includes, it will not be
+seen then, and so other pages that use the page title probably won't use
+it. (Barring luck with build order.)
+
+There is a simple fix for this, just add `scan => 1` when registering the
+preprocess hook for the template plugin.
+
+However, the overhead of this has to be considered. It means that, on every
+scan pass, every page containing a template will cause the template to be
+loaded and filled out. This can be some serious additional overhead.
+
+--[[Joey]] 
index 37fb59071607e042b7476fcc738419a6ff97cd72..486a4d1864a2e731cb9d7d6cd6bc37c9f2705609 100644 (file)
@@ -7,4 +7,5 @@ developers monitor [[RecentChanges]] closely, via the webpage, email,
 [CIA](http://cia.navi.cx), and IRC, and respond in a timely fashion.
 
 You could also drop by the IRC channel `#ikiwiki` on
-[OFTC](http://www.oftc.net/) (`irc.oftc.net`).
+[OFTC](http://www.oftc.net/) (`irc.oftc.net`), or use the
+[identi.ca ikiwiki group](http://identi.ca/group/ikiwiki).
diff --git a/doc/forum/chinese_character_problem.mdwn b/doc/forum/chinese_character_problem.mdwn
new file mode 100644 (file)
index 0000000..c203ec4
--- /dev/null
@@ -0,0 +1,21 @@
+just finished setting up ikiwiki..
+
+I can type chinese, save and display it correctly in ikiwiki for the first time. However, when i try to edit the page again, the chinese character in the form is unrecognizable. you can see it here <http://ikiwiki.perlchina.org/>
+
+I am using the latest ikiwiki(manually installed as non-root user) and CGI::FormBuilder(3.0501) on Debian 4.0
+
+这个没问题 it is not a problem on ikiwiki website though.
+
+Thanks.
+
+
+> Is your system perhaps not configured with a utf-8 default locale? Or ikiwiki not configured to use it?
+> Make sure that some utf-8 locale is enabled (in /etc/locale.gen on Debian for example) and try setting `locale` in your > ikiwiki setup file. --[[Joey]]
+
+I have installed locales-all and locale -a shows that zh_CN.UTF-8 is installed(there is no /etc/local.gen file though). then I enabled this line "locale => 'zh_CN.UTF-8'" in my wiki setup and -setup again. but that generated lots error messages "Missing constant domain at (eval 30) line 3"
+
+sorry being a n00b on this thing  what else can I do?
+
+> See [[bugs/Missing_constant_domain_at_IkiWiki.pm_line_842]].
+> Looks like you need to upgrade to a newer version of 
+> [[cpan Locale::gettext]] --[[Joey]] 
index 74db319435b346ce8aee6854717947c72c4d389e..f29a118bfea91d9957c30022312e558bc3b8b980 100644 (file)
@@ -139,6 +139,15 @@ Supported fields:
   pages unchanged and avoid_flooding_aggregators
   (see [[!iki tips/howto_avoid_flooding_aggregators]]).
 
+* updated
+
+  Specifies a fake modification time for a page, to be output into RSS and
+  Atom feeds. This is useful to avoid flooding aggregators that sort by
+  modification time, like Planet: for instance, when editing an old blog post
+  to add tags, you could set `updated` to be one second later than the original
+  value. The date/time can be given in any format that
+  [[!cpan TimeDate]] can understand, just like the `date` field.
+
 If the field is not one of the above predefined fields, the metadata will be
 written to the generated html page as a &lt;meta&gt; header. However, this
 won't be allowed if the [[!iki plugins/htmlscrubber desc=htmlscrubber]] plugin is enabled,
diff --git a/doc/ikiwiki/directive/pagestats/discussion.mdwn b/doc/ikiwiki/directive/pagestats/discussion.mdwn
new file mode 100644 (file)
index 0000000..3c9dc71
--- /dev/null
@@ -0,0 +1,10 @@
+I am trying to create a tag cloud using:  
+           
+     \[[!pagestats  pages="tags/*"]]
+
+Nothing shows up when I first used this directive. I found that I had to create a page for the tag for it to show up in pagestats.
+I would rather not find and create a page for every tag I have created or will create. Is there an easier way to create a list of tags?
+
+Thanks
+
+----
diff --git a/doc/ikiwiki/directive/testpagespec/discussion.mdwn b/doc/ikiwiki/directive/testpagespec/discussion.mdwn
new file mode 100644 (file)
index 0000000..66c9a9c
--- /dev/null
@@ -0,0 +1,6 @@
+How does one test a user identity?  I tried "pagename and user(username) for the match, and had a "no user specified" error.
+
+> You can't test them with this directive, because such pagespecs test to
+> see if logged in user, who is performing some action, matches. When the
+> page with the directive is built, the concept of a user being logged in
+> doesn't really apply. --[[Joey]] 
index 0733c90c8efd7cc8a47b55d91f3cdd10fbcc1432..4eed3722ccc744595fc8380e68e69dc9e1ad6450 100644 (file)
@@ -65,3 +65,30 @@ How can I fix this?  --[[sabr]]
 
 > I don't see why that wouldn't work. Can I download the source to your
 > wiki from somewhere to investigate? --[[Joey]]
+
+----
+
+Should negation work with user(), with locked_pages in setup?  I
+experimented with setting locked_pages => 'user(someuser)' and was able to
+edit as a different user.  However, setting locked_pages =>
+'!user(someuser)' doesn't seem to allow edits for only 'someuser' - it
+locks out all users.
+
+> Negation works with anything in any PageSpec. I tested the case you
+> describe, and a negated pagespec worked for me; all users except the
+> listed user (and except wiki admins of course) were locked out.
+> --[[Joey]] 
+
+>> It must be a local problem, then, cause I've tried it with two separate 
+>> machines.  Both are running the most recent release of ikiwiki in 
+>> pkgsrc - 2.66.  Perhaps an update to a newer version would solve the issue.
+
+----
+
+Is there a way to refer to all subpages of the current page, if  the name of the 
+current page is not known (i.e. the pagespec is used in a template)? The ./ syntax
+does not seem suitable for this, as
+
+> \[[!map pages="./*"]]
+
+also lists the current page and all its siblings.
index 2a51dfd9dc19e9f1510c92f5c16ca245815c325d..989a425c6cdd0ffeea4d098f14f0440a8d3efed5 100644 (file)
@@ -105,6 +105,8 @@ Personal sites and blogs
 * [[xma]] is using ikiwiki (<http://maillard.mobi/~xma/>)
 * [[JanWalzer|jwalzer]]'s [homepage](http://wa.lzer.net/) -- Work in Progress
 * [[Adam_Trickett|ajt]]'s home intranet/sanbox system ([Internet site & blog](http://www.iredale.net/) -- not ikiwiki yet)
+* [[Simon_McVittie|smcv]]'s [website](http://www.pseudorandom.co.uk/) and
+  [blog](http://smcv.pseudorandom.co.uk/)
 
 Schools
 =======
index b5757070f1c9549824c79532e379c79b95910dd0..c1129a4358cc9a9e75364be6c3a837a54e617825 100644 (file)
@@ -178,3 +178,53 @@ I've tried a couple of times and my cpan has never recognised Bundle::IkiWiki. I
 > Can you show how it fails to find the bundle? --[[Joey]]
 
 >> I was not. Next time I build I will have to try that (I'll need to tweak it as I already override PERL5LIB; also I need to specify http proxies). Thanks for your help! -- [[users/Jon]]
+
+---
+
+##Further problems with Bundle::IkiWiki
+I'm also having trouble with finding Bundle::IkiWiki.  I've tried it with the environment settings and without them, and also using the interactive 
+form of the cpan command.  I've also gone to cpan.org and searched -- eg
+
+    http://search.cpan.org/search?query=ikiwiki&mode=all
+
+and no Bundle for IkiWiki comes up at all.
+
+The error I get from the various cpan attempts is basically always the same:
+
+    Warning: Cannot install Bundle::IkiWiki, don't know what it is.
+    Try the command
+
+        i /Bundle::IkiWiki/
+
+    to find objects with matching identifiers.
+
+When I try that command, BTW, it basically seems to find the same stuff I get when searching on the cpan web site.
+
+This happens both on Ubuntu 8.04 and CentOS 5.1
+
+Any help would be greatly appreciated... --kent
+
+> Bundle::IkiWiki is included in ikiwiki itself, so of course cpan.org
+> does not know about it.
+> 
+> If you can show me exactly what command you ran (the tested, working
+> commands on the parent page?) and how it failed, I can try to debug
+> your problem.
+
+Just today I noticed the "Bundle" subdirectory.  What a moron I am! :-)  Also, I misunderstood the PERL5LIB=`pwd` part -- 
+I glibly thought it indicated the sink for the installation of the modules, rather than the source, and I was running 
+the cpan command from another window in a different directory, and just spiraled down into error...
+
+> The real question in my mind is why you'd want to do this at all when
+> using Ubuntu, which incldues packages of ikiwiki and all its
+> dependencies. --[[Joey]]
+
+For ubuntu 8.04: 
+
+    $ ikiwiki --version
+    ikiwiki version 2.32.3ubuntu2.1
+    $
+
+I was just trying to get the latest version.
+
+In any case, thanks for the help, and thanks for the superb software.  I really like it a lot.
index bdc37343225897f7aabd8b2b747a963afede97cf..09b68523eaddb1932dd0a19a1e82ede32004ad2e 100644 (file)
@@ -1,7 +1,7 @@
 I've produced a [code_swarm](http://vis.cs.ucdavis.edu/~ogawa/codeswarm/)
 visualization of the first 2+ years of ikiwiki's commit history. 
 
-[[!img screenshot.png size="480x360"]]
+[[!img screenshot.png size="480x360" alt="screenshot"]]
 
 * [15 mb avi](http://kitenet.net/~joey/screencasts/ikiwiki_swarm.avi)
 * [stream on vimeo](http://vimeo.com/1324348)
index a090f9c603377e4f0e2488a98eb35145ffb4162b..1d152faac19b224e2502a430ba3a41862e503ecc 100644 (file)
@@ -3,8 +3,9 @@
 
 This plugin adds antispam support to ikiwiki, using the
 [blogspam.net](http://blogspam.net/) API. Both page edits and
-[[comment|comments]] postings can be checked for spam. Currently,
-detected spam is not saved for human review, it is just rejected.
+[[comment|comments]] postings can be checked for spam. Page edits that
+appear to contain spam will be rejected; comments that look spammy will be
+stored in a queue for moderation by an admin.
 
 The plugin requires the [[!cpan RPC::XML]] perl module.
 
index 72b11af645a607711af4a3d16b39057d74ff9738..c13a6daa6a1ddb88e0d3f1b8973a3c029c56a815 100644 (file)
@@ -41,3 +41,12 @@ There are some global options for the setup file:
   specify a name for themselves, and the \[[!meta author]] and
   \[[!meta authorurl]] directives will not be overridden by the comments
   plugin
+
+## comment moderation
+
+If you enable the [[blogspam]] plugin, comments that appear spammy will be
+held for moderation. Wiki admins can access the comment moderation queue
+via a button on their Preferences page.
+
+The comments are stored in `.ikiwiki/comments_pending/`, and can be
+deleted, or moved into the wiki's srcdir to be posted.
index edd6651854b42b06221c5aea98be037976900ea1..f2d46c391f796d964d5010155960346115a97d4f 100644 (file)
@@ -171,3 +171,118 @@ Any thoughts on this?
 
 I've set this plugin development aside for a while. I will be back and
 finish it at some point in the first quarter of 2009. --[[intrigeri]]
+
+> Abstract: Joey, please have a look at my po and meta branches.
+> 
+> Detailed progress report:
+> 
+> * it seems the po branch in your repository has not been tracking my
+>   own po branch for two months. any config issue?
+> * all the plugin's todo items have been completed, robustness tests
+>   done
+> * I've finished the detailed security audit, and the fix for po4a
+>   bugs has entered upstream CVS last week
+> * I've merged your new `checkcontent` hook with the `cansave` hook
+>   I previously introduced in my own branch; blogspam plugin updated
+>   accordingly
+> * the rename hook changes we discussed elsewhere are also part of my
+>   branch
+> * I've introduced two new hooks (`canremove` and `canrename`), not
+>   a big deal; IMHO, they extend quite logically the plugin interface
+> * as highlighted on [[bugs/pagetitle_function_does_not_respect_meta_titles]],
+>   my `meta` branch contains a new feature that is really useful in a
+>   translatable wiki
+> 
+> As a conclusion, I'm feeling that my branches are ready to be
+> merged; only thing missing, I guess, are a bit of discussion and
+> subsequent adjustments.
+> 
+> --[[intrigeri]]
+
+> I've looked it over and updated my branch with some (untested)
+> changes.
+> 
+>> I've merged your changes into my branch. Only one was buggy.
+> 
+> Sorry, I'd forgotten about your cansave hook.. sorry for the duplicate
+> work there.
+> 
+> Reviewing the changes, mostly outside of `po.pm`, I have
+> the following issues.
+>  
+> * renamepage to renamelink change would break the ikiwiki
+>   3.x API, which I've promised not to do, so needs to be avoided
+>   somehow. (Sorry, I guess I dropped the ball on not getting this
+>   API change in before cutting 3.0..)
+>> 
+>> Fixed, see [[todo/need_global_renamepage_hook]].
+>>
+> * I don't understand the parentlinks code change and need to figure it
+>   out. Can you explain what is going on there?
+>> 
+>> I'm calling `bestlink` there so that po's injected `bestlink` is
+>> run. This way, the parent links of a page link to the parent page
+>> version in the proper language, depending on the
+>> `po_link_to=current` and `po_link_to=negotiated` settings.
+>> Moreover, when using my meta branch enhancements plus meta title to
+>> make pages titles translatable, this small patch is needed to get
+>> the translated titles into parentlinks.
+>> 
+> * canrename's mix of positional and named parameters is way too
+>   ugly to get into an ikiwiki API. Use named parameters
+>   entirely. Also probably should just use named parameters
+>   for canremove.
+> * `skeleton.pm.example`'s canrename needs fixing to use either
+>   the current or my suggested parameters.
+>> 
+>> Done.
+>> 
+> * I don't like the exporting of `%backlinks` and `$backlinks_calculated`
+>   (the latter is exported but not used).
+>> 
+>> The commit message for 85f865b5d98e0122934d11e3f3eb6703e4f4c620
+>> contains the rationale for this change. I guess I don't understand
+>> the subtleties of `our` use, and perldoc does not help me a lot.
+>> IIRC, I actually did not use `our` to "export" these variables, but
+>> rather to have them shared between `Render.pm` uses.
+>>
+>>> My wording was unclear, I meant exposing. --[[Joey]]
+>>>  
+> * What is this `IkiWiki::nicepagetitle` and why are you
+>   injecting it into that namespace when only your module uses it?
+>   Actually, I can't even find a caller of it in your module.
+>> 
+>> I guess you should have a look to my `meta` branch and to
+>> [[bugs/pagetitle_function_does_not_respect_meta_titles]] in order
+>> to understand this :)
+>>
+>>> It would probably be good if I could merge this branch without 
+>>> having to worry about also immediatly merging that one. --[[Joey]] 
+>> 
+> * I'm very fearful of the `add_depends` in `postscan`. 
+>   Does this make every page depend on every page that links
+>   to it? Won't this absurdly bloat the dependency pagespecs
+>   and slow everything down? And since nicepagetitle is given
+>   as the reason for doing it, and nicepagetitle isn't used,
+>   why do it?
+>> 
+>> As explained in the 85f865b5d98e0122934d11e3f3eb6703e4f4c620 log:
+>> this feature hits performance a bit. Its cost was quite small in my
+>> real-world use-cases (a few percents bigger refresh time), but
+>> could be bigger in worst cases. When using the po plugin with my
+>> meta branch changes (i.e. the `nicepagetitle` thing), and having
+>> enabled the option to display translation status in links, this
+>> maintains the translation status up-to-date in backlinks. Same when
+>> using meta title to make the pages titles translatable. It does
+>> help having a nice and consistent translated wiki, but as it can
+>> also involve problems, I just turned it into an option.
+>> 
+> * The po4a Suggests should be versioned to the first version
+>   that can be used safely, and that version documented in 
+>   `plugins/po.mdwn`.
+>>
+>> Done.
+>> 
+>> --[[intrigeri]]
+> 
+> --[[Joey]] 
index d39b5971583eeef6e65c0ac7d838ddcd3fc92c34..a39264e18018b380d5bee9f70e2a3f1b04deaecc 100644 (file)
@@ -1,14 +1,8 @@
-This is the [[SandBox]], a page anyone can edit to try out ikiwiki.
-
-hello
-
-testing 1..2..3!!
-
-----
-
-I am testing the edit box provided through ikiwiki.cgi.
+This is the [[SandBox]], a page anyone can edit to try out ikiwiki (version [[!version  ]]).
 
 ----
+test
+[[中文显示]]
 
 Here's a paragraph.
 
@@ -59,10 +53,6 @@ Bulleted list
        * four
         * five
 
-* a new list
- * with sub heads
- * like this
-
 ----
 
 [[!template id=note text="this is generated by the [[plugins/haiku]] plugin"]]
@@ -82,7 +72,6 @@ The haiku will change after every save, mind you.
 * [![ikiwiki logo](http://ikiwiki.info/logo/ikiwiki.png)](http://ikiwiki.info)
 * <a href="http://www.google.com/">plain old html link</a>
 * [[foo]]
-* WikiLink
 
 -----
 
index 81a260afd78ef97a18d9ef4727c12627cc37bd00..a6e6734e3124151829d585b2b566e5347df84c03 100644 (file)
@@ -23,6 +23,8 @@
        margin: 0;
        padding: 6px;
        list-style-type: none;
+}
+.pageheader .actions ul {
        border-bottom: 1px solid #000;
 }
 
@@ -339,11 +341,6 @@ input#searchbox {
        border: 2px solid;
        background-color: #dee;
        color: black;
-       
-       /* Nonstandard, but very nice. */
-       opacity: 0.95;
-       -moz-opacity: 0.95;
-       filter: alpha(opacity=95);
 }
 
 /* Formbuilder styling */
diff --git a/doc/todo/avatar.mdwn b/doc/todo/avatar.mdwn
new file mode 100644 (file)
index 0000000..b8aa232
--- /dev/null
@@ -0,0 +1,47 @@
+[[!tag wishlist]]
+
+It would be nice if ikiwiki, particularly [[plugins/comments]]
+supported user avatar icons. I was considering adding a directive for this,
+as designed below.
+
+However, there is no *good* service for mapping openids to avatars --
+openavatar has many issues, including not supporting delegated openids, and
+after trying it, I don't trust it to push users toward. 
+Perhaps instead ikiwiki could get the email address from the openid
+provider, though I think the perl openid modules don't support the openid
+2.x feature that allows that.
+
+At the moment, working on this doesn't feel like a good use of my time.
+--[[Joey]]
+
+Hmm.. unless is just always used a single provider (gravatar) and hashed
+the openid. Then wavatars could be used to get a unique avatar per openid
+at least. --[[Joey]] 
+
+----
+
+The directive displays a small avatar image for a user. Pass it the
+email address, openid, or wiki username of the user.
+
+       \[[!avatar user@example.com]]
+       \[[!avatar http://joey.kitenet.net/]]
+       \[[!avatar user]]
+
+The avatars are provided by various sites. For email addresses, it uses a
+[gravatar](http://gravatar.com/). For openid,
+[openavatar](http://www.openvatar.com/) is used. For a wiki username, the
+user's email address is looked up and the gravatar for that user is
+displayed. (Of course, the user has to have filled in their email address
+on their Preferences page for that to work.)
+
+An optional second parameter can be included, containing additional
+options to pass in the 
+[gravatar url](http://en.gravatar.com/site/implement/url).
+For example, this asks for a smaller gravatar, and if a user does
+not have a gravatar, uses a cute auto-generated "wavatar" avatar.
+
+       \[[!gravatar user@example.com "size=40&default=wavatar"]]
+
+The `gravitar_options` setting in the setup file can be used to
+specify additional options to pass. So for example if you want
+to use wavatars everywhere, set it to "default=wavatar".
index f4e18baa210f406a441cfe657e2417cfde79b175..62e91eee40a8f5bbe5ec291962786ba7fe6a57e4 100644 (file)
@@ -55,3 +55,28 @@ would solve my problem. Hmmm? --[[intrigeri]]
 >> In my `po` branch, I renamed `renamepage` to `renamelink`, and
 >> created a `rename` hook that is passed a reference to `@torename`.
 >> --[[intrigeri]]
+
+>>> As Joey highlights it on [[plugins/contrib/po]], it's too late to
+>>> merge such a change, as the 3.x plugin API is released and should
+>>> not be broken. I will thus keep the existing `renamepage` as it
+>>> is, and call `rename` the global hook I need. --[[intrigeri]]
+
+>>>> Done in my `po` branch. --[[intrigeri]]
+
+I think I see a problem in the rename hook. The hook is called
+before the plugin adds any subpages to the set of pages to rename.
+So, if the user choses to rename subpages, po will not notice
+they are moving, and will not move their po files.
+Perhaps the hooks should be moved to come after subpages are added.
+This would, though, mean that if the hook somehow decides to add
+entirely other pages to the list, their subpages would not be
+automatically added.
+
+I also have some qualms about the design of the hook. In particular,
+passing the mutable array reference probably makes it impossible
+to use from external plugins. Instead it could return any additional
+rename hashes it wants to add. Or, if the ability to modify existing
+hashes is desired, it could return the full set of hashes.
+
+--[[Joey]] 
diff --git a/doc/todo/overriding_displayed_modification_time.mdwn b/doc/todo/overriding_displayed_modification_time.mdwn
new file mode 100644 (file)
index 0000000..160d315
--- /dev/null
@@ -0,0 +1,27 @@
+Some aggregators, like Planet, sort by mtime rather than ctime. This
+means that posts with modified content come to the top (which seems odd
+to me, but is presumably what the aggregator's author or operator
+wants),
+
+> Hah! That's so charitable I hope you can deduct it from your taxes. ;-)
+> --[[Joey]] 
+
+but it also means that posts with insignificant edits (like
+adding tags) come to the top too. Atom defines `<updated>` to be the date
+of the last *significant* change, so it's fine that ikiwiki defaults to
+using the mtime, but it would be good to have a way for the author to
+say "that edit was insignificant, don't use that mtime".
+
+> Yes, this is a real limitiation of ikiwiki's atom support. --[[Joey]] 
+
+See smcv's 'updated' branch for a basic implementation, which only affects
+the Atom `<updated>` field or the RSS equivalent.
+
+Other places the updated metadata item could be used (opinions on whether
+each should use it or not, please):
+
+* sorting by mtime in the inline directive
+* displaying "last edited" on ordinary pages
+
+> Tending toward no for both, but willing to be convinced otherwise..
+> [[merged|done]] --[[Joey]]  
index 3b9f6c0fdf31810b94bcbe6abd495a89b67c186d..c4e78ca0bb7147eba8765b5185820f3beb279eda 100644 (file)
@@ -56,3 +56,5 @@ the templates. I'd prefer not having to touch Perl though...
 Yes, Template::Toolkit is very powerful. But I think it's somehow overkill for a wiki. HTML::Template can keep things simple, though.  --[weakish](http://weakish.int.eu.org/blog/)
 
 I'd have to agree that Template::Toolkit is overkill and personally I'm not a fan, but it is very popular (there is even a book) and the new version (3) is alleged to be much more nimble than current version.  --[[ajt]]
+
+HTML::Template's HTML-like markup prevents me from editing templates in KompoZer or other WYSIWYG HTML editors.  The editor tries to render the template markup rather than display it verbatim, and large parts of the template become invisible.  A markup syntax that doesn't confuse editors (such as Template::Toolkit's "[% FOO %]") may promote template customization.  The ability to replace the template engine would be within the spirit of ikiwiki's extensibility. --Rocco
index c52aa8f0f1efbff2cfe435ae794c0e5a604fe788..59d1affba20f97c4e8e7f7db94588cb9a5533076 100644 (file)
@@ -7,4 +7,4 @@ My repository containing ikiwiki branches:
 * gitweb: http://git.pseudorandom.co.uk/smcv/ikiwiki.git
 * anongit: git://git.pseudorandom.co.uk/git/smcv/ikiwiki.git
 
-Currently working on the [[plugins/contrib/comments]] plugin.
+Currently thinking about a [[users/smcv/gallery]] plugin.
index 40e9f627916395ba564f9ccfa3bd9f4e5ece8248..5b4c6fe00e844f8d1981e7caa9c1f3e244ad4a8b 100644 (file)
@@ -13,10 +13,10 @@ and Facebook's Photos "application".
 
 The web UI I'm trying to achieve consists of one
 [HTML page of thumbnails](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/)
-as an entry point to the gallery, where each thumbnail
-links to
+as an entry point to the gallery, where each thumbnail links to
 [a "viewer" HTML page](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/img_0068/)
-with a full size image, next/previous thumbnail links, and [[plugins/comments]].
+with a full size image, next/previous thumbnail links, and
+[[plugins/comments]].
 
 (The Summer of Code [[plugins/contrib/gallery]] plugin does the
 next/previous UI in Javascript using Lightbox, which means that
@@ -44,13 +44,14 @@ Other features that would be good to have:
 
 * rendering an `<object>/<embed>` arrangement to display videos, and possibly
   thumbnailing them in the same way as totem-video-thumbnailer
-  (my camera can record short videos, so some of my web photo galleries contain
-  them)
+  (my camera can record short videos, so some of my web photo galleries
+  contain them)
 
 My plan is to have these directives:
 
-* \[[!gallery]] registers the page it's on as a gallery, and displays all photos
-  that are part of this gallery but not part of a \[[!gallerysection]] (below).
+* \[[!gallery]] registers the page it's on as a gallery, and displays all
+  photos that are part of this gallery but not part of a \[[!gallerysection]]
+  (below).
 
   All images (i.e. `*.png *.jpg *.gif`) that are attachments to the gallery page
   or its subpages are considered to be part of the gallery.
@@ -65,7 +66,8 @@ My plan is to have these directives:
 * \[[!gallerysection filter="[[ikiwiki/PageSpec]]"]] displays all photos in the
   gallery that match the filter
 
-So, [the gallery I'm using as an example](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/)
+So,
+[the gallery I'm using as an example](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/)
 could look something like this:
 
     \[[!gallery]]
@@ -85,13 +87,6 @@ could look something like this:
 
 ## Implementation ideas
 
-The photo galleries I have at the moment, like the Panic Cell example above,
-are made by using an external script to parse XML gallery descriptions (lists
-of image filenames, with metadata such as titles), and using this to write IkiWiki
-markup into a directory which is then used as an underlay. This is a hack, but it
-works. The use of XML is left over from a previous attempt at solving the same
-problem using Django.
-
 The next/previous part this plugin overlaps with [[todo/wikitrails]].
 
 A \[[!galleryimg]] directive to assign metadata to images is probably necessary, so
@@ -100,15 +95,21 @@ the gallery page can contain something like:
     \[[!galleryimg p1010001.jpg title="..." caption="..." tags="foo"]]
     \[[!galleryimg p1010002.jpg title="..." caption="..." tags="foo bar"]]
 
-Making the viewer pages could be rather tricky.
+Making the viewer pages could be rather tricky. Here are some options:
+"synthesize source pages for viewers" is the one I'm leaning towards at the
+moment.
+
+### Viewers' source page is the gallery
 
-One possibility is to write out the viewer pages as a side-effect of preprocessing
-the \[[!gallery]] directive. The proof-of-concept implementation below does this.
-However, this does mean the viewer pages can't have tags or metadata of their own
-and can't be matched by [[pagespecs|ikiwiki/pagespec]] or
+One possibility is to write out the viewer pages as a side-effect of
+preprocessing the \[[!gallery]] directive. The proof-of-concept implementation
+below does this.  However, this does mean the viewer pages can't have tags or
+metadata of their own and can't be matched by [[pagespecs|ikiwiki/pagespec]] or
 [[wikilinks|ikiwiki/wikilink]]. It might be possible to implement tagging by
 using \[[!galleryimg]] to assign the metadata to the *images* instead of their
-viewers, 
+viewers.
+
+### Synthesize source pages for viewers
 
 Another is to synthesize source pages for the viewers. This means they can have
 tags and metadata, but trying to arrange for them to be scanned etc. correctly
@@ -117,13 +118,75 @@ without needing another refresh run is somewhat terrifying.
 the refresh hook, but I don't really like the idea of a refresh hook that scans
 all source pages to see if they contain \[[!gallery]]...
 
-Making the image be the source page (and generate HTML itself) would be possible,
-but I wouldn't want to generate a HTML viewer for every `.jpg` on a site, so
-either the images would have to have a special extension (awkward for uploads from
-Windows users) or the plugin would have to be able to change whether HTML was
-generated in some way (not currently possible).
-
-## Proof-of-concept
+The photo galleries I have at the moment, like the Panic Cell example above,
+are made by using an external script to parse XML gallery descriptions (lists
+of image filenames, with metadata such as titles), and using this to write
+IkiWiki markup into a directory which is then used as an underlay. This is a
+hack, but it works. The use of XML is left over from a previous attempt at
+solving the same problem using Django.
+
+Perhaps a better approach would be to have a setupfile option that names a
+particular underlay directory (meeting the objective of not having large
+photos under source code control) and generates a source page for each file
+in that directory during the refresh hook. The source pages could be in the
+underlay until they are edited (e.g. tagged), at which point they would be
+copied into the source-code-controlled version in the usual way.
+
+The synthetic source pages can be very simple, using the same trick as my
+[[plugins/comments]] plugin (a dedicated [[directive|ikiwiki/directives]]
+encapsulating everything the plugin needs). If the plugin automatically
+gathers information like file size, pixel size, date etc. from the images, then
+only the human-edited information and a filename reference need to be present
+in the source page; with some clever lookup rules based on the filename of
+the source page, not even the photo's filename is necessarily needed.
+
+    \[[!meta title="..."]]
+    \[[!meta date="..."]]
+    \[[!meta copyright="..."]]
+    \[[!tag ...]]
+
+    \[[!galleryimageviewer p1010001.jpg]]
+
+However, this would mean that editing tags and other metadata would require
+editing pages individually. Rather than trying to "fix" that, perhaps it would
+be better to have a special CGI interface for bulk tagging/metadata editing.
+This could even be combined with a bulk upload form (a reasonable number of
+file upload controls - maybe 20 - with metadata alongside each).
+
+Uploading multiple images is necessarily awkward due to restrictions placed on
+file upload controls by browsers for security reasons - sites like Facebook
+allow whole directories to be uploaded at the same time, but they achieve this
+by using a signed Java applet with privileged access to the user's filesystem.
+
+I've found that it's often useful to be able to force the creation time of
+photos (my camera's battery isn't very reliable, and it frequently decides that
+the date is 0000-00-00 00:00:00), so treating the \[[!meta date]] of the source
+page and the creation date of the photo as synonymous would be useful.
+
+### Images are the viewer's source - special filename extension
+
+Making the image be the source page (and generate HTML itself) would be
+possible, but I wouldn't want to generate a HTML viewer for every `.jpg` on a
+site, so either the images would have to have a special extension (awkward for
+uploads from Windows users) or the plugin would have to be able to change
+whether HTML was generated in some way (not currently possible).
+
+### Images are the viewer's source - alter `ispage()`
+
+It might be possible to hack up `ispage()` so some, but not all, images are
+considered to "be a page":
+
+* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg
+* srcdir/gallery/photo.jpg → destdir/gallery/photo/index.html
+
+Perhaps one way to do this would be for the photos to appear in a particular
+underlay directory, which would also fulfil the objective of having photos not
+be version-controlled:
+
+* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg
+* underlay/gallery/photo.jpg → destdir/gallery/photo/index.html
+
+## Proof-of-concept implementation of "viewers' source page is the gallery"
 
     #!/usr/bin/perl
     package IkiWiki::Plugin::gallery;
index dc217cd30f4e72c64b50447e7b301de381f45fa4..fc589367741078aa1c615da73ac782e23293d82a 100644 (file)
@@ -33,6 +33,8 @@ located in /usr/share/ikiwiki/templates by default.
   by the [[plugins/comments]] plugin.
 * `editcomment.tmpl` - This template is the comment post form for the
   [[plugins/comments]] plugin.
+* `commentmoderation.tmpl` - This template is used to produce the comment
+  moderation form.
 
 The [[plugins/pagetemplate]] plugin can allow individual pages to use a
 different template than `page.tmpl`.
index 1b2a9dd15aa368d2980438c2799f150e6401a694..db8fce8da887fe22b4e7a148df3aa3a5b268ad66 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -1,19 +1,21 @@
+# translation of es.po to spanish
 # ikiwiki spanish translation
-# Copyright (C) 2007 The Free Software Foundation, Inc
+# Copyright (C) 2007, 2009 The Free Software Foundation, Inc
 # This file is distributed under the same license as the ikiwiki package.
 #
-# Víctor Moral <victor@taquiones.net>, 2007.
+# Víctor Moral <victor@taquiones.net>, 2007, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: es\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2009-01-17 18:19-0500\n"
-"PO-Revision-Date: 2008-12-19 08:10+0100\n"
-"Last-Translator: Víctor Moral <victor@taquiones.net>\n"
-"Language-Team: Spanish <es@li.org>\n"
+"PO-Revision-Date: 2009-01-19 08:58+0100\n"
+"Language-Team: spanish <es@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Last-Translator: Víctor Moral <victor@taquiones.net>\n"
+"X-Generator: KBabel 1.11.4\n"
 
 #: ../IkiWiki/CGI.pm:113
 msgid "You need to log in first."
@@ -21,8 +23,7 @@ msgstr "Antes es necesario identificarse."
 
 #: ../IkiWiki/CGI.pm:145
 msgid "login failed, perhaps you need to turn on cookies?"
-msgstr ""
-"registro fallido, ¿ tal vez necesita activar las cookies en el navegador ?"
+msgstr "registro fallido, ¿ tal vez necesita activar las cookies en el navegador ?"
 
 #: ../IkiWiki/CGI.pm:163 ../IkiWiki/CGI.pm:280
 msgid "Your login session has expired."
@@ -58,8 +59,7 @@ msgstr "Contenido añadido activado vía web."
 
 #: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
-msgstr ""
-"¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !"
+msgstr "¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !"
 
 #: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
@@ -176,11 +176,11 @@ msgstr "creación de índice automática"
 msgid ""
 "Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
 "\">blogspam</a>: "
-msgstr ""
+msgstr "Lo siento, pero el analizador <a href=\"http://blospam.net\">blogspam</a> dice que el texto puede ser spam."
 
 #: ../IkiWiki/Plugin/blogspam.pm:105
 msgid "blogspam server failure: "
-msgstr ""
+msgstr "fallo del servidor blogspam: "
 
 #: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:296
 #: ../IkiWiki/Plugin/inline.pm:354 ../IkiWiki/Plugin/opendiscussion.pm:26
@@ -339,8 +339,7 @@ msgstr ""
 
 #: ../IkiWiki/Plugin/google.pm:31
 msgid "Failed to parse url, cannot determine domain name"
-msgstr ""
-"Error en el análisis del URL, no puedo determinar el nombre del dominio"
+msgstr "Error en el análisis del URL, no puedo determinar el nombre del dominio"
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -422,8 +421,7 @@ msgstr "La página %s está bloqueada y no puede modificarse"
 
 #: ../IkiWiki/Plugin/mdwn.pm:44
 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed"
-msgstr ""
-"el modo multimarkdown está activo, pero no está instalado Text::MultiMarkdown"
+msgstr "el modo multimarkdown está activo, pero no está instalado Text::MultiMarkdown"
 
 #: ../IkiWiki/Plugin/mdwn.pm:67
 #, perl-format
@@ -848,8 +846,7 @@ msgid "plugins"
 msgstr "complementos"
 
 #: ../IkiWiki/Plugin/websetup.pm:395
-msgid ""
-"The configuration changes shown below require a wiki rebuild to take effect."
+msgid "The configuration changes shown below require a wiki rebuild to take effect."
 msgstr ""
 "Los cambios en la configuración que se muestran más abajo precisan una "
 "reconstrucción del wiki para tener efecto."
@@ -965,8 +962,7 @@ msgstr "el programa %s no parece ser ejecutable"
 
 #: ../IkiWiki/Wrapper.pm:20
 msgid "cannot create a wrapper that uses a setup file"
-msgstr ""
-"no puedo crear un programa envoltorio que utiliza un archivo de configuración"
+msgstr "no puedo crear un programa envoltorio que utiliza un archivo de configuración"
 
 #: ../IkiWiki/Wrapper.pm:24
 msgid "wrapper filename not specified"
@@ -1054,66 +1050,10 @@ msgid "What revision control system to use?"
 msgstr "¿ Qué sistema de control de versiones empleará ?"
 
 #: ../auto.setup:20
-#, fuzzy
 msgid "What wiki user (or openid) will be admin?"
-msgstr ""
-"¿ Qué usuario del wiki (ó identificador openid) será el administrador del "
-"wiki ? "
+msgstr "¿ Qué usuario del wiki (ó qué identificador openid) será el empleado como administrador ? "
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr "¿ Cuál es el dominio para el servidor web ?"
 
-#~ msgid "failed to find url in html"
-#~ msgstr ""
-#~ "El complemento googlecalendar no ha encontrado un URL en el código html "
-
-#~ msgid "processed ok at %s"
-#~ msgstr "proceso completado con éxito a %s"
-
-#~ msgid "Your password has been emailed to you."
-#~ msgstr "Se le ha enviado su contraseña por correo electrónico."
-
-#~ msgid "polygen failed"
-#~ msgstr "El programa polygen ha fallado"
-
-#~ msgid "cleaning hyperestraier search index"
-#~ msgstr "limpiando el índice de búsquedas de hyperestraier"
-
-#~ msgid "updating hyperestraier search index"
-#~ msgstr "actualizando el índice de búsquedas de hyperstraier"
-
-#~ msgid "(not toggleable in preview mode)"
-#~ msgstr "(no se puede cambiar en el modo de previsualización)"
-
-#~ msgid ""
-#~ "REV is not set, not running from mtn post-commit hook, cannot send "
-#~ "notifications"
-#~ msgstr ""
-#~ "La variable de entorno REV no está definida, por lo que no puede "
-#~ "funcionar svn post-commit desde monotone; no puedo enviar ninguna "
-#~ "notificación"
-
-#~ msgid "REV is not a valid revision identifier, cannot send notifications"
-#~ msgstr ""
-#~ "REV no es un identificador de revisión válido, por lo que no puedo enviar "
-#~ "ninguna notificación"
-
-#~ msgid ""
-#~ "REV is not set, not running from svn post-commit hook, cannot send "
-#~ "notifications"
-#~ msgstr ""
-#~ "La variable de entorno REV no está definida, por lo que no puede "
-#~ "funcionar svn post-commit; no puedo enviar ninguna notificación"
-
-#~ msgid "link is no longer supported"
-#~ msgstr "el metadato link ya no puede usarse"
-
-#~ msgid "%s not found"
-#~ msgstr "no he encontrado la plantilla %s "
-
-#~ msgid "What's this?"
-#~ msgstr "¿ Qué es esto ?"
-
-#~ msgid "(use FirstnameLastName)"
-#~ msgstr "(utilice la forma NombreApellidos)"
index 582efccb8d25f667b4dd334068565935d779d516..1b9064ea0d006c48d2a54af0e5afd62ee4743ee0 100644 (file)
@@ -1,6 +1,12 @@
 <div class="comment" id="<TMPL_VAR NAME=INLINEPAGE>">
 
-<div class="comment-subject"><a href="<TMPL_VAR PERMALINK>"><TMPL_VAR TITLE></a></div>
+<div class="comment-subject">
+<TMPL_IF PERMALINK>
+<a href="<TMPL_VAR PERMALINK>"><TMPL_VAR TITLE></a>
+<TMPL_ELSE>
+<TMPL_VAR TITLE>
+</TMPL_IF>
+</div>
 
 <div class="inlinecontent">
 <TMPL_VAR CONTENT>
diff --git a/templates/commentmoderation.tmpl b/templates/commentmoderation.tmpl
new file mode 100644 (file)
index 0000000..e91d314
--- /dev/null
@@ -0,0 +1,29 @@
+<TMPL_IF NAME="COMMENTS">
+<br />
+<form action="<TMPL_VAR CGIURL>" method="post">
+<input type="hidden" name="do" value="commentmoderation" />
+<input type="hidden" name="sid" value="<TMPL_VAR SID>" />
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+<br />  
+<TMPL_LOOP NAME="COMMENTS">
+<div>
+<div>
+<TMPL_VAR VIEW>
+</div>
+<input type="radio" value="Defer" name="<TMPL_VAR ID>" checked />Defer
+<input type="radio" value="Accept" name="<TMPL_VAR ID>" />Accept
+<input type="radio" value="Reject" name="<TMPL_VAR ID>" />Reject
+</div>
+<br />
+</TMPL_LOOP>
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+</form>
+<TMPL_ELSE>
+<p>
+No comments need moderation at this time.
+</p>
+</TMPL_IF>