]> sipb.mit.edu Git - ikiwiki.git/commitdiff
Merge remote branch 'upstream/master' into prv/po
authorintrigeri <intrigeri@boum.org>
Mon, 20 Dec 2010 13:27:21 +0000 (14:27 +0100)
committerintrigeri <intrigeri@boum.org>
Mon, 20 Dec 2010 13:27:21 +0000 (14:27 +0100)
281 files changed:
IkiWiki.pm
IkiWiki/CGI.pm
IkiWiki/Plugin/aggregate.pm
IkiWiki/Plugin/attachment.pm
IkiWiki/Plugin/blogspam.pm
IkiWiki/Plugin/calendar.pm
IkiWiki/Plugin/comments.pm
IkiWiki/Plugin/cutpaste.pm
IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/edittemplate.pm
IkiWiki/Plugin/external.pm
IkiWiki/Plugin/filecheck.pm
IkiWiki/Plugin/format.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/goto.pm
IkiWiki/Plugin/highlight.pm
IkiWiki/Plugin/htmlbalance.pm
IkiWiki/Plugin/htmlscrubber.pm
IkiWiki/Plugin/htmltidy.pm
IkiWiki/Plugin/httpauth.pm
IkiWiki/Plugin/img.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/listdirectives.pm
IkiWiki/Plugin/meta.pm
IkiWiki/Plugin/monotone.pm
IkiWiki/Plugin/more.pm
IkiWiki/Plugin/openid.pm
IkiWiki/Plugin/parentlinks.pm
IkiWiki/Plugin/pinger.pm
IkiWiki/Plugin/po.pm
IkiWiki/Plugin/poll.pm
IkiWiki/Plugin/recentchanges.pm
IkiWiki/Plugin/relativedate.pm
IkiWiki/Plugin/remove.pm
IkiWiki/Plugin/rename.pm
IkiWiki/Plugin/search.pm
IkiWiki/Plugin/skeleton.pm.example
IkiWiki/Plugin/sortnaturally.pm
IkiWiki/Plugin/table.pm
IkiWiki/Plugin/template.pm
IkiWiki/Plugin/teximg.pm
IkiWiki/Plugin/theme.pm
IkiWiki/Plugin/toggle.pm
IkiWiki/Plugin/txt.pm
IkiWiki/Plugin/version.pm
IkiWiki/Plugin/websetup.pm
IkiWiki/Plugin/wmd.pm
IkiWiki/Receive.pm
IkiWiki/Render.pm
IkiWiki/Wrapper.pm
Makefile.PL
README
auto-blog.setup
debian/changelog
debian/control
debian/copyright
doc/bugs/404_plugin_and_lighttpd.mdwn
doc/bugs/Error:_no_text_was_copied_in_this_page_--_missing_page_dependencies.mdwn [new file with mode: 0644]
doc/bugs/Highlight_extension_uses_hard_coded_paths.mdwn
doc/bugs/More_permission_checking.mdwn [new file with mode: 0644]
doc/bugs/UTF-16_and_UTF-32_are_unhandled.mdwn [new file with mode: 0644]
doc/bugs/__34__Currently_enabled_SSH_keys:__34___shows_only_first_139_characters_of_each_key.mdwn [new file with mode: 0644]
doc/bugs/aggregate_generates_long_filenames.mdwn [new file with mode: 0644]
doc/bugs/argument_isn__39__t_numeric:_mixing_templates_and_creation__95__date.mdwn [new file with mode: 0644]
doc/bugs/blog_spam_plugin_not_allowing_non-ASCII_chars__63__.mdwn [new file with mode: 0644]
doc/bugs/can__39__t_mix_template_vars_inside_directives.mdwn [new file with mode: 0644]
doc/bugs/class_parameter_of_img_directive_behave_not_as_documented.mdwn [new file with mode: 0644]
doc/bugs/cutpaste.pm:_missing_filter_call.mdwn [new file with mode: 0644]
doc/bugs/git.pm_should_prune_remote_branches_when_fetching.mdwn [new file with mode: 0644]
doc/bugs/git_commit_adds_files_that_were_not_tracked.mdwn [new file with mode: 0644]
doc/bugs/htmlbalance_fails_with_HTML-Tree_v4.mdwn [new file with mode: 0644]
doc/bugs/httpauth_conflicts_with_git_anon_push.mdwn [new file with mode: 0644]
doc/bugs/ikiwiki_ignores_PATH_environment.mdwn [new file with mode: 0644]
doc/bugs/img_plugin_and_class_attr.mdwn [new file with mode: 0644]
doc/bugs/inline_action_buttons_circumvent_exclude_criteria_from_edittemplate__39__s_match__61____34____34___pagespec.mdwn [new file with mode: 0644]
doc/bugs/logout_in_ikiwiki.mdwn [new file with mode: 0644]
doc/bugs/monotone_backend_does_not_support_srcdir_in_subdir.mdwn [new file with mode: 0644]
doc/bugs/more_and_RSS_generation.mdwn [new file with mode: 0644]
doc/bugs/po:_apache_config_serves_index.rss_for_index.mdwn [new file with mode: 0644]
doc/bugs/po:_markdown_link_parse_bug.mdwn [new file with mode: 0644]
doc/bugs/po:_po_files_instead_of_html_files.mdwn
doc/bugs/po:broken_links_to_translatable_basewiki_pages_that_lack_po_fies.mdwn [new file with mode: 0644]
doc/bugs/rename_fixup_not_attributed_to_author.mdwn [new file with mode: 0644]
doc/bugs/rss_feeds_do_not_use_recommended_encoding_of_entities_for_some_fields.mdwn
doc/bugs/rst_fails_on_file_containing_only_a_number.mdwn
doc/bugs/web_reversion_on_ikiwiki.info.mdwn [new file with mode: 0644]
doc/css.mdwn
doc/css_market.mdwn
doc/css_market/actiontabs.css [deleted file]
doc/examples/blog.mdwn
doc/features.mdwn
doc/forum/404_-_not_found.mdwn [new file with mode: 0644]
doc/forum/404_-_not_found/comment_1_3dea2600474f77fb986767da4d507d62._comment [new file with mode: 0644]
doc/forum/404_-_not_found/comment_2_948e4678be6f82d9b541132405351a2c._comment [new file with mode: 0644]
doc/forum/404_-_not_found/comment_3_4c7b1fa88776815bbc6aa286606214c2._comment [new file with mode: 0644]
doc/forum/Asciidoc_plugin.mdwn [new file with mode: 0644]
doc/forum/Blog_posting_times_and_ikiwiki_state.mdwn [new file with mode: 0644]
doc/forum/Blog_posting_times_and_ikiwiki_state/comment_1_87304dfa2caea7e526cdb04917524e8c._comment [new file with mode: 0644]
doc/forum/Can__39__t_get_comments_plugin_working.mdwn
doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__.mdwn [new file with mode: 0644]
doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__/comment_1_15651796492a6f04a19f4a481947c97c._comment [new file with mode: 0644]
doc/forum/Discussion_PageSpec__63__.mdwn [new file with mode: 0644]
doc/forum/Dump_plugin.mdwn [new file with mode: 0644]
doc/forum/Dump_plugin/comment_1_bfce80b3f5be78ec28692330843d4ae1._comment [new file with mode: 0644]
doc/forum/Forward_slashes_being_escaped_as_252F.mdwn [new file with mode: 0644]
doc/forum/How_to_list_new_pages__44___inline__63__.mdwn [new file with mode: 0644]
doc/forum/How_to_list_new_pages__44___inline__63__/comment_1_e989b18bade34a92a9c8fe7099036e15._comment [new file with mode: 0644]
doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links.mdwn [new file with mode: 0644]
doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links/comment_1_3fe4c5967e704355f9b594aed46baf67._comment [new file with mode: 0644]
doc/forum/Moving_wiki.git_folder__63__.mdwn [new file with mode: 0644]
doc/forum/Moving_wiki.git_folder__63__/comment_1_05238461520613f4ed1b0d02ece663bd._comment [new file with mode: 0644]
doc/forum/Moving_wiki.git_folder__63__/comment_2_72b2b842dfa0cfaf899fe7af12977519._comment [new file with mode: 0644]
doc/forum/Need_something_more_powerful_than_Exclude.mdwn [new file with mode: 0644]
doc/forum/Need_something_more_powerful_than_Exclude/comment_2_0019cd6b34c8d8678b2532de57a92d15._comment [new file with mode: 0644]
doc/forum/Need_something_more_powerful_than_Exclude/comment_2_f577ab6beb9912471949d8d18c790267._comment [new file with mode: 0644]
doc/forum/Need_something_more_powerful_than_Exclude/comment_3_1ed260b0083a290688425a006a83f603._comment [new file with mode: 0644]
doc/forum/Need_something_more_powerful_than_Exclude/comment_4_c39bdaf38e1e20db74eb26f0560bd673._comment [new file with mode: 0644]
doc/forum/PageSpec_results_from_independent_checkout.mdwn [new file with mode: 0644]
doc/forum/cutpaste.pm_not_only_file-local.mdwn
doc/forum/editing_a_comment.mdwn
doc/forum/field_and_forms.mdwn [new file with mode: 0644]
doc/forum/field_and_forms/comment_1_a0e976cb79f03dcff5e9a4511b90d160._comment [new file with mode: 0644]
doc/forum/how_can_I_use___39____47____39___as_tagbase__63__.mdwn [new file with mode: 0644]
doc/forum/how_can_I_use___39____47____39___as_tagbase__63__/comment_1_e7897651ba8d9156526d36d6b7744eae._comment [new file with mode: 0644]
doc/forum/how_do_I_revert_edits_in_the_web_mode__63__.mdwn
doc/forum/how_do_I_revert_edits_in_the_web_mode__63__/comment_1_e4720e8e4fe74bd6cba746e8259832e6._comment [new file with mode: 0644]
doc/forum/ikiwiki_+_mathjax.mdwn [new file with mode: 0644]
doc/forum/ikiwiki_vim_integration.mdwn [new file with mode: 0644]
doc/forum/link_autocompletion_in_vim.mdwn
doc/forum/recovering_original_title_with_meta_directive.mdwn [new file with mode: 0644]
doc/forum/report_pagination.mdwn
doc/forum/using_l10n__39__d_basewiki.mdwn [new file with mode: 0644]
doc/forum/using_l10n__39__d_basewiki/comment_1_eaab671848ee6129f6fe9399474eeac0._comment [new file with mode: 0644]
doc/forum/using_l10n__39__d_basewiki/comment_2_d907676a1db1210ca59506673c564359._comment [new file with mode: 0644]
doc/forum/using_l10n__39__d_basewiki/comment_3_5e9d5bc5ecaf63f9bfe3315b09a279aa._comment [new file with mode: 0644]
doc/forum/using_svn+ssh_with_ikiwiki.mdwn [new file with mode: 0644]
doc/git.mdwn
doc/ikiwiki/directive/aggregate/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/if.mdwn
doc/ikiwiki/directive/more.mdwn
doc/ikiwiki/directive/table/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/template.mdwn
doc/ikiwiki/pagespec.mdwn
doc/ikiwikiusers.mdwn
doc/install.mdwn
doc/install/discussion.mdwn
doc/news/openid.mdwn
doc/news/openid/discussion.mdwn
doc/news/version_3.20100610.mdwn [deleted file]
doc/news/version_3.20100623.mdwn [deleted file]
doc/news/version_3.20100704.mdwn [deleted file]
doc/news/version_3.20100722.mdwn [deleted file]
doc/news/version_3.20100804.mdwn [deleted file]
doc/news/version_3.20100815.mdwn [deleted file]
doc/news/version_3.20100926.mdwn [new file with mode: 0644]
doc/news/version_3.20101019.mdwn [new file with mode: 0644]
doc/news/version_3.20101023.mdwn [new file with mode: 0644]
doc/news/version_3.20101112.mdwn [new file with mode: 0644]
doc/news/version_3.20101129.mdwn [new file with mode: 0644]
doc/news/version_3.20101201.mdwn [new file with mode: 0644]
doc/plugins/aggregate/discussion.mdwn
doc/plugins/autoindex/discussion.mdwn
doc/plugins/contrib/default_content_for___42__copyright__42___and___42__license__42__.mdwn
doc/plugins/contrib/field/discussion.mdwn
doc/plugins/contrib/headinganchors/discussion.mdwn
doc/plugins/contrib/ikiwiki/directive/ymlfront.mdwn
doc/plugins/contrib/imailhide.mdwn [new file with mode: 0644]
doc/plugins/contrib/report/ikiwiki/directive/report.mdwn
doc/plugins/contrib/texinfo.mdwn
doc/plugins/contrib/ymlfront.mdwn
doc/plugins/contrib/ymlfront/discussion.mdwn
doc/plugins/htmlscrubber.mdwn
doc/plugins/po.mdwn
doc/plugins/recentchanges.mdwn
doc/plugins/theme.mdwn
doc/plugins/write.mdwn
doc/plugins/write/external.mdwn
doc/rcs.mdwn
doc/sandbox.mdwn
doc/sandbox/Fantasia.mdwn [new file with mode: 0644]
doc/sandbox/Mooooo.mdwn [new file with mode: 0644]
doc/sandbox/Nur_so..mdwn [new file with mode: 0644]
doc/sandbox/Post.mdwn [deleted file]
doc/sandbox/Testing_blog_entry.mdwn [new file with mode: 0644]
doc/sandbox/bullet_list_and_code_test.mdwn [new file with mode: 0644]
doc/sandbox/hey.mdwn [new file with mode: 0644]
doc/sandbox/prova_blog.html [deleted file]
doc/sandbox/revert_me.mdwn [new file with mode: 0644]
doc/security.mdwn
doc/setup.mdwn
doc/setup/byhand.mdwn
doc/setup/discussion.mdwn
doc/shortcuts.mdwn
doc/shortcuts/discussion.mdwn [new file with mode: 0644]
doc/smileys/icon-error.png
doc/style.css
doc/templates.mdwn
doc/templates/discussion.mdwn
doc/themes.mdwn [new file with mode: 0644]
doc/themes/actiontabs_small.png [new file with mode: 0644]
doc/themes/blueview_small.png [new file with mode: 0644]
doc/themes/goldtype_small.png [new file with mode: 0644]
doc/themes/none_small.png [new file with mode: 0644]
doc/tips/convert_mediawiki_to_ikiwiki/discussion.mdwn
doc/tips/dot_cgi.mdwn
doc/tips/html5.mdwn
doc/tips/ikiwiki_on_Mac_OS_X_Snow_Leopard.mdwn [new file with mode: 0644]
doc/tips/ikiwiki_on_Mac_OS_X_Snow_Leopard/discussion.mdwn [new file with mode: 0644]
doc/tips/nearlyfreespeech.mdwn
doc/tips/nearlyfreespeech/discussion.mdwn
doc/tips/psgi.mdwn [new file with mode: 0644]
doc/tips/spam_and_softwaresites/discussion.mdwn [new file with mode: 0644]
doc/tips/untrusted_git_push.mdwn
doc/tips/vim_and_ikiwiki.mdwn [new file with mode: 0644]
doc/tips/vim_syntax_highlighting.mdwn
doc/todo/Add_nicer_math_formatting.mdwn
doc/todo/Improving_the_efficiency_of_match__95__glob.mdwn [new file with mode: 0644]
doc/todo/__42__forward__42__ing_functionality_for_the_meta_plugin.mdwn
doc/todo/alias_directive.mdwn [new file with mode: 0644]
doc/todo/auto-create_tag_pages_according_to_a_template.mdwn
doc/todo/autoindex_should_use_add__95__autofile.mdwn [new file with mode: 0644]
doc/todo/capitalize_title.mdwn [new file with mode: 0644]
doc/todo/configurable_tidy_command_for_htmltidy.mdwn [new file with mode: 0644]
doc/todo/countdown_directive.mdwn [new file with mode: 0644]
doc/todo/edit_form:_no_fixed_size_for_textarea.mdwn
doc/todo/inline_raw_files.mdwn [new file with mode: 0644]
doc/todo/latex.mdwn
doc/todo/mirrorlist_with_per-mirror_usedirs_settings.mdwn
doc/todo/passwordauth:_sendmail_interface.mdwn
doc/todo/po:_avoid_rebuilding_to_fix_meta_titles.mdwn
doc/todo/po:_remove_po_files_when_disabling_plugin.mdwn
doc/todo/po:_rethink_pagespecs.mdwn
doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn
doc/todo/selective_more_directive.mdwn [new file with mode: 0644]
doc/todo/support_link__40__.__41___in_pagespec.mdwn
doc/todo/transient_pages.mdwn [new file with mode: 0644]
doc/todo/untrusted_git_push_hooks.mdwn [new file with mode: 0644]
doc/todo/use_secure_cookies_for_ssl_logins.mdwn [new file with mode: 0644]
doc/todo/use_templates_for_the_img_plugin.mdwn [new file with mode: 0644]
doc/todo/want_to_avoid_ikiwiki_using_http_or_https_in_urls_to_allow_serving_both.mdwn
doc/todo/web_reversion.mdwn [new file with mode: 0644]
doc/usage.mdwn
doc/users/Remy.mdwn [new file with mode: 0644]
doc/users/anarcat.wiki [new file with mode: 0644]
doc/users/chrysn.mdwn [new file with mode: 0644]
doc/users/dark.mdwn [new file with mode: 0644]
doc/users/harishcm.mdwn
doc/users/tschwinge.mdwn
doc/wikiicons/revert.png [new file with mode: 0644]
ikiwiki.in
ikiwiki.spec
mdwn2man
po/bg.po
po/cs.po
po/da.po
po/de.po
po/es.po
po/fr.po
po/gu.po
po/ikiwiki.pot
po/it.po
po/pl.po
po/po2wiki
po/sv.po
po/tr.po
po/underlay.setup
po/vi.po
t/bazaar.t
t/pagespec_match.t
t/permalink.t
t/rssurls.t [new file with mode: 0755]
t/urlto.t [new file with mode: 0755]
templates/change.tmpl
templates/revert.tmpl [new file with mode: 0644]
templates/rssitem.tmpl
themes/actiontabs/style.css
themes/blueview/style.css
themes/goldtype/background_darkness.png [new file with mode: 0644]
themes/goldtype/base.css [new symlink]
themes/goldtype/header_background.png [new file with mode: 0644]
themes/goldtype/style.css [new file with mode: 0644]

index df8abe2c2711281c220a604aa0ddca09ec915a02..97946bfcf888a185a193cf5d4ef2f2c353cdb058 100644 (file)
@@ -501,6 +501,12 @@ sub defaultconfig () {
        return @ret;
 }
 
+# URL to top of wiki as a path starting with /, valid from any wiki page or
+# the CGI; if that's not possible, an absolute URL. Either way, it ends with /
+my $local_url;
+# URL to CGI script, similar to $local_url
+my $local_cgiurl;
+
 sub checkconfig () {
        # locale stuff; avoid LC_ALL since it overrides everything
        if (defined $ENV{LC_ALL}) {
@@ -537,7 +543,33 @@ sub checkconfig () {
        if ($config{cgi} && ! length $config{url}) {
                error(gettext("Must specify url to wiki with --url when using --cgi"));
        }
-       
+
+       if (length $config{url}) {
+               eval q{use URI};
+               my $baseurl = URI->new($config{url});
+
+               $local_url = $baseurl->path . "/";
+               $local_cgiurl = undef;
+
+               if (length $config{cgiurl}) {
+                       my $cgiurl = URI->new($config{cgiurl});
+
+                       $local_cgiurl = $cgiurl->path;
+
+                       if ($cgiurl->scheme ne $baseurl->scheme or
+                               $cgiurl->authority ne $baseurl->authority) {
+                               # too far apart, fall back to absolute URLs
+                               $local_url = "$config{url}/";
+                               $local_cgiurl = $config{cgiurl};
+                       }
+               }
+
+               $local_url =~ s{//$}{/};
+       }
+       else {
+               $local_cgiurl = $config{cgiurl};
+       }
+
        $config{wikistatedir}="$config{srcdir}/.ikiwiki"
                unless exists $config{wikistatedir} && defined $config{wikistatedir};
 
@@ -717,7 +749,7 @@ sub pagename ($) {
 
        my $type=pagetype($file);
        my $page=$file;
-       $page=~s/\Q.$type\E*$//
+       $page=~s/\Q.$type\E*$//
                if defined $type && !$hooks{htmlize}{$type}{keepextension}
                        && !$hooks{htmlize}{$type}{noextension};
        if ($config{indexpages} && $page=~/(.*)\/index$/) {
@@ -1010,11 +1042,17 @@ sub linkpage ($) {
 sub cgiurl (@) {
        my %params=@_;
 
-       my $cgiurl=$config{cgiurl};
+       my $cgiurl=$local_cgiurl;
+
        if (exists $params{cgiurl}) {
                $cgiurl=$params{cgiurl};
                delete $params{cgiurl};
        }
+
+       unless (%params) {
+               return $cgiurl;
+       }
+
        return $cgiurl."?".
                join("&amp;", map $_."=".uri_escape_utf8($params{$_}), keys %params);
 }
@@ -1022,7 +1060,7 @@ sub cgiurl (@) {
 sub baseurl (;$) {
        my $page=shift;
 
-       return "$config{url}/" if ! defined $page;
+       return $local_url if ! defined $page;
        
        $page=htmlpage($page);
        $page=~s/[^\/]+$//;
@@ -1096,7 +1134,7 @@ sub beautify_urlpath ($) {
        return $url;
 }
 
-sub urlto ($$;$) {
+sub urlto ($;$$) {
        my $to=shift;
        my $from=shift;
        my $absolute=shift;
@@ -1113,6 +1151,12 @@ sub urlto ($$;$) {
                return $config{url}.beautify_urlpath("/".$to);
        }
 
+       if (! defined $from) {
+               my $u = $local_url;
+               $u =~ s{/$}{};
+               return $u.beautify_urlpath("/".$to);
+       }
+
        my $link = abs2rel($to, dirname(htmlpage($from)));
 
        return beautify_urlpath($link);
@@ -1124,7 +1168,7 @@ sub isselflink ($$) {
        my $page=shift;
        my $link=shift;
 
-        return $page eq $link;
+       return $page eq $link;
 }
 
 sub htmllink ($$$;@) {
@@ -1201,7 +1245,7 @@ sub userpage ($) {
 sub openiduser ($) {
        my $user=shift;
 
-       if ($user =~ m!^https?://! &&
+       if (defined $user && $user =~ m!^https?://! &&
            eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) {
                my $display;
 
@@ -1519,6 +1563,69 @@ sub check_content (@) {
        return defined $ok ? $ok : 1;
 }
 
+sub check_canchange (@) {
+       my %params = @_;
+       my $cgi = $params{cgi};
+       my $session = $params{session};
+       my @changes = @{$params{changes}};
+
+       my %newfiles;
+       foreach my $change (@changes) {
+               # This untaint is safe because we check file_pruned and
+               # wiki_file_regexp.
+               my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
+               $file=possibly_foolish_untaint($file);
+               if (! defined $file || ! length $file ||
+                   file_pruned($file)) {
+                       error(gettext("bad file name %s"), $file);
+               }
+
+               my $type=pagetype($file);
+               my $page=pagename($file) if defined $type;
+
+               if ($change->{action} eq 'add') {
+                       $newfiles{$file}=1;
+               }
+
+               if ($change->{action} eq 'change' ||
+                   $change->{action} eq 'add') {
+                       if (defined $page) {
+                               check_canedit($page, $cgi, $session);
+                               next;
+                       }
+                       else {
+                               if (IkiWiki::Plugin::attachment->can("check_canattach")) {
+                                       IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path});
+                                       check_canedit($file, $cgi, $session);
+                                       next;
+                               }
+                       }
+               }
+               elsif ($change->{action} eq 'remove') {
+                       # check_canremove tests to see if the file is present
+                       # on disk. This will fail when a single commit adds a
+                       # file and then removes it again. Avoid the problem
+                       # by not testing the removal in such pairs of changes.
+                       # (The add is still tested, just to make sure that
+                       # no data is added to the repo that a web edit
+                       # could not add.)
+                       next if $newfiles{$file};
+
+                       if (IkiWiki::Plugin::remove->can("check_canremove")) {
+                               IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session);
+                               check_canedit(defined $page ? $page : $file, $cgi, $session);
+                               next;
+                       }
+               }
+               else {
+                       error "unknown action ".$change->{action};
+               }
+
+               error sprintf(gettext("you are not allowed to change %s"), $file);
+       }
+}
+
+
 my $wikilock;
 
 sub lockwiki () {
@@ -1769,12 +1876,14 @@ sub template_depends ($$;@) {
        my $page=shift;
        
        my ($filename, $tpage, $untrusted)=template_file($name);
+       if (! defined $filename) {
+               error(sprintf(gettext("template %s not found"), $name))
+       }
+
        if (defined $page && defined $tpage) {
                add_depends($page, $tpage);
        }
-
-       return unless defined $filename;
-
+       
        my @opts=(
                filter => sub {
                        my $text_ref = shift;
@@ -2323,7 +2432,7 @@ sub glob2re ($) {
        my $re=quotemeta(shift);
        $re=~s/\\\*/.*/g;
        $re=~s/\\\?/./g;
-       return $re;
+       return qr/^$re$/i;
 }
 
 package IkiWiki::FailReason;
@@ -2402,15 +2511,23 @@ sub derel ($$) {
        my $path=shift;
        my $from=shift;
 
-       if ($path =~ m!^\./!) {
-               $from=~s#/?[^/]+$## if defined $from;
-               $path=~s#^\./##;
-               $path="$from/$path" if defined $from && length $from;
+       if ($path =~ m!^\.(/|$)!) {
+               if ($1) {
+                       $from=~s#/?[^/]+$## if defined $from;
+                       $path=~s#^\./##;
+                       $path="$from/$path" if defined $from && length $from;
+               }
+               else {
+                       $path = $from;
+                       $path = "" unless defined $path;
+               }
        }
 
        return $path;
 }
 
+my %glob_cache;
+
 sub match_glob ($$;@) {
        my $page=shift;
        my $glob=shift;
@@ -2418,8 +2535,13 @@ sub match_glob ($$;@) {
        
        $glob=derel($glob, $params{location});
 
-       my $regexp=IkiWiki::glob2re($glob);
-       if ($page=~/^$regexp$/i) {
+       # Instead of converting the glob to a regex every time,
+       # cache the compiled regex to save time.
+       my $re=$glob_cache{$glob};
+       unless (defined $re) {
+               $glob_cache{$glob} = $re = IkiWiki::glob2re($glob);
+       }
+       if ($page =~ $re) {
                if (! IkiWiki::isinternal($page) || $params{internal}) {
                        return IkiWiki::SuccessReason->new("$glob matches $page");
                }
@@ -2537,7 +2659,12 @@ sub match_created_after ($$;@) {
 }
 
 sub match_creation_day ($$;@) {
-       if ((localtime($IkiWiki::pagectime{shift()}))[3] == shift) {
+       my $page=shift;
+       my $d=shift;
+       if ($d !~ /^\d+$/) {
+               return IkiWiki::ErrorReason->new("invalid day $d");
+       }
+       if ((localtime($IkiWiki::pagectime{$page}))[3] == $d) {
                return IkiWiki::SuccessReason->new('creation_day matched');
        }
        else {
@@ -2546,7 +2673,12 @@ sub match_creation_day ($$;@) {
 }
 
 sub match_creation_month ($$;@) {
-       if ((localtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift) {
+       my $page=shift;
+       my $m=shift;
+       if ($m !~ /^\d+$/) {
+               return IkiWiki::ErrorReason->new("invalid month $m");
+       }
+       if ((localtime($IkiWiki::pagectime{$page}))[4] + 1 == $m) {
                return IkiWiki::SuccessReason->new('creation_month matched');
        }
        else {
@@ -2555,7 +2687,12 @@ sub match_creation_month ($$;@) {
 }
 
 sub match_creation_year ($$;@) {
-       if ((localtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) {
+       my $page=shift;
+       my $y=shift;
+       if ($y !~ /^\d+$/) {
+               return IkiWiki::ErrorReason->new("invalid year $y");
+       }
+       if ((localtime($IkiWiki::pagectime{$page}))[5] + 1900 == $y) {
                return IkiWiki::SuccessReason->new('creation_year matched');
        }
        else {
@@ -2574,7 +2711,7 @@ sub match_user ($$;@) {
                return IkiWiki::ErrorReason->new("no user specified");
        }
 
-       if (defined $params{user} && $params{user}=~/^$regexp$/i) {
+       if (defined $params{user} && $params{user}=~$regexp) {
                return IkiWiki::SuccessReason->new("user is $user");
        }
        elsif (! defined $params{user}) {
index f2a32a9581077553d5b542fde40f428c15a5e41a..ede194ff9aee945dc0fb471bedaa47bf93eda829 100644 (file)
@@ -12,7 +12,7 @@ use Encode;
 sub printheader ($) {
        my $session=shift;
        
-       if ($config{sslcookie}) {
+       if ($ENV{HTTPS} || $config{sslcookie}) {
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1, -secure => 1));
        }
@@ -116,7 +116,7 @@ sub cgi_signin ($$;$) {
                required => 'NONE',
                javascript => 0,
                params => $q,
-               action => $config{cgiurl},
+               action => cgiurl(),
                header => 0,
                template => {type => 'div'},
                stylesheet => 1,
@@ -198,7 +198,7 @@ sub cgi_prefs ($$) {
                required => 'NONE',
                javascript => 0,
                params => $q,
-               action => $config{cgiurl},
+               action => cgiurl(),
                template => {type => 'div'},
                stylesheet => 1,
                fieldsets => [
@@ -231,11 +231,11 @@ sub cgi_prefs ($$) {
        
        if ($form->submitted eq 'Logout') {
                $session->delete();
-               redirect($q, $config{url});
+               redirect($q, baseurl(undef));
                return;
        }
        elsif ($form->submitted eq 'Cancel') {
-               redirect($q, $config{url});
+               redirect($q, baseurl(undef));
                return;
        }
        elsif ($form->submitted eq 'Save Preferences' && $form->validate) {
index 7789c4c2a9d38b7e616d9d3b4df8e4d96fe74ec6..9b70e5df053731866c5ad7a494432e6e0b72b4bc 100644 (file)
@@ -210,6 +210,8 @@ sub needsbuild (@) {
                        markunseen($feed->{sourcepage});
                }
        }
+
+       return $needsbuild;
 }
 
 sub preprocess (@) {
@@ -642,7 +644,14 @@ sub add_page (@) {
        $guid->{md5}=$digest;
 
        # Create the page.
-       my $template=template($feed->{template}, blind_cache => 1);
+       my $template;
+       eval {
+               $template=template($feed->{template}, blind_cache => 1);
+       };
+       if ($@) {
+               print STDERR gettext("failed to process template:")." $@";
+               return;
+       }
        $template->param(title => $params{title})
                if defined $params{title} && length($params{title});
        $template->param(content => wikiescape(htmlabs($params{content},
index ee105a1709f3fe71e0e44a47782e9596791dbbf9..bd93d37187454bf4168a9b632b2f1f7acc4d99d1 100644 (file)
@@ -146,7 +146,7 @@ sub formbuilder (@) {
                
                # Check that the user is allowed to edit a page with the
                # name of the attachment.
-               IkiWiki::check_canedit($filename, $q, $session, 1);
+               IkiWiki::check_canedit($filename, $q, $session);
                # And that the attachment itself is acceptable.
                check_canattach($session, $filename, $tempfile);
 
@@ -242,7 +242,7 @@ sub attachment_list ($) {
                        push @ret, {
                                "field-select" => '<input type="checkbox" name="attachment_select" value="'.$f.'" />',
                                link => htmllink($page, $page, $f, noimageinline => 1),
-                               size => IkiWiki::Plugin::filecheck::humansize((stat(_))[7]),
+                               size => IkiWiki::Plugin::filecheck::humansize((stat($f))[7]),
                                mtime => displaytime($IkiWiki::pagemtime{$f}),
                                mtime_raw => $IkiWiki::pagemtime{$f},
                        };
index 8db3780e8888ee9c9188881e80ae26b6715436ff..f0b6cb2a2742519a2796bce8a863500f34d0d5f0 100644 (file)
@@ -4,6 +4,7 @@ package IkiWiki::Plugin::blogspam;
 use warnings;
 use strict;
 use IkiWiki 3.00;
+use Encode;
 
 my $defaulturl='http://test.blogspam.net:8888/';
 
@@ -68,6 +69,7 @@ sub checkcontent (@) {
 
        my $url=$defaulturl;
        $url = $config{blogspam_server} if exists $config{blogspam_server};
+
        my $client = RPC::XML::Client->new($url);
 
        my @options = split(",", $config{blogspam_options})
@@ -90,12 +92,12 @@ sub checkcontent (@) {
 
        my %req=(
                ip => $session->remote_addr(),
-               comment => defined $params{diff} ? $params{diff} : $params{content},
-               subject => defined $params{subject} ? $params{subject} : "",
-               name => defined $params{author} ? $params{author} : "",
-               link => exists $params{url} ? $params{url} : "",
+               comment => encode_utf8(defined $params{diff} ? $params{diff} : $params{content}),
+               subject => encode_utf8(defined $params{subject} ? $params{subject} : ""),
+               name => encode_utf8(defined $params{author} ? $params{author} : ""),
+               link => encode_utf8(exists $params{url} ? $params{url} : ""),
                options => join(",", @options),
-               site => $config{url},
+               site => encode_utf8($config{url}),
                version => "ikiwiki ".$IkiWiki::version,
        );
        my $res = $client->send_request('testComment', \%req);
index bb995d49956e27234e5bb9b621c2caa641b93d40..c7d2b7c01d8943f26e34e43231cc4ee26e0b6847 100644 (file)
@@ -491,6 +491,7 @@ sub needsbuild (@) {
                        }
                }
        }
+       return $needsbuild;
 }
 
 1
index 851f4862eb3a5a39bb0afb387b35dfc60262024d..68ac4cfae4844dd7de3b44e7af9956d00ab3ac75 100644 (file)
@@ -237,7 +237,7 @@ sub preprocess {
        }
 
        if ($params{page} =~ m/\/\Q$config{comments_pagename}\E\d+_/) {
-               $pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1).
+               $pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page})).
                        "#".page_to_id($params{page});
        }
 
@@ -301,7 +301,7 @@ sub editcomment ($$) {
                required => [qw{editcontent}],
                javascript => 0,
                params => $cgi,
-               action => $config{cgiurl},
+               action => IkiWiki::cgiurl(),
                header => 0,
                table => 0,
                template => { template('editcomment.tmpl') },
@@ -372,7 +372,7 @@ sub editcomment ($$) {
                error(gettext("bad page name"));
        }
 
-       my $baseurl = urlto($page, undef, 1);
+       my $baseurl = urlto($page);
 
        $form->title(sprintf(gettext("commenting on %s"),
                        IkiWiki::pagetitle($page)));
@@ -385,8 +385,7 @@ sub editcomment ($$) {
 
        if ($form->submitted eq CANCEL) {
                # bounce back to the page they wanted to comment on, and exit.
-               # CANCEL need not be considered in future
-               IkiWiki::redirect($cgi, urlto($page, undef, 1));
+               IkiWiki::redirect($cgi, $baseurl);
                exit;
        }
 
@@ -552,7 +551,7 @@ sub editcomment ($$) {
                # Jump to the new comment on the page.
                # The trailing question mark tries to avoid broken
                # caches and get the most recent version of the page.
-               IkiWiki::redirect($cgi, urlto($page, undef, 1).
+               IkiWiki::redirect($cgi, urlto($page).
                        "?updated#".page_to_id($location));
 
        }
@@ -656,6 +655,7 @@ sub commentmoderation ($$) {
        $template->param(
                sid => $session->id,
                comments => \@comments,
+               cgiurl => IkiWiki::cgiurl(),
        );
        IkiWiki::printheader($session);
        my $out=$template->output;
@@ -727,6 +727,10 @@ sub previewcomment ($$$) {
        my $page=shift;
        my $time=shift;
 
+       # Previewing a comment should implicitly enable comment posting mode.
+       my $oldpostcomment=$postcomment;
+       $postcomment=1;
+
        my $preview = IkiWiki::htmlize($location, $page, '_comment',
                        IkiWiki::linkify($location, $page,
                        IkiWiki::preprocess($location, $page,
@@ -745,6 +749,8 @@ sub previewcomment ($$$) {
 
        $template->param(have_actions => 0);
 
+       $postcomment=$oldpostcomment;
+
        return $template->output;
 }
 
@@ -804,14 +810,14 @@ sub pagetemplate (@) {
        if ($shown) {
                if ($template->query(name => 'commentsurl')) {
                        $template->param(commentsurl =>
-                               urlto($page, undef, 1).'#comments');
+                               urlto($page).'#comments');
                }
 
                if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
                        # This will 404 until there are some comments, but I
                        # think that's probably OK...
                        $template->param(atomcommentsurl =>
-                               urlto($page, undef, 1).'comments.atom');
+                               urlto($page).'comments.atom');
                }
 
                if ($template->query(name => 'commentslink')) {
@@ -941,14 +947,16 @@ sub match_comment ($$;@) {
        my $page = shift;
        my $glob = shift;
 
-       # To see if it's a comment, check the source file type.
-       # Deal with comments that were just deleted.
-       my $source=exists $IkiWiki::pagesources{$page} ?
-               $IkiWiki::pagesources{$page} :
-               $IkiWiki::delpagesources{$page};
-       my $type=defined $source ? IkiWiki::pagetype($source) : undef;
-       if (! defined $type || $type ne "_comment") {
-               return IkiWiki::FailReason->new("$page is not a comment");
+       if (! $postcomment) {
+               # To see if it's a comment, check the source file type.
+               # Deal with comments that were just deleted.
+               my $source=exists $IkiWiki::pagesources{$page} ?
+                       $IkiWiki::pagesources{$page} :
+                       $IkiWiki::delpagesources{$page};
+               my $type=defined $source ? IkiWiki::pagetype($source) : undef;
+               if (! defined $type || $type ne "_comment") {
+                       return IkiWiki::FailReason->new("$page is not a comment");
+               }
        }
 
        return match_glob($page, "$glob/*", internal => 1, @_);
index 4a88171685b8d94cfaced062a9547ea8c3e6d401..0f6ea0b1f3798650219f7a08a66fa77f85151401 100644 (file)
@@ -5,10 +5,9 @@ use warnings;
 use strict;
 use IkiWiki 3.00;
 
-my %savedtext;
-
 sub import {
        hook(type => "getsetup", id => "cutpaste", call => \&getsetup);
+       hook(type => "needsbuild", id => "cutpaste", call => \&needsbuild);
        hook(type => "preprocess", id => "cut", call => \&preprocess_cut, scan => 1);
        hook(type => "preprocess", id => "copy", call => \&preprocess_copy, scan => 1);
        hook(type => "preprocess", id => "paste", call => \&preprocess_paste);
@@ -23,6 +22,22 @@ sub getsetup () {
                },
 }
 
+sub needsbuild (@) {
+       my $needsbuild=shift;
+       foreach my $page (keys %pagestate) {
+               if (exists $pagestate{$page}{cutpaste}) {
+                       if (exists $pagesources{$page} &&
+                           grep { $_ eq $pagesources{$page} } @$needsbuild) {
+                               # remove state, will be re-added if
+                               # the cut/copy directive is still present
+                               # on rebuild.
+                               delete $pagestate{$page}{cutpaste};
+                       }
+               }
+       }
+       return $needsbuild;
+}
+
 sub preprocess_cut (@) {
        my %params=@_;
 
@@ -32,8 +47,7 @@ sub preprocess_cut (@) {
                }
        }
 
-       $savedtext{$params{page}} = {} if not exists $savedtext{$params{"page"}};
-       $savedtext{$params{page}}->{$params{id}} = $params{text};
+       $pagestate{$params{page}}{cutpaste}{$params{id}} = $params{text};
 
        return "" if defined wantarray;
 }
@@ -47,8 +61,7 @@ sub preprocess_copy (@) {
                }
        }
 
-       $savedtext{$params{page}} = {} if not exists $savedtext{$params{"page"}};
-       $savedtext{$params{page}}->{$params{id}} = $params{text};
+       $pagestate{$params{page}}{cutpaste}{$params{id}} = $params{text};
 
        return IkiWiki::preprocess($params{page}, $params{destpage}, $params{text})
                if defined wantarray;
@@ -63,15 +76,15 @@ sub preprocess_paste (@) {
                }
        }
 
-       if (! exists $savedtext{$params{page}}) {
+       if (! exists $pagestate{$params{page}}{cutpaste}) {
                error gettext('no text was copied in this page');
        }
-       if (! exists $savedtext{$params{page}}->{$params{id}}) {
+       if (! exists $pagestate{$params{page}}{cutpaste}{$params{id}}) {
                error sprintf(gettext('no text was copied in this page with id %s'), $params{id});
        }
 
        return IkiWiki::preprocess($params{page}, $params{destpage},
-               $savedtext{$params{page}}->{$params{id}});
+               $pagestate{$params{page}}{cutpaste}{$params{id}});
 }
 
 1;
index 1a04a72b5568f2980d8a7e00d0eaaa06a62e0e0d..da071d4920fe0e5fcafde8f20419925522278d31 100644 (file)
@@ -75,7 +75,7 @@ sub cgi_editpage ($$) {
                required => [qw{editcontent}],
                javascript => 0,
                params => $q,
-               action => $config{cgiurl},
+               action => IkiWiki::cgiurl(),
                header => 0,
                table => 0,
                template => { template("editpage.tmpl") },
@@ -98,7 +98,7 @@ sub cgi_editpage ($$) {
                error(gettext("bad page name"));
        }
 
-       my $baseurl = urlto($page, undef, 1);
+       my $baseurl = urlto($page);
 
        my $from;
        if (defined $form->field('from')) {
@@ -156,13 +156,13 @@ sub cgi_editpage ($$) {
        my $previewing=0;
        if ($form->submitted eq "Cancel") {
                if ($form->field("do") eq "create" && defined $from) {
-                       redirect($q, urlto($from, undef, 1));
+                       redirect($q, urlto($from));
                }
                elsif ($form->field("do") eq "create") {
-                       redirect($q, $config{url});
+                       redirect($q, baseurl(undef));
                }
                else {
-                       redirect($q, urlto($page, undef, 1));
+                       redirect($q, $baseurl);
                }
                exit;
        }
@@ -262,7 +262,7 @@ sub cgi_editpage ($$) {
                                        @page_locs=$page;
                                }
                                else {
-                                       redirect($q, urlto($page, undef, 1));
+                                       redirect($q, $baseurl);
                                        exit;
                                }
                        }
@@ -434,7 +434,7 @@ sub cgi_editpage ($$) {
                else {
                        # The trailing question mark tries to avoid broken
                        # caches and get the most recent version of the page.
-                       redirect($q, urlto($page, undef, 1)."?updated");
+                       redirect($q, $baseurl."?updated");
                }
        }
 
index 226f83bb4bdfc6dfb11dd326fd6db9d02aae8eae..061242fd82c1f1a76251dac12f8017821688a2a1 100644 (file)
@@ -41,6 +41,8 @@ sub needsbuild (@) {
                        }
                }
        }
+
+       return $needsbuild;
 }
 
 sub preprocess (@) {
@@ -105,9 +107,11 @@ sub formbuilder (@) {
                                                my $template=$pagestate{$registering_page}{edittemplate}{$pagespec};
                                                $form->field(name => "editcontent",
                                                         value =>  filltemplate($template, $page));
-                                               $form->field(name => "type",
-                                                        value => pagetype($pagesources{$template}))
+                                               my $type=pagetype($pagesources{$template})
                                                                if $pagesources{$template};
+                                               $form->field(name => "type",
+                                                        value => $type)
+                                                               if defined $type;
                                                return;
                                        }
                                }
@@ -130,9 +134,6 @@ sub filltemplate ($$) {
                # up a template that doesn't work.
                return "[[!pagetemplate ".gettext("failed to process template:")." $@]]";
        }
-       if (! defined $template) {
-               return;
-       }
 
        $template->param(name => $page);
 
index ec91c79db2149a1b58a63f34aedc4b83b7a76a4a..a4cc1dd3ce32bade13d9477efcba68fdc4a50e1a 100644 (file)
@@ -28,7 +28,9 @@ sub import {
 
        $plugins{$plugin}={in => $plugin_read, out => $plugin_write, pid => $pid,
                accum => ""};
+
        $RPC::XML::ENCODING="utf-8";
+       $RPC::XML::FORCE_STRING_ENCODING="true";
 
        rpc_call($plugins{$plugin}, "import");
 }
index a78058ffed7b15b46e1c1352c88ce70eebc4b00a..4f4e67489a41c51ecae344119362f0ea611d481a 100644 (file)
@@ -148,6 +148,7 @@ sub match_mimetype ($$;@) {
        if (! defined $mimetype) {
                open(my $file_h, "-|", "file", "-bi", $file);
                $mimetype=<$file_h>;
+               chomp $mimetype;
                close $file_h;
        }
        if (! defined $mimetype || $mimetype !~s /;.*//) {
@@ -160,7 +161,7 @@ sub match_mimetype ($$;@) {
        }
 
        my $regexp=IkiWiki::glob2re($wanted);
-       if ($mimetype!~/^$regexp$/i) {
+       if ($mimetype!~$regexp) {
                return IkiWiki::FailReason->new("file MIME type is $mimetype, not $wanted");
        }
        else {
index d54e7113198093a2a939315077f7f99d34c529a8..b596bc0a10343b91cf7287f5b5fa06a81084b055 100644 (file)
@@ -29,22 +29,24 @@ sub preprocess (@) {
        if (! defined $format || ! defined $text) {
                error(gettext("must specify format and text"));
        }
+               
+       # Other plugins can register htmlizeformat hooks to add support
+       # for page types not suitable for htmlize, or that need special
+       # processing when included via format. Try them until one succeeds.
+       my $ret;
+       IkiWiki::run_hooks(htmlizeformat => sub {
+               $ret=shift->($format, $text)
+                       unless defined $ret;
+       });
+
+       if (defined $ret) {
+               return $ret;
+       }
        elsif (exists $IkiWiki::hooks{htmlize}{$format}) {
                return IkiWiki::htmlize($params{page}, $params{destpage},
                                        $format, $text);
        }
        else {
-               # Other plugins can register htmlizefallback
-               # hooks to add support for page types
-               # not suitable for htmlize. Try them until
-               # one succeeds.
-               my $ret;
-               IkiWiki::run_hooks(htmlizefallback => sub {
-                       $ret=shift->($format, $text)
-                               unless defined $ret;
-               });
-               return $ret if defined $ret;
-
                error(sprintf(gettext("unsupported page format %s"), $format));
        }
 }
index d342a7398bd2ce4458241ccb68a5ad6879edd70e..3db4af7291b0d11dcdf8bc89386b93133c963e10 100644 (file)
@@ -9,7 +9,7 @@ use open qw{:utf8 :std};
 
 my $sha1_pattern     = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums
 my $dummy_commit_msg = 'dummy commit';      # message to skip in recent changes
-my $no_chdir=0;
+my $git_dir=undef;
 
 sub import {
        hook(type => "checkconfig", id => "git", call => \&checkconfig);
@@ -27,6 +27,8 @@ sub import {
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
        hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
        hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive);
+       hook(type => "rcs", id => "rcs_preprevert", call => \&rcs_preprevert);
+       hook(type => "rcs", id => "rcs_revert", call => \&rcs_revert);
 }
 
 sub checkconfig () {
@@ -162,9 +164,13 @@ sub safe_git (&@) {
        if (!$pid) {
                # In child.
                # Git commands want to be in wc.
-               if (! $no_chdir) {
+               if (! defined $git_dir) {
                        chdir $config{srcdir}
-                           or error("Cannot chdir to $config{srcdir}: $!");
+                           or error("cannot chdir to $config{srcdir}: $!");
+               }
+               else {
+                       chdir $git_dir
+                           or error("cannot chdir to $git_dir: $!");
                }
                exec @cmdline or error("Cannot exec '@cmdline': $!");
        }
@@ -462,7 +468,7 @@ sub rcs_update () {
        # Update working directory.
 
        if (length $config{gitorigin_branch}) {
-               run_or_cry('git', 'pull', $config{gitorigin_branch});
+               run_or_cry('git', 'pull', '--prune', $config{gitorigin_branch});
        }
 }
 
@@ -490,16 +496,16 @@ sub rcs_commit (@) {
                return $conflict if defined $conflict;
        }
 
-       rcs_add($params{file});
-       return rcs_commit_staged(
-               message => $params{message},
-               session => $params{session},
-       );
+       return rcs_commit_helper(@_);
 }
 
 sub rcs_commit_staged (@) {
        # Commits all staged changes. Changes can be staged using rcs_add,
        # rcs_remove, and rcs_rename.
+       return rcs_commit_helper(@_);
+}
+
+sub rcs_commit_helper (@) {
        my %params=@_;
        
        my %env=%ENV;
@@ -540,10 +546,12 @@ sub rcs_commit_staged (@) {
                        $params{message}.=".";
                }
        }
-       push @opts, '-q';
-       # git commit returns non-zero if file has not been really changed.
-       # so we should ignore its exit status (hence run_or_non).
-       if (run_or_non('git', 'commit', @opts, '-m', $params{message})) {
+       if (exists $params{file}) {
+               push @opts, '--', $params{file};
+       }
+       # git commit returns non-zero if nothing really changed.
+       # So we should ignore its exit status (hence run_or_non).
+       if (run_or_non('git', 'commit', '-m', $params{message}, '-q', @opts)) {
                if (length $config{gitorigin_branch}) {
                        run_or_cry('git', 'push', $config{gitorigin_branch});
                }
@@ -682,7 +690,7 @@ sub findtimes ($$) {
        if (! keys %time_cache) {
                my $date;
                foreach my $line (run_or_die('git', 'log',
-                               '--pretty=format:%ct',
+                               '--pretty=format:%at',
                                '--name-only', '--relative')) {
                        if (! defined $date && $line =~ /^(\d+)$/) {
                                $date=$line;
@@ -718,10 +726,15 @@ sub rcs_getmtime ($) {
        return findtimes($file, 0);
 }
 
-sub rcs_receive () {
+{
+my $ret;
+sub git_find_root {
        # The wiki may not be the only thing in the git repo.
        # Determine if it is in a subdirectory by examining the srcdir,
        # and its parents, looking for the .git directory.
+
+       return @$ret if defined $ret;
+       
        my $subdir="";
        my $dir=$config{srcdir};
        while (! -d "$dir/.git") {
@@ -732,83 +745,139 @@ sub rcs_receive () {
                }
        }
 
+       $ret=[$subdir, $dir];
+       return @$ret;
+}
+
+}
+
+sub git_parse_changes {
+       my @changes = @_;
+
+       my ($subdir, $rootdir) = git_find_root();
+       my @rets;
+       foreach my $ci (@changes) {
+               foreach my $detail (@{ $ci->{'details'} }) {
+                       my $file = $detail->{'file'};
+
+                       # check that all changed files are in the subdir
+                       if (length $subdir &&
+                           ! ($file =~ s/^\Q$subdir\E//)) {
+                               error sprintf(gettext("you are not allowed to change %s"), $file);
+                       }
+
+                       my ($action, $mode, $path);
+                       if ($detail->{'status'} =~ /^[M]+\d*$/) {
+                               $action="change";
+                               $mode=$detail->{'mode_to'};
+                       }
+                       elsif ($detail->{'status'} =~ /^[AM]+\d*$/) {
+                               $action="add";
+                               $mode=$detail->{'mode_to'};
+                       }
+                       elsif ($detail->{'status'} =~ /^[DAM]+\d*/) {
+                               $action="remove";
+                               $mode=$detail->{'mode_from'};
+                       }
+                       else {
+                               error "unknown status ".$detail->{'status'};
+                       }
+
+                       # test that the file mode is ok
+                       if ($mode !~ /^100[64][64][64]$/) {
+                               error sprintf(gettext("you cannot act on a file with mode %s"), $mode);
+                       }
+                       if ($action eq "change") {
+                               if ($detail->{'mode_from'} ne $detail->{'mode_to'}) {
+                                       error gettext("you are not allowed to change file modes");
+                               }
+                       }
+
+                       # extract attachment to temp file
+                       if (($action eq 'add' || $action eq 'change') &&
+                           ! pagetype($file)) {
+                               eval q{use File::Temp};
+                               die $@ if $@;
+                               my $fh;
+                               ($fh, $path)=File::Temp::tempfile(undef, UNLINK => 1);
+                               my $cmd = "cd $git_dir && ".
+                                         "git show $detail->{sha1_to} > '$path'";
+                               if (system($cmd) != 0) {
+                                       error("failed writing temp file '$path'.");
+                               }
+                       }
+
+                       push @rets, {
+                               file => $file,
+                               action => $action,
+                               path => $path,
+                       };
+               }
+       }
+
+       return @rets;
+}
+
+sub rcs_receive () {
        my @rets;
        while (<>) {
                chomp;
                my ($oldrev, $newrev, $refname) = split(' ', $_, 3);
-               
+
                # only allow changes to gitmaster_branch
                if ($refname !~ /^refs\/heads\/\Q$config{gitmaster_branch}\E$/) {
                        error sprintf(gettext("you are not allowed to change %s"), $refname);
                }
-               
+
                # Avoid chdir when running git here, because the changes
                # are in the master git repo, not the srcdir repo.
-               # The pre-recieve hook already puts us in the right place.
-               $no_chdir=1;
-               my @changes=git_commit_info($oldrev."..".$newrev);
-               $no_chdir=0;
-
-               foreach my $ci (@changes) {
-                       foreach my $detail (@{ $ci->{'details'} }) {
-                               my $file = $detail->{'file'};
-
-                               # check that all changed files are in the
-                               # subdir
-                               if (length $subdir &&
-                                   ! ($file =~ s/^\Q$subdir\E//)) {
-                                       error sprintf(gettext("you are not allowed to change %s"), $file);
-                               }
+               # (Also, if a subdir is involved, we don't want to chdir to
+               # it and only see changes in it.)
+               # The pre-receive hook already puts us in the right place.
+               $git_dir=".";
+               push @rets, git_parse_changes(git_commit_info($oldrev."..".$newrev));
+               $git_dir=undef;
+       }
 
-                               my ($action, $mode, $path);
-                               if ($detail->{'status'} =~ /^[M]+\d*$/) {
-                                       $action="change";
-                                       $mode=$detail->{'mode_to'};
-                               }
-                               elsif ($detail->{'status'} =~ /^[AM]+\d*$/) {
-                                       $action="add";
-                                       $mode=$detail->{'mode_to'};
-                               }
-                               elsif ($detail->{'status'} =~ /^[DAM]+\d*/) {
-                                       $action="remove";
-                                       $mode=$detail->{'mode_from'};
-                               }
-                               else {
-                                       error "unknown status ".$detail->{'status'};
-                               }
-                               
-                               # test that the file mode is ok
-                               if ($mode !~ /^100[64][64][64]$/) {
-                                       error sprintf(gettext("you cannot act on a file with mode %s"), $mode);
-                               }
-                               if ($action eq "change") {
-                                       if ($detail->{'mode_from'} ne $detail->{'mode_to'}) {
-                                               error gettext("you are not allowed to change file modes");
-                                       }
-                               }
-                               
-                               # extract attachment to temp file
-                               if (($action eq 'add' || $action eq 'change') &&
-                                    ! pagetype($file)) {
-                                       eval q{use File::Temp};
-                                       die $@ if $@;
-                                       my $fh;
-                                       ($fh, $path)=File::Temp::tempfile("XXXXXXXXXX", UNLINK => 1);
-                                       if (system("git show ".$detail->{sha1_to}." > '$path'") != 0) {
-                                               error("failed writing temp file");
-                                       }
-                               }
+       return reverse @rets;
+}
 
-                               push @rets, {
-                                       file => $file,
-                                       action => $action,
-                                       path => $path,
-                               };
-                       }
-               }
+sub rcs_preprevert ($) {
+       my $rev=shift;
+       my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
+
+       # Examine changes from root of git repo, not from any subdir,
+       # in order to see all changes.
+       my ($subdir, $rootdir) = git_find_root();
+       $git_dir=$rootdir;
+       my @commits=git_commit_info($sha1, 1);
+       $git_dir=undef;
+
+       if (! @commits) {
+               error "unknown commit"; # just in case
        }
 
-       return reverse @rets;
+       # git revert will fail on merge commits. Add a nice message.
+       if (exists $commits[0]->{parents} &&
+           @{$commits[0]->{parents}} > 1) {
+               error gettext("you are not allowed to revert a merge");
+       }
+
+       return git_parse_changes(@commits);
+}
+
+sub rcs_revert ($) {
+       # Try to revert the given rev; returns undef on _success_.
+       my $rev = shift;
+       my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
+
+       if (run_or_non('git', 'revert', '--no-commit', $sha1)) {
+               return undef;
+       }
+       else {
+               run_or_die('git', 'reset', '--hard');
+               return sprintf(gettext("Failed to revert commit %s"), $sha1);
+       }
 }
 
 1
index 42d2425ca2a0dbe85b172fee06eb63ec50b07d00..0eb83fc208de611d05a016ff8fc63c2c6913f1c8 100644 (file)
@@ -52,7 +52,7 @@ sub cgi_goto ($;$) {
                IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
        }
 
-       if (! length $link) {
+       if (! defined $link || ! length $link) {
                IkiWiki::cgi_custom_failure(
                        $q,
                        "404 Not Found",
@@ -64,7 +64,7 @@ sub cgi_goto ($;$) {
                )
        }
        else {
-               IkiWiki::redirect($q, urlto($link, undef, 1));
+               IkiWiki::redirect($q, urlto($link));
        }
 
        exit;
index e517ac5c06aa425771dcac7256a8e3127da8d3bb..9d05e9fcf49126c7d1f97d815e6c3435a82cd83a 100644 (file)
@@ -6,16 +6,12 @@ use strict;
 use IkiWiki 3.00;
 use Encode;
 
-# locations of highlight's files
-my $filetypes="/etc/highlight/filetypes.conf";
-my $langdefdir="/usr/share/highlight/langDefs";
-
 sub import {
        hook(type => "getsetup", id => "highlight",  call => \&getsetup);
        hook(type => "checkconfig", id => "highlight", call => \&checkconfig);
        # this hook is used by the format plugin
-       hook(type => "htmlizefallback", id => "highlight", call =>
-               \&htmlizefallback);
+       hook(type => "htmlizeformat", id => "highlight", 
+               call => \&htmlizeformat, last => 1);
 }
 
 sub getsetup () {
@@ -32,9 +28,29 @@ sub getsetup () {
                        safe => 1,
                        rebuild => 1,
                },
+               filetypes_conf => {
+                       type => "string",
+                       example => "/etc/highlight/filetypes.conf",
+                       description => "location of highlight's filetypes.conf",
+                       safe => 0,
+                       rebuild => undef,
+               },
+               langdefdir => {
+                       type => "string",
+                       example => "/usr/share/highlight/langDefs",
+                       description => "location of highlight's langDefs directory",
+                       safe => 0,
+                       rebuild => undef,
+               },
 }
 
 sub checkconfig () {
+       if (! exists $config{filetypes_conf}) {
+               $config{filetypes_conf}="/etc/highlight/filetypes.conf";
+       }
+       if (! exists $config{langdefdir}) {
+               $config{langdefdir}="/usr/share/highlight/langDefs";
+       }
        if (exists $config{tohighlight}) {
                foreach my $file (split ' ', $config{tohighlight}) {
                        my @opts = $file=~s/^\.// ?
@@ -63,7 +79,7 @@ sub checkconfig () {
        }
 }
 
-sub htmlizefallback {
+sub htmlizeformat {
        my $format=lc shift;
        my $langfile=ext2langfile($format);
 
@@ -80,14 +96,29 @@ my %highlighters;
 
 # Parse highlight's config file to get extension => language mappings.
 sub read_filetypes () {
-       open (IN, $filetypes) || error("$filetypes: $!");
-       while (<IN>) {
-               chomp;
-               if (/^\$ext\((.*)\)=(.*)$/) {
-                       $ext2lang{$_}=$1 foreach $1, split ' ', $2;
+       open (my $f, $config{filetypes_conf}) || error("$config{filetypes_conf}: $!");
+       local $/=undef;
+       my $config=<$f>;
+       close $f;
+
+       # highlight >= 3.2 format (bind-style)
+       while ($config=~m/Lang\s*=\s*\"([^"]+)\"[,\s]+Extensions\s*=\s*{([^}]+)}/sg) {
+               my $lang=$1;
+               foreach my $bit (split ',', $2) {
+                       $bit=~s/.*"(.*)".*/$1/s;
+                       $ext2lang{$bit}=$lang;
+               }
+       }
+
+       # highlight < 3.2 format
+       if (! keys %ext2lang) {
+               foreach (split("\n", $config)) {
+                       if (/^\$ext\((.*)\)=(.*)$/) {
+                               $ext2lang{$_}=$1 foreach $1, split ' ', $2;
+                       }
                }
        }
-       close IN;
+
        $filetypes_read=1;
 }
 
@@ -97,12 +128,12 @@ sub read_filetypes () {
 sub ext2langfile ($) {
        my $ext=shift;
 
-       my $langfile="$langdefdir/$ext.lang";
+       my $langfile="$config{langdefdir}/$ext.lang";
        return $langfile if exists $highlighters{$langfile};
 
        read_filetypes() unless $filetypes_read;
        if (exists $ext2lang{$ext}) {
-               return "$langdefdir/$ext2lang{$ext}.lang";
+               return "$config{langdefdir}/$ext2lang{$ext}.lang";
        }
        # If a language only has one common extension, it will not
        # be listed in filetypes, so check the langfile.
index 26f8e494bf537dba9f2b0c967c71fb9f26067b84..da450eea7ef691c8f16ed4e5a20a2603b0491c22 100644 (file)
@@ -43,7 +43,7 @@ sub sanitize (@) {
        my @nodes = $tree->disembowel();
        foreach my $node (@nodes) {
                if (ref $node) {
-                       $ret .= $node->as_XML();
+                       $ret .= $node->as_HTML(undef, '', {});
                        chomp $ret;
                        $node->delete();
                }
index 927792f791f2160232671e1327db2a379a496e9d..a58a27d5221acc50e932057b9fabaffcf38c7b97 100644 (file)
@@ -57,8 +57,8 @@ sub sanitize (@) {
 
        if (exists $config{htmlscrubber_skip} &&
            length $config{htmlscrubber_skip} &&
-           exists $params{destpage} &&
-           pagespec_match($params{destpage}, $config{htmlscrubber_skip})) {
+           exists $params{page} &&
+           pagespec_match($params{page}, $config{htmlscrubber_skip})) {
                return $params{content};
        }
 
index e6d377f8ab96a853f0bfcbc51ab2d09126e6d14e..1108aeb894e658a35eff011975c1c0b50d14a439 100644 (file)
@@ -15,6 +15,7 @@ use IPC::Open2;
 sub import {
        hook(type => "getsetup", id => "tidy", call => \&getsetup);
        hook(type => "sanitize", id => "tidy", call => \&sanitize);
+       hook(type => "checkconfig", id => "tidy", call => \&checkconfig);
 }
 
 sub getsetup () {
@@ -23,6 +24,18 @@ sub getsetup () {
                        safe => 1,
                        rebuild => undef,
                },
+               htmltidy => {
+                       type => "string",
+                       description => "tidy command line",
+                       safe => 0, # path
+                       rebuild => undef,
+               },
+}
+
+sub checkconfig () {
+       if (! defined $config{htmltidy}) {
+               $config{htmltidy}="tidy -quiet -asxhtml -utf8 --show-body-only yes --show-warnings no --tidy-mark no --markup yes";
+       }
 }
 
 sub sanitize (@) {
@@ -31,7 +44,7 @@ sub sanitize (@) {
        my $pid;
        my $sigpipe=0;
        $SIG{PIPE}=sub { $sigpipe=1 };
-       $pid=open2(*IN, *OUT, 'tidy -quiet -asxhtml -utf8 --show-body-only yes --show-warnings no --tidy-mark no --markup yes 2>/dev/null');
+       $pid=open2(*IN, *OUT, "$config{htmltidy} 2>/dev/null");
 
        # open2 doesn't respect "use open ':utf8'"
        binmode (IN, ':utf8');
index 478f6744656f5bdbd4baa00f79cadb9a74ebd255..cb488449dd680b2ae36aefde23636ba3fdfe6ab8 100644 (file)
@@ -78,19 +78,14 @@ sub formbuilder_setup (@) {
        }
 }
 
-sub test_httpauth_pagespec ($) {
-       my $page=shift;
-
-       return (
-       );
-}
-
 sub canedit ($$$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
 
        if (! defined $cgi->remote_user() &&
+           (! defined $session->param("name") ||
+             ! IkiWiki::userinfo_get($session->param("name"), "regdate")) &&
            defined $config{httpauth_pagespec} &&
            length $config{httpauth_pagespec} &&
            defined $config{cgiauthurl} &&
index 2375ead8968b6a9baf64ff8ac825dbde6a75b82d..103f6b2b3510067f10a5eddf86f8e657ba96fe29 100644 (file)
@@ -152,14 +152,11 @@ sub preprocess (@) {
                $imgurl=urlto($imglink, $params{destpage});
        }
        else {
-               $fileurl="$config{url}/$file";
-               $imgurl="$config{url}/$imglink";
+               $fileurl=urlto($file);
+               $imgurl=urlto($imglink);
        }
 
-       if (exists $params{class}) {
-               $params{class}.=" img";
-       }
-       else {
+       if (! exists $params{class}) {
                $params{class}="img";
        }
 
index 715a3d6523cfcee4e57c125425d19cfdab110298..b58c8780b0ef24637ebe98845b1cdc3b4b4b2739 100644 (file)
@@ -104,7 +104,7 @@ sub checkconfig () {
 }
 
 sub format (@) {
-        my %params=@_;
+       my %params=@_;
 
        # Fill in the inline content generated earlier. This is actually an
        # optimisation.
@@ -160,7 +160,7 @@ sub preprocess_inline (@) {
        my $rss=(($config{rss} || $config{allowrss}) && exists $params{rss}) ? yesno($params{rss}) : $config{rss};
        my $atom=(($config{atom} || $config{allowatom}) && exists $params{atom}) ? yesno($params{atom}) : $config{atom};
        my $quick=exists $params{quick} ? yesno($params{quick}) : 0;
-       my $feeds=! $nested && (exists $params{feeds} ? yesno($params{feeds}) : !$quick && ! $raw);
+       my $feeds=exists $params{feeds} ? yesno($params{feeds}) : !$quick && ! $raw;
        my $emptyfeeds=exists $params{emptyfeeds} ? yesno($params{emptyfeeds}) : 1;
        my $feedonly=yesno($params{feedonly});
        if (! exists $params{show} && ! $archive) {
@@ -269,7 +269,7 @@ sub preprocess_inline (@) {
                        }
                        $params{feedfile}=possibly_foolish_untaint($params{feedfile});
                }
-               $feedbase=targetpage($params{destpage}, "", $params{feedfile});
+               $feedbase=targetpage($params{page}, "", $params{feedfile});
 
                my $feedid=join("\0", $feedbase, map { $_."\0".$params{$_} } sort keys %params);
                if (exists $knownfeeds{$feedid}) {
@@ -300,7 +300,7 @@ sub preprocess_inline (@) {
            IkiWiki->can("cgi_editpage")) {
                # Add a blog post form, with feed buttons.
                my $formtemplate=template_depends("blogpost.tmpl", $params{page}, blind_cache => 1);
-               $formtemplate->param(cgiurl => $config{cgiurl});
+               $formtemplate->param(cgiurl => IkiWiki::cgiurl());
                $formtemplate->param(rootpage => rootpage(%params));
                $formtemplate->param(rssurl => $rssurl) if $feeds && $rss;
                $formtemplate->param(atomurl => $atomurl) if $feeds && $atom;
@@ -336,10 +336,7 @@ sub preprocess_inline (@) {
                                        blind_cache => 1);
                        };
                        if ($@) {
-                               error gettext("failed to process template:")." $@";
-                       }
-                       if (! $template) {
-                               error sprintf(gettext("template %s not found"), $params{template}.".tmpl");
+                               error sprintf(gettext("failed to process template %s"), $params{template}.".tmpl").": $@";
                        }
                }
                my $needcontent=$raw || (!($archive && $quick) && $template->query(name => 'content'));
@@ -509,26 +506,59 @@ sub date_822 ($) {
 }
 
 sub absolute_urls ($$) {
-       # sucky sub because rss sucks
-       my $content=shift;
+       # needed because rss sucks
+       my $html=shift;
        my $baseurl=shift;
 
        my $url=$baseurl;
        $url=~s/[^\/]+$//;
+       my $urltop; # calculated if needed
+
+       my $ret="";
+
+       eval q{use HTML::Parser; use HTML::Tagset};
+       die $@ if $@;
+       my $p = HTML::Parser->new(api_version => 3);
+       $p->handler(default => sub { $ret.=join("", @_) }, "text");
+       $p->handler(start => sub {
+               my ($tagname, $pos, $text) = @_;
+               if (ref $HTML::Tagset::linkElements{$tagname}) {
+                       while (4 <= @$pos) {
+                               # use attribute sets from right to left
+                               # to avoid invalidating the offsets
+                               # when replacing the values
+                               my ($k_offset, $k_len, $v_offset, $v_len) =
+                                       splice(@$pos, -4);
+                               my $attrname = lc(substr($text, $k_offset, $k_len));
+                               next unless grep { $_ eq $attrname } @{$HTML::Tagset::linkElements{$tagname}};
+                               next unless $v_offset; # 0 v_offset means no value
+                               my $v = substr($text, $v_offset, $v_len);
+                               $v =~ s/^([\'\"])(.*)\1$/$2/;
+                               if ($v=~/^#/) {
+                                       $v=$baseurl.$v; # anchor
+                               }
+                               elsif ($v=~/^(?!\w+:)[^\/]/) {
+                                       $v=$url.$v; # relative url
+                               }
+                               elsif ($v=~/^\//) {
+                                       if (! defined $urltop) {
+                                               # what is the non path part of the url?
+                                               my $top_uri = URI->new($url);
+                                               $top_uri->path_query(""); # reset the path
+                                               $urltop = $top_uri->as_string;
+                                       }
+                                       $v=$urltop.$v; # url relative to top of site
+                               }
+                               $v =~ s/\"/&quot;/g; # since we quote with ""
+                               substr($text, $v_offset, $v_len) = qq("$v");
+                       }
+               }
+               $ret.=$text;
+       }, "tagname, tokenpos, text");
+       $p->parse($html);
+       $p->eof;
 
-        # what is the non path part of the url?
-        my $top_uri = URI->new($url);
-        $top_uri->path_query(""); # reset the path
-        my $urltop = $top_uri->as_string;
-
-       $content=~s/(<a(?:\s+(?:class|id)\s*="?\w+"?)?)\s+href=\s*"(#[^"]+)"/$1 href="$baseurl$2"/mig;
-        # relative to another wiki page
-       $content=~s/(<a(?:\s+(?:class|id)\s*="?\w+"?)?)\s+href=\s*"(?!\w+:)([^\/][^"]*)"/$1 href="$url$2"/mig;
-       $content=~s/(<img(?:\s+(?:class|id|width|height)\s*="?\w+"?)*)\s+src=\s*"(?!\w+:)([^\/][^"]*)"/$1 src="$url$2"/mig;
-        # relative to the top of the site
-       $content=~s/(<a(?:\s+(?:class|id)\s*="?\w+"?)?)\s+href=\s*"(?!\w+:)(\/[^"]*)"/$1 href="$urltop$2"/mig;
-       $content=~s/(<img(?:\s+(?:class|id|width|height)\s*="?\w+"?)*)\s+src=\s*"(?!\w+:)(\/[^"]*)"/$1 src="$urltop$2"/mig;
-       return $content;
+       return $ret;
 }
 
 sub genfeed ($$$$$@) {
index 8a67f716026003e8b00135f4de5f1f7da60794a2..835e253886d67e2223bab034643c4823fa8d23bb 100644 (file)
@@ -64,6 +64,8 @@ sub needsbuild (@) {
                        }
                }
        }
+
+       return $needsbuild;
 }
 
 sub preprocess (@) {
index d18585d3d876129990cd829b88f306eb985308fb..abc8f1b1aa1089f60ba62e93dbcca0062696f4f6 100644 (file)
@@ -37,12 +37,13 @@ sub needsbuild (@) {
                        }
                }
        }
+       return $needsbuild;
 }
 
-sub scrub ($$) {
+sub scrub ($$$) {
        if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
                return IkiWiki::Plugin::htmlscrubber::sanitize(
-                       content => shift, destpage => shift);
+                       content => shift, page => shift, destpage => shift);
        }
        else {
                return shift;
@@ -161,7 +162,7 @@ sub preprocess (@) {
        # Metadata handling that happens only during preprocessing pass.
        if ($key eq 'permalink') {
                if (safeurl($value)) {
-                       push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />', $destpage);
+                       push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />', $page, $destpage);
                }
        }
        elsif ($key eq 'stylesheet') {
@@ -197,8 +198,12 @@ sub preprocess (@) {
                                '" rel="openid2.local_id" />' if $delegate ne 1;
                }
                if (exists $params{"xrds-location"} && safeurl($params{"xrds-location"})) {
-                       push @{$metaheaders{$page}}, '<meta http-equiv="X-XRDS-Location"'.
-                               'content="'.encode_entities($params{"xrds-location"}).'" />';
+                       # force url absolute
+                       eval q{use URI};
+                       error($@) if $@;
+                       my $url=URI->new_abs($params{"xrds-location"}, $config{url});
+                       push @{$metaheaders{$page}}, '<meta http-equiv="X-XRDS-Location" '.
+                               'content="'.encode_entities($url).'" />';
                }
        }
        elsif ($key eq 'redir') {
@@ -235,7 +240,7 @@ sub preprocess (@) {
                my $delay=int(exists $params{delay} ? $params{delay} : 0);
                my $redir="<meta http-equiv=\"refresh\" content=\"$delay; URL=$value\" />";
                if (! $safe) {
-                       $redir=scrub($redir, $destpage);
+                       $redir=scrub($redir, $page, $destpage);
                }
                push @{$metaheaders{$page}}, $redir;
        }
@@ -245,7 +250,7 @@ sub preprocess (@) {
                                join(" ", map {
                                        encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
                                } keys %params).
-                               " />\n", $destpage);
+                               " />\n", $page, $destpage);
                }
        }
        elsif ($key eq 'robots') {
@@ -261,12 +266,12 @@ sub preprocess (@) {
                push @{$metaheaders{$page}}, scrub('<meta '.$key.'="'.
                        encode_entities($value).
                        join(' ', map { "$_=\"$params{$_}\"" } keys %params).
-                       ' />', $destpage);
+                       ' />', $page, $destpage);
        }
        else {
                push @{$metaheaders{$page}}, scrub('<meta name="'.
                        encode_entities($key).'" content="'.
-                       encode_entities($value).'" />', $destpage);
+                       encode_entities($value).'" />', $page, $destpage);
        }
 
        return "";
@@ -350,7 +355,7 @@ sub match {
        }
 
        if (defined $val) {
-               if ($val=~/^$re$/i) {
+               if ($val=~$re) {
                        return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT, "" => 1);
                }
                else {
index 95fbcee7648c56c0825d714d15ad7bea37e93621..75bf2f458a48e461eadb91c44ffb9d21e89260c4 100644 (file)
@@ -252,9 +252,20 @@ sub get_changed_files ($$) {
 
        my @ret;
        my %seen = ();
-       
+
+       # we need to strip off the relative path to the source dir
+       # because monotone outputs all file paths absolute according
+       # to the workspace root
+       my $rel_src_dir = $config{'srcdir'};
+       $rel_src_dir =~ s/^\Q$config{'mtnrootdir'}\E\/?//;
+       $rel_src_dir .= "/" if length $rel_src_dir;
+
        while ($changes =~ m/\s*(add_file|patch|delete|rename)\s"(.*?)(?<!\\)"\n/sg) {
                my $file = $2;
+               # ignore all file changes outside the source dir
+               next unless $file =~ m/^\Q$rel_src_dir\E/;
+               $file =~ s/^\Q$rel_src_dir\E//;
+        
                # don't add the same file multiple times
                if (! $seen{$file}) {
                        push @ret, $file;
index 80e339a1be7c876e05820ba2da3e444d97770345..6880e366df3ad40b9404d915b04c28e4d3e3bfa4 100644 (file)
@@ -26,7 +26,10 @@ sub preprocess (@) {
 
        $params{linktext} = $linktext unless defined $params{linktext};
 
-       if ($params{page} ne $params{destpage}) {
+       if ($params{page} ne $params{destpage} &&
+           (! exists $params{pages} ||
+            pagespec_match($params{destpage}, $params{pages},
+                    location => $params{page}))) {
                return "\n".
                        htmllink($params{page}, $params{destpage}, $params{page},
                                linktext => $params{linktext},
index fae9fb77f8388a9e750b1d8e7dfdcee700f76a92..0220a3cf67e7e78adf83c52ca4dbe09a312fa3cd 100644 (file)
@@ -77,7 +77,7 @@ sub openid_selector {
 
        my $template=IkiWiki::template("openid-selector.tmpl");
        $template->param(
-               cgiurl => $config{cgiurl},
+               cgiurl => IkiWiki::cgiurl(),
                (defined $openid_error ? (openid_error => $openid_error) : ()),
                (defined $openid_url ? (openid_url => $openid_url) : ()),
                ($real_cgi_signin ? (nonopenidform => $real_cgi_signin->($q, $session, 1)) : ()),
@@ -148,7 +148,7 @@ sub validate ($$$;$) {
        }
 
        my $cgiurl=$config{openid_cgiurl};
-       $cgiurl=$config{cgiurl} if ! defined $cgiurl;
+       $cgiurl=IkiWiki::cgiurl() if ! defined $cgiurl;
 
        my $trust_root=$config{openid_realm};
        $trust_root=$cgiurl if ! defined $trust_root;
@@ -175,7 +175,7 @@ sub auth ($$) {
                        IkiWiki::redirect($q, $setup_url);
                }
                elsif ($csr->user_cancel) {
-                       IkiWiki::redirect($q, $config{url});
+                       IkiWiki::redirect($q, IkiWiki::baseurl(undef));
                }
                elsif (my $vident = $csr->verified_identity) {
                        $session->param(name => $vident->url);
@@ -249,7 +249,7 @@ sub getobj ($$) {
        }
        
        my $cgiurl=$config{openid_cgiurl};
-       $cgiurl=$config{cgiurl} if ! defined $cgiurl;
+       $cgiurl=IkiWiki::cgiurl() if ! defined $cgiurl;
 
        return Net::OpenID::Consumer->new(
                ua => $ua,
index bbd2c5752f58ac4aa94dc932ac4345a5226266a7..203ea13b649e288fe4935d2743469721c15eb1e1 100644 (file)
@@ -27,7 +27,7 @@ sub parentlinks ($) {
        if (! length $page) {
                # dynamic page
                return {
-                       url => $config{url},
+                       url => IkiWiki::baseurl(undef),
                        page => $config{wikiname},
                };
        }
index c20ecb5d4ef3a663f5496135f56ddb5369c5dd87..932619496c3d3c7634cb1a550a920dae106140a2 100644 (file)
@@ -45,6 +45,7 @@ sub needsbuild (@) {
                        }
                }
        }
+       return $needsbuild;
 }
 
 sub preprocess (@) {
@@ -105,6 +106,8 @@ sub ping {
                        # only ping when a page was changed, so a ping loop
                        # will still be avoided.
                        next if $url=~/^\Q$config{cgiurl}\E/;
+                       my $local_cgiurl = IkiWiki::cgiurl();
+                       next if $url=~/^\Q$local_cgiurl\E/;
                        
                        $ua->get($url);
                }
index f3530faf32d1b710d84c6abc6acb5dfa6182141f..79142ed1fe62396f17cff88cbfe914acb40896f7 100644 (file)
@@ -25,10 +25,12 @@ use File::Temp;
 use Memoize;
 use UNIVERSAL;
 
+my ($master_language_code, $master_language_name);
 my %translations;
 my @origneedsbuild;
 my %origsubs;
 my @slavelanguages; # language codes ordered as in config po_slave_languages
+my %slavelanguages; # language code to name lookup
 
 memoize("istranslatable");
 memoize("_istranslation");
@@ -89,16 +91,13 @@ sub import {
 sub getsetup () {
        return
                plugin => {
-                       safe => 0,
+                       safe => 1,
                        rebuild => 1, # format plugin
                        section => "format",
                },
                po_master_language => {
                        type => "string",
-                       example => {
-                               'code' => 'en',
-                               'name' => 'English'
-                       },
+                       example => "en|English",
                        description => "master language (non-PO files)",
                        safe => 1,
                        rebuild => 1,
@@ -110,7 +109,7 @@ sub getsetup () {
                                'es|Español',
                                'de|Deutsch'
                        ],
-                       description => "slave languages (PO files)",
+                       description => "slave languages (translated via PO files) format: ll|Langname",
                        safe => 1,
                        rebuild => 1,
                },
@@ -132,39 +131,49 @@ sub getsetup () {
 }
 
 sub checkconfig () {
-       foreach my $field (qw{po_master_language}) {
-               if (! exists $config{$field} || ! defined $config{$field}) {
-                       error(sprintf(gettext("Must specify %s when using the %s plugin"),
-                                     $field, 'po'));
+       if (exists $config{po_master_language}) {
+               if (! ref $config{po_master_language}) {
+                       ($master_language_code, $master_language_name)=
+                               splitlangpair($config{po_master_language});
+               }
+               else {
+                       $master_language_code=$config{po_master_language}{code};
+                       $master_language_name=$config{po_master_language}{name};
+                       $config{po_master_language}=joinlangpair($master_language_code, $master_language_name);
                }
        }
+       if (! defined $master_language_code) {
+               $master_language_code='en';
+       }
+       if (! defined $master_language_name) {
+               $master_language_name='English';
+       }
 
        if (ref $config{po_slave_languages} eq 'ARRAY') {
-               my %slaves;
                foreach my $pair (@{$config{po_slave_languages}}) {
-                       my ($code, $name) = ( $pair =~ /^([a-z]{2})\|(.+)$/ );
-                       if (!defined $code || !defined $name) {
-                               error(sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
-                                             $pair));
+                       my ($code, $name)=splitlangpair($pair);
+                       if (defined $code && ! exists $slavelanguages{$code}) {
+                               push @slavelanguages, $code;
+                               $slavelanguages{$code} = $name;
                        }
-                       $slaves{$code} = $name;
-                       push @slavelanguages, $code;
-
                }
-               $config{po_slave_languages} = \%slaves;
        }
        elsif (ref $config{po_slave_languages} eq 'HASH') {
+               %slavelanguages=%{$config{po_slave_languages}};
                @slavelanguages = sort {
                        $config{po_slave_languages}->{$a} cmp $config{po_slave_languages}->{$b};
-               } keys %{$config{po_slave_languages}};
+               } keys %slavelanguages;
+               $config{po_slave_languages}=[
+                       map { joinlangpair($_, $slavelanguages{$_}) } @slavelanguages
+               ]
        }
 
-       delete $config{po_slave_languages}{$config{po_master_language}{code}};;
+       delete $slavelanguages{$master_language_code};
 
        map {
                islanguagecode($_)
                        or error(sprintf(gettext("%s is not a valid language code"), $_));
-       } ($config{po_master_language}{code}, @slavelanguages);
+       } ($master_language_code, @slavelanguages);
 
        if (! exists $config{po_translatable_pages} ||
            ! defined $config{po_translatable_pages}) {
@@ -198,11 +207,11 @@ sub checkconfig () {
                                if -d "$config{underlaydirbase}/po/$ll/$underlay";
                }
        
-               if ($config{po_master_language}{code} ne 'en') {
+               if ($master_language_code ne 'en') {
                        # Add underlay containing translated source files
                        # for the master language.
-                       add_underlay("locale/$config{po_master_language}{code}/$underlay")
-                               if -d "$config{underlaydirbase}/locale/$config{po_master_language}{code}/$underlay";
+                       add_underlay("locale/$master_language_code/$underlay")
+                               if -d "$config{underlaydirbase}/locale/$master_language_code/$underlay";
                }
        }
 }
@@ -221,6 +230,8 @@ sub needsbuild () {
        foreach my $master (keys %translations) {
                map add_depends($_, $master), values %{otherlanguages_pages($master)};
        }
+
+       return $needsbuild;
 }
 
 sub scan (@) {
@@ -510,7 +521,7 @@ sub formbuilder_setup (@) {
        if ($form->field("do") eq "create") {
                # Warn the user: new pages must be written in master language.
                my $template=template("pocreatepage.tmpl");
-               $template->param(LANG => $config{po_master_language}{name});
+               $template->param(LANG => $master_language_name);
                $form->tmpl_param(message => $template->output);
        }
        elsif ($form->field("do") eq "edit") {
@@ -599,7 +610,7 @@ sub mybeautify_urlpath ($) {
 
        my $res=$origsubs{'beautify_urlpath'}->($url);
        if (defined $config{po_link_to} && $config{po_link_to} eq "negotiated") {
-               $res =~ s!/\Qindex.$config{po_master_language}{code}.$config{htmlext}\E$!/!;
+               $res =~ s!/\Qindex.$master_language_code.$config{htmlext}\E$!/!;
                $res =~ s!/\Qindex.$config{htmlext}\E$!/!;
                map {
                        $res =~ s!/\Qindex.$_.$config{htmlext}\E$!/!;
@@ -790,7 +801,7 @@ sub _istranslation ($) {
        return 0 unless defined $masterpage && defined $lang
                         && length $masterpage && length $lang
                         && defined $pagesources{$masterpage}
-                        && defined $config{po_slave_languages}{$lang};
+                        && defined $slavelanguages{$lang};
 
        return (maybe_add_leading_slash($masterpage, $hasleadingslash), $lang)
                if istranslatable($masterpage);
@@ -822,7 +833,7 @@ sub lang ($) {
        if (1 < (my ($masterpage, $lang) = _istranslation($page))) {
                return $lang;
        }
-       return $config{po_master_language}{code};
+       return $master_language_code;
 }
 
 sub islanguagecode ($) {
@@ -835,7 +846,7 @@ sub otherlanguage_page ($$) {
        my $page=shift;
        my $code=shift;
 
-       return masterpage($page) if $code eq $config{po_master_language}{code};
+       return masterpage($page) if $code eq $master_language_code;
        return masterpage($page) . '.' . $code;
 }
 
@@ -849,9 +860,9 @@ sub otherlanguages_codes ($) {
        return \@ret unless istranslation($page) || istranslatable($page);
        my $curlang=lang($page);
        foreach my $lang
-               ($config{po_master_language}{code}, @slavelanguages) {
+               ($master_language_code, @slavelanguages) {
                next if $lang eq $curlang;
-               if ($lang eq $config{po_master_language}{code} ||
+               if ($lang eq $master_language_code ||
                    istranslatedto(masterpage($page), $lang)) {
                        push @ret, $lang;
                }
@@ -1006,10 +1017,10 @@ sub percenttranslated ($) {
 sub languagename ($) {
        my $code=shift;
 
-       return $config{po_master_language}{name}
-               if $code eq $config{po_master_language}{code};
-       return $config{po_slave_languages}{$code}
-               if defined $config{po_slave_languages}{$code};
+       return $master_language_name
+               if $code eq $master_language_code;
+       return $slavelanguages{$code}
+               if defined $slavelanguages{$code};
        return;
 }
 
@@ -1020,13 +1031,13 @@ sub otherlanguagesloop ($) {
        if (istranslation($page)) {
                push @ret, {
                        url => urlto_with_orig_beautiful_urlpath(masterpage($page), $page),
-                       code => $config{po_master_language}{code},
-                       language => $config{po_master_language}{name},
+                       code => $master_language_code,
+                       language => $master_language_name,
                        master => 1,
                };
        }
        foreach my $lang (@{otherlanguages_codes($page)}) {
-               next if $lang eq $config{po_master_language}{code};
+               next if $lang eq $master_language_code;
                my $otherpage = otherlanguage_page($page, $lang);
                push @ret, {
                        url => urlto_with_orig_beautiful_urlpath($otherpage, $page),
@@ -1231,6 +1242,27 @@ sub po4a_options($) {
        return %options;
 }
 
+sub splitlangpair ($) {
+       my $pair=shift;
+
+       my ($code, $name) = ( $pair =~ /^([a-z]{2})\|(.+)$/ );
+       if (! defined $code || ! defined $name ||
+           ! length $code || ! length $name) {
+               # not a fatal error to avoid breaking if used with web setup
+               warn sprintf(gettext("%s has invalid syntax: must use CODE|NAME"),
+                       $pair);
+       }
+
+       return $code, $name;
+}
+
+sub joinlangpair ($$) {
+       my $code=shift;
+       my $name=shift;
+
+       return "$code|$name";
+}
+
 # ,----
 # | PageSpecs
 # `----
@@ -1265,7 +1297,7 @@ sub match_lang ($$;@) {
 
        my $regexp=IkiWiki::glob2re($wanted);
        my $lang=IkiWiki::Plugin::po::lang($page);
-       if ($lang !~ /^$regexp$/i) {
+       if ($lang !~ $regexp) {
                return IkiWiki::FailReason->new("file language is $lang, not $wanted");
        }
        else {
index b333e2cdcff485edd81f4df426e1865c261a1199..2773486a6c69560fdd0a2236607b800dc88b15e6 100644 (file)
@@ -52,7 +52,7 @@ sub preprocess (@) {
        foreach my $choice (@choices) {
                if ($open && exists $config{cgiurl}) {
                        # use POST to avoid robots
-                       $ret.="<form method=\"POST\" action=\"$config{cgiurl}\">\n";
+                       $ret.="<form method=\"POST\" action=\"".IkiWiki::cgiurl()."\">\n";
                }
                my $percent=$total > 0 ? int($choices{$choice} / $total * 100) : 0;
                $ret.="<p>\n";
@@ -103,7 +103,7 @@ sub sessioncgi ($$) {
                my $oldchoice=$session->param($choice_param);
                if (defined $oldchoice && $oldchoice eq $choice) {
                        # Same vote; no-op.
-                       IkiWiki::redirect($cgi, urlto($page, undef, 1));
+                       IkiWiki::redirect($cgi, urlto($page));
                        exit;
                }
 
@@ -153,7 +153,7 @@ sub sessioncgi ($$) {
                error($@) if $@;
                my $cookie = CGI::Cookie->new(-name=> $session->name, -value=> $session->id);
                print $cgi->redirect(-cookie => $cookie,
-                       -url => urlto($page, undef, 1));
+                       -url => urlto($page));
                exit;
        }
 }
index 758b98348d126aa572a537f9f0b359e5baffbb5e..6fccd16f6df6c72590863626042166abaca5f51c 100644 (file)
@@ -13,6 +13,7 @@ sub import {
        hook(type => "refresh", id => "recentchanges", call => \&refresh);
        hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate);
        hook(type => "htmlize", id => "_change", call => \&htmlize);
+       hook(type => "sessioncgi", id => "recentchanges", call => \&sessioncgi);
        # Load goto to fix up links from recentchanges
        IkiWiki::loadplugin("goto");
 }
@@ -60,6 +61,76 @@ sub refresh ($) {
        }
 }
 
+sub sessioncgi ($$) {
+       my ($q, $session) = @_;
+       my $do = $q->param('do');
+       my $rev = $q->param('rev');
+
+       return unless $do eq 'revert' && $rev;
+
+       my @changes=$IkiWiki::hooks{rcs}{rcs_preprevert}{call}->($rev);
+       IkiWiki::check_canchange(
+               cgi => $q,
+               session => $session,
+               changes => \@changes,
+       );
+
+       eval q{use CGI::FormBuilder};
+       error($@) if $@;
+       my $form = CGI::FormBuilder->new(
+               name => "revert",
+               header => 0,
+               charset => "utf-8",
+               method => 'POST',
+               javascript => 0,
+               params => $q,
+               action => IkiWiki::cgiurl(),
+               stylesheet => 1,
+               template => { template('revert.tmpl') },
+               fields => [qw{revertmessage do sid rev}],
+       );
+       my $buttons=["Revert", "Cancel"];
+
+       $form->field(name => "revertmessage", type => "text", size => 80);
+       $form->field(name => "sid", type => "hidden", value => $session->id,
+               force => 1);
+       $form->field(name => "do", type => "hidden", value => "revert",
+               force => 1);
+
+       IkiWiki::decode_form_utf8($form);
+
+       if ($form->submitted eq 'Revert' && $form->validate) {
+               IkiWiki::checksessionexpiry($q, $session, $q->param('sid'));
+               my $message=sprintf(gettext("This reverts commit %s"), $rev);
+               if (defined $form->field('revertmessage') &&
+                   length $form->field('revertmessage')) {
+                       $message=$form->field('revertmessage')."\n\n".$message;
+               }
+               my $r = $IkiWiki::hooks{rcs}{rcs_revert}{call}->($rev);
+               error $r if defined $r;
+               IkiWiki::disable_commit_hook();
+               IkiWiki::rcs_commit_staged(
+                       message => $message,
+                       session => $session,
+               );
+               IkiWiki::enable_commit_hook();
+       
+               require IkiWiki::Render;
+               IkiWiki::refresh();
+               IkiWiki::saveindex();
+       }
+       elsif ($form->submitted ne 'Cancel') {
+               $form->title(sprintf(gettext("confirm reversion of %s"), $rev));
+               $form->tmpl_param(diff => encode_entities(scalar IkiWiki::rcs_diff($rev)));
+               $form->field(name => "rev", type => "hidden", value => $rev, force => 1);
+               IkiWiki::showform($form, $buttons, $session, $q);
+               exit 0;
+       }
+
+       IkiWiki::redirect($q, urlto($config{recentchangespage}));
+       exit 0;
+}
+
 # Enable the recentchanges link.
 sub pagetemplate (@) {
        my %params=@_;
@@ -107,12 +178,21 @@ sub store ($$$) {
                        else {
                                $_->{link} = pagetitle($_->{page});
                        }
-                       $_->{baseurl}="$config{url}/" if length $config{url};
+                       $_->{baseurl}=IkiWiki::baseurl(undef) if length $config{url};
 
                        $_;
                } @{$change->{pages}}
        ];
        push @{$change->{pages}}, { link => '...' } if $is_excess;
+       
+       if (length $config{cgiurl} &&
+           exists $IkiWiki::hooks{rcs}{rcs_preprevert} &&
+           exists $IkiWiki::hooks{rcs}{rcs_revert}) {
+               $change->{reverturl} = IkiWiki::cgiurl(
+                       do => "revert",
+                       rev => $change->{rev}
+               );
+       }
 
        $change->{author}=$change->{user};
        my $oiduser=eval { IkiWiki::openiduser($change->{user}) };
@@ -146,7 +226,7 @@ sub store ($$$) {
                wikiname => $config{wikiname},
        );
        
-       $template->param(permalink => "$config{url}/$config{recentchangespage}/#change-".titlepage($change->{rev}))
+       $template->param(permalink => urlto($config{recentchangespage}, undef)."#change-".titlepage($change->{rev}))
                if exists $config{url};
        
        IkiWiki::run_hooks(pagetemplate => sub {
index 7296889ab28f21c9c642e468d503dc502428ede7..4ae0be8615852db38222ebd892fd5c216bd5b4bf 100644 (file)
@@ -28,18 +28,17 @@ sub format (@) {
 
        if (! ($params{content}=~s!^(<body[^>]*>)!$1.include_javascript($params{page})!em)) {
                # no <body> tag, probably in preview mode
-               $params{content}=include_javascript($params{page}, 1).$params{content};
+               $params{content}=include_javascript(undef).$params{content};
        }
        return $params{content};
 }
 
-sub include_javascript ($;$) {
-       my $page=shift;
-       my $absolute=shift;
+sub include_javascript ($) {
+       my $from=shift;
        
-       return '<script src="'.urlto("ikiwiki/ikiwiki.js", $page, $absolute).
+       return '<script src="'.urlto("ikiwiki/ikiwiki.js", $from).
                '" type="text/javascript" charset="utf-8"></script>'."\n".
-               '<script src="'.urlto("ikiwiki/relativedate.js", $page, $absolute).
+               '<script src="'.urlto("ikiwiki/relativedate.js", $from).
                '" type="text/javascript" charset="utf-8"></script>';
 }
 
index 95f148183cba558be65a95a9687992293d122839..bc481502a7dc8ecaa179e781d4a2c4dc3348d7b2 100644 (file)
@@ -42,9 +42,6 @@ sub check_canremove ($$$) {
                error(sprintf(gettext("%s is not a file"), $file));
        }
        
-       # Must be editable.
-       IkiWiki::check_canedit($page, $q, $session);
-
        # If a user can't upload an attachment, don't let them delete it.
        # This is sorta overkill, but better safe than sorry.
        if (! defined pagetype($pagesources{$page})) {
@@ -74,6 +71,7 @@ sub check_canremove ($$$) {
                        }
                }
        });
+       return defined $canremove ? $canremove : 1;
 }
 
 sub formbuilder_setup (@) {
@@ -102,7 +100,7 @@ sub confirmation_form ($$) {
                method => 'POST',
                javascript => 0,
                params => $q,
-               action => $config{cgiurl},
+               action => IkiWiki::cgiurl(),
                stylesheet => 1,
                fields => [qw{do page}],
        );
@@ -121,6 +119,7 @@ sub removal_confirm ($$@) {
        my @pages=@_;
 
        foreach my $page (@pages) {
+               IkiWiki::check_canedit($page, $q, $session);
                check_canremove($page, $q, $session);
        }
 
@@ -198,6 +197,7 @@ sub sessioncgi ($$) {
                        # and that the user is allowed to edit(/remove) it.
                        my @files;
                        foreach my $page (@pages) {
+                               IkiWiki::check_canedit($page, $q, $session);
                                check_canremove($page, $q, $session);
                                
                                # This untaint is safe because of the
@@ -240,7 +240,7 @@ sub sessioncgi ($$) {
                                if (! exists $pagesources{$parent}) {
                                        $parent="index";
                                }
-                               IkiWiki::redirect($q, urlto($parent, '/', 1));
+                               IkiWiki::redirect($q, urlto($parent));
                        }
                }
                else {
index 61d39d4b568d74b3766984f585862ae698b9957b..57747d3c9df00141a1ade61e823c453a2ecbcc33 100644 (file)
@@ -108,6 +108,7 @@ sub check_canrename ($$$$$$) {
                        }
                }
        });
+       return defined $canrename ? $canrename : 1;
 }
 
 sub rename_form ($$$) {
@@ -125,7 +126,7 @@ sub rename_form ($$$) {
                method => 'POST',
                javascript => 0,
                params => $q,
-               action => $config{cgiurl},
+               action => IkiWiki::cgiurl(),
                stylesheet => 1,
                fields => [qw{do page new_name attachment}],
        );
@@ -573,11 +574,10 @@ sub fixlinks ($$$) {
                                eval { writefile($file, $config{srcdir}, $content) };
                                next if $@;
                                my $conflict=IkiWiki::rcs_commit(
-                                       $file,
-                                       sprintf(gettext("update for rename of %s to %s"), $rename->{srcfile}, $rename->{destfile}),
-                                       $token,
-                                       $session->param("name"),
-                                       $session->remote_addr(),
+                                       file => $file,
+                                       message => sprintf(gettext("update for rename of %s to %s"), $rename->{srcfile}, $rename->{destfile}),
+                                       token => $token,
+                                       session => $session,
                                );
                                push @fixedlinks, $page if ! defined $conflict;
                        }
index 8fb9dff0ca082bb16b6332c052e848408db162b8..78eb750b5f670caabe5840a51f589319eccf1204 100644 (file)
@@ -58,7 +58,7 @@ sub pagetemplate (@) {
        if ($template->query(name => "searchform")) {
                if (! defined $form) {
                        my $searchform = template("searchform.tmpl", blind_cache => 1);
-                       $searchform->param(searchaction => $config{cgiurl});
+                       $searchform->param(searchaction => IkiWiki::cgiurl());
                        $searchform->param(html5 => $config{html5});
                        $form=$searchform->output;
                }
@@ -176,7 +176,7 @@ sub cgi ($) {
                # only works for GET requests
                chdir("$config{wikistatedir}/xapian") || error("chdir: $!");
                $ENV{OMEGA_CONFIG_FILE}="./omega.conf";
-               $ENV{CGIURL}=$config{cgiurl},
+               $ENV{CGIURL}=IkiWiki::cgiurl();
                IkiWiki::loadindex();
                $ENV{HELPLINK}=htmllink("", "", "ikiwiki/searching",
                        noimageinline => 1, linktext => "Help");
index 341d678679b65706b6189d509d06e0fd77f07772..7974d5e5325f396a6bd90cc446e239bed9a0c44f 100644 (file)
@@ -73,7 +73,11 @@ sub refresh () {
 }
 
 sub needsbuild ($) {
+       my $needsbuild=shift;
+
        debug("skeleton plugin needsbuild");
+
+       return $needsbuild;
 }
 
 sub preprocess (@) {
index 62e42767c99a48170ddb58c1473b8b49131ad24b..b038b2f9a662358c015806bd22a7159c51b922c6 100644 (file)
@@ -7,6 +7,7 @@ no warnings;
 
 sub import {
        hook(type => "getsetup", id => "sortnaturally", call => \&getsetup);
+       hook(type => "checkconfig", id => "sortnaturally", call => \&checkconfig);
 }
 
 sub getsetup {
index 2edd1eacd11a329d71d81add93c431462685ef03..f3c425a37dacd9d1389f0c53a0d7fbc52469c70b 100644 (file)
@@ -40,6 +40,9 @@ sub preprocess (@) {
                # scan that file too.
                return unless exists $params{file};
 
+               # Preprocess in scan-only mode.
+               IkiWiki::preprocess($params{page}, $params{page}, $params{data}, 1);
+
                IkiWiki::run_hooks(scan => sub {
                        shift->(
                                page => $params{page},
@@ -47,9 +50,6 @@ sub preprocess (@) {
                        );
                });
 
-               # Preprocess in scan-only mode.
-               IkiWiki::preprocess($params{page}, $params{page}, $params{data}, 1);
-
                return;
        }
 
index db26bfe315a254ddc8bdafef07abf83c4a819deb..3df06e652eeee285d51690b9d2178d6e0fb2b8ca 100644 (file)
@@ -41,12 +41,9 @@ sub preprocess (@) {
                        blind_cache => 1);
        };
        if ($@) {
-               error gettext("failed to process template:")." $@";
-       }
-       if (! $template) {
-               error sprintf(gettext("%s not found"),
+               error sprintf(gettext("failed to process template %s"),
                        htmllink($params{page}, $params{destpage},
-                               "/templates/$params{id}"))
+                               "/templates/$params{id}"))." $@";
        }
 
        $params{basename}=IkiWiki::basename($params{page});
index 521af499fc77323870951883b49736509081cd8f..195792acaa593bd627626061c4d5cfac6f31aa72 100644 (file)
@@ -13,6 +13,7 @@ use IkiWiki 3.00;
 
 my $default_prefix = <<EOPREFIX;
 \\documentclass{article}
+\\usepackage[utf8]{inputenc}
 \\usepackage{amsmath}
 \\usepackage{amsfonts}
 \\usepackage{amssymb}
index 03b0816ed6fc5a6c42f0da916d898c6633eb7d15..ee94547e90c51dad608b020e1be6bc0a434d38d7 100644 (file)
@@ -60,6 +60,7 @@ sub needsbuild ($) {
                
                $wikistate{theme}{currenttheme}=$config{theme};
        }
+       return $needsbuild;
 }
 
 1
index 1f93f87fe5f714e4b22e195cdc9b780311c14c65..af4d2ba3a858774ac6b77be58479fb2a4a18d69c 100644 (file)
@@ -70,19 +70,18 @@ sub format (@) {
                $params{content}=~s/<div class="toggleableend">//g;
                if (! ($params{content}=~s!^(<body[^>]*>)!$1.include_javascript($params{page})!em)) {
                        # no <body> tag, probably in preview mode
-                       $params{content}=include_javascript($params{page}, 1).$params{content};
+                       $params{content}=include_javascript(undef).$params{content};
                }
        }
        return $params{content};
 }
 
-sub include_javascript ($;$) {
-       my $page=shift;
-       my $absolute=shift;
+sub include_javascript ($) {
+       my $from=shift;
        
-       return '<script src="'.urlto("ikiwiki/ikiwiki.js", $page, $absolute).
+       return '<script src="'.urlto("ikiwiki/ikiwiki.js", $from).
                '" type="text/javascript" charset="utf-8"></script>'."\n".
-               '<script src="'.urlto("ikiwiki/toggle.js", $page, $absolute).
+               '<script src="'.urlto("ikiwiki/toggle.js", $from).
                '" type="text/javascript" charset="utf-8"></script>';
 }
 
index 0d9a0b35bd8abf6be895c4d1ce85f64a6077ded1..fcfb68be90891fca4a46ef512b43548362ffb9e1 100644 (file)
@@ -17,6 +17,7 @@ sub import {
        hook(type => "getsetup", id => "txt", call => \&getsetup);
        hook(type => "filter", id => "txt", call => \&filter);
        hook(type => "htmlize", id => "txt", call => \&htmlize);
+       hook(type => "htmlizeformat", id => "txt", call => \&htmlizeformat);
 
        eval q{use URI::Find};
        if (! $@) {
@@ -46,25 +47,42 @@ sub filter (@) {
                        will_render($params{page}, 'robots.txt');
                        writefile('robots.txt', $config{destdir}, $content);
                }
-
-               encode_entities($content, "<>&");
-               if ($findurl) {
-                       my $finder = URI::Find->new(sub {
-                               my ($uri, $orig_uri) = @_;
-                               return qq|<a href="$uri">$orig_uri</a>|;
-                       });
-                       $finder->find(\$content);
-               }
-               $content = "<pre>" . $content . "</pre>";
+               return txt2html($content);
        }
 
        return $content;
 }
 
+sub txt2html ($) {
+       my $content=shift;
+       
+       encode_entities($content, "<>&");
+       if ($findurl) {
+               my $finder = URI::Find->new(sub {
+                       my ($uri, $orig_uri) = @_;
+                       return qq|<a href="$uri">$orig_uri</a>|;
+               });
+               $finder->find(\$content);
+       }
+       return "<pre>" . $content . "</pre>";
+}
+
 # We need this to register the .txt file extension
 sub htmlize (@) {
        my %params=@_;
        return $params{content};
 }
 
+sub htmlizeformat ($$) {
+       my $format=shift;
+       my $content=shift;
+
+       if ($format eq 'txt') {
+               return txt2html($content);
+       }
+       else {
+               return;
+       }
+}
+
 1
index c13643478ab25012c5aacab3f0c9ca43aa2b2689..fc265526c15e41682efec8c7702d3a54e5efcf17 100644 (file)
@@ -37,6 +37,7 @@ sub needsbuild (@) {
                        }
                }
        }
+       return $needsbuild;
 }
 
 sub preprocess (@) {
index 11b4428e3fc0a55f6637516c56b2dca8a7460163..6a51903016830c17339f2130a964f87708ae15b0 100644 (file)
@@ -219,7 +219,8 @@ sub showfields ($$$@) {
                                options => [ [ 1 => $description ] ],
                                fieldset => $section,
                        );
-                       if (! $form->submitted) {
+                       if (! $form->submitted ||
+                           ($info{advanced} && $form->submitted eq 'Advanced Mode')) {
                                $form->field(name => $name, value => $value);
                        }
                }
@@ -287,7 +288,7 @@ sub showform ($$) {
                fieldsets => [
                        [main => gettext("main")], 
                ],
-               action => $config{cgiurl},
+               action => IkiWiki::cgiurl(),
                template => {type => 'div'},
                stylesheet => 1,
        );
@@ -295,6 +296,7 @@ sub showform ($$) {
        $form->field(name => "do", type => "hidden", value => "setup",
                force => 1);
        $form->field(name => "rebuild_asked", type => "hidden");
+       $form->field(name => "showadvanced", type => "hidden");
 
        if ($form->submitted eq 'Basic Mode') {
                $form->field(name => "showadvanced", type => "hidden", 
@@ -342,7 +344,7 @@ sub showform ($$) {
        IkiWiki::decode_form_utf8($form);
        
        if ($form->submitted eq "Cancel") {
-               IkiWiki::redirect($cgi, $config{url});
+               IkiWiki::redirect($cgi, IkiWiki::baseurl(undef));
                return;
        }
        elsif (($form->submitted eq 'Save Setup' || $form->submitted eq 'Rebuild Wiki') && $form->validate) {
@@ -473,7 +475,7 @@ sub showform ($$) {
                                                join(" ", @command), $ret).
                                        '</p>';
                                open(OUT, ">", $config{setupfile}) || error("$config{setupfile}: $!");
-                               print OUT $oldsetup;
+                               print OUT Encode::encode_utf8($oldsetup);
                                close OUT;
                        }
 
index 71d7c9d17f51e49ec17aee087e984f3e8a7b9b79..134cfb9101b51d48bbabc6a47b7aaba1b73ff699 100644 (file)
@@ -31,14 +31,13 @@ sub formbuilder_setup (@) {
                        $form->field("do") eq "comment";
 
        $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
-               include_javascript(undef, 1));
+               include_javascript(undef));
 }
 
-sub include_javascript ($;$) {
-       my $page=shift;
-       my $absolute=shift;
+sub include_javascript ($) {
+       my $from=shift;
 
-       my $wmdjs=urlto("wmd/wmd.js", $page, $absolute);
+       my $wmdjs=urlto("wmd/wmd.js", $from);
        return <<"EOF"
 <script type="text/javascript">
 wmd_options = {
index fdd463025457f918458168a2671f7c97dd2a37ab..c73adfbbb84b34462eaa474ca315570aba85cc44 100644 (file)
@@ -48,10 +48,10 @@ EOF
 
 sub test () {
        exit 0 if trusted();
-       
+
        IkiWiki::lockwiki();
        IkiWiki::loadindex();
-       
+
        # Dummy up a cgi environment to use when calling check_canedit
        # and friends.
        eval q{use CGI};
@@ -72,63 +72,12 @@ sub test () {
                        regdate => time,
                }) || error("failed adding user");
        }
-       
-       my %newfiles;
-
-       foreach my $change (IkiWiki::rcs_receive()) {
-               # This untaint is safe because we check file_pruned and
-               # wiki_file_regexp.
-               my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
-               $file=IkiWiki::possibly_foolish_untaint($file);
-               if (! defined $file || ! length $file ||
-                   IkiWiki::file_pruned($file)) {
-                       error(gettext("bad file name %s"), $file);
-               }
-
-               my $type=pagetype($file);
-               my $page=pagename($file) if defined $type;
-               
-               if ($change->{action} eq 'add') {
-                       $newfiles{$file}=1;
-               }
-
-               if ($change->{action} eq 'change' ||
-                   $change->{action} eq 'add') {
-                       if (defined $page) {
-                               if (IkiWiki->can("check_canedit")) {
-                                       IkiWiki::check_canedit($page, $cgi, $session);
-                                       next;
-                               }
-                       }
-                       else {
-                               if (IkiWiki::Plugin::attachment->can("check_canattach")) {
-                                       IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path});
-                                       next;
-                               }
-                       }
-               }
-               elsif ($change->{action} eq 'remove') {
-                       # check_canremove tests to see if the file is present
-                       # on disk. This will fail is a single commit adds a
-                       # file and then removes it again. Avoid the problem
-                       # by not testing the removal in such pairs of changes.
-                       # (The add is still tested, just to make sure that
-                       # no data is added to the repo that a web edit
-                       # could not add.)
-                       next if $newfiles{$file};
-
-                       if (IkiWiki::Plugin::remove->can("check_canremove")) {
-                               IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session);
-                               next;
-                       }
-               }
-               else {
-                       error "unknown action ".$change->{action};
-               }
-               
-               error sprintf(gettext("you are not allowed to change %s"), $file);
-       }
 
+       IkiWiki::check_canchange(
+               cgi => $cgi,
+               session => $session,
+               changes => [IkiWiki::rcs_receive()]
+       );
        exit 0;
 }
 
index 9921915b49ddd96a4ce2970653d205d99a568b1a..8e8336b994070f442061e8bc2929525a77033549 100644 (file)
@@ -5,7 +5,6 @@ package IkiWiki;
 use warnings;
 use strict;
 use IkiWiki;
-use Encode;
 
 my (%backlinks, %rendered);
 our %brokenlinks;
@@ -94,7 +93,8 @@ sub genpage ($$) {
        }
        if (defined $config{historyurl} && length $config{historyurl}) {
                my $u=$config{historyurl};
-               $u=~s/\[\[file\]\]/$pagesources{$page}/g;
+               my $p=uri_escape_utf8($pagesources{$page});
+               $u=~s/\[\[file\]\]/$p/g;
                $template->param(historyurl => $u);
                $actions++;
        }
@@ -759,7 +759,10 @@ sub refresh () {
        my ($new, $internal_new)=find_new_files($files);
        my ($del, $internal_del)=find_del_files($pages);
        my ($changed, $internal_changed)=find_changed($files);
-       run_hooks(needsbuild => sub { shift->($changed) });
+       run_hooks(needsbuild => sub {
+               my $ret=shift->($changed, [@$del, @$internal_del]);
+               $changed=$ret if ref $ret eq 'ARRAY';
+       });
        my $oldlink_targets=calculate_old_links($changed, $del);
 
        foreach my $file (@$changed) {
index 927368fae964d678ab04aa866154b61677f80176..5eb96f4ae0d168598fe9d6a54a644294fbcb517a 100644 (file)
@@ -128,7 +128,7 @@ EOF
 #include <sys/file.h>
 
 extern char **environ;
-char *newenviron[$#envsave+6];
+char *newenviron[$#envsave+7];
 int i=0;
 
 void addenv(char *var, char *val) {
@@ -147,6 +147,7 @@ $check_commit_hook
 @wrapper_hooks
 $envsave
        newenviron[i++]="HOME=$ENV{HOME}";
+       newenviron[i++]="PATH=$ENV{PATH}";
        newenviron[i++]="WRAPPED_OPTIONS=$configstring";
 
 #ifdef __TINYC__
index 4b2e2854485de200f9ccebabd6b80686795f5f97..7906f65934f5cf549b697c507b7321b7b97bafcb 100755 (executable)
@@ -13,6 +13,18 @@ pure_install:: extra_install
 
 VER=$(shell perl -e '$$_=<>;print m/\((.*?)\)/'<debian/changelog)
 
+# Parameterized programs used by Makefile.
+FIND?=find
+SED?=sed
+
+# Additional configurable path variables.
+W3M_CGI_BIN?=$(PREFIX)/lib/w3m/cgi-bin
+
+tflag=$(shell if [ -n "$$NOTAINT" ] && [ "$$NOTAINT" != 1 ]; then printf -- "-T"; fi)
+extramodules=$(shell if [ "$$PROFILE" = 1 ]; then printf -- "-d:NYTProf"; fi)
+outprogs=ikiwiki.out ikiwiki-transition.out ikiwiki-calendar.out
+scripts=ikiwiki-update-wikilist ikiwiki-makerepo
+
 PROBABLE_INST_LIB=$(shell \\
        if [ "$(INSTALLDIRS)" = "perl" ]; then \\
                echo $(INSTALLPRIVLIB); \\
@@ -23,14 +35,6 @@ PROBABLE_INST_LIB=$(shell \\
        fi \\
 )
 
-# Additional configurable path variables.
-W3M_CGI_BIN?=$(PREFIX)/lib/w3m/cgi-bin
-
-tflag=$(shell if [ -n "$$NOTAINT" ] && [ "$$NOTAINT" != 1 ]; then printf -- "-T"; fi)
-extramodules=$(shell if [ "$$PROFILE" = 1 ]; then printf -- "-d:NYTProf"; fi)
-outprogs=ikiwiki.out ikiwiki-transition.out ikiwiki-calendar.out
-scripts=ikiwiki-update-wikilist ikiwiki-makerepo
-
 %.out: %.in
        ./pm_filter $(PREFIX) $(VER) $(PROBABLE_INST_LIB) < $< > $@
        chmod +x $@
@@ -46,7 +50,7 @@ extra_build: $(outprogs) ikiwiki.setup docwiki
        ./mdwn2man ikiwiki-update-wikilist 1 doc/ikiwiki-update-wikilist.mdwn > ikiwiki-update-wikilist.man
        ./mdwn2man ikiwiki-calendar 1 doc/ikiwiki-calendar.mdwn > ikiwiki-calendar.man
        $(MAKE) -C po
-       sed -i.bkp "s/Version:.*/Version: $$(perl -e '$$_=<>;print m/\((.*?)\)/'<debian/changelog)/" ikiwiki.spec
+       $(SED) -i.bkp "s/Version:.*/Version: $$(perl -e '$$_=<>;print m/\((.*?)\)/'<debian/changelog)/" ikiwiki.spec
        rm -f ikiwiki.spec.bkp
        
 docwiki:
@@ -63,9 +67,9 @@ myclean: clean
 
 underlay_install:
        install -d $(DESTDIR)$(PREFIX)/share/ikiwiki
-       for dir in `cd underlays && find . -follow -type d ! -regex '.*\.svn.*'`; do \
+       for dir in `cd underlays && $(FIND) . -follow -type d ! -regex '.*\.svn.*'`; do \
                install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
-               for file in `find underlays/$$dir -follow -maxdepth 1 -type f`; do \
+               for file in `$(FIND) underlays/$$dir -follow -maxdepth 1 -type f`; do \
                        cp -aL $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir 2>/dev/null || \
                        install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
                done; \
@@ -80,12 +84,15 @@ underlay_install:
                fi \
        done
 
-       # Themes have their style.css appended to the normal one.
+       # Themes have their base.css (if present) and then
+       # style.css appended to the normal one.
        for theme in themes/*; do \
                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 $$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 \
                                cp -aL $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$file 2>/dev/null || \
                                install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$file; \
@@ -95,26 +102,26 @@ underlay_install:
 
 extra_install: underlay_install
        # Install example sites.
-       for dir in `cd doc/examples; find . -type d ! -regex '.*\.svn.*'`; do \
+       for dir in `cd doc/examples; $(FIND) . -type d ! -regex '.*\.svn.*'`; do \
                install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$dir; \
        done
-       for file in `cd doc/examples; find . -type f ! -regex '.*\.svn.*'`; do \
+       for file in `cd doc/examples; $(FIND) . -type f ! -regex '.*\.svn.*'`; do \
                cp -aL doc/examples/$$file $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$file 2>/dev/null || \
                install -m 644 doc/examples/$$file $(DESTDIR)$(PREFIX)/share/ikiwiki/examples/$$file; \
        done
 
-       for dir in `find templates -follow -type d ! -regex '.*\.svn.*'`; do \
+       for dir in `$(FIND) templates -follow -type d ! -regex '.*\.svn.*'`; do \
                install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
-               for file in `find $$dir -follow -maxdepth 1 -type f`; do \
+               for file in `$(FIND) $$dir -follow -maxdepth 1 -type f`; do \
                        install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
                done; \
        done
        
        install -d $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins
-       for file in `find plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* -name \*.py`; do \
+       for file in `$(FIND) plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* -name \*.py`; do \
                install -m 644 $$file $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins; \
        done
-       for file in `find plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* ! -name \*.py ! -name \*.pyc`; do \
+       for file in `$(FIND) plugins -maxdepth 1 -type f ! -path plugins/.\* ! -name \*demo\* ! -name \*.py ! -name \*.pyc`; do \
                install -m 755 $$file $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins; \
        done
 
@@ -136,7 +143,7 @@ extra_install: underlay_install
 
        install -d $(DESTDIR)$(PREFIX)/bin
        for prog in $(outprogs) $(scripts); do \
-               install $$prog $(DESTDIR)$(PREFIX)/bin/$$(echo $$prog | sed 's/\.out//'); \
+               install $$prog $(DESTDIR)$(PREFIX)/bin/$$(echo $$prog | $(SED) 's/\.out//'); \
        done
 
        $(MAKE) -C po install DESTDIR=$(DESTDIR) PREFIX=$(PREFIX)
diff --git a/README b/README
index 7efc59a519626c77439cb9afcb4894068e9e394e..611b9a45bf8188d6bf5e3bb48ac9745d67322a37 100644 (file)
--- a/README
+++ b/README
@@ -14,6 +14,10 @@ A few special variables you can set while using the Makefile.PL:
   unless your perl is less buggy than mine -- see
   http://bugs.debian.org/411786)
 
+  MAKE, FIND, and SED can be used to specify where you have the GNU
+  versions of those tools installed, if the normal make, find, and sed
+  are not GNU.
+
   There are also other variables supported by MakeMaker, including PREFIX,
   INSTALL_BASE, and DESTDIR. See ExtUtils::MakeMaker(3).
 
index 980074ec3affe8a7426586166903a1c9884361ed..0eb83ded614a2b4e2b2397bf8d2db897984317db 100644 (file)
@@ -36,7 +36,7 @@ IkiWiki::Setup::Automator->import(
        cgiurl => "http://$domain/~$ENV{USER}/$wikiname_short/ikiwiki.cgi",
        cgi_wrapper => "$ENV{HOME}/public_html/$wikiname_short/ikiwiki.cgi",
        adminemail => "$ENV{USER}\@$domain",
-       add_plugins => [qw{goodstuff websetup comments opendiscussion blogspam calendar sidebar}],
+       add_plugins => [qw{goodstuff websetup comments blogspam calendar sidebar}],
        disable_plugins => [qw{}],
        libdir => "$ENV{HOME}/.ikiwiki",
        rss => 1,
@@ -49,6 +49,6 @@ IkiWiki::Setup::Automator->import(
        archive_pagespec => "page(posts/*) and !*/Discussion",
        global_sidebars => 0,
        discussion => 0,
-       locked_pages => "*",
+       locked_pages => "* and !postcomment(*)",
        tagbase => "tags",
 )
index fb445a3fffdbaa93f9ea58aadf43659aa84a6384..ea6356f724145940221eafff66e7905cf90c673d 100644 (file)
@@ -1,4 +1,142 @@
-ikiwiki (3.20100816) UNRELEASED; urgency=low
+ikiwiki (3.20101202) UNRELEASED; urgency=low
+
+  * Better support for serving the same site on multiple urls. (Such as
+    a http and a https url, or a ipv4 and an ipv6 url.)
+    (Thanks, smcv)
+  * API: urlto without a defined second parameter now generates an url
+    that starts with "/" (when possible; eg when the site's url and cgiurl
+    are on the same domain).
+  * Now when users log in via https, ikiwiki sends a secure cookie, that can
+    only be used over https. If the user switches to using http, they will
+    need to re-login. (smcv)
+  * inline: Display feed buttons for nested inlines, linking to the inlined
+    page's feed. (Giuseppe Bilotta)
+  * goldtype: New theme, based on blueview, contributed by Lars Wirzenius.
+
+ -- Joey Hess <joeyh@debian.org>  Mon, 29 Nov 2010 14:44:13 -0400
+
+ikiwiki (3.20101201) unstable; urgency=low
+
+  * meta: Fix calling of htmlscrubber to pass the page parameter.
+    The change of the htmlscrubber to look at page rather than destpage
+    caused htmlscrubber_skip to not work for meta directives.
+
+ -- Joey Hess <joeyh@debian.org>  Wed, 01 Dec 2010 20:28:01 -0400
+
+ikiwiki (3.20101129) unstable; urgency=low
+
+  * websetup: Fix encoding problem when restoring old setup file.
+  * more: Add pages parameter to limit where the more is displayed.
+    (thanks, dark)
+  * Fix escaping of filenames in historyurl. (Thanks, aj)
+  * inline: Improve RSS url munging to use a proper html parser,
+    and support all elements that HTML::Tagset knows about. 
+    (Which doesn't include html5 just yet, but then the old version
+    didn't either.) Bonus: 4 times faster than old regexp method.
+  * Optimise glob() pagespec. (Thanks, Kathryn and smcv)
+  * highlight: Support new format of filetypes.conf used by version 3.2
+    of the highlight package.
+  * edittemplate: Fix crash if using a .tmpl file or other non-page file
+    as a template for a new page.
+  * git: Fix temp file location.
+  * rename: Fix to pass named parameters to rcs_commit.
+  * git: Avoid adding files when committing, so as not to implicitly add
+    files like recentchanges files that are not normally checked in,
+    when fixing links after rename.
+
+ -- Joey Hess <joeyh@debian.org>  Mon, 29 Nov 2010 13:59:10 -0400
+
+ikiwiki (3.20101112) unstable; urgency=HIGH
+
+  * txt: Fix display when used inside a format directive.
+  * highlight: Ensure that other, more-specific format plugins,
+    like txt are used in preference to this one in case of ties.
+  * htmltidy, sortnaturally: Add missing checkconfig hook
+    registration. Closes: #601912
+    (Thanks, Craig Lennox and Tuomas Jormola)
+  * git: Use author date, not committer date. Closes: #602012
+    (Thanks, Tuomas Jormola)
+  * Fix htmlscrubber_skip to be matched on the source page, not the page it is
+    inlined into. Should allow setting to "* and !comment(*)" to scrub
+    comments, but leave your blog posts unscrubbed, etc. CVE-2010-1673
+  * comments: Make postcomment() pagespec work when previewing a comment,
+    including during moderation. CVE-2010-1673
+  * comments: Make comment() pagespec also match comments that are being
+    posted. CVE-2010-1673
+
+ -- Joey Hess <joeyh@debian.org>  Fri, 12 Nov 2010 00:36:06 -0400
+
+ikiwiki (3.20101023) unstable; urgency=low
+
+  * Fix typo that broke anonymous git push.
+  * Fix web reversion when the srcdir is in a subdir of the git repo.
+
+ -- Joey Hess <joeyh@debian.org>  Sat, 23 Oct 2010 16:36:50 -0400
+
+ikiwiki (3.20101019) unstable; urgency=low
+
+  * Fix test suite failure on other side of date line.
+  * htmltidy: Allow configuring tidy parameters in setup file.
+    (W. Trevor King)
+  * Updated French program translation. Closes: #598918
+  * git: Added new rcs_revert and rcs_preprevert hooks.
+  * recentchanges: Add revert buttons to RecentChanges page, and
+    implement web-based reversion interface.
+  * Thanks to Peter Gammie for his assistance with the web-based reversion
+    feature.
+  * actiontabs: More consistent styling of Hn tags.
+  * websetup: Fix saving of advanced mode changes.
+  * websetup: Fix defaults of checkboxes in advanced mode.
+  * monotone: Fix recentchanges page when the srcdir is not at the top
+    of the monotone workspace. Thanks, tommyd.
+  * img: If a class is specified, don't also put the img in the img
+    class.
+  * auto-blog.setup: Don't enable opendiscussion by default; require users be
+    logged in to post comments.
+
+ -- Joey Hess <joeyh@debian.org>  Tue, 19 Oct 2010 02:32:23 -0400
+
+ikiwiki (3.20100926) unstable; urgency=low
+
+  * meta: Ensure that the url specified by xrds-location is absolute.
+  * attachment: Fix attachment file size display.
+  * Propigate PATH into wrapper.
+  * htmlbalance: Fix compatibility with HTML::Tree 4.0. (smcv)
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 26 Sep 2010 23:02:54 -0400
+
+ikiwiki (3.20100915) unstable; urgency=low
+
+  * needsbuild hook interface changed; the hooks should now return
+    the modified array of things that need built. (Backwards compatibility
+    code keeps plugins using the old interface working.)
+  * Remove PATH overriding code in ikiwiki script that was present to make
+    perl taint checking happy, but taint checking is disabled.
+  * teximg: Use Unicode UTF-8 encoding by default. Closes: #596067
+    Thanks, Paul Menzel.
+  * po: Make the po_master_language use a langpair like "en|English",
+    so it can be configured via the web.
+  * po: Allow enabling via web setup.
+  * po: Auto-upgrade old format settings to new formats when writing
+    setup file.
+  * Pass array of names of files that have been deleted to needsbuild hook
+    as second parameter, to allow for plugins that needs access to this
+    information earlier than the delete hook.
+  * actiontabs: Improve tab padding.
+  * blueview: Fix display of links to translated pages in the page header.
+  * Set isPermaLink="no" for guids in rss feeds. 
+  * blogspam: Fix crash when content contained utf-8.
+  * external: Disable RPC::XML's "smart" encoding, which sent ints
+    for strings that contained only a number, fixing a longstanding crash
+    of the rst plugin.
+  * git: When updating from remote, use git pull --prune, to avoid possible
+    errors from conflicting obsolete remote branches.
+  * cutpaste: Fix bug that occured in some cases involving inlines when
+    text was pasted on a page before being cut.
+
+ -- Joey Hess <joeyh@debian.org>  Wed, 15 Sep 2010 16:29:01 -0400
+
+ikiwiki (3.20100831) unstable; urgency=low
 
   * filecheck: Fall back to using the file command if the freedesktop
     magic file cannot identify a file.
@@ -10,8 +148,23 @@ ikiwiki (3.20100816) UNRELEASED; urgency=low
     the bug and providing access to debug it.
   * style.css: Use relative, not absolute font sizes. Thanks, Giuseppe Bilotta.
   * htmlscrubber: Do not scrub url anchors that contain colons.
-
- -- Joey Hess <joeyh@debian.org>  Sun, 15 Aug 2010 11:45:48 -0400
+  * Danish translation update. Closes: #594673
+  * highlight: Make location of highlight's files configurable in setup
+    file to allow for nonstandard installations.
+  * Allow "link(.)" and similar PageSpecs. Thanks, Giuseppe Bilotta.
+  * Run the preprocess hooks in scan mode *before* the scan hooks.
+    This allows the po plugin to register a scan hook that runs
+    last and rescans pages after all data from the first scan pass is
+    completed. This avoids the po plugin needing to rebuild some pages.
+    (intrigeri)
+  * po: Fix some bugs that affected l10n.ikiwiki.info's unusual
+    setup. (intrigeri)
+  * t/bazaar.t: Work around bzr 2.2.0's new requirement to configure
+    bzr whoami before committing.
+  * httpauth: Avoid redirecting the user to the cgiauthurl if
+    they already have a login session.
+
+ -- Joey Hess <joeyh@debian.org>  Tue, 31 Aug 2010 14:22:47 -0400
 
 ikiwiki (3.20100815) unstable; urgency=medium
 
index 049a685b0d7fc3ce9b912f0e8f011b6d08533c5d..71c9e18bbf9bf09c818d65f15010d54f470b9ae1 100644 (file)
@@ -10,7 +10,7 @@ Build-Depends-Indep: dpkg-dev (>= 1.9.0), libxml-simple-perl,
   libfile-chdir-perl,
 Maintainer: Joey Hess <joeyh@debian.org>
 Uploaders: Josh Triplett <josh@freedesktop.org>
-Standards-Version: 3.9.0
+Standards-Version: 3.9.1
 Homepage: http://ikiwiki.info/
 Vcs-Git: git://git.ikiwiki.info/
 Vcs-Browser: http://git.ikiwiki.info/?p=ikiwiki
@@ -32,7 +32,7 @@ Suggests: viewvc | gitweb | viewcvs, libsearch-xapian-perl,
   xapian-omega (>= 1.0.5), librpc-xml-perl, libtext-wikiformat-perl,
   python, python-docutils, polygen, tidy, libhtml-tree-perl,
   libxml-feed-perl, libmailtools-perl, perlmagick,
-  libfile-mimeinfo-perl, libcrypt-ssleay-perl,
+  libfile-mimeinfo-perl, file, libcrypt-ssleay-perl,
   liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl,
   libtext-csv-perl, graphviz, libnet-amazon-s3-perl,
   libsparkline-php, texlive, dvipng, libtext-wikicreole-perl,
index 74391e2cfe6dc870339dd35ff66e4ffc22bd520e..300dd110b1b5e1489ecc6d8a934ae4f595d2462f 100644 (file)
@@ -214,6 +214,10 @@ Files: underlays/themes/blueview/*
 Copyright: © 2009,2010 Bernd Zeimetz
 License: GPL-2+
 
+Files: underlays/themes/goldtype/*
+Copyright: © Lars Wirzenius
+License: GPL-2+
+
 License: BSD-C2
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
index e478d98c32e0d5c615621020213d7d9efde03bbd..8508d0dcd6df94e3cc07da36c5139e87274f2e0a 100644 (file)
@@ -1,5 +1,15 @@
 Lighttpd apparently sets REDIRECT_STATUS=200 for the server.error-handler-404 page. This breaks the [[plugins/404]] plugin which checks this variable for 404 before processing the URI. It also doesn't seem to set REDIRECT_URL.
 
+> For what it's worth, the first half is <http://redmine.lighttpd.net/issues/1828>.
+> One workaround would be to make this script your 404 handler:
+>
+>     #!/bin/sh
+>     REDIRECT_STATUS=404; export REDIRECT_STATUS
+>     REDIRECT_URL="$SERVER_NAME$REQUEST_URI"; export REDIRECT_URL
+>     exec /path/to/your/ikiwiki.cgi "$@"
+>
+> --[[smcv]]
+
 I was able to fix my server to check the REQUEST_URI for ikiwiki.cgi and to continue processing if it was not found, passing $ENV{SEVER_NAME} . $ENV{REQUEST_URI} as the first parameter to cgi_page_from_404. However, my perl is terrible and I just made it work rather than figuring out exactly what to do to get it to work on both lighttpd and apache.
 
 This is with lighttpd 1.4.19 on Debian.
diff --git a/doc/bugs/Error:_no_text_was_copied_in_this_page_--_missing_page_dependencies.mdwn b/doc/bugs/Error:_no_text_was_copied_in_this_page_--_missing_page_dependencies.mdwn
new file mode 100644 (file)
index 0000000..0082eed
--- /dev/null
@@ -0,0 +1,46 @@
+That one has bitten me for some time; here is the minimal testcase.  There is
+also an equivalent (I suppose) problem when using another plugin, but I hope
+it's enough to track it down for this one.
+
+    $ tar -xj < [bug-dep_order.tar.bz2](http://schwinge.homeip.net/~thomas/tmp/bug-dep_order.tar.bz2)
+    $ cd bug-dep_order/
+    $ ./render_locally
+    [...]
+    $ find "$PWD".rendered/ -print0 | xargs -0 grep 'no text was copied'
+    $ [no output]
+    $ touch news/2010-07-31.mdwn 
+    $ ./render_locally 
+    refreshing wiki..
+    scanning news/2010-07-31.mdwn
+    building news/2010-07-31.mdwn
+    building news.mdwn, which depends on news/2010-07-31
+    building index.mdwn, which depends on news/2010-07-31
+    done
+    $ find "$PWD".rendered/ -print0 | xargs -0 grep 'no text was copied'
+    /home/thomas/tmp/hurd-web/bug-dep_order.rendered/news.html:<p>[[!paste <span class="error">Error: no text was copied in this page</span>]]</p>
+    /home/thomas/tmp/hurd-web/bug-dep_order.rendered/news.html:<p>[[!paste <span class="error">Error: no text was copied in this page</span>]]</p>
+
+This error shows up only for *news.html*, but not in *news/2010-07-31* or for
+the aggregation in *index.html* or its RSS and atom files.
+
+--[[tschwinge]]
+
+> So the cutpaste plugin, in order to support pastes
+> that come before the corresponding cut in the page,
+> relies on the scan hook being called for the page
+> before it is preprocessed.
+> 
+> In the case of an inline, this doesn't happen, if
+> the page in question has not changed.
+> 
+> Really though it's not just inline, it's potentially anything
+> that preprocesses content. None of those things guarantee that
+> scan gets re-run on it first. 
+> 
+> I think cutpaste is going beyond the intended use of scan hooks,
+> which is to gather link information, not do arbitrary data collection.
+> Requiring scan be run repeatedly could be a lot more work.
+> 
+> Using `%pagestate` to store the cut content when scanning would be 
+> one way to fix this bug. It would mean storing potentially big chunks 
+> of page content in the indexdb. [[done]] --[[Joey]]  
index 1b9cb2e2d42377f8499792c34c9665610a0b2cf8..275661fb89cca3775cf43a83f1569513ad77708f 100644 (file)
@@ -1 +1,3 @@
 The [[plugins/highlight]] plugin hard codes some paths up the top of the plugin.  This means that you need to edit the ikiwiki source if you have highlight installed in a non-standard location (e.g. if you have done a user-level install of the highlight package).
+
+> configurable now, [[done]] --[[Joey]] 
diff --git a/doc/bugs/More_permission_checking.mdwn b/doc/bugs/More_permission_checking.mdwn
new file mode 100644 (file)
index 0000000..e56cda9
--- /dev/null
@@ -0,0 +1,9 @@
+I'm often confused about permissions and I wish ikiwiki could stamp it's foot down and ensure all the permissions are correctly (canonically?) setup.
+
+I keep ending up having to `sudo chown -R :www-data` and `sudo chmod -R g+w` on srcdir, destdir. I'm never quite sure what is the best practice for the srcdirs' `/srv/git/` is. Currently everything looks like `hendry:www-data` with ug+rw.
+
+I think I've triggered these problems by (not thinking and) running `ikiwiki --rebuild --setup /home/hendry/.ikiwiki/mywiki.setup` as my user.
+
+I don't know if there can be some lookup with `/etc/ikiwiki/wikilist`.  Though shouldn't everything be under the `www-data` group in reality?
+
+Also when I use `sudo ikiwiki -setup /etc/ikiwiki/auto.setup`, I think I create a ton of problems for myself since everything is created as the root user, right? And `/etc/ikiwiki/wikilist` doesn't seem to have the latest created wiki added. I have to reluctantly manually do this.
diff --git a/doc/bugs/UTF-16_and_UTF-32_are_unhandled.mdwn b/doc/bugs/UTF-16_and_UTF-32_are_unhandled.mdwn
new file mode 100644 (file)
index 0000000..21df334
--- /dev/null
@@ -0,0 +1,20 @@
+Wide characters should probably be supported, or, at the very least, warned about.
+
+Test case:
+
+    mkdir -p ikiwiki-utf-test/raw ikiwiki-utf-test/rendered
+    for page in txt mdwn; do
+      echo hello > ikiwiki-utf-test/raw/$page.$page
+      for text in 8 16 16BE 16LE 32 32BE 32LE; do
+        iconv -t UTF$text ikiwiki-utf-test/raw/$page.$page > ikiwiki-utf-test/raw/$page-utf$text.$page;
+      done
+    done
+    ikiwiki --verbose --plugin txt --plugin mdwn ikiwiki-utf-test/raw/ ikiwiki-utf-test/rendered/
+    www-browser ikiwiki-utf-test/rendered/ || x-www-browser ikiwiki-utf-test/rendered/
+    # rm -r ikiwiki-utf-test/ # some browsers rather stupidly daemonize themselves, so this operation can't easily be safely automated
+
+BOMless LE and BE input is probably a lost cause.
+
+Optimally, UTF-16 (which is ubiquitous in the Windows world) and UTF-32 should be fully supported, probably by converting to mostly-UTF-8 and using `&#xXXXX;` or `&#DDDDD;` XML escapes where necessary.
+
+Suboptimally, UTF-16 and UTF-32 should be converted to UTF-8 where cleanly possible and a warning printed where impossible.
diff --git a/doc/bugs/__34__Currently_enabled_SSH_keys:__34___shows_only_first_139_characters_of_each_key.mdwn b/doc/bugs/__34__Currently_enabled_SSH_keys:__34___shows_only_first_139_characters_of_each_key.mdwn
new file mode 100644 (file)
index 0000000..3c3352f
--- /dev/null
@@ -0,0 +1,12 @@
+At least at http://free-thursday.pieni.net/ikiwiki.cgi the "SSH keys" page shows only the first 139 characters of each SSH key. I'm using iceweasel in 1024x768 resolution and there are not scrollbars visible.
+
+Please contact me at timo.lindfors@iki.fi
+
+> I have access to the same wiki, and do not see the problem Timo sees. I see 380 chars of the SSH keys, and do have a scrollbar.
+> Weird. --liw
+
+> Also, that's a Branchable.com site and the bug, if any is
+> in ikiwiki-hosting's plugin, not ikiwiki proper. Moved
+> [here](http://ikiwiki-hosting.branchable.com/bugs/__34__Currently_enabled_SSH_keys:__34___shows_only_first_139_characters_of_each_key/) --[[Joey]] 
+
+[[!tag done]]
diff --git a/doc/bugs/aggregate_generates_long_filenames.mdwn b/doc/bugs/aggregate_generates_long_filenames.mdwn
new file mode 100644 (file)
index 0000000..fae8333
--- /dev/null
@@ -0,0 +1,37 @@
+the [[plugins/aggregate]] plugin mashes the `title` of an aggregated post into a filename.  This results in long filenames.  I have hit a filesystem length limitation on several occasions.  Some (ab)uses of RSS, e.g., twitter,
+generate long titles.  Especially once you throw escaping into the mix:
+
+    $ ikiwiki --setup testsetup --aggregate --refresh
+    failed to write ./test/lifestream/Hidden_Features_Of_Perl__44___PHP__44___Javascript__44___C__44___C++__44___C__35____44___Java__44___Ruby___46____46____46__._aggregated.ikiwiki-new: File name too long
+    aggregation failed with code 9216
+    $ echo $?
+    25
+
+It would also appear this abrubtly terminates aggregate processing (if not ikiwiki itself).  Only after moving my test repo to `/tmp` to shorten the filename did I see newer RSS feeds (from a totally different source) picked up.
+
+
+-- [[Jon]]
+
+> I have to wonder what filesystem you have there where 147 characters
+> is a long filename. Ikiwiki already uses `POSIX::pathconf` on the srcdir
+> to look up `_PC_NAME_MAX`
+> to see if the filename is too long, and shortens it, so it seems
+> that, in additional to having a rather antique long filename limit, your
+> system also doesn't properly expose it via pathconf. Not sure what
+> ikiwiki can do here. --[[Joey]]
+
+>> This is an ext4 filesystem with default settings (which appears to mean
+>> 256 bytes for pathnames).  Despite the error saying file name, it's
+>> definitely a path issue since moving my test repo to `/tmp`from
+>> `/home/jon/wd/mine/www` hides the problem. I note the following comment
+>> in `aggregate.pm`:
+
+               # Make sure that the file name isn't too long. 
+               # NB: This doesn't check for path length limits.
+
+>> I don't fully grok the aggregate source yet, but I wouldn't rule out
+>> a bug in the path length checking, personally.  I'm happy to try and
+>> find it myself though :) -- [[Jon]]
+
+>>> Path length seems unlikely, since the max is 4096 there.
+>>> --[[Joey]] 
diff --git a/doc/bugs/argument_isn__39__t_numeric:_mixing_templates_and_creation__95__date.mdwn b/doc/bugs/argument_isn__39__t_numeric:_mixing_templates_and_creation__95__date.mdwn
new file mode 100644 (file)
index 0000000..ff98ba5
--- /dev/null
@@ -0,0 +1,62 @@
+I get the following error when building my wiki
+
+    Argument "\x{3c}\x{54}..." isn't numeric in numeric eq (==) at /usr/share/perl5/IkiWiki.pm line 2547.
+    Argument "\x{3c}\x{54}..." isn't numeric in numeric eq (==) at /usr/share/perl5/IkiWiki.pm line 2547.
+
+that line corresponds to
+
+    sub match_creation_year ($$;@) {
+       if ((localtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) { <-- this one
+               return IkiWiki::SuccessReason->new('creation_year matched');
+       }
+
+A git bisect shows that the offending commit introduced this hunk
+
+
+    --- /dev/null
+    +++ b/templates/all_entry.mdwn
+    @@ -0,0 +1,23 @@
+    +## <TMPL_VAR year>
+    +
+    +There
+    +<TMPL_IF current>
+    +have been
+    +<TMPL_ELSE>
+    +were
+    +</TMPL_IF>
+    +[[!pagecount pages="
+    +log/* and !tagged(aggregation) and !*/Discussion and !tagged(draft)
+    +and creation_year(<TMPL_VAR year>)
+    +and !*.png and !*.jpg
+    +"]] posts
+    +<TMPL_IF current>
+    +so far
+    +</TMPL_IF>
+    +in <TMPL_VAR year>.
+    +
+    +[[!inline pages="
+    +    log/* and !tagged(aggregation) and !*/Discussion and !tagged(draft)
+    +    and creation_year(<TMPL_VAR year>)
+    +    and !*.png and !*.jpg
+    +    " archive=yes feeds=no]]
+
+The lines which feature creation_year(<TMPL_VAR year>) are most likely the culprits.  That would explain why the error was repeated twice, and would tally with the file in `templates/` being rendered, rather than the inclusionists.
+
+A workaround is to move the template outside of the srcdir into the external templates directory and include the file suffix when using it, e.g.
+
+    \[[!template id=all_entry.tmpl year=2010 current=true]]
+
+I believed (until I tested) that the [[ikiwiki/directive/if]] directive, with the `included()` test, would be an option here, E.g.
+
+    \[[!if test="included()" then="""
+    ...template...
+    """ else="""
+    Nothing to see here.
+    """]]
+
+However this doesn't work.  I assume "included" in this context means e.g. via an `inline` or `map`, not template trans-clusion. -- [[Jon]]
+
+> As far as I know, this bug was fixed in
+> 4a75dee651390b79ce4ceb1d951b02e28b3ce83a on October 20th. [[done]] --[[Joey]]
+
+>> Sorry Joey, I'll make sure to reproduce stuff against master in future. [[Jon]]
diff --git a/doc/bugs/blog_spam_plugin_not_allowing_non-ASCII_chars__63__.mdwn b/doc/bugs/blog_spam_plugin_not_allowing_non-ASCII_chars__63__.mdwn
new file mode 100644 (file)
index 0000000..59bf93d
--- /dev/null
@@ -0,0 +1,15 @@
+Hi,
+
+I'm trying to add a comment, and ikiwiki fails with this error message:
+
+    Error: HTTP::Message content must be bytes at /usr/share/perl5/RPC/XML/Client.pm line 308
+
+This seems to happen because I had a non-ASCII character in the comment (an ellipse, …).
+The interesting part is that the comment preview works fine, just the save fails. Probably
+this means that the blogspam plugin is the culprit (hence the error in RPC::XML::Client library).
+I'm using version 3.20100815~bpo50+. Thanks!
+
+> I've filed an upstream bug about this on RPC::XML:
+> <https://rt.cpan.org/Ticket/Display.html?id=61333>
+> 
+> Worked around it in blogspam by decoding. [[done]] --[[Joey]]
diff --git a/doc/bugs/can__39__t_mix_template_vars_inside_directives.mdwn b/doc/bugs/can__39__t_mix_template_vars_inside_directives.mdwn
new file mode 100644 (file)
index 0000000..e91a892
--- /dev/null
@@ -0,0 +1,61 @@
+I often find myself wrapping the same boiler plate around [[ikiwiki/directives/img]] img directives, so I tried to encapsulate it using the following [[ikiwiki/directives/template]]:
+
+
+    <div class="image">
+    [\[!img <TMPL_VAR raw_href>
+    size="<TMPL_VAR raw_size>"
+    
+    <TMPL_IF alt>
+      alt="<TMPL_VAR raw_alt>"
+    <TMPL_ELSE>
+      <TMPL_IF caption>
+        alt="<TMPL_VAR raw_alt>"
+      <TMPL_ELSE>
+        alt="[pic]"
+      </TMPL_IF>
+    </TMPL_IF>
+    
+    ]]
+    <TMPL_IF caption>
+    <p><TMPL_VAR raw_caption></p>
+    </TMPL_IF>
+    </div>
+
+The result, even with htmlscrubber disabled, is mangled, something like
+
+    <div class="image">
+    <span class="createlink"><a href="http://jmtd.net/cgi?
+        page=size&amp;from=log0.000000old_new_test&amp;do=create"
+        rel="nofollow">?</a>size</span>
+    
+    </div>
+
+Any suggestions gladly received. -- [[Jon]]
+
+> Well, you *should* be able to do things like this, and in my testing, I
+> *can*. I used your exact example above (removing the backslash escape)
+> and invoked it as:
+>      \[[!template id=test href=himom.png size=100x]]
+> 
+> And got just what you would expect.
+> 
+> I don't know what went wrong for you, but I don't see a bug here. 
+> My guess, at the moment, is that you didn't specify the required href
+> and size parameters when using the template. If I leave those off,
+> I of course reproduce what you reported, since the img directive gets
+> called with no filename, and so assumes the size parameter is the image
+> to display.. [[done]]? --[[Joey]] 
+
+>> Hmm, eek. Just double-checked, and done a full rebuild. No dice! Version 3.20100831. Feel free to leave this marked done, It probably *is* PEBKAC. I shall look again in day time. -- [[Jon]]
+
+>>> As always, if you'd like to mail me a larger test case that reproduces a
+>>> problem for you, I can take a look at it. --[[Joey]]
+
+>>>> <s>Thank you for the offer.  I might still take you up on it.  I've just proven that this
+>>>> does work for a clean repo / bare bones test case. -- [[Jon]]</s> Figured it out. The
+>>>> problem was I'd copied a page (old_new) which had two images embedded in it to test.
+>>>> I'd stored the images under a subdir "old_new". The new page was called "old_new_test"
+>>>> and the images thus could not be found by a pagespec "some-image.jpg". Adjusting the
+>>>> href argument to the template (consequently the src argument to img) to
+>>>> "old_new/some-image.jpg" fixed it all. [[done]], PEBKAC. Thank you for your time :)
+>>>> -- [[Jon]]
diff --git a/doc/bugs/class_parameter_of_img_directive_behave_not_as_documented.mdwn b/doc/bugs/class_parameter_of_img_directive_behave_not_as_documented.mdwn
new file mode 100644 (file)
index 0000000..e779776
--- /dev/null
@@ -0,0 +1,31 @@
+On [[ikiwiki/directive/img/]] I read that
+
+> You can also pass alt, title, class, align, id, hspace, and vspace
+> parameters. These are passed through unchanged to the html img tag.
+
+but when I pass `class="myclass"` to an img directive, I obtain
+
+    <img class="myclass img" ...
+
+I found that this behaviour was added in commit f6db10d:
+
+> img: Add a margin around images displayed by this directive.
+>
+> Particularly important for floating images, which could before be placed
+> uncomfortably close to text.
+    
+which adds to img.pm:
+    
+    if (exists $params{class}) {
+            $params{class}.=" img";
+    }
+    else {
+            $params{class}="img";
+    }
+
+I would prefer if the `img` class were only added if no class attribute is
+passed.
+
+If you keep the current behaviour, please document it.
+
+> [[done]] --[[Joey]] 
diff --git a/doc/bugs/cutpaste.pm:_missing_filter_call.mdwn b/doc/bugs/cutpaste.pm:_missing_filter_call.mdwn
new file mode 100644 (file)
index 0000000..4b22fd0
--- /dev/null
@@ -0,0 +1,55 @@
+Consider this:
+
+    $ wget http://schwinge.homeip.net/~thomas/tmp/cutpaste_filter.tar.bz2
+    $ wget http://schwinge.homeip.net/~thomas/tmp/cutpaste_filter.patch
+    
+    $ tar -xj < cutpaste_filter.tar.bz2
+    $ cd cutpaste_filter/
+    $ ./render_locally
+    $ find "$PWD".rendered/ -type f -print0 | xargs -0 grep -H -E 'FOO|BAR'
+    [notice one FOO in there]
+    $ rm -rf .ikiwiki "$PWD".rendered
+    
+    $ cp /usr/share/perl5/IkiWiki/Plugin/cutpaste.pm .library/IkiWiki/Plugin/
+    $ patch -p0 < ../cutpaste_filter.patch
+    $ ./render_locally
+    $ find "$PWD".rendered/ -type f -print0 | xargs -0 grep -H -E 'FOO|BAR'
+    [correct; notice no more FOO]
+
+I guess this needs a general audit -- there are other places where `preprocess`
+is being doing without `filter`ing first, for example in the same file, `copy`
+function.
+
+--[[tschwinge]]
+
+> So, in English, page text inside a cut directive will not be filtered.
+> Because the cut directive takes the text during the scan pass, before
+> filtering happens.
+> 
+> Commit 192ce7a238af9021b0fd6dd571f22409af81ebaf and
+> [[bugs/po_vs_templates]] has to do with this.
+> There I decided that filter hooks should *only* act on the complete
+> text of a page. 
+> 
+> I also suggested that anything that wants to reliably
+> s/FOO/BAR/ should probably use a sanitize hook, not a filter hook.
+> I think that would make sense in this example.
+> 
+> I don't see any way to make cut text be filtered while satisfying these
+> constraints, without removing cutpaste's ability to have forward pastes
+> of text cut laster in the page. (That does seems like an increasingly
+> bad idea..) --[[Joey]]
+
+> > OK -- so the FOO/BAR thing was only a very stripped-down example, of
+> > course, and the real thing is being observed with the
+> > *[[plugins/contrib/getfield]]* plugin.  This one needs to run *before*
+> > `preprocess`ing, for its `{{$page#field}}` syntax is (a) meant to be usable
+> > inside ikiwiki directives, and (b) the field values are meant to still be
+> > `preprocess`ed before being embedded.  That's why it's using the `filter`
+> > hook instead of `sanitize`.
+
+> > Would adding another kind of hook be a way to fix this?  My idea is that
+> > *cut* (and others) would then take their data not during `scan`ning, but
+> > *after* `filter`ing.
+
+> > --[[tschwinge]]
diff --git a/doc/bugs/git.pm_should_prune_remote_branches_when_fetching.mdwn b/doc/bugs/git.pm_should_prune_remote_branches_when_fetching.mdwn
new file mode 100644 (file)
index 0000000..5dc4250
--- /dev/null
@@ -0,0 +1,14 @@
+The _git_ module does not appear ever to prune obsolete remote branches in the _srcdir_ repository, leading to spurious errors when fetching.
+
+Pruning remote branches can be done automatically with the --prune option to "git fetch" or in a separate command "git remote prune".
+
+--[[blipvert]]
+
+> I'll need more information than that before I add extra processing
+> work to the current git commands it uses. I don't see any errors here
+> from obsolete remote branches. --[[Joey]] 
+
+Suppose a remote repository contains a branch named "foo", and you fetch from it.  Then, someone renames that branch to "foo/bar".  The next time you fetch from that repository, you will get an error because the obsolete branch "foo" is blocking the branch "foo/bar" from being created (due to the way git stores refs for branches).  Pruning gets around the problem.  It doesn't really add much overhead to the fetch, and in fact it can *save* overhead since obsolete branches do consume resources (any commits they point to cannot be garbage collected).  --[[blipvert]]
+
+> Ok, so git pull --prune can be used to do everything in one command.
+> [[done]] --[[Joey]] 
diff --git a/doc/bugs/git_commit_adds_files_that_were_not_tracked.mdwn b/doc/bugs/git_commit_adds_files_that_were_not_tracked.mdwn
new file mode 100644 (file)
index 0000000..587650c
--- /dev/null
@@ -0,0 +1,19 @@
+Commit 3650d0265bc501219bc6d5cd4fa91a6b6ecd793a seems to have been caused by
+a bug in ikiwiki. recentchanges/* was added to the git repo incorrectly.
+
+Part of the problem seems to be that git's `rcs_commit` does a git add followed
+by a `rcs_commit_staged`, and so calling `rcs_commit` on files that were
+not checked in before adds them, incorrectly.
+
+I'm unsure yet why the recentchanges files were being committed. Possibly
+because of the link fixup code run when renaming a page. --[[Joey]] 
+
+> See also [[bugs/rename fixup not attributed to author]]. --[[smcv]]
+
+> Ok, there was a call to `rcs_commit` that was still using non-named
+> parameters, which confused it thuroughly, and I think caused
+> 'git add .' to be called. I've fixed that.
+> 
+> I think there is still potential for the problem I described above to
+> occur during a rename or possibly otherwise. Ok.. fixed `rcs_commit`
+> to not add too. [[done]] --[[Joey]] 
diff --git a/doc/bugs/htmlbalance_fails_with_HTML-Tree_v4.mdwn b/doc/bugs/htmlbalance_fails_with_HTML-Tree_v4.mdwn
new file mode 100644 (file)
index 0000000..9242706
--- /dev/null
@@ -0,0 +1,18 @@
+[[!template id=gitbranch branch=smcv/ready/htmlbalance author="[[smcv]]"]]
+[[!tag patch]]
+
+My one-patch htmlbalance branch fixes incompatibility with HTML::Tree 4.0.
+From the git commit:
+
+    The HTML::Tree changelog says:
+    
+        [THINGS THAT MAY BREAK YOUR CODE OR TESTS]
+        ...
+        * Attribute names are now validated in as_XML and invalid names will
+          cause an error.
+    
+    and indeed the regression tests do get an error.
+
+--[[smcv]]
+
+[[done]] --[[Joey]]
diff --git a/doc/bugs/httpauth_conflicts_with_git_anon_push.mdwn b/doc/bugs/httpauth_conflicts_with_git_anon_push.mdwn
new file mode 100644 (file)
index 0000000..91507f5
--- /dev/null
@@ -0,0 +1,25 @@
+Someone tried to report a bug using IRC while I was on vacation.
+--[[Joey]] 
+
+<pre>
+julm: [11:58:35] han, it's me the problem; I was generating a post-update hook instead of a pre-receive hook
+julm: [12:03:59] why does the pre-receive hook return: "Status: 302 Found" and a "Location: <url>"? Is it normal?
+julm: [00:08:44] it's Plugin/httpauth.pm which is outputing those Status and Location
+julm: [00:09:12] problem is that it's an anonymous push via git://
+julm: [03:28:53] hacked my way to fix it somehow: http://git.internet.alpes.fr.eu.org/?p=web/ikiwiki.git;a=commitdiff;h=7211df4f7457c3afab53822a97cbd21825c473f4
+</pre>
+
+Analysis: 
+
+* IkiWiki::Receive calls `check_canedit`.
+* httpauth's canedit hook returns an error handler function
+  which redirects the browser through the cgiauthurl.
+  (Similarly, signinedit's hook may call needsignin, which
+  can display a signin form.
+* That doesn't work well when doing a git anon push. :)
+* Also, IkiWiki::Receive calls `check_canattach` and
+  `check_canremove`, which both also call `check_canedit`.
+
+So, all these calls need to avoid running the error handler
+functions returned by canedit hooks, and just return error
+messages. [[done]] --[[Joey]] 
diff --git a/doc/bugs/ikiwiki_ignores_PATH_environment.mdwn b/doc/bugs/ikiwiki_ignores_PATH_environment.mdwn
new file mode 100644 (file)
index 0000000..6781d4b
--- /dev/null
@@ -0,0 +1,24 @@
+At the very top of the main ikiwiki executable script the `PATH` environment is set like this:
+
+    $ENV{PATH}="/usr/local/bin:/usr/bin:/bin:/opt/local/bin";
+
+This makes it a little hard to specify which specific binaries should be used, especially if there is more than one of them available (see c.f. <http://trac.macports.org/ticket/26333> where the MacPorts-supplied, up-to-date subversion should be used and not an arcane one from the base distro / OS). Is there a specific reason why ikiwiki wipes out `$PATH` like this or could that line be improved to
+
+    $ENV{PATH}="$ENV{PATH}:/usr/local/bin:/usr/bin:/bin:/opt/local/bin";
+
+? The alternative is of course to patch ikiwiki as suggested in the bug, but I wanted to ask here first :)
+
+> You can use the ENV setting in your setup file to set any environment
+> variables you like. Since ikiwiki.cgi is run by the web browser, that
+> is the best way to ensure ikiwiki always runs with a given variable set.
+> 
+> As a suid program, the ikiwiki wrappers have to sanitize the environment.
+> The ikiwiki script's own sanitization of PATH was done to make perl taint
+> checking happy, but as taint checking is disabled anyway, I have removed
+> that. [[done]] --[[Joey]] 
+
+Question: Do ikiwiki.cgi and the RCS post-commit script sanitize the $PATH separately from bin/ikiwiki?  If not, then bin/ikiwiki is probably right to sanitize the $PATH; otherwise you've created a security hole with access to the account that ikiwiki is SUID to. It'd be nice if /opt/local/bin were earlier in the $PATH, but that can be changed (as noted) in the setup file. [[Glenn|geychaner@mac.com]] (Also the person who started this by filing an issue with MacPorts; I'm experimenting with ikiwiki for collaborative documentation.)
+
+> The suid wrappers remove all environment variables except for a few used
+> for CGI. PATH is not propigated by them, so when they run ikiwiki it will
+> get the system's default path now. --[[Joey]]
diff --git a/doc/bugs/img_plugin_and_class_attr.mdwn b/doc/bugs/img_plugin_and_class_attr.mdwn
new file mode 100644 (file)
index 0000000..7e880b4
--- /dev/null
@@ -0,0 +1,27 @@
+The [[plugins/img]] plugin is not generating the proper `class`
+attribute in its HTML output.
+
+The plugin receives something like the following:
+
+    \[[!img 129199047595759991.jpg class="centered"]]
+
+And is supossed to generate an HTML code like the following:
+
+    <img src="129199047595759991.jpg" class="centered" />
+
+But is generating the following
+
+    <img src="129199047595759991.jpg" class="centered img" />
+
+This seems to be happening with all images inserted using the plugin (that use
+the `class=yaddayadda` argument to the `img` directive.) I remember it didn't
+happen before, and I suspect an ikiwiki upgrade is to blame. I tested with a
+blog created from scratch, and a single post, and the problem appeared there
+too.
+
+This is happening with version 3.20100815 of ikiwiki.
+
+[[jerojasro]]
+
+> How is this a bug? It's perfectly legal html for a class attribute to 
+> put an element into multiple classes. [[notabug|done]] --[[Joey]] 
diff --git a/doc/bugs/inline_action_buttons_circumvent_exclude_criteria_from_edittemplate__39__s_match__61____34____34___pagespec.mdwn b/doc/bugs/inline_action_buttons_circumvent_exclude_criteria_from_edittemplate__39__s_match__61____34____34___pagespec.mdwn
new file mode 100644 (file)
index 0000000..45481bf
--- /dev/null
@@ -0,0 +1,13 @@
+ikiwiki verison: 3.20100815.2
+
+If I instruct editemplate to only match the top level pages in a directory using 
+
+    match="foo/* and !foo/*/* and !foo/*/*/*"
+
+everything works as expected for pages created via links on other wiki pages. So, if I open foo/bar (or any other page on the wiki) and create a link to foo/bar/bug, edittemplate appropriately does not insert any text into the new page. 
+
+However, if I use an inline directive like the following 
+
+    !inline pages="page(foo/bar/*)" rootpage="foo/bar" postform=yes actions=yes
+
+every page created via the action buttons incorrectly pulls in the text from the edittemplate registration. Changing the order of the conditions in the match="" pagespec has no impact. 
diff --git a/doc/bugs/logout_in_ikiwiki.mdwn b/doc/bugs/logout_in_ikiwiki.mdwn
new file mode 100644 (file)
index 0000000..d9b6df6
--- /dev/null
@@ -0,0 +1,31 @@
+It looks like there is no way to logout of ikiwiki at present, meaning that if you edit the ikiwiki in, say, a cybercafe, the cookie remains... is there some other security mechanism in place that can check for authorization, or should I hack in a logout routine into ikiwiki.cgi?
+
+> Click on "Preferences". There is a logout button there. --liw
+
+> It would be nice if it were not buried there, but putting it on the
+> action bar statically would be confusing. The best approach might be to
+> use javascript. --[[Joey]] 
+
+
+>> I agree that javascript seems to be a solution, but my brain falls 
+>> off the end of the world while looking at ways to manipulate the DOM. 
+>> (I'd argue also in favor of the openid_provider cookie expiring 
+>>  in less time than it does now, and being session based)
+
+>>> (The `openid_provider` cookie is purely a convenience cookie to
+>>> auto-select the user's openid provider the next time they log
+>>> in. As such, it cannot be a session cookie. It does not provide any
+>>> personally-identifying information so it should not really matter 
+>>> when it expires.) --[[Joey]]
+
+>> It would be nice to move navigational elements to the upper right corner 
+>> of the page...
+
+>> I have two kinds of pages (wiki and blog), and three classes of users  
+
+>> anonymous users - display things like login, help, and recentchanges,
+
+>> non-admin users - on a per subdir basis (blog and !blog) display 
+>> logout, help, recentchanges, edit, comment 
+
+>> admin users - logout, help, recentchanges, edit, comment, etc
diff --git a/doc/bugs/monotone_backend_does_not_support_srcdir_in_subdir.mdwn b/doc/bugs/monotone_backend_does_not_support_srcdir_in_subdir.mdwn
new file mode 100644 (file)
index 0000000..35f624f
--- /dev/null
@@ -0,0 +1,5 @@
+The [[rcs/monotone]] backend does not currently support putting the ikiwiki srcdir
+in a subdirectory of the repository.  It must be at the top. Git has
+special code to handle this case. --[[Joey]] 
+
+[[done]]
diff --git a/doc/bugs/more_and_RSS_generation.mdwn b/doc/bugs/more_and_RSS_generation.mdwn
new file mode 100644 (file)
index 0000000..00ab43f
--- /dev/null
@@ -0,0 +1,20 @@
+I'd like the more plugin and RSS to play better together. In the case of the html generation of the main page of a blog, I'd like to get the first paragraph out, but keep RSS as a full feed.
+
+Maybe there is a different plugin (I also tried toggle)? 
+
+> I am not a fan of the more directive (thus the rant about it sucking
+> embedded in its [[example|ikiwiki/directive/more]]). But I don't think 
+> that weakening it to not work in rss feeds is a good idea, if someone
+> wants to force users to go somewhere to view their full content, 
+> they should be able to do it, even though it does suck.
+> 
+> The toggle directive will degrade fairly well in an rss feed to
+> display the full text. (There is an annoying toggle link that does
+> nothing when embedded in an rss feed). --[[Joey]]
+
+I also note, that at least currently, more seems to break on a few pages, not being parsed at all when aggregated into the front page. 
+
+> It's just a simple directive, it should work anywhere any directive will,
+> and does as far as I can see. Details? --[[Joey]]
+
+see also: [[/bugs/rss_feeds_do_not_use_recommended_encoding_of_entities_for_some_fields/]]
diff --git a/doc/bugs/po:_apache_config_serves_index.rss_for_index.mdwn b/doc/bugs/po:_apache_config_serves_index.rss_for_index.mdwn
new file mode 100644 (file)
index 0000000..a2b68c4
--- /dev/null
@@ -0,0 +1,36 @@
+The apache config documented in [[plugins/po]] has a subtle bug. It works
+until a site gets an index.atom or index.rss file. (Acutally, with po
+enabled, they're called index.en.atom or index.en.rss etc, but the result
+is the same).
+
+Then, when wget, curl, or w3m is pointed at http://site/, apache serves
+up the rss/atom file rather than the index page.
+
+Analysis:
+
+* /etc/mime.types gives mime types to .rss and .atom files
+* `mod_negotiation`'s MultiViews allows any file with a mime type to be
+  served up via content negotiation, if the client requests that type.
+* wget etc send `Accept: */*` to accept all content types. Compare
+  with firefox, which sends `Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*`
+* So apache has a tie between a html encoded Enlish file, and a rss encoded
+  English file and the client has no preference. In a tie, apache will serve up the
+  *smallest* file, which tends to be the rss file. (Apache's docs say it uses that
+  strange criteria to break ties; see <http://httpd.apache.org/docs/2.0/mod/mod_mime.html#multiviewsmatch>)
+
+The only way I have found to work around this problem is to remove
+atom and rss from /etc/mime.types. Of course, that has other undesirable
+results. 
+
+I wonder if it would be worth making the po plugin generate apache 
+[type map files](http://httpd.apache.org/docs/2.0/mod/mod_negotiation.html#typemaps).
+That should avoid this problem.
+--[[Joey]]
+
+Update: A non-intrusive fix is to add this to apache configuration. 
+This tunes the "quality" of the rss and atom files, in an apparently currently
+undocumented way (though someone on #httpd suggested it should get documented).
+Result is that apache will prefer serving index.html. --[[Joey]]  [[done]]
+
+       AddType application/rss+xml;qs=0.8 .rss
+       AddType application/atom+xml;qs=0.8 .atom
diff --git a/doc/bugs/po:_markdown_link_parse_bug.mdwn b/doc/bugs/po:_markdown_link_parse_bug.mdwn
new file mode 100644 (file)
index 0000000..1071500
--- /dev/null
@@ -0,0 +1,14 @@
+Apparently this is legal markdown, though unusual syntax for a link:
+
+       [Branchable](http://www.branchable.com/ "Ikiwiki hosting") 
+
+If that is put on a translatable page, the translations display it not as a
+link, but as plain text.
+
+Probably a po4a bug, but I don't see the bug clearly in the gernerated po
+file:
+
+       "This was posted automatically by [Branchable](http://www.branchable.com/ "
+       "\"Ikiwiki hosting\") when I signed up."
+
+--[[Joey]] 
index 933e348c40d0333de1d43e2e5edbb78c976240b6..8238f50dfdf9f722f43fc9209aad94d35c0999e1 100644 (file)
@@ -3,4 +3,20 @@ At the bottom of this page, there is the "Links" line:
 Links: index index.fr templates templates.fr  
 When i click on "templates.fr", i get the po.file instead of html.  
    
-    Sorry for the noise! I set "po_master_language" to fr and all was ok. [[done]].
+    Sorry for the noise! I set "po_master_language" to fr and all was ok.
+
+> Any chance you could be a bit more verbose about what the
+> misconfiguration was? I don't think the po plugin should behave like that
+> in any configuration. Unless, perhaps, it was just not configured to
+> support any languages at all, and so the po file was treated as a raw
+> file. --[[Joey]] 
+  
+>> I can reproduce the bug with:  
+       # po plugin  
+       # master language (non-PO files)  
+       po_master_language => {  
+         code => 'en',  
+         name => 'English'  
+       },  
+       # slave languages (PO files)  
+       po_slave_languages => [qw{fr|Français}],  
diff --git a/doc/bugs/po:broken_links_to_translatable_basewiki_pages_that_lack_po_fies.mdwn b/doc/bugs/po:broken_links_to_translatable_basewiki_pages_that_lack_po_fies.mdwn
new file mode 100644 (file)
index 0000000..121d338
--- /dev/null
@@ -0,0 +1,73 @@
+broken links to translatable basewiki pages that lack po files
+--------------------------------------------------------------
+
+If a page is not translated yet, the "translated" version of it
+displays wikilinks to other, existing (but not yet translated?)
+pages as edit links, as if those pages do not exist. 
+
+That's really confusing, especially as clicking such a link
+brings up an edit form to create a new, english page.
+
+This is with po_link_to=current or negotiated. With default, it doesn't
+happen.. 
+
+Also, this may only happen if the page being linked to is coming from an
+underlay, and the underlays lack translation to a given language.
+--[[Joey]] 
+
+> Any simple testcase to reproduce it, please? I've never seen this
+> happen yet. --[[intrigeri]]
+
+>> Sure, go here <http://l10n.ikiwiki.info/smiley/smileys/index.sv.html>
+>> (Currently 0% translateed) and see the 'WikiLink' link at the bottom,
+>> which goes to <http://l10n.ikiwiki.info/ikiwiki.cgi?page=ikiwiki/wikilink&from=smiley/smileys&do=create>
+>> Compare with eg, the 100% translated Dansk version, where
+>> the WikiLink link links to the English WikiLink page. --[[Joey]] 
+
+>>> Seems not related to the page/string translation status: the 0%
+>>> translated Spanish version has the correct link, just like the
+>>> Dansk version => I'm changing the bug title accordingly.
+>>>
+>>> I tested forcing the sv html page to be rebuilt by translating a
+>>> string in it, it did not fix the bug. I did the same for the
+>>> Spanish page, it did not introduce the bug. So this is really
+>>> weird.
+>>>
+>>> The smiley underlay seems to be the only place where the wrong
+>>> thing happens: the basewiki underlay has similar examples
+>>> that do not exhibit this bug. An underlay linking to another might
+>>> be necessary to reproduce it. Going to dig deeper. --[[intrigeri]]
+
+>>>> After a few hours lost in the Perl debugger, I think I have found
+>>>> the root cause of the problem: in l10n wiki's configured
+>>>> `underlaydir`, the basewiki is present in every slave language
+>>>> that is enabled for this wiki *but* Swedish. With such a
+>>>> configuration, the `ikiwiki/wikilink` page indeed does not exist
+>>>> in Swedish language: no `ikiwiki/wikilink.sv.po` can be found
+>>>> where ikiwiki is looking. Have a look to
+>>>> <http://l10n.ikiwiki.info/ikiwiki/>, the basewiki is not
+>>>> available in Swedish language on this wiki. So this is not a po
+>>>> bug, but a configuration or directories layout issue. This is
+>>>> solved by adding the Swedish basewiki to the underlay dir, which
+>>>> is I guess not a possibility in the l10n wiki context. I guess
+>>>> this could be solved by adding `SRCDIR/basewiki` as an underlay
+>>>> to your l10n wiki configuration, possibly using the
+>>>> `add_underlays` configuration directive. --[[intrigeri]]
+
+>>>>> There is no complete Swedish underlay translation yet, so it is not
+>>>>> shipped in ikiwiki. I don't think it's a misconfiguration to use
+>>>>> a language that doesn't have translated underlays. --[[Joey]] 
+
+>>>>>> Ok. The problem is triggered when using a language that doesn't
+>>>>>> have translated underlays, *and* defining
+>>>>>> `po_translatable_pages` in a way that renders the base wiki
+>>>>>> pages translatable in po's view of things, which in turns makes
+>>>>>> the po plugin act as if the translation pages did exist,
+>>>>>> although they do not in this case. I still need to have a deep
+>>>>>> look at the underlays-related code you added to `po.pm` a while
+>>>>>> ago. Stay tuned. --[[intrigeri]]
+
+>>>>>>> Fixed in my po branch, along with other related small bugs that
+>>>>>>> happen in the very same situation only. --[[intrigeri]]
+
+>>>>>>>> Merged. Not tested yet, but I trust you; [[done]] --[[Joey]] 
diff --git a/doc/bugs/rename_fixup_not_attributed_to_author.mdwn b/doc/bugs/rename_fixup_not_attributed_to_author.mdwn
new file mode 100644 (file)
index 0000000..bcfafac
--- /dev/null
@@ -0,0 +1,12 @@
+When I renamed `todo/transient_in-memory_pages` to [[todo/transient pages]],
+`rename::fixlinks` was meant to blame me for the link-fixing commit, and title it
+`update for rename of %s to %s`. Instead, it blamed Joey for the commit,
+and didn't set a commit message.
+
+(It also committed a pile of recentchanges pages which shouldn't have
+been committed, for which see [[bugs/git_commit_adds_files_that_were_not_tracked]].)
+
+--[[smcv]]
+
+> It was calling `rcs_commit` old-style, and so not passing the session
+> object that is used to get the user's name. [[fixed|done]] --[[Joey]] 
index 48c1689971cc6f1e8c6c7b3a58ad5679dedef8b3..0a435cea33a4220b3ada48df349662374c407ee4 100644 (file)
@@ -34,3 +34,19 @@ For Atom, at least, I believe adding `type="xhtml"` to the title element will wo
 > Update: Ok, I've fixed this for titles, as a special case, but the
 > underlying problem remains for other fields in rss feeds (such as
 > author), so I'm leaving this bug report open. --[[Joey]]
+
+>> I'm curious if there has been any progress on better RSS output?
+>> I've been prototyping a new blog and getting good RSS out of it 
+>> seems important as the bulk of my current readers use RSS.
+>> I note, in passing that the "more" plugin doesn't quite do what 
+>> I want either - I'd like to pass a full RSS feed of a post and only
+>> have "more" apply to the front page of the blog. Is there a way to do that?
+>> -- [[dtaht]]
+>> 
+>>> To be clear, the RSS spec sucks to such an extent that, as far as
+>>> I know, there is no sort of title escaping that will work in all 
+>>> RSS consumers. Titles are currently escaped in the way 
+>>> that tends to break the fewest according to what I've read.
+>>> If you're unlucky enough to 
+>>> have a "&" or "<" in your **name**, then you may still run into 
+>>> problems with how that is escaped in rss feeds. --[[Joey]]
index dab3b7e5bf58059947e433fcb5e5594ed5a3e3e1..99e46aac9c4018f67366152ec1c135ca51f84776 100644 (file)
@@ -24,3 +24,6 @@ throwing code..):
 > No, still the same failure. I think it's failing parsing the input data,
 > (which perl probably transmitted as an int due to perl internals)
 > not writing out its response. --[[Joey]]
+
+> On second thought, this was a bug in ikiwiki, it should be transmitting
+> that as a string. Fixed in external.pm --[[Joey]] 
diff --git a/doc/bugs/web_reversion_on_ikiwiki.info.mdwn b/doc/bugs/web_reversion_on_ikiwiki.info.mdwn
new file mode 100644 (file)
index 0000000..6f18cfc
--- /dev/null
@@ -0,0 +1,14 @@
+I created [[sandbox/revert me]] and then tried the revert button on
+[[recentchanges]], but I was not allowed to revert it. The specific error
+was
+
+    Error: you are not allowed to change sandbox/revert_me.mdwn
+
+I've just tried reading through the revert code, and I haven't figured out
+what permission I am lacking.  Perhaps the error message could be a little
+clearer on that. The error might have been thrown by git_parse_changes in
+git.pm or check_canchange in IkiWiki.pm, via IkiWiki::Receive. -- Jon
+
+[[fixed|done]] --[[Joey]]
+
+: Brilliant, many thanks. -- [[Jon]]
index 35db57b0c05a6e12bc439308a4016ad1e54af910..bc070cb99872d3fda19978338a8f43fe0dac7882 100644 (file)
@@ -9,7 +9,7 @@ defining brand new rendering rules.
 While ikiwiki's default use of stylesheets is intentionally quite plain and
 minimalistic, CSS allows creating any kind of look you can dream up.
 
-The [[theme_plugin|plugins/theme]] provides some prepackaged themes in an
+The [[theme_plugin|plugins/theme]] provides some prepackaged [[themes]] in an
 easy to use way.
 
 The [[css_market]] page is an attempt to collect user contributed local.css
index 0e5a687406eb15ba4f855e3577d260da59e9393d..1838b2f600a25dc40ebbd4ddc4a7059e31d86308 100644 (file)
@@ -4,9 +4,11 @@ User contributed stylesheet files for ikiwiki. Unless otherwise noted,
 these style sheets can be installed by copying them into your wiki's source
 dir with a filename of `local.css`.
 
+Some of stylesheets have developed into fullfledged [[themes]] that are
+included in ikiwiki for easy use.
+
 Feel free to add your own stylesheets here. (Upload as wiki pages; wiki
-gnomes will convert them to css files..) Selected ones from here are
-included in the [[theme_plugin|plugins/theme]].
+gnomes will convert them to css files..)
 
 * **[[css_market/zack.css]]**, contributed by [[StefanoZacchiroli]],
   customized mostly for *blogging purposes*, can be seen in action on 
@@ -46,15 +48,11 @@ included in the [[theme_plugin|plugins/theme]].
 
 * **[contraste.css][4]**, contributed by [[Blanko]]. Can be seen on [Contraste Demo][5]. Local.css and templates available [here][6].
 
-* **[[css_market/actiontabs.css]]**, contributed by [[svend]]. This style sheet displays
-  the action list (Edit, RecentChanges, etc.) as tabs.
-  [[!meta stylesheet="actiontabs"]]
-
 * **[wiki.css](http://cyborginstitute.net/includes/wiki.css)** by [[tychoish]]. 
   I typically throw this in as `local.css` in new wikis as a slightly more clear and readable
   layout for wikis that need to be functional and elegant, but not necessarily uniquely designed. 
   Currently in use by the [the outeralliance wiki](http://oa.criticalfutures.com/). 
-  
 
 If your web browser allows selecting between multiple stylesheets, this
 page can be viewed using many of the stylesheets above. For example, if
diff --git a/doc/css_market/actiontabs.css b/doc/css_market/actiontabs.css
deleted file mode 100644 (file)
index a1dc47e..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ikiwiki local style sheet */
-
-/* Add local styling here, instead of modifying style.css. */
-
-a {
-       text-decoration: none;
-       color: #005a9c;
-}
-
-a:hover {
-       text-decoration: underline;
-}
-
-
-hr {
-       border-style: none;
-       background-color: #999;
-       height: 1px;
-}
-
-code, pre {
-    background: #eee;
-}
-
-pre {
-    padding: .5em;
-}
-
-body {
-       margin: 0;
-       padding: 0;
-       font-family: sans-serif;
-       color: black;
-       background: white;
-}
-
-.pageheader {
-       margin: 0;
-       padding: 1em 2em 0 2em;
-       background: #eee;
-       border-color: #999;
-       border-style: none none solid none;
-       border-width: 1px;
-}
-
-.header {
-       font-size: 100%;
-       font-weight: normal;
-}
-
-.title {
-       display: block;
-       margin-top: .2em;
-       font: 140% sans-serif;
-       text-transform: capitalize;
-}
-
-.actions {
-       text-align: right;
-       padding: 0;
-}
-
-#content, #comments, #footer {
-       margin: 1em 2em;
-}
-
-#pageinfo {
-       border-color: #999;
-}
-
-.inlinepage {
-       margin: .4em 0;
-       padding: .4em 0;
-       border-style: none;
-       border-top: 1px solid #aaa;
-}
-
-.inlineheader {
-       font-size: 120%;
-       font-weight: normal;
-}
-
-h1 { font: 120% sans-serif }
-h2 { font: bold 100% sans-serif }
-h3 { font: italic 100% sans-serif }
-h4, h5, h6 { font: small-caps 100% sans-serif }
-
-/* Smaller headings for inline pages */
-.inlinepage h1 { font-size: 110% }
-.inlinepage h2 { font-size: 100% }
-.inlinepage h3 { font-size: 100% }
-
-.pageheader .actions ul {
-       border-style: none
-}
-
-.actions ul {
-       font-size: 75%;
-       padding: 0;
-       border-style: none;
-}
-
-.actions ul li a {
-       text-decoration: none;
-}
-
-.actions ul li {
-       margin: 0;
-       padding: .1em .5em 0 .5em;
-       background: white;
-       border-color: #999;
-       border-style: solid solid none solid;
-       border-width: 1px;
-}
-
-div.recentchanges {
-       border-style: none;
-}
-
-.pagecloud {
-       width: auto;
-}
index b25601227b41ae39e51728d8e7747ee03e27db98..5f8f6c3ce192bc2e02d7d566e8032fdb3810316d 100644 (file)
@@ -10,8 +10,8 @@ Some additional configuration you might want to do, if not using
 
 * Make sure to configure ikiwiki to generate RSS or Atom feeds.
 
-* Make sure you have the tag plugin enabled, and the `tagbase` set to
-  "tags". Tag pages will then automatically be created.
+* Make sure you have the [[tag|plugins/tag]] plugin enabled, and the
`tagbase` set to "tags". Tag pages will then automatically be created.
   An example of how to tag a post is:
        \[[!tag life]]
 
index 1f81687036187bba170aea03a7b8c1b921ad589a..0dbdba5df1fe37e79c7311ab74dc9194d7dc2810 100644 (file)
@@ -77,6 +77,8 @@ Ikiwiki aims to produce
 Ikiwiki generates html using [[templates]], and uses [[css]], so you
 can change the look and layout of all pages in any way you would like.
 
+Ikiwiki ships with several ready to use [[themes]].
+
 ## [[Plugins]]
 
 Plugins can be used to add additional features to ikiwiki. The interface is
diff --git a/doc/forum/404_-_not_found.mdwn b/doc/forum/404_-_not_found.mdwn
new file mode 100644 (file)
index 0000000..dc33189
--- /dev/null
@@ -0,0 +1,22 @@
+Hi,
+
+I've followed the tutorial to install ikiwiki.  Once installed (on a Ubuntu
+10.04 distro running under VirtualBox on a Windows XP, SP3 host), I can
+access the **http://ubuntu1004/index.lighttpd.html** page without any
+issues.
+
+But when I try to access the page **http://ubuntu1004/~geertvc/gwiki** (as
+is mentioned at the end of the ikiwiki setup), I get the error message
+"**404 - not found**".
+
+I've also followed the "dot-cgi" trick, but with the same negative result.
+The web server I've installed, is lighttpd.
+
+What did I miss?
+
+Best rgds,
+
+--Geert
+
+> Perhaps your webserver is not exporting your `public_html` directory
+> in `~geertvc`? Check its configuration. --[[Joey]] 
diff --git a/doc/forum/404_-_not_found/comment_1_3dea2600474f77fb986767da4d507d62._comment b/doc/forum/404_-_not_found/comment_1_3dea2600474f77fb986767da4d507d62._comment
new file mode 100644 (file)
index 0000000..453419c
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://jmtd.livejournal.com/"
+ ip="188.222.50.68"
+ subject="comment 1"
+ date="2010-09-09T21:41:07Z"
+ content="""
+You probably need to run \"lighttpd-enable-mod userdir\"
+"""]]
diff --git a/doc/forum/404_-_not_found/comment_2_948e4678be6f82d9b541132405351a2c._comment b/doc/forum/404_-_not_found/comment_2_948e4678be6f82d9b541132405351a2c._comment
new file mode 100644 (file)
index 0000000..c3fb72d
--- /dev/null
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawllEHb4oGNaUrl7vyziQGrxAlQFri_BfaE"
+ nickname="Geert"
+ subject="comment 2"
+ date="2010-09-12T06:45:27Z"
+ content="""
+After a re-installation of ikiwiki (first removed all old files), I get the following feedback:
+
+    Successfully set up gwiki:
+           url:         http://ubuntu1004/~geertvc/gwiki
+           srcdir:      ~/gwiki
+           destdir:     ~/public_html/gwiki
+           repository:  ~/gwiki.git
+    To modify settings, edit ~/gwiki.setup and then run:
+           ikiwiki -setup ~/gwiki.setup
+
+
+In the lighttpd config file (/etc/lighttpd/lighttpd.conf), I've now changed the item \"server.document-root\" from the default \"/var/www\" to (in my case) \"/home/geertvc/public_html/gwiki\".  I've taken the destdir location (see above) as document root for lighttpd.
+
+When doing this, I can see the \"index.html\" page of ikiwiki (by typing the following URL in the address box of the browser: \"ubuntu1004/index.html\").  So, that seems to be the right modification, right?  Or isn't it?
+
+Note: when I take the directory \"/home/geertvc/gwiki\" (= the URL given above), then things do not work.  I can't see the content of \"index.html\", I get the error message I mentioned in my initial post (404 - not found).
+
+But when clicking, for instance, the \"Edit\" button, the link brings me to the following location:
+
+    http://ubuntu1004/~geertvc/gwiki/ikiwiki.cgi?page=index&do=edit
+
+However, there's not at all a file called \"ikiwiki.cgi\" at that location.  The location of the file \"ikiwiki.cgi\" is \"/home/geertvc/public_html/gwiki\", so why is the link \"Edit\" leading me to that (wrong?) location?
+
+Apparently, something is still wrong with my settings.  Hope, with the above information, someone can put me on the right track...
+"""]]
diff --git a/doc/forum/404_-_not_found/comment_3_4c7b1fa88776815bbc6aa286606214c2._comment b/doc/forum/404_-_not_found/comment_3_4c7b1fa88776815bbc6aa286606214c2._comment
new file mode 100644 (file)
index 0000000..9f606f0
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://jmtd.livejournal.com/"
+ ip="78.105.191.131"
+ subject="Follow instructions"
+ date="2010-09-12T12:26:49Z"
+ content="""
+Please re-read my comment. If you enable usersdirs then /~user corresponds to ~/public_html. The change you have made has / corresponding instead, which is why the links don't work.
+"""]]
diff --git a/doc/forum/Asciidoc_plugin.mdwn b/doc/forum/Asciidoc_plugin.mdwn
new file mode 100644 (file)
index 0000000..57d6fd9
--- /dev/null
@@ -0,0 +1,14 @@
+I have completely overhauled the Asciidoc plugin for ikiwiki that was created by [[Karl Mowson|http://www.mowson.org/karl/colophon/]].  The source can be downloaded from my [[Dropbox|http://dl.dropbox.com/u/11256359/asciidoc.pm]].
+
+### Features
+
+* Uses a filter hook to escape WikiLinks and Directives using Asciidoc `+++` passthrough macros, to avoid them being processed by Asciidoc. This behavior is configurable in the wiki setup file.
+* Adds a preprocessor directive 'asciidoc' which allows extra Asciidoc command-line options to be passed on a per-page basis. Each parameter name is the option name (the leading `--` will be inserted automatically), and the parameter value is the option value. Currently, only 'conf-file' and 'doctype' are allowed (or even useful).
+* Sets the page title from the first line in the Asciidoc file using a meta directive. This behavior is configurable in the wiki setup file.
+* Searches for an Asciidoc configuration file named the same as the wiki if none is specified in the setup file.
+* Asciidoc configuration files are stored in the wiki. They should be named `._conf` to avoid publishing them.
+
+### Problems
+
+* Escaping Directives is not optimal. It prevents markup from being used in Directives, and the passthrough macros have to include extra spaces to avoid having directives that return an empty string collapse to `++++++`. In addition, I had to borrow the regexps from the Ikiwiki source code; it would be nice if this were available as part of the API.
+* Handling of Asciidoc errors is suboptimal; they are simply inserted into the returned page.  This could be fixed in Perl 5.12 by using the run_forked() in IPC::Cmd.
diff --git a/doc/forum/Blog_posting_times_and_ikiwiki_state.mdwn b/doc/forum/Blog_posting_times_and_ikiwiki_state.mdwn
new file mode 100644 (file)
index 0000000..0c1da5b
--- /dev/null
@@ -0,0 +1,28 @@
+What I wanted
+-------------
+
+I thought to myself it would be nice to see from the console the dates that my ikiwiki blog posts were published.  Especially as I would like to know the order of my todo list without having to view the webpage.
+
+What I discovered
+-----------------
+
+Looked at the code and saw the functions for grabbing the ctime from git but couldn't reconcile them to the "Posted" date in the RSS feed.  Some more reading and I figured out that the Posted time is taken from the UNIX ctime when first uploaded into the repository and this information is stored in the page state via a Perl storable database - indexdb. (I'm sure most know this but to be clear in UNIX ctime is *not* the actual creation time of a file. UNIX has no facility for recording the actual creation time - however on first upload to the wiki it's good enough).
+
+Wrote a Perl script to query and sort indexdb.  Now I can list my todos or blog posts in the order they appear on the web.  Handy.
+
+However the ikiwiki state is specifically excluded via '.gitignore'.  I work a lot on trains and not having this file in my cloned wiki means I can't list published posts or my todos in the proper order.  I can get an approximation from git logs but, dam it, I want it the same!
+
+What can I do?
+--------------
+
+Is it a spectacularly bad idea to include the ikiwiki state file in my cloned repo (I suspect it is).  What else could be done?  Can I disable pagestate somehow or force ikiwiki to always use git commit times for Posted times?
+
+> Have you tried running ikiwiki with the `--gettime` option on your laptop,
+> to force it to retrieve initial commit times from git? You should only
+> need to do that once, and it'll be cached in the pagestate thereafter.
+>
+> Because that functionality is slow on every supported VCS except git,
+> ikiwiki tries to avoid using it unless it's really needed. [[rcs]]
+> lists it as "fast" for git, though, so depending how fast it really is
+> and how large your wiki is, you might be able to get away with running
+> ikiwiki with `--gettime` all the time? --[[smcv]]
diff --git a/doc/forum/Blog_posting_times_and_ikiwiki_state/comment_1_87304dfa2caea7e526cdb04917524e8c._comment b/doc/forum/Blog_posting_times_and_ikiwiki_state/comment_1_87304dfa2caea7e526cdb04917524e8c._comment
new file mode 100644 (file)
index 0000000..62bae02
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmwYptyV5ptNt8LCbMYsmpcNkk9_DRt-EY"
+ nickname="Matt"
+ subject="comment 1"
+ date="2010-11-04T11:52:53Z"
+ content="""
+Perhaps I have a different setup from you but on my laptop I don't have ikiwiki installed - only a clone of the git repo.  You mean to run --gettime on the post-update git hook?
+"""]]
index 06b7fdd84cbeb082e404a655f386ec385d3dc7fd..f189d9b64f20946bdc7084e34c4063bc152748d0 100644 (file)
@@ -1,7 +1,16 @@
 I feel like I must be missing something.
 
-My blog is based on Ikiwiki, and uses /yyyy/mm/dd/title/ for blog posts. Because I use the plugin that generates index pages for subdirectories, I have to use /????/??/??/* to identify posts and avoid missing the index pages for years, months and days.
+My blog is based on Ikiwiki, and uses /yyyy/mm/dd/title/ for blog posts.
+Because I use the plugin that generates index pages for subdirectories, I
+have to use /????/??/??/* to identify posts and avoid missing the index
+pages for years, months and days.
 
 I've enabled the comments plugin, but no matter what I do, I can't seem to make the comment form appear on my posts. I've removed the entire site and have rebuilt. I've set the pagespec to /????/??/??/* and ./????/??/??/*, but neither seems to work. I don't see any output, or anything else to indicate that pages aren't working.
 
 Are there any other plugins that need to be enabled for this to work? I think I've locked things down such that anonymous users can't edit by enabling signinedit and setting a lock, but this may be blocking the ability to comment (though I don't recall seeing anything in the docs about needing additional plugins.)
+
+> Just use '????/??/??/*' , and it will work.
+> [[Pagespecs|ikiwiki/pagespec]] are automatically matched absolute to the
+> top of the site, and adding a leading "/" is not necessary and will 
+> make the PageSpec not match. (And the relative PageSpec with "./" is
+> not right in this case either). --[[Joey]] 
diff --git a/doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__.mdwn b/doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__.mdwn
new file mode 100644 (file)
index 0000000..8d67006
--- /dev/null
@@ -0,0 +1,7 @@
+I have been mucking about with ikiwiki for two whole days now. 
+
+I like many things about it. Even though I've been spending most of my time wrestling with css I did manage to write a whole lot of blog posts and love what ikiwiki is doing for the "revise" part of my writing cycle. And I like the idea of integrating the wiki and the blog into one unifying architecture....
+
+But... I would like very much to have different page templates for blogging and wiki-ing, some way of specifying that for stuff in the "/posts" directory I'd rather use blogpost.tmpl rather than page.tmpl. I just spent a few minutes looking at the perl for this (I assume Render.pm) and my mind dumped core...
+
+(generically, some way to specify output formatting on a subdirectory basis would be good) 
diff --git a/doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__/comment_1_15651796492a6f04a19f4a481947c97c._comment b/doc/forum/Different_templates_for_subdirectories__63_____40__Blogging_and_Wiki_pages__41__/comment_1_15651796492a6f04a19f4a481947c97c._comment
new file mode 100644 (file)
index 0000000..e92f410
--- /dev/null
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlY5yDefnXSHvWGbJ9kvhnAyQZiAAttENk"
+ nickname="Javier"
+ subject="comment 1"
+ date="2010-10-21T15:00:50Z"
+ content="""
+You can do what you want with the [[ikiwiki/directive/pagetemplate]] directive, but in a slightly cumbersome way, because you have to say what template you want in every page that differs from the default.
+
+See also: [[templates]]
+
+And, a perhaps more proper solution to your problem, although I don't fully understand the way of tackling it, in [[todo/multiple_template_directories]].
+
+If you could create a proper page in this wiki, centralizing all the knowledge dispersed in those pages, it would be nice ;)
+
+--[[jerojasro]]
+"""]]
diff --git a/doc/forum/Discussion_PageSpec__63__.mdwn b/doc/forum/Discussion_PageSpec__63__.mdwn
new file mode 100644 (file)
index 0000000..2860d0d
--- /dev/null
@@ -0,0 +1,3 @@
+I've looked around but haven't found it. Can you set a Discussion PageSpec so only certain pages allow discussion?
+
+> Not currently, sorry. --[[Joey]] 
diff --git a/doc/forum/Dump_plugin.mdwn b/doc/forum/Dump_plugin.mdwn
new file mode 100644 (file)
index 0000000..ff3bfea
--- /dev/null
@@ -0,0 +1,4 @@
+I have a second plugin that adds a directive 'dump', and dumps all sorts of information (env variables and template variables) about a page into the end of the page. It's cheesy, but it's available in my [[Dropbox|http://dl.dropbox.com/u/11256359/dump.pm]] as well as the Asciidoc plugin.
+
+### Issues
+* It really ought to use some kind of template instead of HTML. In fact, it ought to embed its information in template variables of some kind rather than stuffing it into the end of the page.
diff --git a/doc/forum/Dump_plugin/comment_1_bfce80b3f5be78ec28692330843d4ae1._comment b/doc/forum/Dump_plugin/comment_1_bfce80b3f5be78ec28692330843d4ae1._comment
new file mode 100644 (file)
index 0000000..855b72b
--- /dev/null
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawngqGADV9fidHK5qabIzKN0bx1ZIfvaTqs"
+ nickname="Glenn"
+ subject="New dump plugin"
+ date="2010-10-03T00:45:47Z"
+ content="""
+I took my own advice and rewrote the dump plugin so that it uses a template.  A sample template has been added to my [[Dropbox|http://dl.dropbox.com/u/11256359/dump.tmpl]].
+
+### Issues:
+
+* Dumps appear at the end of the page rather than where the directive occurs.
+* For some reason I haven't yet figured out, dumps don't appear in page previews.
+* I haven't tested inlined content and the dump plugin.
+"""]]
diff --git a/doc/forum/Forward_slashes_being_escaped_as_252F.mdwn b/doc/forum/Forward_slashes_being_escaped_as_252F.mdwn
new file mode 100644 (file)
index 0000000..5df81e5
--- /dev/null
@@ -0,0 +1,33 @@
+When I try to edit a page that has a forward slash in the URL, I get "Error:
+bad page name". I think the problem is because the forward slash is escaped as
+`%252F` instead of `%2F`.
+
+For example, if I go to `http://ciffer.net/~svend/tech/hosts/` and click Edit,
+I am sent to a page with the URL
+`http://ciffer.net/~svend/ikiwiki.cgi?page=tech%252Fhosts&do=edit`.
+
+I am running ikiwiki 3.20100504~bpo50+1 on Debian Lenny.
+
+
+> But on your page, the Edit link is escaped normally and correctly (using %2F).
+> Look at the page source!
+> 
+> The problem is that your web server is forcing a hard (302) redirect
+> to the doubly-escaped url. In wireshark I see your web server send back:
+
+       HTTP/1.1 302 Found\r\n
+       Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch
+       Location: http://ciffer.net/~svend/ikiwiki.cgi?page=tech%252Fhosts&do=edit
+
+> You'll need to investigate why your web server is doing that... --[[Joey]]
+
+>> Thanks for pointing me in the right direction. I have the following redirect
+>> in my Apache config.
+
+       RewriteEngine on
+       RewriteCond %{HTTP_HOST} ^www\.ciffer\.net$
+       RewriteRule /(.*) http://ciffer.net/$1 [L,R]
+
+>> and my ikiwiki url setting contained `www.ciffer.net`, which was causing the
+>> redirect. Correcting the url fixed the problem. I'm still not sure why
+>> Apache was mangling the URL. --[[Svend]]
diff --git a/doc/forum/How_to_list_new_pages__44___inline__63__.mdwn b/doc/forum/How_to_list_new_pages__44___inline__63__.mdwn
new file mode 100644 (file)
index 0000000..f28e8b9
--- /dev/null
@@ -0,0 +1,5 @@
+Hi, I'd love to include a "New posts" list into my front page, like at <http://danhixon.github.com/> for example.
+
+It should be different from recent changes in that it shouldn't show modifications of existing pages, and in that it would be inside a page with other content.
+
+Thanks, Thomas
diff --git a/doc/forum/How_to_list_new_pages__44___inline__63__/comment_1_e989b18bade34a92a9c8fe7099036e15._comment b/doc/forum/How_to_list_new_pages__44___inline__63__/comment_1_e989b18bade34a92a9c8fe7099036e15._comment
new file mode 100644 (file)
index 0000000..cf6f642
--- /dev/null
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="use an inline directive"
+ date="2010-11-29T20:39:37Z"
+ content="""
+This is what the [[ikiwiki/directive/inline]] directive is for. It's often used, to for example, show new posts to a blog. If you want to show new posts to anywhere in your site, or whatever, you can configure the [[ikiwiki/PageSpec]] in it to do that, too. 
+
+For example, you could use this:
+
+    The most recent 3 pages added to this site:
+    \[[!inline pages=\"*\" archive=yes show=4]]
+"""]]
diff --git a/doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links.mdwn b/doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links.mdwn
new file mode 100644 (file)
index 0000000..fcffe69
--- /dev/null
@@ -0,0 +1,3 @@
+Map Plugin, would like to add ?updated to all links created.
+
+When I edit a page and then click that page in a map in a sidebar Safari always shows me a cached page. 
diff --git a/doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links/comment_1_3fe4c5967e704355f9b594aed46baf67._comment b/doc/forum/Map_Plugin__44___would_like_to_add___63__updated_to_all_links/comment_1_3fe4c5967e704355f9b594aed46baf67._comment
new file mode 100644 (file)
index 0000000..ce1a785
--- /dev/null
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="justint"
+ ip="24.182.207.250"
+ subject="skip it"
+ date="2010-10-13T05:30:50Z"
+ content="""
+skip it, I added 
+
+    <meta http-equiv=\"expires\" value=\"Thu, 16 Mar 2000 11:00:00 GMT\" />
+    <meta http-equiv=\"pragma\" content=\"no-cache\" />
+
+to my page.tmpl and the problem went away.
+"""]]
diff --git a/doc/forum/Moving_wiki.git_folder__63__.mdwn b/doc/forum/Moving_wiki.git_folder__63__.mdwn
new file mode 100644 (file)
index 0000000..77d1da1
--- /dev/null
@@ -0,0 +1,17 @@
+Hi folks, I created a simple wiki to keep notes and references for projects, it's worked quite nice so far.  I decided to use git as it's what I use daily to manage code, and it's available on all my machines.
+
+Anyway, I wanted to move all the wiki source stuff into a subfolder so that it stops cluttering up my ~ directory.  However, there seems to be a problem with moving wiki.git (I moved wiki, wiki.git and wiki.setup) and I'm not sure where to tell ikiwiki that the git directory has been moved.  I changed 
+
+    srcdir => '/home/pixel/.notebook/wiki',
+    git_wrapper => '/home/pixel/.notebook/wiki.git/hooks/post-update',
+
+and that seems to be fine.  However when I go to run ikiwiki --setup things go wrong:
+
+    pixel@tosh: [~ (ruby-1.9.2-p0)] ➔ ikiwiki -setup .notebook/wiki.setup 
+    successfully generated /home/pixel/public_html/wiki/ikiwiki.cgi
+    successfully generated /home/pixel/.notebook/wiki.git/hooks/post-update
+    fatal: '/home/pixel/wiki.git' does not appear to be a git repository
+    fatal: The remote end hung up unexpectedly
+    'git pull origin' failed:  at /usr/share/perl5/IkiWiki/Plugin/git.pm line 193.
+
+I've gone through wiki.setup and nothing has jumped out as the place to set this, have I missed something?
diff --git a/doc/forum/Moving_wiki.git_folder__63__/comment_1_05238461520613f4ed1b0d02ece663bd._comment b/doc/forum/Moving_wiki.git_folder__63__/comment_1_05238461520613f4ed1b0d02ece663bd._comment
new file mode 100644 (file)
index 0000000..d654591
--- /dev/null
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://users.itk.ppke.hu/~cstamas/openid/"
+ ip="212.183.140.47"
+ subject="comment 1"
+ date="2010-10-27T22:45:28Z"
+ content="""
+I think you want to edit
+
+    .git/config
+
+"""]]
diff --git a/doc/forum/Moving_wiki.git_folder__63__/comment_2_72b2b842dfa0cfaf899fe7af12977519._comment b/doc/forum/Moving_wiki.git_folder__63__/comment_2_72b2b842dfa0cfaf899fe7af12977519._comment
new file mode 100644 (file)
index 0000000..f2e7ece
--- /dev/null
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://pixel.dreamwidth.org/"
+ ip="65.29.14.21"
+ subject="comment 2"
+ date="2010-10-28T02:54:15Z"
+ content="""
+That did it thanks!
+
+Should I make some sort of edit in the setup page?  I've used git for a while and for whatever reason it never occurred to me that this was from git, not from ikiwiki itself.
+"""]]
diff --git a/doc/forum/Need_something_more_powerful_than_Exclude.mdwn b/doc/forum/Need_something_more_powerful_than_Exclude.mdwn
new file mode 100644 (file)
index 0000000..5e80432
--- /dev/null
@@ -0,0 +1,5 @@
+When I originally looked at the "exclude" option, I thought it meant that it excluded pages completely, but it apparently doesn't.  What I've found in practice is that a file which matches the "exclude" regex is excluded from *processing*, but it is still copied over to the destination directory.  Thus, for example, if I have "^Makefile$" as the exclude pattern, and I have a file `src/foo/Makefile`, then that file is copied unaltered into `dest/foo/Makefile`.  However, what I want is for `src/foo/Makefile` to be completely ignored: that it is not only not processed, but not even *copied* into the destination directory.
+
+I'm not sure if the current behaviour is a bug or a feature, but I would like a "totally ignore this file" feature if it's possible to have one.
+
+-- [[KathrynAndersen]]
diff --git a/doc/forum/Need_something_more_powerful_than_Exclude/comment_2_0019cd6b34c8d8678b2532de57a92d15._comment b/doc/forum/Need_something_more_powerful_than_Exclude/comment_2_0019cd6b34c8d8678b2532de57a92d15._comment
new file mode 100644 (file)
index 0000000..7842cae
--- /dev/null
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://smcv.pseudorandom.co.uk/"
+ nickname="smcv"
+ subject="expression anchored too closely?"
+ date="2010-11-23T10:43:21Z"
+ content="""
+It looks as though you might only be excluding a top-level Makefile, and not a Makefile in subdirectories. Try excluding `(^|/)Makefile$` instead, for instance? (See `wiki_file_prune_regexps` in `IkiWiki.pm` for hints.)
+
+The match operation in `&file_pruned` ends up a bit like this:
+
+    \"foo/Makefile\" =~ m{…|…|…|(^|/)Makefile$}
+"""]]
diff --git a/doc/forum/Need_something_more_powerful_than_Exclude/comment_2_f577ab6beb9912471949d8d18c790267._comment b/doc/forum/Need_something_more_powerful_than_Exclude/comment_2_f577ab6beb9912471949d8d18c790267._comment
new file mode 100644 (file)
index 0000000..bd964d5
--- /dev/null
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://kerravonsen.dreamwidth.org/"
+ ip="60.241.8.244"
+ subject="Missed It By That Much"
+ date="2010-11-25T02:55:20Z"
+ content="""
+I discovered that I not only needed to change the regexp, but I also needed to delete .ikiwiki/indexdb because `file_pruned` only gets called for files that aren't in the `%pagesources` hash, and since the file in question was already there because it had been put there before the exclude regex was changed, it wasn't even being checked!
+
+[[KathrynAndersen]]
+
+"""]]
diff --git a/doc/forum/Need_something_more_powerful_than_Exclude/comment_3_1ed260b0083a290688425a006a83f603._comment b/doc/forum/Need_something_more_powerful_than_Exclude/comment_3_1ed260b0083a290688425a006a83f603._comment
new file mode 100644 (file)
index 0000000..8b93acd
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2010-11-29T20:41:49Z"
+ content="""
+`%pagesources` gets nuked when you rebuild the whole wiki with eg, ikiwiki -setup or ikiwiki -rebuild. So you shouldn't normally need to remove the indexdb, just rebuild when making this sort of change that affects the whole site.
+"""]]
diff --git a/doc/forum/Need_something_more_powerful_than_Exclude/comment_4_c39bdaf38e1e20db74eb26f0560bd673._comment b/doc/forum/Need_something_more_powerful_than_Exclude/comment_4_c39bdaf38e1e20db74eb26f0560bd673._comment
new file mode 100644 (file)
index 0000000..15f1fec
--- /dev/null
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://kerravonsen.dreamwidth.org/"
+ ip="60.241.8.244"
+ subject="comment 4"
+ date="2010-11-30T02:35:43Z"
+ content="""
+One would think that would be the case, yes, but for some reason it didn't work for me. 8-(
+
+[[KathrynAndersen]]
+"""]]
diff --git a/doc/forum/PageSpec_results_from_independent_checkout.mdwn b/doc/forum/PageSpec_results_from_independent_checkout.mdwn
new file mode 100644 (file)
index 0000000..693287d
--- /dev/null
@@ -0,0 +1,8 @@
+I'd like to be able to do PageSpec matches independent of the Ikiwiki checkout, but at best I'm currently restricted to copying over and using whatever is in the indexdb with this approach:
+
+    perl -MIkiWiki -le '$config{wikistatedir}=".ikiwiki"; IkiWiki::loadindex(); print foreach pagespec_match_list("", shift)' "bugs/*"
+
+I get the impression there's a way to build up enough state to run pagespec matches without doing any rendering, but I don't know how. Any ideas? -- JoeRayhawk
+
+> It's not possible to build up enough state without at a minimum
+> performing the scan pass of rendering on every page. --[[Joey]] 
index 3563e3e0133bef9118054e65384ccffadb3626f1..0c5221cc9b832ba9933c8910522c8746e9324f4e 100644 (file)
@@ -3,7 +3,7 @@ has \[[!cut id=foo text="foo"]], and fileB does \[[!absorb pagenames=fileA]],
 and can then use \[[!paste id=foo]].
 
 Therefore, I've written an [*absorb* directive /
-plugin](http://www.thomas.schwinge.homeip.net/tmp/absorb.pm), which is meant to
+plugin](http://schwinge.homeip.net/~thomas/tmp/absorb.pm), which is meant to
 absorb pages in order to get hold of their *cut* and *copy* directives'
 contents.  This does work as expected.  But it also absorbs page fileA's *meta*
 values, like a *meta title*, etc.  How to avoid / solve this?
index 8bddab3fbcfd13ebe7ab60c8728f7cc46180617e..eb534365ee33acbf770dda431e19cbc6642b097b 100644 (file)
@@ -1 +1,11 @@
 Is it possible to edit a comment? I did not find any button for it.
+
+> It was a design decision to not allow editing comments via the web
+> interface. The thinking being that comments on blogs tend to not allow
+> editing, and allowing wiki-style editing by anyone would sort of defeat
+> the purpose of comments.
+> 
+> I do think there is room to support more forum-style comments in ikiwiki.
+> As long as the comment is not posted by an anonymous user, it would be
+> possible to open up editing to the original commenter. One day, perhaps..
+> --[[Joey]] 
diff --git a/doc/forum/field_and_forms.mdwn b/doc/forum/field_and_forms.mdwn
new file mode 100644 (file)
index 0000000..97fda18
--- /dev/null
@@ -0,0 +1,13 @@
+Dear ikiwiki users, and specially [[users/KathrynAndersen]] ([[users/rubykat]]):
+have you considered some way of extending ikiwiki to allow some kind of
+on-the-fly generation of web forms to create new pages? these web forms should
+offer as many fields as one has defined in some [[page
+template|plugins/contrib/ftemplate]], and, once POSTed, should create a page
+using that template, with those fields already filled with the values the user
+provided.
+
+I see this a a generalization of the `postform` option of the
+[[ikiwiki/directive/inline]] directive. That option tells ikiwiki to create a
+form with one field already filled (title).
+
+What are your ideas about this?
diff --git a/doc/forum/field_and_forms/comment_1_a0e976cb79f03dcff5e9a4511b90d160._comment b/doc/forum/field_and_forms/comment_1_a0e976cb79f03dcff5e9a4511b90d160._comment
new file mode 100644 (file)
index 0000000..3e10dbb
--- /dev/null
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://kerravonsen.dreamwidth.org/"
+ ip="60.241.8.244"
+ subject="Limitations"
+ date="2010-11-23T02:18:52Z"
+ content="""
+I'd already had a look at this idea before you posted this suggestion, and I ran into difficulties.
+So far as I can see, it makes most sense to use the mechanisms already in place for editing pages, and enhance them.
+Unfortunately, the whole edit-page setup expects a template file (by default, when editing pages, editpage.tmpl)
+and anything apart from \"submit\" buttons must have a placeholder in the template file, or it doesn't get displayed at all in the form.
+At least, that's what I've found - I could be mistaken.
+
+But if it's true, that rather puts the kybosh on dynamically generated forms, so far as I can see.
+I mean, if you knew beforehand what all your fields were going to be, you could make a copy of editpage.tmpl, add in your fields where you want, and then make a plugin that uses that template instead of editpage.tmpl, but that's very limited.
+
+If someone could come up with a way of making dynamic forms, that would solve the problem, but I've come up against a brick wall myself.  Joey?  Anyone?
+
+-- [[KathrynAndersen]]
+"""]]
diff --git a/doc/forum/how_can_I_use___39____47____39___as_tagbase__63__.mdwn b/doc/forum/how_can_I_use___39____47____39___as_tagbase__63__.mdwn
new file mode 100644 (file)
index 0000000..8a24152
--- /dev/null
@@ -0,0 +1,13 @@
+I'd like tags to be top-level pages, like /some-tag.
+
+I achieve this most of the time by *not* defining `tagbase`.
+
+However, this goes wrong if the name of a tag matches the name of a page further down a tree.
+
+Example:
+
+ * tag scm, corresponding page /scm
+ * a page /log/scm tagged 'scm' does not link to /scm
+ * a page /log/puppet tagged 'scm' links to /log/scm in the Tags: section
+
+Is this possible, or am I pushing tags too far (again)? -- [[Jon]]
diff --git a/doc/forum/how_can_I_use___39____47____39___as_tagbase__63__/comment_1_e7897651ba8d9156526d36d6b7744eae._comment b/doc/forum/how_can_I_use___39____47____39___as_tagbase__63__/comment_1_e7897651ba8d9156526d36d6b7744eae._comment
new file mode 100644 (file)
index 0000000..361c51b
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2010-12-05T20:15:28Z"
+ content="""
+From the code, it seems to me like setting tagbase to \"/\" would actually do what you want. Does it not work?
+"""]]
index 7686a7a083ed6e2b858a58a6cf9b6687092419ee..d69b3801b5b08e7220e4033498848ba3fb691b6b 100644 (file)
@@ -33,3 +33,14 @@ Puzzled a bit :-/
 >>>> had its own history browser (somewhere down my todo list). --[[schmonz]]
 
 >>>> Yup, having a possibility to revert a single file would suffice.
+
+---
+
+Perer Gammie and I are working on reversion over at [[todo/web_reversion]].
+--[[Joey]] 
+
+Update: Web reversion is now supported by ikiwiki. Only changes committed
+to your wiki after you upgrade to the version of ikiwiki that supports it
+will get revert buttons on the RecentChanges page. If you want to force
+adding buttons for older changes, you can delete `recentchanges/*._change`
+from your srcdir, and rebuild the wiki. --[[Joey]] 
diff --git a/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__/comment_1_e4720e8e4fe74bd6cba746e8259832e6._comment b/doc/forum/how_do_I_revert_edits_in_the_web_mode__63__/comment_1_e4720e8e4fe74bd6cba746e8259832e6._comment
new file mode 100644 (file)
index 0000000..597cab2
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmlZJCPogIE74m6GSCmkbJoMZiWNOlXcjI"
+ nickname="Ian"
+ subject="comment 1"
+ date="2010-09-24T19:01:08Z"
+ content="""
++1 for a \"revert\" web plugin which at least handles the simple cases. -- Ian Osgood, The TOVA Company
+"""]]
diff --git a/doc/forum/ikiwiki_+_mathjax.mdwn b/doc/forum/ikiwiki_+_mathjax.mdwn
new file mode 100644 (file)
index 0000000..1279a2c
--- /dev/null
@@ -0,0 +1 @@
+Is it possible to use [mathjax](http://www.mathjax.org/) in ikiwiki to typeset math formulas? If so, is this compatible with the [wmd](http://ikiwiki.info/plugins/wmd/) plugin?
diff --git a/doc/forum/ikiwiki_vim_integration.mdwn b/doc/forum/ikiwiki_vim_integration.mdwn
new file mode 100644 (file)
index 0000000..4724807
--- /dev/null
@@ -0,0 +1,17 @@
+Hi all. I upgraded the [ikiwiki-nav plugin](http://www.vim.org/scripts/script.php?script_id=2968)
+so that now it supports:
+
+  * Jumping to the file corresponding to the wikilink under the cursor.
+  * Creating the file corresponding to the wikilink under the cursor (including
+  directories if necessary.)
+  * Jumping to the previous/next wikilink in the current file.
+  * Autocomplete link names.
+
+Download it from [here](http://www.vim.org/scripts/script.php?script_id=2968)
+
+I've also created a new page unifying all the hints available here to use vim
+with ikiwiki files, in [[tips/vim_and_ikiwiki]]
+
+
+--[[jerojasro]]
+
index 7d3ed8b02294ca165f4f4c0ead128ce1aed7b34e..a46c7e4c1d7249e871f9788c9b5a752b2c0553fe 100644 (file)
@@ -1,5 +1,10 @@
+This page is deprecated. See [[tips/vim_and_ikiwiki]] for the most up to date
+content.
+
+------
+
 I extended the functionality of the [ikiwiki-nav plugin](http://www.vim.org/scripts/script.php?script_id=2968)
-(see [[here|tips/follow_wikilinks_from_inside_vim]]) to allow completion of
+(see [[here|tips/vim_ikiwiki_ftplugin]]) to allow completion of
 wikilinks from inside vim, through the omnicompletion mechanism.
 
 It still has some bugs, but is usable, and will not destroy your data. It can
diff --git a/doc/forum/recovering_original_title_with_meta_directive.mdwn b/doc/forum/recovering_original_title_with_meta_directive.mdwn
new file mode 100644 (file)
index 0000000..ad0b02a
--- /dev/null
@@ -0,0 +1 @@
+When using the \[[!meta title=""]] directive, the documentation states that a template variable is set when the title is overridden.  However, how does one recover the original page title? --[[Glenn|geychaner@mac.com]]
index d609fd502fcdab9d18c2408144258e8bbe3f4ee6..03a77b16def7016772f1f667bf53ff42715c7229 100644 (file)
@@ -9,3 +9,10 @@ Approaches:
 3. some other approach I haven't thought of.
 
 I'm afraid that whatever approach I take, it will end up being a kludge.
+
+> Well, it should be perfectly fine, and non-kludgy for a single page to
+> generate multiple html files. Just make sure that html files have names
+> that won't conflict with the html files generated by some other page.
+> 
+> Of course the caveat is that since such files are not pages, you won't 
+> be able to use wikilinks to link directly to them, etc. --[[Joey]]
diff --git a/doc/forum/using_l10n__39__d_basewiki.mdwn b/doc/forum/using_l10n__39__d_basewiki.mdwn
new file mode 100644 (file)
index 0000000..a361d18
--- /dev/null
@@ -0,0 +1,7 @@
+Hey there!
+
+I'm trying to get the translated version of basewiki activated in my wiki. Setting "locale => 'de_DE.UTF-8'" gave me some german messages on the CLI and a few changes in the wiki itself but the basewiki is still english. The files in /usr/share/ikiwiki/po/de/ are there.
+
+As I understand, [[plugins/po]] is just for translating.
+
+So, what am I doing wrong? 
diff --git a/doc/forum/using_l10n__39__d_basewiki/comment_1_eaab671848ee6129f6fe9399474eeac0._comment b/doc/forum/using_l10n__39__d_basewiki/comment_1_eaab671848ee6129f6fe9399474eeac0._comment
new file mode 100644 (file)
index 0000000..1f21b48
--- /dev/null
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2010-12-05T20:12:17Z"
+ content="""
+The translated basewiki depends on the po plugin being enabled and configured with the language(s) to use.
+"""]]
diff --git a/doc/forum/using_l10n__39__d_basewiki/comment_2_d907676a1db1210ca59506673c564359._comment b/doc/forum/using_l10n__39__d_basewiki/comment_2_d907676a1db1210ca59506673c564359._comment
new file mode 100644 (file)
index 0000000..c8d1e4e
--- /dev/null
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://xlogon.net/bacuh"
+ ip="93.182.190.4"
+ subject="comment 2"
+ date="2010-12-05T22:48:53Z"
+ content="""
+This works, thanks.
+
+But is there also a way to get \"Edit\" etc. and the buttons behind it translated?
+"""]]
diff --git a/doc/forum/using_l10n__39__d_basewiki/comment_3_5e9d5bc5ecaf63f9bfe3315b09a279aa._comment b/doc/forum/using_l10n__39__d_basewiki/comment_3_5e9d5bc5ecaf63f9bfe3315b09a279aa._comment
new file mode 100644 (file)
index 0000000..f72bb37
--- /dev/null
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2010-12-05T22:53:12Z"
+ content="""
+That requires translating the templates, which has never quite been finished. [[todo/l10n]] discusses that.
+
+(You can edit the templates yourself of course and manually translate.)
+"""]]
diff --git a/doc/forum/using_svn+ssh_with_ikiwiki.mdwn b/doc/forum/using_svn+ssh_with_ikiwiki.mdwn
new file mode 100644 (file)
index 0000000..8d9c27e
--- /dev/null
@@ -0,0 +1,11 @@
+Just as an experiment, I tried running ikiwiki using a remote repository, i.e. via "svn+ssh". After setting up the repo and relocating the working copy, unfortunately, it doesn't work; editing a page gives the error:
+
+> Error: no element found at line 3, column 0, byte 28 at /opt/local/lib/perl5/vendor_perl/5.10.1/darwin-multi-2level/XML/Parser.pm line 187
+
+I think this is because, despite a SetEnv directive in the apache configuration, the CGI wrapper is expunging SVN_SSH from the environment (based on perusing the source of Wrapper.pm and looking at "envsave" there at the top). Is this the case? --[[Glenn|geychaner@mac.com]]
+
+> That seems likely. You can edit Wrapper.pm and add SVN_SSH to the @envsave list and rebuild your wrappers to test it. --Joey
+
+A better way(?) would be to add a plugin to set the SVN_SSH variable at the appropriate moment (or even to add this to the SVN plugin).  What kind of hook should this be; it needs to run just *after* the CGI script cleans its environment? --[[Glenn|geychaner@mac.com]]
+
+Actually, this probably doesn't need to be a plugin; setting SVN_SSH in ENV can probably be done through the setup file.  (Right?)  --[[Glenn|geychaner@mac.com]]
index 88608d4b550dc0e3e8969ef053a0c67c06fb2836..5943097e64b4ffd0b4a3b2557c70489ce55f2449 100644 (file)
@@ -65,6 +65,7 @@ think about merging them. This is recommended. :-)
 * [[privat]] `git://github.com/privat/ikiwiki.git`
 * [[blipvert]] `git://github.com/blipvert/ikiwiki.git`
 * [[bzed|BerndZeimetz]] `git://git.recluse.de/users/bzed/ikiwiki.git`
+* [[wtk]]: `git://github.com/wking/ikiwiki.git`
 
 ## branches
 
diff --git a/doc/ikiwiki/directive/aggregate/discussion.mdwn b/doc/ikiwiki/directive/aggregate/discussion.mdwn
new file mode 100644 (file)
index 0000000..ddece97
--- /dev/null
@@ -0,0 +1,10 @@
+It would be awesome if table could aggregrate remote CSVs too. I want something like:
+
+     !table file="http://cyclehireapp.com/cyclehirelive/cyclehire.csv"
+
+> Ok, but that has nothing to do with the aggregate plugin. File a
+> [[todo]]?
+> 
+> Anyway, it seems difficult, how would it know when the remote content
+> had changed? Aggregate has its cron job support and has time stamps
+> in rss feeds to rely on. --[[Joey]] 
index 2cbf70cdf4af699f2ec30ad72bd1fc6aac14cf56..492adf4993239ea775ba2756eaa0a08c3a8fe12a 100644 (file)
@@ -43,6 +43,8 @@ with the following additional tests:
 
 * included()
 
-  Tests whether the page is being included onto another page.
+  Tests whether the page is being included onto another page, for example
+  via [[inline]] or [[map]].  Note that pages inserted into other pages
+  via [[template]] are not matched here.
 
 [[!meta robots="noindex, follow"]]
index 50655191001371b9c34d4c305c118676b7e4f80e..bda1427f39b6d3e688dc589b4ffd82aa3b09dc19 100644 (file)
@@ -11,6 +11,11 @@ leads to the full version of the page. Use it like this:
 
 If the `linktext` parameter is omitted it defaults to just "more".
 
+An optional `pages` parameter can be used to specify a
+[[ikiwiki/PageSpec]], and then the "more" link will only be displayed
+when the page is inlined into a page matching that PageSpec, and otherwise
+the full content shown.
+
 Note that you can accomplish something similar using a [[toggle]] instead.
 
 [[!meta robots="noindex, follow"]]
diff --git a/doc/ikiwiki/directive/table/discussion.mdwn b/doc/ikiwiki/directive/table/discussion.mdwn
new file mode 100644 (file)
index 0000000..87d2e0c
--- /dev/null
@@ -0,0 +1 @@
+The problem I have in my tables, is that some fields contain example HTML that needs to be escaped.
index 6c50fa32e45e370af28c94c0a027633aa9accc21..9e3ae54dfd6209c92528ace49ad5ae2b3279d486 100644 (file)
@@ -34,11 +34,15 @@ large chunks of marked up text to be embedded into a template:
 The template is a regular wiki page, located in the `templates/`
 subdirectory inside the source directory of the wiki.
 
-(Alternatively, templates can be stored in a directory outside the wiki,
+Alternatively, templates can be stored in a directory outside the wiki,
 as files with the extension ".tmpl".
-By default, these are searched for in `/usr/share/ikiwiki/templates`;
+By default, these are searched for in `/usr/share/ikiwiki/templates`,
 the `templatedir` setting can be used to make another directory be searched
-first.)
+first.  When referring to templates outside the wiki source directory, the "id"
+parameter is not interpreted as a pagespec, and you must include the full filename
+of the template page, including the ".tmpl" extension. E.g.:
+
+    \[[!template id=blogpost.tmpl]]
 
 The template uses the syntax used by the [[!cpan HTML::Template]] perl
 module, which allows for some fairly complex things to be done. Consult its
index c66395f8441397764124e4fe693a17f18dc5767a..fe1af4c153404c35aa21232c7d0f68ddfad55f6b 100644 (file)
@@ -32,6 +32,7 @@ Some more elaborate limits can be added to what matches using these functions:
   tags matched by a glob)
 * "`backlink(page)`" - matches only pages that a given page links to
 * "`creation_month(month)`" - matches only files created on the given month
+  number
 * "`creation_day(mday)`" - or day of the month
 * "`creation_year(year)`" - or year
 * "`created_after(page)`" - matches only files created after the given page
@@ -78,3 +79,7 @@ filenames of the pages in the wiki, so a pagespec "foo" used on page
 "a/b" will not match a page named "a/foo" or "a/b/foo". To match
 relative to the directory of the page containing the pagespec, you can
 use "./". For example, "./foo" on page "a/b" matches page "a/foo".
+
+To indicate the name of the page the PageSpec is used in, you can
+use a single dot. For example, `link(.)` matches all the pages
+linking to the page containing the PageSpec.
index e76d547cc4b5c081279695dae21c74f2495647bc..cd274c4451bf126237e5ccd5c5899b3fed643500 100644 (file)
@@ -60,7 +60,7 @@ Projects & Organizations
 * [Serialist](http://serialist.net/)'s static pages (documentation, blog).  We actually have ikiwiki generate its static content as HTML fragments using a modified page.tmpl template, and then the FastCGI powering our site grabs those fragments and embeds them in the standard dynamic site template.
 * [Apua IT](http://apua.se/)
 * [PDFpirate Community](http://community.pdfpirate.org/)
-* [Banu](https://www.banu.com/)
+* [Banu](https://banu.com/) uses Ikiwiki for its website, to convert static Markdown pages into PHP scripts which are served along with non-Ikiwiki PHP generated contents. The static contents benefit from use of Ikiwiki's plugins. Ikiwiki is purely used as a CMS and no wiki or web-based editing is allowed. Ikiwiki is run offline, and the resulting scripts are uploaded using rsync to the website.
 
 Personal sites and blogs
 ========================
@@ -154,10 +154,15 @@ Personal sites and blogs
 * [Ertug Karamatli](http://pages.karamatli.com)
 * [Jonatan Walck](http://jonatan.walck.i2p/) a weblog + wiki over [I2P](http://i2p2.de/). Also [mirrored](http://jonatan.walck.se/) to the Internet a few times per day.
 * [Daniel Wayne Armstrong](http://circuidipity.com/)
-* [Mukund](https://www.mukund.org/)
+* [Mukund](https://mukund.org/)
 * [Nicolas Schodet](http://ni.fr.eu.org/)
 * [weakish](http://weakish.github.com)
 * [Thomas Kane](http://planetkane.org/)
+* [Marco Silva](http://marcot.eti.br/) a weblog + wiki using the [darcs](http://darcs.net) backend
+* [NeX-6](http://nex-6.taht.net/) ikiwiki blog and wiki running over ipv6
+* [Jason Riedy](http://lovesgoodfood.com/jason/), which may occasionally look funny if I'm playing with my branch...
+* [pmate](http://pmate.nfshost.com)'s homepage and [blog](http://pmate.nfshost.com/blog/)
+* [tychoish.com](http://tychoish.com/) - a blog/wiki mashup. blog posts are "rhizomes."
 
 Please feel free to add your own ikiwiki site!
 
index cc3a4c29f186ca1d0c952c28b14733dda70d0659..f38ae2aabacacc72cef9a2f93aac21c305cedade 100644 (file)
@@ -41,5 +41,6 @@ If you're using a shared hosting provider, of the sort where you don't have
 root, you can still install ikiwiki. There are tutorials covering this for
 a few providers:
 
+
 * [[tips/NearlyFreeSpeech]]
 * [[tips/DreamHost]]
index 02cdb29c915092bdeb3ac55b0eb32464d73f5f8d..c06893ec1c0880f1646c88ed3f160d252681577f 100644 (file)
@@ -269,3 +269,65 @@ Any suggestions? Whew!
        perl Makefile.PL INSTALL_BASE=$HOME PREFIX=
        make
        make install
+
+---
+
+03 September 2010, Report on successful manual install in Debian 5 (Lenny) AMD64:
+
+note: Maybe much more easy using backports, but using this tools you get a plain user cpan  :)
+
+This where my steps:
+
+As root (#):
+
+        aptitude install build-essential curl perl
+
+
+As plain user ($), I use to install user perl modules using local::lib
+
+        mkdir -p "$HOME/downloads"
+        cd "$HOME/downloads/"
+        wget http://search.cpan.org/CPAN/authors/id/G/GE/GETTY/local-lib-1.006007.tar.gz
+        wget http://ftp.de.debian.org/debian/pool/main/i/ikiwiki/ikiwiki_3.20100831.tar.gz
+        tar -zxf local-lib-1.006007.tar.gz 
+        cd local-lib-1.006007/
+        perl Makefile.PL --bootstrap=~/.perl5
+        make test && make install
+        echo 'eval $(perl -I$HOME/.perl5/lib/perl5 -Mlocal::lib=$HOME/.perl5)' >>~/.bashrc
+        . ~/.bashrc
+        curl -L http://cpanmin.us | perl - App::cpanminus
+        cpanm CGI::FormBuilder
+        cpanm CGI::Session
+        cpanm HTML::Parser
+        cpanm HTML::Template
+        cpanm HTML::Scrubber
+        cpanm Text::Markdown
+        cpanm URI
+        cd ..
+        tar -zxf ikiwiki_3.20100831.tar.gz
+        cd ikiwiki/
+        perl Makefile.PL INSTALL_BASE= PREFIX=/home/$USER/.perl5
+        make test    # All tests successful.
+        make install INSTALL_BASE=/home/$USER/.perl5
+        . ~/.bashrc
+
+Using cpan or cpanm with local::lib, you can install any other dependency, as plain user (in your home). XS modules may need -dev packages.
+
+After all, here it's:
+
+        ikiwiki -version
+        ikiwiki version 3.20100831
+
+It seems like this installation looses the /etc files (we're as plain user), but this can be used as a workaround:
+
+        ikiwiki -setup ~/downloads/ikiwiki/auto.setup
+
+I've not investigated more the /etc files ussage, but does not seems like a good idea to be as plain user...
+
+        /etc/ikiwiki/wikilist does not exist
+        ** Failed to add you to the system wikilist file.
+        ** (Probably ikiwiki-update-wikilist is not SUID root.)
+        ** Your wiki will not be automatically updated when ikiwiki is upgraded.
+
+
+Iñigo
index 4f1ee7bf75c88dfbcae70e735f9f3186629515d4..87f640321b15a4399c04a9bebd62e569b247376e 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 64 "Accept only OpenID for logins" 21 "Accept only password logins" 36 "Accept both"]]
+[[!poll 67 "Accept only OpenID for logins" 21 "Accept only password logins" 41 "Accept both"]]
index e611fa77b819c36b3fc6da04e0c33bc0aa5baa1f..bc9856ad90dd9b21fed91592663c03a2b05c6345 100644 (file)
@@ -80,3 +80,17 @@ which fails here? Or is something broken in Ikiwiki's implementation?
 > [[bugs/OpenID_delegation_fails_on_my_server]] --[[Joey]]
 
 Yes. I'd only recently set up my server as a delegate under wordpress, so still thought that perhaps the issue was on my end. But I'd since used my delegate successfully elsewhere, so I filed it as a bug against ikiwiki.
+
+----
+###Pretty Painless
+I just tried logging it with OpenID and it Just Worked.  Pretty painless.  If you want to turn off password authentication on ikiwiki.info, I say go for it. --[[blipvert]]
+
+> I doubt I will. The new login interface basically makes password login
+> and openid cooexist nicely. --[[Joey]] 
+
+###LiveJournal openid
+One caveat to the above is that, of course, OpenID is a distributed trust system which means you do have to think about the trust aspect.  A case in point is livejournal.com whose OpenID implementation is badly broken in one important respect:  If a LiveJournal user deletes his or her journal, and a different user registers a journal with the same name (this is actually quite a common occurrence on LiveJournal), they in effect inherit the previous journal owner's identity.  LiveJournal does not even have a mechanism in place for a remote site even to detect that a journal has changed hands.  It is an extremely dodgy situation which they seem to have *no* intention of fixing, and the bottom line is that the "identity" represented by a *username*.livejournal.com token should not be trusted as to its long-term uniqueness.  Just FYI.  --[[blipvert]]
+
+----
+
+Submitting bugs in the OpenID components will be difficult if OpenID must be working first...
diff --git a/doc/news/version_3.20100610.mdwn b/doc/news/version_3.20100610.mdwn
deleted file mode 100644 (file)
index ee7c86d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-ikiwiki 3.20100610 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * creation\_day() etc use local time, not gmtime. To match calendars, which
-     use local time.
-   * img: Fill in missing height or width when scaling image.
-   * Remove example blog tag pages; allow autotag creation to create them
-     when used.
-   * Fix support for globbing in tagged() pagespecs.
-   * Fix display of sidebar when previewing page edit. (Thanks, privat)
-   * relativedate: Fix problem with localised dates not working.
-   * editpage: Avoid storing accidental state changes when previewing pages.
-   * page.tmpl: Add a div around the page content, and comments, to aide in
-     sidebar styling.
-   * style.css: Improvements to make floating sidebar fit much better on
-     pages with inlines.
-   * calendar: Shorten day names, and improve styling of month calendar.
-   * style.css: Reduced sidebar width back to 20ex from 30; the month calendar
-     will now fit in the smaller width, and 30 was feeling too large."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100623.mdwn b/doc/news/version_3.20100623.mdwn
deleted file mode 100644 (file)
index 684217e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-ikiwiki 3.20100623 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * openid: Add openid\_realm and openid\_cgiurl configuration options,
-     useful in a few edge case setups.
-   * attachment: Show files from underlay in attachments list.
-   * img: Support hspace and vspace attributes.
-   * editpage: Rename "comments" field to avoid CSS conflict with the
-     comments div.
-   * edittemplate: Make silent mode not disable display when the template
-     page does not exist, so it can be easily created.
-   * edittemplate: Look for template pages under templates/ like everything
-     else (still looks in old location for backwards compatibility).
-   * attachment: When inserting links, insert img directives for images,
-     if that plugin is enabled.
-   * websetup: Allow enabling plugins listed in disable\_plugins.
-   * editpage, comments: Fix broken links in sidebar (due to forcebaseurl).
-     (Thanks, privat)
-   * calendar: Tune archive\_pagespec to only match pages, not other files.
-   * Fix issues with combining unicode srcdirs and source files.
-     (Workaround bug #586045)
-   * Make --gettime be honored after initial setup.
-   * git: Fix --gettime to properly support utf8 filenames.
-   * attachment: Support Windows paths when taking basename of client-supplied
-     file name.
-   * theme: New plugin, allows easily themeing a site via the underlay.
-   * Added actiontabs theme by Svend Sorensen.
-   * Added blueview theme by Bernd Zeimetz.
-   * mercurial: Fix buggy getctime code. Closes: #[586279](http://bugs.debian.org/586279)
-   * link: Enhanced to handle URLs and email addresses. (Bernd Zeimetz)"""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100704.mdwn b/doc/news/version_3.20100704.mdwn
deleted file mode 100644 (file)
index 9d2792c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-ikiwiki 3.20100704 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Changes to avoid display of ugly google openids, by displaying
-     a username taken from openid.
-   * API: Add new optional field nickname to rcs\_recentchanges.
-   * API: rcs\_commit and rcs\_commit\_staged are now passed named
-     parameters.
-   * openid: Store nickname based on username or email provided from
-     openid provider.
-   * git: Record the nickname from openid in the git author email.
-   * comment: Record the username from openid in the comment page.
-   * Fixed some confusion and bugginess about whether
-     rcs\_getctime/rcs\_getmtime were passed absolute or relative filenames.
-     (Make it relative like everything else.)
-   * hnb: Fixed broken use of mkstemp that had caused dangling temp files,
-     and prevented actually rendering hnb files.
-   * Use comment template on comments page of example blog.
-   * comment.tmpl: Fix up display when inline uses it to display a non-comment
-     page. (Such as a discussion page.)
-   * git: Added git\_wrapper\_background\_command option. Can be used to eg,
-     make the git wrapper push to github in the background after ikiwiki
-     runs.
-   * po: Added needstranslation() pagespec. (intrigeri)
-   * po: Added support for .html source pages. (intrigeri)
-   * comment: Fix problem moderating comments of certian pages with utf-8
-     in their name."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100722.mdwn b/doc/news/version_3.20100722.mdwn
deleted file mode 100644 (file)
index 27ed1fd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-ikiwiki 3.20100722 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * img: Add a margin around images displayed by this directive.
-   * comments: Added commentmoderation directive for easy linking to the
-     comment moderation queue.
-   * aggregate: Write timestamp next aggregation can happen to
-     .ikiwiki/aggregatetime, to allow for more sophisticated cron jobs.
-   * Add --changesetup mode that allows easily changing options in a
-     setup file.
-   * openid: Fix handling of utf-8 nicknames.
-   * Clarified what the filter hook should be passed: Only be the raw,
-     complete text of a page. Not a snippet, or data read in from an
-     unrelated file.
-   * template: Do not pass filled in template through filter hook.
-     Avoids causing breakage in po plugin.
-   * color, comments, conditional, cutpaste, more, sidebar, toggle: Also
-     avoid unnecessary calls to filter hook.
-   * po: needstranslation() pagespec can have a percent specified.
-   * Drop Cache-Control must-revalidate (Firefox 3.5.10 does not seem to have
-     the caching problem that was added to work around). Closes: #[588623](http://bugs.debian.org/588623)
-   * Made much more robust in cases where multiple source files produce
-     conflicting files/directories in the destdir.
-   * Updated French translation from Philippe Batailler. Closes: #[589423](http://bugs.debian.org/589423)
-   * po: Fix selflink display on tranlsated pages. (intrigeri)
-   * Avoid showing 'Add a comment' link at the bottom of the comment post form."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100804.mdwn b/doc/news/version_3.20100804.mdwn
deleted file mode 100644 (file)
index be85cb9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-ikiwiki 3.20100804 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * template: Fix dependency tracking. Broken in version 3.20100427.
-   * po: The po\_slave\_languages setting is now a list, so the order of
-     translated languages can be controlled. (intrigeri)
-   * git: Fix gitweb historyurl examples so "diff to current" links work.
-     (Thanks jrayhawk)
-   * meta: Allow syntax closer to html meta to be used.
-   * Add new disable hook, allowing plugins to perform cleanup after they
-     have been disabled.
-   * Use Digest::SHA built into perl rather than external Digest::SHA1
-     to simplify dependencies. Closes: #[591040](http://bugs.debian.org/591040)
-   * Fixes a bug that prevented matching deleted pages when using the page()
-     PageSpec."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100815.mdwn b/doc/news/version_3.20100815.mdwn
deleted file mode 100644 (file)
index 1073933..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-ikiwiki 3.20100815 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix po test suite to not assume ikiwiki's underlay is already installed.
-     Closes: #[593047](http://bugs.debian.org/593047)"""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20100926.mdwn b/doc/news/version_3.20100926.mdwn
new file mode 100644 (file)
index 0000000..b56e577
--- /dev/null
@@ -0,0 +1,6 @@
+ikiwiki 3.20100926 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * meta: Ensure that the url specified by xrds-location is absolute.
+   * attachment: Fix attachment file size display.
+   * Propigate PATH into wrapper.
+   * htmlbalance: Fix compatibility with HTML::Tree 4.0. (smcv)"""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20101019.mdwn b/doc/news/version_3.20101019.mdwn
new file mode 100644 (file)
index 0000000..86c302e
--- /dev/null
@@ -0,0 +1,20 @@
+ikiwiki 3.20101019 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix test suite failure on other side of date line.
+   * htmltidy: Allow configuring tidy parameters in setup file.
+     (W. Trevor King)
+   * Updated French program translation. Closes: #[598918](http://bugs.debian.org/598918)
+   * git: Added new rcs\_revert and rcs\_preprevert hooks.
+   * recentchanges: Add revert buttons to RecentChanges page, and
+     implement web-based reversion interface.
+   * Thanks to Peter Gammie for his assistance with the web-based reversion
+     feature.
+   * actiontabs: More consistent styling of Hn tags.
+   * websetup: Fix saving of advanced mode changes.
+   * websetup: Fix defaults of checkboxes in advanced mode.
+   * monotone: Fix recentchanges page when the srcdir is not at the top
+     of the monotone workspace. Thanks, tommyd.
+   * img: If a class is specified, don't also put the img in the img
+     class.
+   * auto-blog.setup: Don't enable opendiscussion by default; require users be
+     logged in to post comments."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20101023.mdwn b/doc/news/version_3.20101023.mdwn
new file mode 100644 (file)
index 0000000..44bed6b
--- /dev/null
@@ -0,0 +1,4 @@
+ikiwiki 3.20101023 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix typo that broke anonymous git push.
+   * Fix web reversion when the srcdir is in a subdir of the git repo."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20101112.mdwn b/doc/news/version_3.20101112.mdwn
new file mode 100644 (file)
index 0000000..ad59144
--- /dev/null
@@ -0,0 +1,17 @@
+ikiwiki 3.20101112 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * txt: Fix display when used inside a format directive.
+   * highlight: Ensure that other, more-specific format plugins,
+     like txt are used in preference to this one in case of ties.
+   * htmltidy, sortnaturally: Add missing checkconfig hook
+     registration. Closes: #[601912](http://bugs.debian.org/601912)
+     (Thanks, Craig Lennox and Tuomas Jormola)
+   * git: Use author date, not committer date. Closes: #[602012](http://bugs.debian.org/602012)
+     (Thanks, Tuomas Jormola)
+   * Fix htmlscrubber\_skip to be matched on the source page, not the page it is
+     inlined into. Should allow setting to "* and !comment(*)" to scrub
+     comments, but leave your blog posts unscrubbed, etc.
+   * comments: Make postcomment() pagespec work when previewing a comment,
+     including during moderation.
+   * comments: Make comment() pagespec also match comments that are being
+     posted."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20101129.mdwn b/doc/news/version_3.20101129.mdwn
new file mode 100644 (file)
index 0000000..366ad6e
--- /dev/null
@@ -0,0 +1,20 @@
+ikiwiki 3.20101129 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * websetup: Fix encoding problem when restoring old setup file.
+   * more: Add pages parameter to limit where the more is displayed.
+     (thanks, dark)
+   * Fix escaping of filenames in historyurl. (Thanks, aj)
+   * inline: Improve RSS url munging to use a proper html parser,
+     and support all elements that HTML::Tagset knows about.
+     (Which doesn't include html5 just yet, but then the old version
+     didn't either.) Bonus: 4 times faster than old regexp method.
+   * Optimise glob() pagespec. (Thanks, Kathryn and smcv)
+   * highlight: Support new format of filetypes.conf used by version 3.2
+     of the highlight package.
+   * edittemplate: Fix crash if using a .tmpl file or other non-page file
+     as a template for a new page.
+   * git: Fix temp file location.
+   * rename: Fix to pass named parameters to rcs\_commit.
+   * git: Avoid adding files when committing, so as not to implicitly add
+     files like recentchanges files that are not normally checked in,
+     when fixing links after rename."""]]
\ No newline at end of file
diff --git a/doc/news/version_3.20101201.mdwn b/doc/news/version_3.20101201.mdwn
new file mode 100644 (file)
index 0000000..410640c
--- /dev/null
@@ -0,0 +1,5 @@
+ikiwiki 3.20101201 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * meta: Fix calling of htmlscrubber to pass the page parameter.
+     The change of the htmlscrubber to look at page rather than destpage
+     caused htmlscrubber\_skip to not work for meta directives."""]]
\ No newline at end of file