Merge branch 'master'
authorJoey Hess <joey@gnu.kitenet.net>
Sat, 4 Apr 2009 21:27:48 +0000 (17:27 -0400)
committerJoey Hess <joey@gnu.kitenet.net>
Sat, 4 Apr 2009 21:27:48 +0000 (17:27 -0400)
Conflicts:
doc/ikiwiki-makerepo.mdwn

544 files changed:
Bundle/IkiWiki.pm
Bundle/IkiWiki/Extras.pm
IkiWiki.pm
IkiWiki/CGI.pm
IkiWiki/Plugin/404.pm [new file with mode: 0644]
IkiWiki/Plugin/aggregate.pm
IkiWiki/Plugin/amazon_s3.pm
IkiWiki/Plugin/anonok.pm
IkiWiki/Plugin/attachment.pm
IkiWiki/Plugin/autoindex.pm
IkiWiki/Plugin/blogspam.pm [new file with mode: 0644]
IkiWiki/Plugin/brokenlinks.pm
IkiWiki/Plugin/bzr.pm
IkiWiki/Plugin/calendar.pm
IkiWiki/Plugin/camelcase.pm
IkiWiki/Plugin/color.pm
IkiWiki/Plugin/comments.pm [new file with mode: 0644]
IkiWiki/Plugin/conditional.pm
IkiWiki/Plugin/creole.pm
IkiWiki/Plugin/cutpaste.pm
IkiWiki/Plugin/ddate.pm
IkiWiki/Plugin/editdiff.pm
IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/edittemplate.pm
IkiWiki/Plugin/embed.pm
IkiWiki/Plugin/external.pm
IkiWiki/Plugin/favicon.pm
IkiWiki/Plugin/filecheck.pm
IkiWiki/Plugin/format.pm [new file with mode: 0644]
IkiWiki/Plugin/fortune.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/goodstuff.pm
IkiWiki/Plugin/google.pm
IkiWiki/Plugin/googlecalendar.pm [deleted file]
IkiWiki/Plugin/goto.pm [new file with mode: 0644]
IkiWiki/Plugin/graphviz.pm
IkiWiki/Plugin/haiku.pm
IkiWiki/Plugin/hnb.pm
IkiWiki/Plugin/html.pm
IkiWiki/Plugin/htmlbalance.pm [new file with mode: 0644]
IkiWiki/Plugin/htmlscrubber.pm
IkiWiki/Plugin/htmltidy.pm
IkiWiki/Plugin/httpauth.pm
IkiWiki/Plugin/img.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/link.pm
IkiWiki/Plugin/linkmap.pm
IkiWiki/Plugin/listdirectives.pm
IkiWiki/Plugin/lockedit.pm
IkiWiki/Plugin/map.pm
IkiWiki/Plugin/mdwn.pm
IkiWiki/Plugin/mercurial.pm
IkiWiki/Plugin/meta.pm
IkiWiki/Plugin/mirrorlist.pm
IkiWiki/Plugin/monotone.pm
IkiWiki/Plugin/more.pm
IkiWiki/Plugin/norcs.pm
IkiWiki/Plugin/opendiscussion.pm
IkiWiki/Plugin/openid.pm
IkiWiki/Plugin/orphans.pm
IkiWiki/Plugin/otl.pm
IkiWiki/Plugin/pagecount.pm
IkiWiki/Plugin/pagestats.pm
IkiWiki/Plugin/pagetemplate.pm
IkiWiki/Plugin/parentlinks.pm
IkiWiki/Plugin/passwordauth.pm
IkiWiki/Plugin/pingee.pm
IkiWiki/Plugin/pinger.pm
IkiWiki/Plugin/poll.pm
IkiWiki/Plugin/polygen.pm
IkiWiki/Plugin/postsparkline.pm
IkiWiki/Plugin/prettydate.pm
IkiWiki/Plugin/progress.pm
IkiWiki/Plugin/rawhtml.pm
IkiWiki/Plugin/recentchanges.pm
IkiWiki/Plugin/recentchangesdiff.pm
IkiWiki/Plugin/relativedate.pm [new file with mode: 0644]
IkiWiki/Plugin/remove.pm
IkiWiki/Plugin/rename.pm
IkiWiki/Plugin/repolist.pm [new file with mode: 0644]
IkiWiki/Plugin/search.pm
IkiWiki/Plugin/shortcut.pm
IkiWiki/Plugin/sidebar.pm
IkiWiki/Plugin/signinedit.pm
IkiWiki/Plugin/skeleton.pm.example
IkiWiki/Plugin/smiley.pm
IkiWiki/Plugin/sparkline.pm
IkiWiki/Plugin/svn.pm
IkiWiki/Plugin/table.pm
IkiWiki/Plugin/tag.pm
IkiWiki/Plugin/template.pm
IkiWiki/Plugin/testpagespec.pm
IkiWiki/Plugin/teximg.pm
IkiWiki/Plugin/textile.pm
IkiWiki/Plugin/tla.pm
IkiWiki/Plugin/toc.pm
IkiWiki/Plugin/toggle.pm
IkiWiki/Plugin/txt.pm
IkiWiki/Plugin/typography.pm
IkiWiki/Plugin/underlay.pm [new file with mode: 0644]
IkiWiki/Plugin/version.pm
IkiWiki/Plugin/websetup.pm
IkiWiki/Plugin/wikitext.pm
IkiWiki/Plugin/wmd.pm [new file with mode: 0644]
IkiWiki/Receive.pm [new file with mode: 0644]
IkiWiki/Render.pm
IkiWiki/Setup.pm
IkiWiki/Setup/Automator.pm
IkiWiki/Setup/Standard.pm
IkiWiki/UserInfo.pm
IkiWiki/Wrapper.pm
Makefile.PL
auto-blog.setup [new file with mode: 0644]
auto.setup
debian/NEWS
debian/changelog
debian/compat
debian/control
debian/copyright
debian/docs [new file with mode: 0644]
debian/link [new file with mode: 0644]
debian/preinst
debian/rules
doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn [new file with mode: 0644]
doc/bugs/Allow_overriding_of_symlink_restriction.mdwn
doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn [new file with mode: 0644]
doc/bugs/Can__39__t_create_root_page.mdwn
doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn [new file with mode: 0644]
doc/bugs/Error:_Your_login_session_has_expired._.mdwn [new file with mode: 0644]
doc/bugs/Git:_web_commit_message_not_utf-8.mdwn [new file with mode: 0644]
doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn [new file with mode: 0644]
doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn [new file with mode: 0644]
doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn [new file with mode: 0644]
doc/bugs/Insecure_dependency_in_eval_while_running_with_-T_switch.mdwn
doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn [new file with mode: 0644]
doc/bugs/Monotone_rcs_support.mdwn
doc/bugs/No_link_for_blog_items_when_filename_contains_a_colon.mdwn
doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn [new file with mode: 0644]
doc/bugs/Problem_with_toc.pm_plug-in.mdwn
doc/bugs/Problems_with_graphviz.pm_plug-in.mdwn
doc/bugs/RecentChanges_broken_with_empty_svnpath.mdwn
doc/bugs/SVG_files_not_recognized_as_images.mdwn [new file with mode: 0644]
doc/bugs/Spaces_in_link_text_for_ikiwiki_links.mdwn
doc/bugs/Titles_are_lower-cased_when_creating_a_page.mdwn
doc/bugs/URLs_with_parentheses_displayed_badly.mdwn [new file with mode: 0644]
doc/bugs/Use_install__40__1__41___instead_of_cp__40__1__41___for_installing_files.mdwn
doc/bugs/Warns_about_use_of_uninitialized_value_if_prefix__95__directives_is_on_and_a_directive_does_not_contain_a_space.mdwn
doc/bugs/basewiki_uses_meta_directives_but_meta_is_not_enabled_by_default.mdwn [new file with mode: 0644]
doc/bugs/beautify__95__urlpath_will_add_.__47___even_if_it_is_already_present.mdwn [new file with mode: 0644]
doc/bugs/bugfix_for:___34__mtn:_operation_canceled:_Broken_pipe__34_____40__patch__41__.mdwn [new file with mode: 0644]
doc/bugs/bzr_RecentChanges_dates_start_from_1969.mdwn [new file with mode: 0644]
doc/bugs/bzr_plugin_does_not_define_rcs__95__diff.mdwn [new file with mode: 0644]
doc/bugs/cannot_preview_shortcuts.mdwn [new file with mode: 0644]
doc/bugs/cannot_reliably_use_meta_in_template.mdwn [new file with mode: 0644]
doc/bugs/comments_produce_broken_links_in_RecentChanges.mdwn [new file with mode: 0644]
doc/bugs/disabling_backlinks.mdwn
doc/bugs/dumpsetup_does_not_save_destdir.mdwn [new file with mode: 0644]
doc/bugs/entirely_negated_pagespec_matches_internal_pages.mdwn
doc/bugs/feedfile_does_the_wrong_thing_from_index.mdwn2.mdwn [new file with mode: 0644]
doc/bugs/git_stderr_output_causes_problems.mdwn
doc/bugs/gitweb_deficiency_w.r.t._log_messages.mdwn
doc/bugs/gitweb_deficiency_w.r.t._newly_created_pages.mdwn
doc/bugs/html5_support.mdwn [new file with mode: 0644]
doc/bugs/http_proxy_for_openid.mdwn
doc/bugs/images_in_inlined_pages_have_wrong_relative_URL.mdwn
doc/bugs/img_plugin_should_pass_through_class_attribute.mdwn
doc/bugs/inline_sort-by-title_issues.mdwn
doc/bugs/inline_sort_order_and_meta_date_value.mdwn [new file with mode: 0644]
doc/bugs/links_misparsed_in_CSV_files.mdwn [new file with mode: 0644]
doc/bugs/lockedit_plugin_should_alert_user_about_an_invalid_pagespec_in_preferences.mdwn
doc/bugs/login_page_should_note_cookie_requirement.mdwn [new file with mode: 0644]
doc/bugs/markdown_bug:_email_escaping_and_plus_addresses.mdwn
doc/bugs/mercurial_fail_to_add.mdwn
doc/bugs/messed_up_repository.mdwn [new file with mode: 0644]
doc/bugs/methodResponse_in_add__95__plugins.mdwn
doc/bugs/multiple_pages_with_same_name.mdwn
doc/bugs/output_of_successful_rename_should_list_the_full_path_to_affected_pages.mdwn [new file with mode: 0644]
doc/bugs/pagespec_parsing_chokes_on_function__40____41__.mdwn
doc/bugs/pagetitle_function_does_not_respect_meta_titles.mdwn
doc/bugs/prune_causing_taint_mode_failures.mdwn
doc/bugs/quieten_mercurial.mdwn
doc/bugs/recentchanges_feed_links.mdwn
doc/bugs/relative_date_weird_results.mdwn [new file with mode: 0644]
doc/bugs/remove_orphaned_sparkline-php_from_Suggests.mdwn [new file with mode: 0644]
doc/bugs/rst_tweak.mdwn
doc/bugs/search_for_locale_data_in_the_installed_location.mdwn
doc/bugs/shortcut_plugin_will_not_work_without_shortcuts.mdwn.mdwn [new file with mode: 0644]
doc/bugs/ssl_certificates_not_checked_with_openid.mdwn
doc/bugs/stray___60____47__p__62___tags.mdwn [new file with mode: 0644]
doc/bugs/support_for_openid2_logins.mdwn [new file with mode: 0644]
doc/bugs/table_external_file_links.mdwn [new file with mode: 0644]
doc/bugs/tags__44___backlinks_and_3.x.mdwn [new file with mode: 0644]
doc/bugs/tbasewiki__95__brokenlinks.t_broken.mdwn
doc/bugs/textile_plugin_dies_if_input_has_a_non-utf8_character.mdwn
doc/bugs/txt_plugin_having_problems_with_meta_directives.mdwn [new file with mode: 0644]
doc/bugs/unicode_chars_in_wikiname_break_auth.mdwn [new file with mode: 0644]
doc/bugs/user_links_on_recentchanges_pages_problem.mdwn [new file with mode: 0644]
doc/contact.mdwn
doc/convert.mdwn [new file with mode: 0644]
doc/css_market.mdwn
doc/css_market/actiontabs.css [new file with mode: 0644]
doc/css_market/discussion.mdwn
doc/css_market/zack.css
doc/download.mdwn
doc/examples/blog.mdwn
doc/examples/blog/index.mdwn
doc/examples/blog/posts/first_post.mdwn
doc/examples/softwaresite/index.mdwn
doc/forum.mdwn
doc/forum/Adding_new_markup_to_markdown.mdwn [new file with mode: 0644]
doc/forum/Darcs_as_the_RCS___63__.mdwn [new file with mode: 0644]
doc/forum/How_does_ikiwiki_remember_times__63__.mdwn [new file with mode: 0644]
doc/forum/How_to_fix___34__does_not_map_to_Unicode__34___errors__63__.mdwn [new file with mode: 0644]
doc/forum/Is_there_a_pagespec_for_creation_dates_relative_to_today__63__.mdwn
doc/forum/Migrating_old_repository_to_new_ikiwiki_system__63__.mdwn [new file with mode: 0644]
doc/forum/What_is_wrong_with_my_recentchange_page___63__.mdwn [new file with mode: 0644]
doc/forum/chinese_character_problem.mdwn [new file with mode: 0644]
doc/forum/discussion.mdwn [new file with mode: 0644]
doc/forum/ikiwiki__39__s_notion_of_time.mdwn [new file with mode: 0644]
doc/forum/managing_todo_lists.mdwn [new file with mode: 0644]
doc/forum/multi-user_setup_of_ikiwiki__44___gitosis_and_apache2_in_Debian_Sid.mdwn
doc/forum/usedirs___38___indexpages_using_problem.mdwn [new file with mode: 0644]
doc/forum/wiki_name_in_page_titles.mdwn [new file with mode: 0644]
doc/freesoftware/discussion.mdwn [new file with mode: 0644]
doc/git.mdwn
doc/ikiwiki-makerepo.mdwn
doc/ikiwiki-transition.mdwn
doc/ikiwiki/directive.mdwn
doc/ikiwiki/directive/cutpaste.mdwn
doc/ikiwiki/directive/format.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/inline.mdwn
doc/ikiwiki/directive/inline/discussion.mdwn
doc/ikiwiki/directive/linkmap.mdwn
doc/ikiwiki/directive/meta.mdwn
doc/ikiwiki/directive/pagestats/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/tag.mdwn
doc/ikiwiki/directive/testpagespec/discussion.mdwn [new file with mode: 0644]
doc/ikiwiki/markdown.mdwn
doc/ikiwiki/pagespec.mdwn
doc/ikiwiki/pagespec/attachment.mdwn
doc/ikiwiki/pagespec/discussion.mdwn
doc/ikiwiki/wikilink/discussion.mdwn
doc/ikiwikiusers.mdwn
doc/ikiwikiusers/discussion.mdwn
doc/index/discussion.mdwn
doc/index/openid/discussion.mdwn [new file with mode: 0644]
doc/install.mdwn
doc/install/discussion.mdwn
doc/news/code_swarm.mdwn
doc/news/git_push_to_this_wiki.mdwn [new file with mode: 0644]
doc/news/git_push_to_this_wiki/discussion.mdwn [new file with mode: 0644]
doc/news/ikiwiki_version_3.0.mdwn [new file with mode: 0644]
doc/news/openid.mdwn
doc/news/openid/discussion.mdwn
doc/news/version_2.62.1.mdwn [deleted file]
doc/news/version_2.63.mdwn [deleted file]
doc/news/version_2.64.mdwn [deleted file]
doc/news/version_2.65.mdwn [deleted file]
doc/news/version_2.66.mdwn [deleted file]
doc/news/version_2.68.mdwn [new file with mode: 0644]
doc/news/version_2.69.mdwn [new file with mode: 0644]
doc/news/version_2.70.mdwn [new file with mode: 0644]
doc/news/version_2.71.mdwn [new file with mode: 0644]
doc/news/version_2.72.mdwn [new file with mode: 0644]
doc/news/version_3.09.mdwn [new file with mode: 0644]
doc/pagehistory.mdwn
doc/plugins/404.mdwn [new file with mode: 0644]
doc/plugins/aggregate.mdwn
doc/plugins/aggregate/discussion.mdwn
doc/plugins/anonok.mdwn
doc/plugins/autoindex/discussion.mdwn [new file with mode: 0644]
doc/plugins/blogspam.mdwn [new file with mode: 0644]
doc/plugins/calendar.mdwn
doc/plugins/calendar/discussion.mdwn
doc/plugins/comments.mdwn [new file with mode: 0644]
doc/plugins/comments/discussion.mdwn [new file with mode: 0644]
doc/plugins/contrib.mdwn
doc/plugins/contrib/default_content_for___42__copyright__42___and___42__license__42__.mdwn
doc/plugins/contrib/gallery.mdwn
doc/plugins/contrib/headinganchors.mdwn
doc/plugins/contrib/highlightcode.mdwn
doc/plugins/contrib/linguas.mdwn
doc/plugins/contrib/mediawiki.mdwn [new file with mode: 0644]
doc/plugins/contrib/opml.mdwn [new file with mode: 0644]
doc/plugins/contrib/opml/discussion.mdwn [new file with mode: 0644]
doc/plugins/contrib/po.mdwn [new file with mode: 0644]
doc/plugins/contrib/siterel2pagerel.mdwn
doc/plugins/contrib/sourcehighlight.mdwn
doc/plugins/contrib/unixauth.mdwn
doc/plugins/contrib/unixauth/discussion.mdwn
doc/plugins/creole.mdwn
doc/plugins/creole/discussion.mdwn
doc/plugins/cutpaste.mdwn
doc/plugins/ddate.mdwn
doc/plugins/discussion.mdwn
doc/plugins/embed.mdwn
doc/plugins/format.mdwn [new file with mode: 0644]
doc/plugins/format/discussion.mdwn [new file with mode: 0644]
doc/plugins/goodstuff.mdwn
doc/plugins/google/discussion.mdwn [new file with mode: 0644]
doc/plugins/googlecalendar.mdwn [deleted file]
doc/plugins/goto.mdwn [new file with mode: 0644]
doc/plugins/htmlbalance.mdwn [new file with mode: 0644]
doc/plugins/htmlbalance/discussion.mdwn [new file with mode: 0644]
doc/plugins/htmlscrubber.mdwn
doc/plugins/htmltidy.mdwn
doc/plugins/img/discussion.mdwn
doc/plugins/lockedit.mdwn
doc/plugins/mdwn/discussion.mdwn [new file with mode: 0644]
doc/plugins/meta.mdwn
doc/plugins/pagecount.mdwn
doc/plugins/passwordauth/discussion.mdwn
doc/plugins/pingee.mdwn
doc/plugins/prettydate.mdwn
doc/plugins/relativedate.mdwn [new file with mode: 0644]
doc/plugins/repolist.mdwn [new file with mode: 0644]
doc/plugins/rst.mdwn
doc/plugins/shortcut/discussion.mdwn
doc/plugins/tag.mdwn
doc/plugins/tag/discussion.mdwn
doc/plugins/textile/discussion.mdwn [deleted file]
doc/plugins/type/date.mdwn [new file with mode: 0644]
doc/plugins/underlay.mdwn [new file with mode: 0644]
doc/plugins/wmd.mdwn [new file with mode: 0644]
doc/plugins/write.mdwn
doc/plugins/write/discussion.mdwn
doc/plugins/write/external.mdwn
doc/plugins/write/tutorial.mdwn
doc/rcs/details.mdwn
doc/rcs/git.mdwn
doc/rcs/mercurial.mdwn
doc/rcs/monotone.mdwn
doc/roadmap.mdwn
doc/robots.txt [new file with mode: 0644]
doc/sandbox.mdwn
doc/sandbox/Omgwtf_a_blof_post__33____33____33____33____33__1__33__1__33__11111__33____33____33__1__33__1__33____33__1five.html [new file with mode: 0644]
doc/sandbox/castle/discussion/jon_tests_too.mdwn
doc/sandbox/foobak.mdwn [new file with mode: 0644]
doc/sandbox/한글.mdwn [new file with mode: 0644]
doc/sandbox/한글페이지.mdwn [new file with mode: 0644]
doc/security.mdwn
doc/setup.mdwn
doc/setup/byhand.mdwn [new file with mode: 0644]
doc/setup/discussion.mdwn
doc/style.css
doc/tips/DreamHost.mdwn
doc/tips/Git_repository_and_web_server_on_different_hosts.mdwn [new file with mode: 0644]
doc/tips/Google_custom_search.mdwn
doc/tips/apache_cgi.mdwn [deleted file]
doc/tips/comments_feed.mdwn [new file with mode: 0644]
doc/tips/convert_MoinMoin_and_TWiki_to_ikiwiki.mdwn [new file with mode: 0644]
doc/tips/convert_mediawiki_to_ikiwiki.mdwn [new file with mode: 0644]
doc/tips/convert_mediawiki_to_ikiwiki/discussion.mdwn [new file with mode: 0644]
doc/tips/dot_cgi.mdwn [new file with mode: 0644]
doc/tips/emacs_syntax_highlighting.mdwn [new file with mode: 0644]
doc/tips/embedding_content.mdwn [new file with mode: 0644]
doc/tips/github.mdwn [new file with mode: 0644]
doc/tips/howto_avoid_flooding_aggregators.mdwn
doc/tips/inside_dot_ikiwiki.mdwn
doc/tips/inside_dot_ikiwiki/discussion.mdwn
doc/tips/laptop_wiki_with_git.mdwn
doc/tips/laptop_wiki_with_git/discussion.mdwn
doc/tips/lighttpd_cgi.mdwn [deleted file]
doc/tips/markdown_and_eclipse.mdwn [new file with mode: 0644]
doc/tips/nearlyfreespeech.mdwn
doc/tips/untrusted_git_push.mdwn [new file with mode: 0644]
doc/tips/untrusted_git_push/discussion.mdwn [new file with mode: 0644]
doc/tips/upgrade_to_3.0.mdwn [new file with mode: 0644]
doc/tips/using_the_web_interface_with_a_real_text_editor.mdwn
doc/tips/vim_syntax_highlighting.mdwn
doc/tips/vim_syntax_highlighting/discussion.mdwn
doc/tips/vim_syntax_highlighting/ikiwiki.vim
doc/todo/Add_DATE_parameter_for_use_in_templates.mdwn
doc/todo/Add_camelcase_exclusions.mdwn [new file with mode: 0644]
doc/todo/Add_showdown_GUI_input__47__edit.mdwn
doc/todo/Add_support_for_latest_Text::Markdown_as_found_on_CPAN.mdwn
doc/todo/Allow_change_of_wiki_file_types.mdwn
doc/todo/Allow_disabling_edit_and_preferences_links.mdwn [new file with mode: 0644]
doc/todo/Allow_edittemplate_to_set_file_type.mdwn
doc/todo/Allow_filenames_that_are_all_type.mdwn [new file with mode: 0644]
doc/todo/Bestdir_along_with_bestlink_in_IkiWiki.pm.mdwn
doc/todo/Default_text_for_new_pages.mdwn
doc/todo/Feature_parity_with_Trac.mdwn
doc/todo/Gallery.mdwn
doc/todo/Give_access_to_more_TMPL__95__VAR_variables_in_templates_inserted_by_the_template_plugin.mdwn
doc/todo/Improve_display_of_OpenIDs.mdwn [new file with mode: 0644]
doc/todo/Inline_plugin_option_to_show_full_page_path.mdwn
doc/todo/Move_teximg_latex_preamble_to_config_file.mdwn
doc/todo/New_preprocessor_directive_syntax/discussion.mdwn
doc/todo/Option_to_make_title_an_h1__63__.mdwn
doc/todo/RecentChanges_page_links_without_cgi_wrapper.mdwn [new file with mode: 0644]
doc/todo/Set_arbitrary_date_to_be_used_by_calendar_plugin.mdwn
doc/todo/Silence_monotone_warning.mdwn
doc/todo/Support_wildcard_inside_of_link__40____41___within_a_pagespec.mdwn
doc/todo/Untrusted_push_in_Monotone.mdwn [new file with mode: 0644]
doc/todo/Wrapper_config_with_multiline_regexp.mdwn
doc/todo/add_forward_age_sorting_option_to_inline.mdwn
doc/todo/allow_disabling_backlinks.mdwn [new file with mode: 0644]
doc/todo/anti-spam_protection.mdwn
doc/todo/apache_404_ErrorDocument_handler.mdwn [new file with mode: 0644]
doc/todo/applydiff_plugin.mdwn
doc/todo/auto-create_tag_pages_according_to_a_template.mdwn
doc/todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion.mdwn
doc/todo/avatar.mdwn [new file with mode: 0644]
doc/todo/avoid_thrashing.mdwn [new file with mode: 0644]
doc/todo/blogpost_plugin.mdwn
doc/todo/bzr.mdwn
doc/todo/cas_authentication.mdwn
doc/todo/clear_page_to_delete.mdwn [new file with mode: 0644]
doc/todo/color_plugin.mdwn
doc/todo/comments.mdwn [new file with mode: 0644]
doc/todo/configurable_timezones.mdwn
doc/todo/darcs.mdwn
doc/todo/datearchives-plugin.mdwn
doc/todo/different_search_engine.mdwn
doc/todo/directive_docs.mdwn
doc/todo/discussion_page_as_blog.mdwn
doc/todo/dynamic_rootpage.mdwn
doc/todo/enable-htaccess-files.mdwn
doc/todo/firm_up_plugin_interface.mdwn
doc/todo/format_escape.mdwn
doc/todo/fortune:_select_options_via_environment.mdwn
doc/todo/generic___39__do__61__goto__39___for_CGI.mdwn [new file with mode: 0644]
doc/todo/httpauth_feature_parity_with_passwordauth.mdwn [new file with mode: 0644]
doc/todo/index.html_allowed.mdwn
doc/todo/inline:_numerical_ordering_by_title.mdwn
doc/todo/inline_plugin:_ability_to_override_feed_name.mdwn [new file with mode: 0644]
doc/todo/inline_plugin:_hide_feed_buttons_if_empty.mdwn [new file with mode: 0644]
doc/todo/inline_postform_autotitles.mdwn [new file with mode: 0644]
doc/todo/language_definition_for_the_meta_plugin.mdwn
doc/todo/latex.mdwn
doc/todo/location_of_external_plugins.mdwn [new file with mode: 0644]
doc/todo/location_of_ikiwiki-w3m.cgi.mdwn [new file with mode: 0644]
doc/todo/mbox.mdwn
doc/todo/mdwn_preview.mdwn [new file with mode: 0644]
doc/todo/mercurial.mdwn
doc/todo/meta_rcsid.mdwn
doc/todo/missingparents.pm.mdwn
doc/todo/modify_page_filename_in_plugin.mdwn
doc/todo/natural_sorting.mdwn [new file with mode: 0644]
doc/todo/need_global_renamepage_hook.mdwn [new file with mode: 0644]
doc/todo/overriding_displayed_modification_time.mdwn [new file with mode: 0644]
doc/todo/pagespec_relative_to_a_target.mdwn
doc/todo/pingback_support.mdwn [new file with mode: 0644]
doc/todo/plugin.mdwn
doc/todo/provide_inline_diffs_in_recentchanges.mdwn
doc/todo/provide_sha1_for_git_diffurl.mdwn [new file with mode: 0644]
doc/todo/rcs_updates_needed.mdwn [moved from doc/todo/rcs_updates_needed_for_rename_and_remove.mdwn with 54% similarity]
doc/todo/redirect_automatically_after_rename.mdwn [new file with mode: 0644]
doc/todo/relative_pagespec_deficiency.mdwn [new file with mode: 0644]
doc/todo/replace_HTML::Template_with_Template_Toolkit.mdwn
doc/todo/require_CAPTCHA_to_edit.mdwn
doc/todo/rewrite_ikiwiki_in_haskell.mdwn [new file with mode: 0644]
doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn [new file with mode: 0644]
doc/todo/source_link.mdwn
doc/todo/structured_page_data.mdwn
doc/todo/support_creole_markup.mdwn
doc/todo/supporting_comments_via_disussion_pages.mdwn
doc/todo/syntax_highlighting.mdwn [new file with mode: 0644]
doc/todo/syntax_highlighting/discussion.mdwn [new file with mode: 0644]
doc/todo/tag_pagespec_function.mdwn [new file with mode: 0644]
doc/todo/tidy_git__39__s_ctime_debug_output.mdwn
doc/todo/tla.mdwn
doc/todo/tmplvars_plugin.mdwn
doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn [new file with mode: 0644]
doc/todo/tracking_bugs_with_dependencies.mdwn
doc/todo/turn_edittemplate_verbosity_off_by_default.mdwn
doc/todo/using_meta_titles_for_parentlinks.html [deleted file]
doc/todo/varioki_--_add_template_variables___40__with_closures_for_values__41___in_ikiwiki.setup.mdwn
doc/todo/wiki-formatted_comments_with_syntax_plugin.mdwn
doc/todo/wikiwyg.mdwn
doc/usage.mdwn
doc/users/Edward_Betts.mdwn
doc/users/StevenBlack.mdwn [new file with mode: 0644]
doc/users/ajt.mdwn [new file with mode: 0644]
doc/users/alexander.mdwn [new file with mode: 0644]
doc/users/cfm.mdwn [new file with mode: 0644]
doc/users/hb/discussion.mdwn
doc/users/intrigeri.mdwn
doc/users/jasonblevins.mdwn
doc/users/jelmer.mdwn [new file with mode: 0644]
doc/users/jon.mdwn [new file with mode: 0644]
doc/users/jondowland.mdwn [deleted file]
doc/users/joshtriplett.mdwn
doc/users/jrblevin.mdwn [new file with mode: 0644]
doc/users/jwalzer.mdwn [new file with mode: 0644]
doc/users/neale.mdwn [new file with mode: 0644]
doc/users/nolan.mdwn [new file with mode: 0644]
doc/users/seanh.mdwn [new file with mode: 0644]
doc/users/simonraven.mdwn [new file with mode: 0644]
doc/users/smcv.mdwn
doc/users/smcv/gallery.mdwn [new file with mode: 0644]
doc/users/svend.mdwn [new file with mode: 0644]
doc/users/weakish.mdwn [new file with mode: 0644]
doc/users/weakishjiang.mdwn [new file with mode: 0644]
doc/users/xma.mdwn [new file with mode: 0644]
doc/users/xma/discussion.mdwn [new file with mode: 0644]
doc/wikiicons/openidlogin-bg.gif
doc/wikitemplates.mdwn
docwiki.setup
gitremotes [new file with mode: 0755]
ikiwiki-makerepo
ikiwiki-transition
ikiwiki.in
plugins/externaldemo
pm_filter
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/pl.po
po/sv.po
po/vi.po
t/404.t [new file with mode: 0755]
t/basewiki_brokenlinks/index.mdwn
t/beautify_urlpath.t [new file with mode: 0755]
t/git.t
t/htmlbalance.t [new file with mode: 0755]
t/openiduser.t [new file with mode: 0755]
t/pagename.t
t/pagespec_match.t
t/pagespec_merge.t
t/pagetype.mdwn [deleted file]
t/tinyblog/index.mdwn
t/yesno.t [new file with mode: 0755]
templates/atomitem.tmpl
templates/change.tmpl
templates/comment.tmpl [new file with mode: 0644]
templates/commentmoderation.tmpl [new file with mode: 0644]
templates/editcomment.tmpl [new file with mode: 0644]
templates/editpage.tmpl
templates/googleform.tmpl
templates/inlinepage.tmpl
templates/misc.tmpl
templates/page.tmpl
templates/rssitem.tmpl
underlays/basewiki/directive.mdwn [deleted symlink]
underlays/javascript/ikiwiki.js [new file with mode: 0644]
underlays/javascript/relativedate.js [new file with mode: 0644]
underlays/javascript/toggle.js [new file with mode: 0644]

index 74832323a1dd7616950c7a68441526cf21b82f2e..769791d305b17ce03f6159a8d3094dbdb026cb80 100644 (file)
@@ -16,17 +16,17 @@ perl -MCPAN -e 'install Bundle::IkiWiki'
 
 =head1 CONTENTS
 
-XML::Simple
 Text::Markdown
-Date::Parse
-HTML::Template
 HTML::Scrubber
-CGI
+HTML::Template
+HTML::Parser
+URI
+XML::Simple
+Date::Parse
 CGI::FormBuilder
 CGI::Session
 Mail::Sendmail
-HTML::Parser
-URI
+CGI
 Data::Dumper
 
 =head1 AUTHOR
index abf596f0060712ca599fa5326da026b447fc947f..40b36e7c81fa4563af46d3d1e5fe673b9d755e61 100644 (file)
@@ -31,6 +31,11 @@ Text::Textile
 Text::WikiFormat
 XML::Feed
 Net::Amazon::S3
+Text::WikiCreole
+Term::ReadLine::Gnu
+HTML::Tree
+Authen::Passphrase
+Sort::Naturally
 
 =head1 AUTHOR
 
index 633c5138180a9f87f4a974bef3322492c1d08ada..ee07258ecce01cac5c94ecdf3878cf2a94213778 100644 (file)
@@ -21,11 +21,12 @@ our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
                  bestlink htmllink readfile writefile pagetype srcfile pagename
                  displaytime will_render gettext urlto targetpage
                 add_underlay pagetitle titlepage linkpage newpagefile
+                inject
                  %config %links %pagestate %wikistate %renderedfiles
                  %pagesources %destsources);
-our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
+our $VERSION = 3.00; # plugin interface version, next is ikiwiki version
 our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE
-my $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE
+our $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE
 
 # Optimisation.
 use Memoize;
@@ -33,7 +34,7 @@ memoize("abs2rel");
 memoize("pagespec_translate");
 memoize("file_pruned");
 
-sub getsetup () { #{{{
+sub getsetup () {
        wikiname => {
                type => "string",
                default => "wiki",
@@ -99,7 +100,7 @@ sub getsetup () { #{{{
                type => "string",
                default => '',
                example => "/var/www/wiki/ikiwiki.cgi",
-               description => "cgi wrapper to generate",
+               description => "filename of cgi wrapper to generate",
                safe => 0, # file
                rebuild => 0,
        },
@@ -119,7 +120,7 @@ sub getsetup () { #{{{
        },
        default_plugins => {
                type => "internal",
-               default => [qw{mdwn link inline htmlscrubber passwordauth
+               default => [qw{mdwn link inline meta htmlscrubber passwordauth
                                openid signinedit lockedit conditional
                                recentchanges parentlinks editpage}],
                description => "plugins to enable by default",
@@ -173,7 +174,7 @@ sub getsetup () { #{{{
        verbose => {
                type => "boolean",
                example => 1,
-               description => "display verbose messages when building?",
+               description => "display verbose messages?",
                safe => 1,
                rebuild => 0,
        },
@@ -193,7 +194,7 @@ sub getsetup () { #{{{
        },
        prefix_directives => {
                type => "boolean",
-               default => 0,
+               default => 1,
                description => "use '!'-prefixed preprocessor directives?",
                safe => 0, # changing requires manual transition
                rebuild => 1,
@@ -276,13 +277,20 @@ sub getsetup () { #{{{
        },
        umask => {
                type => "integer",
-               description => "",
                example => "022",
                description => "force ikiwiki to use a particular umask",
                advanced => 1,
                safe => 0, # paranoia
                rebuild => 0,
        },
+       wrappergroup => {
+               type => "string",
+               example => "ikiwiki",
+               description => "group for wrappers to run in",
+               advanced => 1,
+               safe => 0, # paranoia
+               rebuild => 0,
+       },
        libdir => {
                type => "string",
                default => "",
@@ -381,6 +389,13 @@ sub getsetup () { #{{{
                safe => 0,
                rebuild => 0,
        },
+       test_receive => {
+               type => "internal",
+               default => 0,
+               description => "running in receive test mode",
+               safe => 0,
+               rebuild => 0,
+       },
        getctime => {
                type => "internal",
                default => 0,
@@ -395,6 +410,13 @@ sub getsetup () { #{{{
                safe => 0,
                rebuild => 0,
        },
+       wikistatedir => {
+               type => "internal",
+               default => undef,
+               description => "path to the .ikiwiki directory holding ikiwiki state",
+               safe => 0,
+               rebuild => 0,
+       },
        setupfile => {
                type => "internal",
                default => undef,
@@ -403,15 +425,15 @@ sub getsetup () { #{{{
                rebuild => 0,
        },
        allow_symlinks_before_srcdir => {
-               type => "string",
+               type => "boolean",
                default => 0,
                description => "allow symlinks in the path leading to the srcdir (potentially insecure)",
                safe => 0,
                rebuild => 0,
        },
-} #}}}
+}
 
-sub defaultconfig () { #{{{
+sub defaultconfig () {
        my %s=getsetup();
        my @ret;
        foreach my $key (keys %s) {
@@ -419,9 +441,9 @@ sub defaultconfig () { #{{{
        }
        use Data::Dumper;
        return @ret;
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        # locale stuff; avoid LC_ALL since it overrides everything
        if (defined $ENV{LC_ALL}) {
                $ENV{LANG} = $ENV{LC_ALL};
@@ -459,7 +481,7 @@ sub checkconfig () { #{{{
        }
        
        $config{wikistatedir}="$config{srcdir}/.ikiwiki"
-               unless exists $config{wikistatedir};
+               unless exists $config{wikistatedir} && defined $config{wikistatedir};
 
        if (defined $config{umask}) {
                umask(possibly_foolish_untaint($config{umask}));
@@ -468,9 +490,9 @@ sub checkconfig () { #{{{
        run_hooks(checkconfig => sub { shift->() });
 
        return 1;
-} #}}}
+}
 
-sub listplugins () { #{{{
+sub listplugins () {
        my %ret;
 
        foreach my $dir (@INC, $config{libdir}) {
@@ -488,9 +510,9 @@ sub listplugins () { #{{{
        }
 
        return keys %ret;
-} #}}}
+}
 
-sub loadplugins () { #{{{
+sub loadplugins () {
        if (defined $config{libdir} && length $config{libdir}) {
                unshift @INC, possibly_foolish_untaint($config{libdir});
        }
@@ -511,15 +533,15 @@ sub loadplugins () { #{{{
 
        run_hooks(getopt => sub { shift->() });
        if (grep /^-/, @ARGV) {
-               print STDERR "Unknown option: $_\n"
+               print STDERR "Unknown option (or missing parameter): $_\n"
                        foreach grep /^-/, @ARGV;
                usage();
        }
 
        return 1;
-} #}}}
+}
 
-sub loadplugin ($) { #{{{
+sub loadplugin ($) {
        my $plugin=shift;
 
        return if grep { $_ eq $plugin} @{$config{disable_plugins}};
@@ -545,9 +567,9 @@ sub loadplugin ($) { #{{{
        }
        $loaded_plugins{$plugin}=1;
        return 1;
-} #}}}
+}
 
-sub error ($;$) { #{{{
+sub error ($;$) {
        my $message=shift;
        my $cleaner=shift;
        log_message('err' => $message) if $config{syslog};
@@ -555,15 +577,15 @@ sub error ($;$) { #{{{
                $cleaner->();
        }
        die $message."\n";
-} #}}}
+}
 
-sub debug ($) { #{{{
+sub debug ($) {
        return unless $config{verbose};
        return log_message(debug => @_);
-} #}}}
+}
 
 my $log_open=0;
-sub log_message ($$) { #{{{
+sub log_message ($$) {
        my $type=shift;
 
        if ($config{syslog}) {
@@ -583,56 +605,63 @@ sub log_message ($$) { #{{{
        else {
                return print STDERR "@_\n";
        }
-} #}}}
+}
 
-sub possibly_foolish_untaint ($) { #{{{
+sub possibly_foolish_untaint ($) {
        my $tainted=shift;
        my ($untainted)=$tainted=~/(.*)/s;
        return $untainted;
-} #}}}
+}
 
-sub basename ($) { #{{{
+sub basename ($) {
        my $file=shift;
 
        $file=~s!.*/+!!;
        return $file;
-} #}}}
+}
 
-sub dirname ($) { #{{{
+sub dirname ($) {
        my $file=shift;
 
        $file=~s!/*[^/]+$!!;
        return $file;
-} #}}}
+}
 
-sub pagetype ($) { #{{{
+sub isinternal ($) {
        my $page=shift;
+       return exists $pagesources{$page} &&
+               $pagesources{$page} =~ /\._([^.]+)$/;
+}
+
+sub pagetype ($) {
+       my $file=shift;
        
-       if ($page =~ /\.([^.]+)$/) {
+       if ($file =~ /\.([^.]+)$/) {
                return $1 if exists $hooks{htmlize}{$1};
        }
+       my $base=basename($file);
+       if (exists $hooks{htmlize}{$base} &&
+           $hooks{htmlize}{$base}{noextension}) {
+               return $base;
+       }
        return;
-} #}}}
+}
 
-sub isinternal ($) { #{{{
-       my $page=shift;
-       return exists $pagesources{$page} &&
-               $pagesources{$page} =~ /\._([^.]+)$/;
-} #}}}
-
-sub pagename ($) { #{{{
+sub pagename ($) {
        my $file=shift;
 
        my $type=pagetype($file);
        my $page=$file;
-       $page=~s/\Q.$type\E*$// if defined $type && !$hooks{htmlize}{$type}{keepextension};
+       $page=~s/\Q.$type\E*$//
+               if defined $type && !$hooks{htmlize}{$type}{keepextension}
+                       && !$hooks{htmlize}{$type}{noextension};
        if ($config{indexpages} && $page=~/(.*)\/index$/) {
                $page=$1;
        }
        return $page;
-} #}}}
+}
 
-sub newpagefile ($$) { #{{{
+sub newpagefile ($$) {
        my $page=shift;
        my $type=shift;
 
@@ -642,27 +671,31 @@ sub newpagefile ($$) { #{{{
        else {
                return $page."/index.".$type;
        }
-} #}}}
+}
 
-sub targetpage ($$) { #{{{
+sub targetpage ($$;$) {
        my $page=shift;
        my $ext=shift;
+       my $filename=shift;
        
-       if (! $config{usedirs} || $page eq 'index') {
+       if (defined $filename) {
+               return $page."/".$filename.".".$ext;
+       }
+       elsif (! $config{usedirs} || $page eq 'index') {
                return $page.".".$ext;
        }
        else {
                return $page."/index.".$ext;
        }
-} #}}}
+}
 
-sub htmlpage ($) { #{{{
+sub htmlpage ($) {
        my $page=shift;
        
        return targetpage($page, $config{htmlext});
-} #}}}
+}
 
-sub srcfile_stat { #{{{
+sub srcfile_stat {
        my $file=shift;
        my $nothrow=shift;
 
@@ -672,26 +705,27 @@ sub srcfile_stat { #{{{
        }
        error("internal error: $file cannot be found in $config{srcdir} or underlay") unless $nothrow;
        return;
-} #}}}
+}
 
-sub srcfile ($;$) { #{{{
+sub srcfile ($;$) {
        return (srcfile_stat(@_))[0];
-} #}}}
+}
 
-sub add_underlay ($) { #{{{
+sub add_underlay ($) {
        my $dir=shift;
 
-       if ($dir=~/^\//) {
-               unshift @{$config{underlaydirs}}, $dir;
+       if ($dir !~ /^\//) {
+               $dir="$config{underlaydir}/../$dir";
        }
-       else {
-               unshift @{$config{underlaydirs}}, "$config{underlaydir}/../$dir";
+
+       if (! grep { $_ eq $dir } @{$config{underlaydirs}}) {
+               unshift @{$config{underlaydirs}}, $dir;
        }
 
        return 1;
-} #}}}
+}
 
-sub readfile ($;$$) { #{{{
+sub readfile ($;$$) {
        my $file=shift;
        my $binary=shift;
        my $wantfd=shift;
@@ -705,11 +739,15 @@ sub readfile ($;$$) { #{{{
        binmode($in) if ($binary);
        return \*$in if $wantfd;
        my $ret=<$in>;
+       # check for invalid utf-8, and toss it back to avoid crashes
+       if (! utf8::valid($ret)) {
+               $ret=encode_utf8($ret);
+       }
        close $in || error("failed to read $file: $!");
        return $ret;
-} #}}}
+}
 
-sub prep_writefile ($$) { #{{{
+sub prep_writefile ($$) {
        my $file=shift;
        my $destdir=shift;
        
@@ -733,9 +771,9 @@ sub prep_writefile ($$) { #{{{
        }
 
        return 1;
-} #}}}
+}
 
-sub writefile ($$$;$$) { #{{{
+sub writefile ($$$;$$) {
        my $file=shift; # can include subdirs
        my $destdir=shift; # directory to put file in
        my $content=shift;
@@ -763,10 +801,10 @@ sub writefile ($$$;$$) { #{{{
                error("failed renaming $newfile to $destdir/$file: $!", $cleanup);
 
        return 1;
-} #}}}
+}
 
 my %cleared;
-sub will_render ($$;$) { #{{{
+sub will_render ($$;$) {
        my $page=shift;
        my $dest=shift;
        my $clear=shift;
@@ -790,9 +828,9 @@ sub will_render ($$;$) { #{{{
        $destsources{$dest}=$page;
 
        return 1;
-} #}}}
+}
 
-sub bestlink ($$) { #{{{
+sub bestlink ($$) {
        my $page=shift;
        my $link=shift;
        
@@ -828,15 +866,15 @@ sub bestlink ($$) { #{{{
 
        #print STDERR "warning: page $page, broken link: $link\n";
        return "";
-} #}}}
+}
 
-sub isinlinableimage ($) { #{{{
+sub isinlinableimage ($) {
        my $file=shift;
        
        return $file =~ /\.(png|gif|jpg|jpeg)$/i;
-} #}}}
+}
 
-sub pagetitle ($;$) { #{{{
+sub pagetitle ($;$) {
        my $page=shift;
        my $unescaped=shift;
 
@@ -848,31 +886,31 @@ sub pagetitle ($;$) { #{{{
        }
 
        return $page;
-} #}}}
+}
 
-sub titlepage ($) { #{{{
+sub titlepage ($) {
        my $title=shift;
        # support use w/o %config set
        my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_";
        $title=~s/([^$chars]|_)/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
        return $title;
-} #}}}
+}
 
-sub linkpage ($) { #{{{
+sub linkpage ($) {
        my $link=shift;
        my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_";
        $link=~s/([^$chars])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
        return $link;
-} #}}}
+}
 
-sub cgiurl (@) { #{{{
+sub cgiurl (@) {
        my %params=@_;
 
        return $config{cgiurl}."?".
                join("&amp;", map $_."=".uri_escape_utf8($params{$_}), keys %params);
-} #}}}
+}
 
-sub baseurl (;$) { #{{{
+sub baseurl (;$) {
        my $page=shift;
 
        return "$config{url}/" if ! defined $page;
@@ -881,9 +919,9 @@ sub baseurl (;$) { #{{{
        $page=~s/[^\/]+$//;
        $page=~s/[^\/]+\//..\//g;
        return $page;
-} #}}}
+}
 
-sub abs2rel ($$) { #{{{
+sub abs2rel ($$) {
        # Work around very innefficient behavior in File::Spec if abs2rel
        # is passed two relative paths. It's much faster if paths are
        # absolute! (Debian bug #376658; fixed in debian unstable now)
@@ -894,9 +932,16 @@ sub abs2rel ($$) { #{{{
        my $ret=File::Spec->abs2rel($path, $base);
        $ret=~s/^// if defined $ret;
        return $ret;
-} #}}}
+}
 
-sub displaytime ($;$) { #{{{
+sub displaytime ($;$) {
+       # Plugins can override this function to mark up the time to
+       # display.
+       return '<span class="date">'.formattime(@_).'</span>';
+}
+
+sub formattime ($;$) {
+       # Plugins can override this function to format the time.
        my $time=shift;
        my $format=shift;
        if (! defined $format) {
@@ -906,25 +951,25 @@ sub displaytime ($;$) { #{{{
        # strftime doesn't know about encodings, so make sure
        # its output is properly treated as utf8
        return decode_utf8(POSIX::strftime($format, localtime($time)));
-} #}}}
+}
 
-sub beautify_urlpath ($) { #{{{
+sub beautify_urlpath ($) {
        my $url=shift;
 
-       if ($config{usedirs}) {
-               $url =~ s!/index.$config{htmlext}$!/!;
+       # Ensure url is not an empty link, and if necessary,
+       # add ./ to avoid colon confusion.
+       if ($url !~ /^\// && $url !~ /^\.\.?\//) {
+               $url="./$url";
        }
 
-       # Ensure url is not an empty link, and
-       # if it's relative, make that explicit to avoid colon confusion.
-       if ($url !~ /^\//) {
-               $url="./$url";
+       if ($config{usedirs}) {
+               $url =~ s!/index.$config{htmlext}$!/!;
        }
 
        return $url;
-} #}}}
+}
 
-sub urlto ($$;$) { #{{{
+sub urlto ($$;$) {
        my $to=shift;
        my $from=shift;
        my $absolute=shift;
@@ -944,9 +989,9 @@ sub urlto ($$;$) { #{{{
        my $link = abs2rel($to, dirname(htmlpage($from)));
 
        return beautify_urlpath($link);
-} #}}}
+}
 
-sub htmllink ($$$;@) { #{{{
+sub htmllink ($$$;@) {
        my $lpage=shift; # the page doing the linking
        my $page=shift; # the page that will contain the link (different for inline)
        my $link=shift;
@@ -1009,9 +1054,9 @@ sub htmllink ($$$;@) { #{{{
        }
 
        return "<a href=\"$bestlink\"@attrs>$linktext</a>";
-} #}}}
+}
 
-sub userlink ($) { #{{{
+sub userlink ($) {
        my $user=shift;
 
        my $oiduser=eval { openiduser($user) };
@@ -1026,9 +1071,9 @@ sub userlink ($) { #{{{
                        length $config{userdir} ? $config{userdir}."/".$user : $user
                ), noimageinline => 1);
        }
-} #}}}
+}
 
-sub htmlize ($$$$) { #{{{
+sub htmlize ($$$$) {
        my $page=shift;
        my $destpage=shift;
        my $type=shift;
@@ -1063,9 +1108,9 @@ sub htmlize ($$$$) { #{{{
        }
 
        return $content;
-} #}}}
+}
 
-sub linkify ($$$) { #{{{
+sub linkify ($$$) {
        my $page=shift;
        my $destpage=shift;
        my $content=shift;
@@ -1079,11 +1124,11 @@ sub linkify ($$$) { #{{{
        });
        
        return $content;
-} #}}}
+}
 
 our %preprocessing;
 our $preprocess_preview=0;
-sub preprocess ($$$;$$) { #{{{
+sub preprocess ($$$;$$) {
        my $page=shift; # the page the data comes from
        my $destpage=shift; # the page the data will appear in (different for inline)
        my $content=shift;
@@ -1236,9 +1281,9 @@ sub preprocess ($$$;$$) { #{{{
 
        $content =~ s{$regex}{$handle->($1, $2, $3, $4)}eg;
        return $content;
-} #}}}
+}
 
-sub filter ($$$) { #{{{
+sub filter ($$$) {
        my $page=shift;
        my $destpage=shift;
        my $content=shift;
@@ -1249,16 +1294,79 @@ sub filter ($$$) { #{{{
        });
 
        return $content;
-} #}}}
+}
 
-sub indexlink () { #{{{
+sub indexlink () {
        return "<a href=\"$config{url}\">$config{wikiname}</a>";
-} #}}}
+}
+
+sub check_canedit ($$$;$) {
+       my $page=shift;
+       my $q=shift;
+       my $session=shift;
+       my $nonfatal=shift;
+       
+       my $canedit;
+       run_hooks(canedit => sub {
+               return if defined $canedit;
+               my $ret=shift->($page, $q, $session);
+               if (defined $ret) {
+                       if ($ret eq "") {
+                               $canedit=1;
+                       }
+                       elsif (ref $ret eq 'CODE') {
+                               $ret->() unless $nonfatal;
+                               $canedit=0;
+                       }
+                       elsif (defined $ret) {
+                               error($ret) unless $nonfatal;
+                               $canedit=0;
+                       }
+               }
+       });
+       return defined $canedit ? $canedit : 1;
+}
+
+sub check_content (@) {
+       my %params=@_;
+       
+       return 1 if ! exists $hooks{checkcontent}; # optimisation
+
+       if (exists $pagesources{$params{page}}) {
+               my @diff;
+               my %old=map { $_ => 1 }
+                       split("\n", readfile(srcfile($pagesources{$params{page}})));
+               foreach my $line (split("\n", $params{content})) {
+                       push @diff, $line if ! exists $old{$_};
+               }
+               $params{content}=join("\n", @diff);
+       }
+
+       my $ok;
+       run_hooks(checkcontent => sub {
+               return if defined $ok;
+               my $ret=shift->(%params);
+               if (defined $ret) {
+                       if ($ret eq "") {
+                               $ok=1;
+                       }
+                       elsif (ref $ret eq 'CODE') {
+                               $ret->() unless $params{nonfatal};
+                               $ok=0;
+                       }
+                       elsif (defined $ret) {
+                               error($ret) unless $params{nonfatal};
+                               $ok=0;
+                       }
+               }
+
+       });
+       return defined $ok ? $ok : 1;
+}
 
 my $wikilock;
 
-sub lockwiki (;$) { #{{{
-       my $wait=@_ ? shift : 1;
+sub lockwiki () {
        # Take an exclusive lock on the wiki to prevent multiple concurrent
        # run issues. The lock will be dropped on program exit.
        if (! -d $config{wikistatedir}) {
@@ -1266,32 +1374,21 @@ sub lockwiki (;$) { #{{{
        }
        open($wikilock, '>', "$config{wikistatedir}/lockfile") ||
                error ("cannot write to $config{wikistatedir}/lockfile: $!");
-       if (! flock($wikilock, 2 | 4)) { # LOCK_EX | LOCK_NB
-               if ($wait) {
-                       debug("wiki seems to be locked, waiting for lock");
-                       my $wait=600; # arbitrary, but don't hang forever to 
-                                     # prevent process pileup
-                       for (1..$wait) {
-                               return if flock($wikilock, 2 | 4);
-                               sleep 1;
-                       }
-                       error("wiki is locked; waited $wait seconds without lock being freed (possible stuck process or stale lock?)");
-               }
-               else {
-                       return 0;
-               }
+       if (! flock($wikilock, 2)) { # LOCK_EX
+               error("failed to get lock");
        }
        return 1;
-} #}}}
+}
 
-sub unlockwiki () { #{{{
+sub unlockwiki () {
+       POSIX::close($ENV{IKIWIKI_CGILOCK_FD}) if exists $ENV{IKIWIKI_CGILOCK_FD};
        return close($wikilock) if $wikilock;
        return;
-} #}}}
+}
 
 my $commitlock;
 
-sub commit_hook_enabled () { #{{{
+sub commit_hook_enabled () {
        open($commitlock, '+>', "$config{wikistatedir}/commitlock") ||
                error("cannot write to $config{wikistatedir}/commitlock: $!");
        if (! flock($commitlock, 1 | 4)) { # LOCK_SH | LOCK_NB to test
@@ -1300,23 +1397,23 @@ sub commit_hook_enabled () { #{{{
        }
        close($commitlock) || error("failed closing commitlock: $!");
        return 1;
-} #}}}
+}
 
-sub disable_commit_hook () { #{{{
+sub disable_commit_hook () {
        open($commitlock, '>', "$config{wikistatedir}/commitlock") ||
                error("cannot write to $config{wikistatedir}/commitlock: $!");
        if (! flock($commitlock, 2)) { # LOCK_EX
                error("failed to get commit lock");
        }
        return 1;
-} #}}}
+}
 
-sub enable_commit_hook () { #{{{
+sub enable_commit_hook () {
        return close($commitlock) if $commitlock;
        return;
-} #}}}
+}
 
-sub loadindex () { #{{{
+sub loadindex () {
        %oldrenderedfiles=%pagectime=();
        if (! $config{rebuild}) {
                %pagesources=%pagemtime=%oldlinks=%links=%depends=
@@ -1376,9 +1473,9 @@ sub loadindex () { #{{{
                $destsources{$_}=$page foreach @{$renderedfiles{$page}};
        }
        return close($in);
-} #}}}
+}
 
-sub saveindex () { #{{{
+sub saveindex () {
        run_hooks(savestate => sub { shift->() });
 
        my %hookids;
@@ -1434,18 +1531,18 @@ sub saveindex () { #{{{
                error("failed renaming $newfile to $config{wikistatedir}/indexdb", $cleanup);
        
        return 1;
-} #}}}
+}
 
-sub template_file ($) { #{{{
+sub template_file ($) {
        my $template=shift;
 
        foreach my $dir ($config{templatedir}, "$installdir/share/ikiwiki/templates") {
                return "$dir/$template" if -e "$dir/$template";
        }
        return;
-} #}}}
+}
 
-sub template_params (@) { #{{{
+sub template_params (@) {
        my $filename=template_file(shift);
 
        if (! defined $filename) {
@@ -1464,14 +1561,14 @@ sub template_params (@) { #{{{
                @_
        );
        return wantarray ? @ret : {@ret};
-} #}}}
+}
 
-sub template ($;@) { #{{{
+sub template ($;@) {
        require HTML::Template;
        return HTML::Template->new(template_params(@_));
-} #}}}
+}
 
-sub misctemplate ($$;@) { #{{{
+sub misctemplate ($$;@) {
        my $title=shift;
        my $pagebody=shift;
        
@@ -1488,9 +1585,9 @@ sub misctemplate ($$;@) { #{{{
                shift->(page => "", destpage => "", template => $template);
        });
        return $template->output;
-}#}}}
+}
 
-sub hook (@) { # {{{
+sub hook (@) {
        my %param=@_;
        
        if (! exists $param{type} || ! ref $param{call} || ! exists $param{id}) {
@@ -1501,109 +1598,86 @@ sub hook (@) { # {{{
        
        $hooks{$param{type}}{$param{id}}=\%param;
        return 1;
-} # }}}
+}
 
-sub run_hooks ($$) { # {{{
+sub run_hooks ($$) {
        # Calls the given sub for each hook of the given type,
        # passing it the hook function to call.
        my $type=shift;
        my $sub=shift;
 
        if (exists $hooks{$type}) {
-               my @deferred;
+               my (@first, @middle, @last);
                foreach my $id (keys %{$hooks{$type}}) {
-                       if ($hooks{$type}{$id}{last}) {
-                               push @deferred, $id;
-                               next;
+                       if ($hooks{$type}{$id}{first}) {
+                               push @first, $id;
+                       }
+                       elsif ($hooks{$type}{$id}{last}) {
+                               push @last, $id;
+                       }
+                       else {
+                               push @middle, $id;
                        }
-                       $sub->($hooks{$type}{$id}{call});
                }
-               foreach my $id (@deferred) {
+               foreach my $id (@first, @middle, @last) {
                        $sub->($hooks{$type}{$id}{call});
                }
        }
 
        return 1;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        $hooks{rcs}{rcs_update}{call}->(@_);
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        $hooks{rcs}{rcs_prepedit}{call}->(@_);
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        $hooks{rcs}{rcs_commit}{call}->(@_);
-} #}}}
+}
 
-sub rcs_commit_staged ($$$) { #{{{
+sub rcs_commit_staged ($$$) {
        $hooks{rcs}{rcs_commit_staged}{call}->(@_);
-} #}}}
+}
 
-sub rcs_add ($) { #{{{
+sub rcs_add ($) {
        $hooks{rcs}{rcs_add}{call}->(@_);
-} #}}}
+}
 
-sub rcs_remove ($) { #{{{
+sub rcs_remove ($) {
        $hooks{rcs}{rcs_remove}{call}->(@_);
-} #}}}
+}
 
-sub rcs_rename ($$) { #{{{
+sub rcs_rename ($$) {
        $hooks{rcs}{rcs_rename}{call}->(@_);
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        $hooks{rcs}{rcs_recentchanges}{call}->(@_);
-} #}}}
+}
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        $hooks{rcs}{rcs_diff}{call}->(@_);
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        $hooks{rcs}{rcs_getctime}{call}->(@_);
-} #}}}
+}
 
-sub globlist_to_pagespec ($) { #{{{
-       my @globlist=split(' ', shift);
-
-       my (@spec, @skip);
-       foreach my $glob (@globlist) {
-               if ($glob=~/^!(.*)/) {
-                       push @skip, $glob;
-               }
-               else {
-                       push @spec, $glob;
-               }
-       }
+sub rcs_receive () {
+       $hooks{rcs}{rcs_receive}{call}->();
+}
 
-       my $spec=join(' or ', @spec);
-       if (@skip) {
-               my $skip=join(' and ', @skip);
-               if (length $spec) {
-                       $spec="$skip and ($spec)";
-               }
-               else {
-                       $spec=$skip;
-               }
-       }
-       return $spec;
-} #}}}
-
-sub is_globlist ($) { #{{{
-       my $s=shift;
-       return ( $s =~ /[^\s]+\s+([^\s]+)/ && $1 ne "and" && $1 ne "or" );
-} #}}}
-
-sub safequote ($) { #{{{
+sub safequote ($) {
        my $s=shift;
        $s=~s/[{}]//g;
        return "q{$s}";
-} #}}}
+}
 
-sub add_depends ($$) { #{{{
+sub add_depends ($$) {
        my $page=shift;
        my $pagespec=shift;
        
@@ -1617,9 +1691,9 @@ sub add_depends ($$) { #{{{
        }
 
        return 1;
-} # }}}
+}
 
-sub file_pruned ($$) { #{{{
+sub file_pruned ($$) {
        require File::Spec;
        my $file=File::Spec->canonpath(shift);
        my $base=File::Spec->canonpath(shift);
@@ -1627,9 +1701,9 @@ sub file_pruned ($$) { #{{{
 
        my $regexp='('.join('|', @{$config{wiki_file_prune_regexps}}).')';
        return $file =~ m/$regexp/ && $file ne $base;
-} #}}}
+}
 
-sub gettext { #{{{
+sub gettext {
        # Only use gettext in the rare cases it's needed.
        if ((exists $ENV{LANG} && length $ENV{LANG}) ||
            (exists $ENV{LC_ALL} && length $ENV{LC_ALL}) ||
@@ -1650,39 +1724,50 @@ sub gettext { #{{{
        else {
                return shift;
        }
-} #}}}
+}
 
-sub yesno ($) { #{{{
+sub yesno ($) {
        my $val=shift;
 
-       return (defined $val && lc($val) eq gettext("yes"));
-} #}}}
+       return (defined $val && (lc($val) eq gettext("yes") || lc($val) eq "yes" || $val eq "1"));
+}
+
+sub inject {
+       # Injects a new function into the symbol table to replace an
+       # exported function.
+       my %params=@_;
 
-sub pagespec_merge ($$) { #{{{
+       # This is deep ugly perl foo, beware.
+       no strict;
+       no warnings;
+       if (! defined $params{parent}) {
+               $params{parent}='::';
+               $params{old}=\&{$params{name}};
+               $params{name}=~s/.*:://;
+       }
+       my $parent=$params{parent};
+       foreach my $ns (grep /^\w+::/, keys %{$parent}) {
+               $ns = $params{parent} . $ns;
+               inject(%params, parent => $ns) unless $ns eq '::main::';
+               *{$ns . $params{name}} = $params{call}
+                       if exists ${$ns}{$params{name}} &&
+                          \&{${$ns}{$params{name}}} == $params{old};
+       }
+       use strict;
+       use warnings;
+}
+
+sub pagespec_merge ($$) {
        my $a=shift;
        my $b=shift;
 
        return $a if $a eq $b;
-
-        # Support for old-style GlobLists.
-        if (is_globlist($a)) {
-                $a=globlist_to_pagespec($a);
-        }
-        if (is_globlist($b)) {
-                $b=globlist_to_pagespec($b);
-        }
-
        return "($a) or ($b)";
-} #}}}
+}
 
-sub pagespec_translate ($) { #{{{
+sub pagespec_translate ($) {
        my $spec=shift;
 
-       # Support for old-style GlobLists.
-       if (is_globlist($spec)) {
-               $spec=globlist_to_pagespec($spec);
-       }
-
        # Convert spec to perl code.
        my $code="";
        while ($spec=~m{
@@ -1715,7 +1800,7 @@ sub pagespec_translate ($) { #{{{
                                $code.="IkiWiki::PageSpec::match_$1(\$page, ".safequote($2).", \@_)";
                        }
                        else {
-                               $code.=' 0';
+                               $code.="IkiWiki::FailReason->new(".safequote(qq{unknown function in pagespec "$word"}).")";
                        }
                }
                else {
@@ -1724,14 +1809,14 @@ sub pagespec_translate ($) { #{{{
        }
 
        if (! length $code) {
-               $code=0;
+               $code="IkiWiki::FailReason->new('empty pagespec')";
        }
 
        no warnings;
        return eval 'sub { my $page=shift; '.$code.' }';
-} #}}}
+}
 
-sub pagespec_match ($$;@) { #{{{
+sub pagespec_match ($$;@) {
        my $page=shift;
        my $spec=shift;
        my @params=@_;
@@ -1742,69 +1827,76 @@ sub pagespec_match ($$;@) { #{{{
        }
 
        my $sub=pagespec_translate($spec);
-       return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") if $@;
+       return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"")
+               if $@ || ! defined $sub;
        return $sub->($page, @params);
-} #}}}
+}
 
-sub pagespec_valid ($) { #{{{
+sub pagespec_valid ($) {
        my $spec=shift;
 
        my $sub=pagespec_translate($spec);
        return ! $@;
-} #}}}
-       
-sub glob2re ($) { #{{{
+}
+
+sub glob2re ($) {
        my $re=quotemeta(shift);
        $re=~s/\\\*/.*/g;
        $re=~s/\\\?/./g;
        return $re;
-} #}}}
+}
 
 package IkiWiki::FailReason;
 
-use overload ( #{{{
+use overload (
        '""'    => sub { ${$_[0]} },
        '0+'    => sub { 0 },
        '!'     => sub { bless $_[0], 'IkiWiki::SuccessReason'},
        fallback => 1,
-); #}}}
+);
 
-sub new { #{{{
+sub new {
        my $class = shift;
        my $value = shift;
        return bless \$value, $class;
-} #}}}
+}
 
 package IkiWiki::SuccessReason;
 
-use overload ( #{{{
+use overload (
        '""'    => sub { ${$_[0]} },
        '0+'    => sub { 1 },
        '!'     => sub { bless $_[0], 'IkiWiki::FailReason'},
        fallback => 1,
-); #}}}
+);
 
-sub new { #{{{
+sub new {
        my $class = shift;
        my $value = shift;
        return bless \$value, $class;
-}; #}}}
+};
 
 package IkiWiki::PageSpec;
 
-sub match_glob ($$;@) { #{{{
+sub derel ($$) {
+       my $path=shift;
+       my $from=shift;
+
+       if ($path =~ m!^\./!) {
+               $from=~s#/?[^/]+$## if defined $from;
+               $path=~s#^\./##;
+               $path="$from/$path" if length $from;
+       }
+
+       return $path;
+}
+
+sub match_glob ($$;@) {
        my $page=shift;
        my $glob=shift;
        my %params=@_;
        
-       my $from=exists $params{location} ? $params{location} : '';
-       
-       # relative matching
-       if ($glob =~ m!^\./!) {
-               $from=~s#/?[^/]+$##;
-               $glob=~s#^\./##;
-               $glob="$from/$glob" if length $from;
-       }
+       $glob=derel($glob, $params{location});
 
        my $regexp=IkiWiki::glob2re($glob);
        if ($page=~/^$regexp$/i) {
@@ -1818,26 +1910,20 @@ sub match_glob ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("$glob does not match $page");
        }
-} #}}}
+}
 
-sub match_internal ($$;@) { #{{{
+sub match_internal ($$;@) {
        return match_glob($_[0], $_[1], @_, internal => 1)
-} #}}}
+}
 
-sub match_link ($$;@) { #{{{
+sub match_link ($$;@) {
        my $page=shift;
        my $link=lc(shift);
        my %params=@_;
 
+       $link=derel($link, $params{location});
        my $from=exists $params{location} ? $params{location} : '';
 
-       # relative matching
-       if ($link =~ m!^\.! && defined $from) {
-               $from=~s#/?[^/]+$##;
-               $link=~s#^\./##;
-               $link="$from/$link" if length $from;
-       }
-
        my $links = $IkiWiki::links{$page};
        return IkiWiki::FailReason->new("$page has no links") unless $links && @{$links};
        my $bestlink = IkiWiki::bestlink($from, $link);
@@ -1849,18 +1935,25 @@ sub match_link ($$;@) { #{{{
                else {
                        return IkiWiki::SuccessReason->new("$page links to page $p matching $link")
                                if match_glob($p, $link, %params);
+                       $p=~s/^\///;
+                       $link=~s/^\///;
+                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link")
+                               if match_glob($p, $link, %params);
                }
        }
        return IkiWiki::FailReason->new("$page does not link to $link");
-} #}}}
+}
 
-sub match_backlink ($$;@) { #{{{
+sub match_backlink ($$;@) {
        return match_link($_[1], $_[0], @_);
-} #}}}
+}
 
-sub match_created_before ($$;@) { #{{{
+sub match_created_before ($$;@) {
        my $page=shift;
        my $testpage=shift;
+       my %params=@_;
+       
+       $testpage=derel($testpage, $params{location});
 
        if (exists $IkiWiki::pagectime{$testpage}) {
                if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) {
@@ -1873,11 +1966,14 @@ sub match_created_before ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("$testpage has no ctime");
        }
-} #}}}
+}
 
-sub match_created_after ($$;@) { #{{{
+sub match_created_after ($$;@) {
        my $page=shift;
        my $testpage=shift;
+       my %params=@_;
+       
+       $testpage=derel($testpage, $params{location});
 
        if (exists $IkiWiki::pagectime{$testpage}) {
                if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) {
@@ -1890,36 +1986,36 @@ sub match_created_after ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("$testpage has no ctime");
        }
-} #}}}
+}
 
-sub match_creation_day ($$;@) { #{{{
+sub match_creation_day ($$;@) {
        if ((gmtime($IkiWiki::pagectime{shift()}))[3] == shift) {
                return IkiWiki::SuccessReason->new('creation_day matched');
        }
        else {
                return IkiWiki::FailReason->new('creation_day did not match');
        }
-} #}}}
+}
 
-sub match_creation_month ($$;@) { #{{{
+sub match_creation_month ($$;@) {
        if ((gmtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift) {
                return IkiWiki::SuccessReason->new('creation_month matched');
        }
        else {
                return IkiWiki::FailReason->new('creation_month did not match');
        }
-} #}}}
+}
 
-sub match_creation_year ($$;@) { #{{{
+sub match_creation_year ($$;@) {
        if ((gmtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) {
                return IkiWiki::SuccessReason->new('creation_year matched');
        }
        else {
                return IkiWiki::FailReason->new('creation_year did not match');
        }
-} #}}}
+}
 
-sub match_user ($$;@) { #{{{
+sub match_user ($$;@) {
        shift;
        my $user=shift;
        my %params=@_;
@@ -1937,9 +2033,9 @@ sub match_user ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("user is $params{user}, not $user");
        }
-} #}}}
+}
 
-sub match_admin ($$;@) { #{{{
+sub match_admin ($$;@) {
        shift;
        shift;
        my %params=@_;
@@ -1957,9 +2053,9 @@ sub match_admin ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("user is not an admin");
        }
-} #}}}
+}
 
-sub match_ip ($$;@) { #{{{
+sub match_ip ($$;@) {
        shift;
        my $ip=shift;
        my %params=@_;
@@ -1974,6 +2070,6 @@ sub match_ip ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("IP is $params{ip}, not $ip");
        }
-} #}}}
+}
 
 1
index dac522eea470a544248c9c77406009b27d4d9997..04f24b04f986c2618b0cbf619e09ba7dfbff58ee 100644 (file)
@@ -9,7 +9,7 @@ use IkiWiki::UserInfo;
 use open qw{:utf8 :std};
 use Encode;
 
-sub printheader ($) { #{{{
+sub printheader ($) {
        my $session=shift;
        
        if ($config{sslcookie}) {
@@ -19,9 +19,9 @@ sub printheader ($) { #{{{
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1));
        }
-} #}}}
+}
 
-sub showform ($$$$;@) { #{{{
+sub showform ($$$$;@) {
        my $form=shift;
        my $buttons=shift;
        my $session=shift;
@@ -38,7 +38,7 @@ sub showform ($$$$;@) { #{{{
        print misctemplate($form->title, $form->render(submit => $buttons), @_);
 }
 
-sub redirect ($$) { #{{{
+sub redirect ($$) {
        my $q=shift;
        my $url=shift;
        if (! $config{w3mmode}) {
@@ -48,9 +48,9 @@ sub redirect ($$) { #{{{
                print "Content-type: text/plain\n";
                print "W3m-control: GOTO $url\n\n";
        }
-} #}}}
+}
 
-sub decode_cgi_utf8 ($) { #{{{
+sub decode_cgi_utf8 ($) {
        # decode_form_utf8 method is needed for 5.10
        if ($] < 5.01) {
                my $cgi = shift;
@@ -58,9 +58,9 @@ sub decode_cgi_utf8 ($) { #{{{
                        $cgi->param($f, map { decode_utf8 $_ } $cgi->param($f));
                }
        }
-} #}}}
+}
 
-sub decode_form_utf8 ($) { #{{{
+sub decode_form_utf8 ($) {
        if ($] >= 5.01) {
                my $form = shift;
                foreach my $f ($form->field) {
@@ -70,11 +70,11 @@ sub decode_form_utf8 ($) { #{{{
                        );
                }
        }
-} #}}}
+}
 
 # Check if the user is signed in. If not, redirect to the signin form and
 # save their place to return to later.
-sub needsignin ($$) { #{{{
+sub needsignin ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -85,9 +85,9 @@ sub needsignin ($$) { #{{{
                cgi_savesession($session);
                exit;
        }
-} #}}} 
+}
 
-sub cgi_signin ($$) { #{{{
+sub cgi_signin ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -127,9 +127,9 @@ sub cgi_signin ($$) { #{{{
        }
 
        showform($form, $buttons, $session, $q);
-} #}}}
+}
 
-sub cgi_postsignin ($$) { #{{{
+sub cgi_postsignin ($$) {
        my $q=shift;
        my $session=shift;
        
@@ -142,11 +142,16 @@ sub cgi_postsignin ($$) { #{{{
                exit;
        }
        else {
-               error(gettext("login failed, perhaps you need to turn on cookies?"));
+               if ($config{sslcookie} && ! $q->https()) {
+                       error(gettext("probable misconfiguration: sslcookie is set, but you are attepting to login via http, not https"));
+               }
+               else {
+                       error(gettext("login failed, perhaps you need to turn on cookies?"));
+               }
        }
-} #}}}
+}
 
-sub cgi_prefs ($$) { #{{{
+sub cgi_prefs ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -203,25 +208,9 @@ sub cgi_prefs ($$) { #{{{
        
        my $user_name=$session->param("name");
 
-       # XXX deprecated, should be removed eventually
-       $form->field(name => "banned_users", size => 50, fieldset => "admin");
-       if (! is_admin($user_name)) {
-               $form->field(name => "banned_users", type => "hidden");
-       }
        if (! $form->submitted) {
                $form->field(name => "email", force => 1,
                        value => userinfo_get($user_name, "email"));
-               if (is_admin($user_name)) {
-                       my $value=join(" ", get_banned_users());
-                       if (length $value) {
-                               $form->field(name => "banned_users", force => 1,
-                                       value => join(" ", get_banned_users()),
-                                       comment => "deprecated; please move to banned_users in setup file");
-                       }
-                       else {
-                               $form->field(name => "banned_users", type => "hidden");
-                       }
-               }
        }
        
        if ($form->submitted eq 'Logout') {
@@ -239,48 +228,48 @@ sub cgi_prefs ($$) { #{{{
                                error("failed to set email");
                }
 
-               # XXX deprecated, should be removed eventually
-               if (is_admin($user_name)) {
-                       set_banned_users(grep { ! is_admin($_) }
-                                       split(' ',
-                                               $form->field("banned_users"))) ||
-                               error("failed saving changes");
-                       if (! length $form->field("banned_users")) {
-                               $form->field(name => "banned_users", type => "hidden");
-                       }
-               }
-
                $form->text(gettext("Preferences saved."));
        }
        
        showform($form, $buttons, $session, $q);
-} #}}}
+}
 
-sub check_banned ($$) { #{{{
+sub cgi_custom_failure ($$) {
+       my $header=shift;
+       my $message=shift;
+
+       print $header;
+       print $message;
+
+       # Internet Explod^Hrer won't show custom 404 responses
+       # unless they're >= 512 bytes
+       print ' ' x 512;
+
+       exit;
+}
+
+sub check_banned ($$) {
        my $q=shift;
        my $session=shift;
 
        my $name=$session->param("name");
        if (defined $name) {
-               # XXX banned in userinfo is deprecated, should be removed
-               # eventually, and only banned_users be checked.
-               if (userinfo_get($session->param("name"), "banned") ||
-                   grep { $name eq $_ } @{$config{banned_users}}) {
-                       print $q->header(-status => "403 Forbidden");
+               if (grep { $name eq $_ } @{$config{banned_users}}) {
                        $session->delete();
-                       print gettext("You are banned.");
                        cgi_savesession($session);
-                       exit;
+                       cgi_custom_failure(
+                               $q->header(-status => "403 Forbidden"),
+                               gettext("You are banned."));
                }
        }
 }
 
-sub cgi_getsession ($) { #{{{
+sub cgi_getsession ($) {
        my $q=shift;
 
-       eval q{use CGI::Session};
+       eval q{use CGI::Session; use HTML::Entities};
        error($@) if $@;
-       CGI::Session->name("ikiwiki_session_".encode_utf8($config{wikiname}));
+       CGI::Session->name("ikiwiki_session_".encode_entities($config{wikiname}));
        
        my $oldmask=umask(077);
        my $session = eval {
@@ -294,18 +283,34 @@ sub cgi_getsession ($) { #{{{
        umask($oldmask);
 
        return $session;
-} #}}}
+}
+
+# To guard against CSRF, the user's session id (sid)
+# can be stored on a form. This function will check
+# (for logged in users) that the sid on the form matches
+# the session id in the cookie.
+sub checksessionexpiry ($$) {
+       my $q=shift;
+       my $session = shift;
 
-sub cgi_savesession ($) { #{{{
+       if (defined $session->param("name")) {
+               my $sid=$q->param('sid');
+               if (! defined $sid || $sid ne $session->id) {
+                       error(gettext("Your login session has expired."));
+               }
+       }
+}
+
+sub cgi_savesession ($) {
        my $session=shift;
 
        # Force session flush with safe umask.
        my $oldmask=umask(077);
        $session->flush;
        umask($oldmask);
-} #}}}
+}
 
-sub cgi (;$$) { #{{{
+sub cgi (;$$) {
        my $q=shift;
        my $session=shift;
 
@@ -331,7 +336,7 @@ sub cgi (;$$) { #{{{
                        error("\"do\" parameter missing");
                }
        }
-       
+
        # Need to lock the wiki before getting a session.
        lockwiki();
        loadindex();
@@ -375,16 +380,16 @@ sub cgi (;$$) { #{{{
        else {
                error("unknown do parameter");
        }
-} #}}}
+}
 
 # Does not need to be called directly; all errors will go through here.
-sub cgierror ($) { #{{{
+sub cgierror ($) {
        my $message=shift;
 
        print "Content-type: text/html\n\n";
        print misctemplate(gettext("Error"),
                "<p class=\"error\">".gettext("Error").": $message</p>");
        die $@;
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/404.pm b/IkiWiki/Plugin/404.pm
new file mode 100644 (file)
index 0000000..bae9e15
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+# Copyright © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+package IkiWiki::Plugin::404;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "cgi", id => '404',  call => \&cgi);
+       IkiWiki::loadplugin("goto");
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       # not really a matter of safety, but enabling/disabling
+                       # through a web interface is useless - it needs web
+                       # server admin action too
+                       safe => 0,
+                       rebuild => 0,
+               }
+}
+
+sub cgi_page_from_404 ($$$) {
+       my $path = shift;
+       my $baseurl = shift;
+       my $usedirs = shift;
+
+       # fail if missing from environment or whatever
+       return undef unless defined $path;
+       return undef unless defined $baseurl;
+
+       # with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or
+       #    /~fred/foo/bar/index.html
+       # with usedirs off, path is like /~fred/foo/bar.html
+       # baseurl is like 'http://people.example.com/~fred'
+
+       # convert baseurl to ~fred
+       unless ($baseurl =~ s{^https?://[^/]+/?}{}) {
+               return undef;
+       }
+
+       # convert path to /~fred/foo/bar
+       if ($usedirs) {
+               $path =~ s/\/*(?:index\.$config{htmlext})?$//;
+       }
+       else {
+               $path =~ s/\.$config{htmlext}$//;
+       }
+
+       # remove /~fred/
+       unless ($path =~ s{^/*\Q$baseurl\E/*}{}) {
+               return undef;
+       }
+
+       # special case for the index
+       unless ($path) {
+               return 'index';
+       }
+
+       return $path;
+}
+
+sub cgi ($) {
+       my $cgi=shift;
+
+       if (exists $ENV{REDIRECT_STATUS} && 
+           $ENV{REDIRECT_STATUS} eq '404') {
+               my $page = cgi_page_from_404($ENV{REDIRECT_URL},
+                       $config{url}, $config{usedirs});
+               IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
+       }
+}
+
+1;
index 26c5cc9ae209bd63c90adb573014c333ecb34644..e1baae666a02ffe0e9230ed4d81667a2f7ece79a 100644 (file)
@@ -4,7 +4,7 @@ package IkiWiki::Plugin::aggregate;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Parser;
 use HTML::Tagset;
 use HTML::Entities;
@@ -14,7 +14,7 @@ use open qw{:utf8 :std};
 my %feeds;
 my %guids;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "aggregate", call => \&getopt);
        hook(type => "getsetup", id => "aggregate", call => \&getsetup);
        hook(type => "checkconfig", id => "aggregate", call => \&checkconfig);
@@ -26,9 +26,9 @@ sub import { #{{{
        if (exists $config{aggregate_webtrigger} && $config{aggregate_webtrigger}) {
                hook(type => "cgi", id => "aggregate", call => \&cgi);
        }
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
         eval q{use Getopt::Long};
        error($@) if $@;
         Getopt::Long::Configure('pass_through');
@@ -36,9 +36,9 @@ sub getopt () { #{{{
                "aggregate" => \$config{aggregate},
                "aggregateinternal!" => \$config{aggregateinternal},
        );
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -46,7 +46,7 @@ sub getsetup () { #{{{
                },
                aggregateinternal => {
                        type => "boolean",
-                       example => 0,
+                       example => 1,
                        description => "enable aggregation to internal pages?",
                        safe => 0, # enabling needs manual transition
                        rebuild => 0,
@@ -58,16 +58,20 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
+
+sub checkconfig () {
+       if (! defined $config{aggregateinternal}) {
+               $config{aggregateinternal}=1;
+       }
 
-sub checkconfig () { #{{{
        if ($config{aggregate} && ! ($config{post_commit} && 
                                     IkiWiki::commit_hook_enabled())) {
                launchaggregation();
        }
-} #}}}
+}
 
-sub cgi ($) { #{{{
+sub cgi ($) {
        my $cgi=shift;
 
        if (defined $cgi->param('do') &&
@@ -90,9 +94,9 @@ sub cgi ($) { #{{{
                }
                exit 0;
        }
-} #}}}
+}
 
-sub launchaggregation () { #{{{
+sub launchaggregation () {
        # See if any feeds need aggregation.
        loadstate();
        my @feeds=needsaggregate();
@@ -135,16 +139,16 @@ sub launchaggregation () { #{{{
        unlockaggregate();
 
        return 1;
-} #}}}
+}
 
 #  Pages with extension _aggregated have plain html markup, pass through.
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        return $params{content};
-} #}}}
+}
 
 # Used by ikiwiki-transition aggregateinternal.
-sub migrate_to_internal { #{{{
+sub migrate_to_internal {
        if (! lockaggregate()) {
                error("an aggregation process is currently running");
        }
@@ -190,9 +194,9 @@ sub migrate_to_internal { #{{{
        IkiWiki::unlockwiki;
        
        unlockaggregate();
-} #}}}
+}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
        
        loadstate();
@@ -206,9 +210,9 @@ sub needsbuild (@) { #{{{
                        markunseen($feed->{sourcepage});
                }
        }
-} # }}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        foreach my $required (qw{name url}) {
@@ -245,6 +249,7 @@ sub preprocess (@) { #{{{
        $feed->{template}=$params{template} . ".tmpl";
        delete $feed->{unseen};
        $feed->{lastupdate}=0 unless defined $feed->{lastupdate};
+       $feed->{lasttry}=$feed->{lastupdate} unless defined $feed->{lasttry};
        $feed->{numposts}=0 unless defined $feed->{numposts};
        $feed->{newposts}=0 unless defined $feed->{newposts};
        $feed->{message}=gettext("new feed") unless defined $feed->{message};
@@ -265,9 +270,9 @@ sub preprocess (@) { #{{{
               ($feed->{newposts} ? "; ".$feed->{newposts}.
                                    " ".gettext("new") : "").
               ")";
-} # }}}
+}
 
-sub delete (@) { #{{{
+sub delete (@) {
        my @files=@_;
 
        # Remove feed data for removed pages.
@@ -275,9 +280,9 @@ sub delete (@) { #{{{
                my $page=pagename($file);
                markunseen($page);
        }
-} #}}}
+}
 
-sub markunseen ($) { #{{{
+sub markunseen ($) {
        my $page=shift;
 
        foreach my $id (keys %feeds) {
@@ -285,11 +290,11 @@ sub markunseen ($) { #{{{
                        $feeds{$id}->{unseen}=1;
                }
        }
-} #}}}
+}
 
 my $state_loaded=0;
 
-sub loadstate () { #{{{
+sub loadstate () {
        return if $state_loaded;
        $state_loaded=1;
        if (-e "$config{wikistatedir}/aggregate") {
@@ -323,9 +328,9 @@ sub loadstate () { #{{{
 
                close IN;
        }
-} #}}}
+}
 
-sub savestate () { #{{{
+sub savestate () {
        return unless $state_loaded;
        garbage_collect();
        my $newfile="$config{wikistatedir}/aggregate.new";
@@ -342,7 +347,8 @@ sub savestate () { #{{{
                                push @line, "tag=$_" foreach @{$data->{tags}};
                        }
                        else {
-                               push @line, "$field=".$data->{$field};
+                               push @line, "$field=".$data->{$field}
+                                       if defined $data->{$field};
                        }
                }
                print OUT join(" ", @line)."\n" || error("write $newfile: $!", $cleanup);
@@ -350,9 +356,9 @@ sub savestate () { #{{{
        close OUT || error("save $newfile: $!", $cleanup);
        rename($newfile, "$config{wikistatedir}/aggregate") ||
                error("rename $newfile: $!", $cleanup);
-} #}}}
+}
 
-sub garbage_collect () { #{{{
+sub garbage_collect () {
        foreach my $name (keys %feeds) {
                # remove any feeds that were not seen while building the pages
                # that used to contain them
@@ -375,9 +381,9 @@ sub garbage_collect () { #{{{
                        delete $guid->{md5};
                }
        }
-} #}}}
+}
 
-sub mergestate () { #{{{
+sub mergestate () {
        # Load the current state in from disk, and merge into it
        # values from the state in memory that might have changed
        # during aggregation.
@@ -390,8 +396,8 @@ sub mergestate () { #{{{
        # fields.
        foreach my $name (keys %myfeeds) {
                if (exists $feeds{$name}) {
-                       foreach my $field (qw{message lastupdate numposts
-                                             newposts error}) {
+                       foreach my $field (qw{message lastupdate lasttry
+                                             numposts newposts error}) {
                                $feeds{$name}->{$field}=$myfeeds{$name}->{$field};
                        }
                }
@@ -407,15 +413,15 @@ sub mergestate () { #{{{
                        $guids{$guid}=$myguids{$guid};
                }
        }
-} #}}}
+}
 
-sub clearstate () { #{{{
+sub clearstate () {
        %feeds=();
        %guids=();
        $state_loaded=0;
-} #}}}
+}
 
-sub expire () { #{{{
+sub expire () {
        foreach my $feed (values %feeds) {
                next unless $feed->{expireage} || $feed->{expirecount};
                my $count=0;
@@ -444,24 +450,24 @@ sub expire () { #{{{
                        }
                }
        }
-} #}}}
+}
 
-sub needsaggregate () { #{{{
+sub needsaggregate () {
        return values %feeds if $config{rebuild};
        return grep { time - $_->{lastupdate} >= $_->{updateinterval} } values %feeds;
-} #}}}
+}
 
-sub aggregate (@) { #{{{
+sub aggregate (@) {
        eval q{use XML::Feed};
        error($@) if $@;
        eval q{use URI::Fetch};
        error($@) if $@;
 
        foreach my $feed (@_) {
-               $feed->{lastupdate}=time;
+               $feed->{lasttry}=time;
                $feed->{newposts}=0;
-               $feed->{message}=sprintf(gettext("processed ok at %s"),
-                       displaytime($feed->{lastupdate}));
+               $feed->{message}=sprintf(gettext("last checked %s"),
+                       displaytime($feed->{lasttry}));
                $feed->{error}=0;
 
                debug(sprintf(gettext("checking feed %s ..."), $feed->{name}));
@@ -483,6 +489,10 @@ sub aggregate (@) { #{{{
                        debug($feed->{message});
                        next;
                }
+
+               # lastupdate is only set if we were able to contact the server
+               $feed->{lastupdate}=$feed->{lasttry};
+
                if ($res->status == URI::Fetch::URI_GONE()) {
                        $feed->{message}=gettext("feed not found");
                        $feed->{error}=1;
@@ -496,15 +506,19 @@ sub aggregate (@) { #{{{
                        # that contains invalid UTF-8 sequences. Convert
                        # feed to ascii to try to work around.
                        $feed->{message}.=" ".sprintf(gettext("(invalid UTF-8 stripped from feed)"));
-                       $content=Encode::decode_utf8($content, 0);
-                       $f=eval{XML::Feed->parse(\$content)};
+                       $f=eval {
+                               $content=Encode::decode_utf8($content, 0);
+                               XML::Feed->parse(\$content)
+                       };
                }
                if ($@) {
                        # Another possibility is badly escaped entities.
                        $feed->{message}.=" ".sprintf(gettext("(feed entities escaped)"));
                        $content=~s/\&(?!amp)(\w+);/&amp;$1;/g;
-                       $content=Encode::decode_utf8($content, 0);
-                       $f=eval{XML::Feed->parse(\$content)};
+                       $f=eval {
+                               $content=Encode::decode_utf8($content, 0);
+                               XML::Feed->parse(\$content)
+                       };
                }
                if ($@) {
                        $feed->{message}=gettext("feed crashed XML::Feed!")." ($@)";
@@ -520,10 +534,15 @@ sub aggregate (@) { #{{{
                }
 
                foreach my $entry ($f->entries) {
-                       my $content=$content=$entry->content->body;
+                       # XML::Feed doesn't work around XML::Atom's bizarre
+                       # API, so we will. Real unicode strings? Yes please.
+                       # See [[bugs/Aggregated_Atom_feeds_are_double-encoded]]
+                       local $XML::Atom::ForceUnicode = 1;
+
+                       my $c=$entry->content;
                        # atom feeds may have no content, only a summary
-                       if (! defined $content && ref $entry->summary) {
-                               $content=$entry->summary->body;
+                       if (! defined $c && ref $entry->summary) {
+                               $c=$entry->summary;
                        }
 
                        add_page(
@@ -531,15 +550,16 @@ sub aggregate (@) { #{{{
                                copyright => $f->copyright,
                                title => defined $entry->title ? decode_entities($entry->title) : "untitled",
                                link => $entry->link,
-                               content => defined $content ? $content : "",
+                               content => (defined $c && defined $c->body) ? $c->body : "",
                                guid => defined $entry->id ? $entry->id : time."_".$feed->{name},
                                ctime => $entry->issued ? ($entry->issued->epoch || time) : time,
+                               base => (defined $c && $c->can("base")) ? $c->base : undef,
                        );
                }
        }
-} #}}}
+}
 
-sub add_page (@) { #{{{
+sub add_page (@) {
        my %params=@_;
        
        my $feed=$params{feed};
@@ -605,7 +625,8 @@ sub add_page (@) { #{{{
        my $template=template($feed->{template}, blind_cache => 1);
        $template->param(title => $params{title})
                if defined $params{title} && length($params{title});
-       $template->param(content => htmlescape(htmlabs($params{content}, $feed->{feedurl})));
+       $template->param(content => wikiescape(htmlabs($params{content},
+               defined $params{base} ? $params{base} : $feed->{feedurl})));
        $template->param(name => $feed->{name});
        $template->param(url => $feed->{url});
        $template->param(copyright => $params{copyright})
@@ -625,23 +646,25 @@ sub add_page (@) { #{{{
                # Store it in pagectime for expiry code to use also.
                $IkiWiki::pagectime{$guid->{page}}=$mtime;
        }
-} #}}}
+       else {
+               # Dummy value for expiry code.
+               $IkiWiki::pagectime{$guid->{page}}=time;
+       }
+}
 
-sub htmlescape ($) { #{{{
+sub wikiescape ($) {
        # escape accidental wikilinks and preprocessor stuff
-       my $html=shift;
-       $html=~s/(?<!\\)\[\[/\\\[\[/g;
-       return $html;
-} #}}}
+       return encode_entities(shift, '\[\]');
+}
 
-sub urlabs ($$) { #{{{
+sub urlabs ($$) {
        my $url=shift;
        my $urlbase=shift;
 
        URI->new_abs($url, $urlbase)->as_string;
-} #}}}
+}
 
-sub htmlabs ($$) { #{{{
+sub htmlabs ($$) {
        # Convert links in html from relative to absolute.
        # Note that this is a heuristic, which is not specified by the rss
        # spec and may not be right for all feeds. Also, see Debian
@@ -677,15 +700,15 @@ sub htmlabs ($$) { #{{{
        $p->eof;
 
        return $ret;
-} #}}}
+}
 
-sub htmlfn ($) { #{{{
+sub htmlfn ($) {
        return shift().".".($config{aggregateinternal} ? "_aggregated" : $config{htmlext});
-} #}}}
+}
 
 my $aggregatelock;
 
-sub lockaggregate () { #{{{
+sub lockaggregate () {
        # Take an exclusive lock to prevent multiple concurrent aggregators.
        # Returns true if the lock was aquired.
        if (! -d $config{wikistatedir}) {
@@ -698,11 +721,11 @@ sub lockaggregate () { #{{{
                return 0;
        }
        return 1;
-} #}}}
+}
 
-sub unlockaggregate () { #{{{
+sub unlockaggregate () {
        return close($aggregatelock) if $aggregatelock;
        return;
-} #}}}
+}
 
 1
index 597539c13b0f2c218955dc81da2f26dfb7aa6fb4..10bf358e44a69148954fc36a0557330016fa4024 100644 (file)
@@ -4,7 +4,7 @@ package IkiWiki::Plugin::amazon_s3;
 use warnings;
 no warnings 'redefine';
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use IkiWiki::Render;
 use Net::Amazon::S3;
 
@@ -16,13 +16,13 @@ BEGIN {
        }
 };
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "amazon_s3", call => \&getopt);
        hook(type => "getsetup", id => "amazon_s3", call => \&getsetup);
        hook(type => "checkconfig", id => "amazon_s3", call => \&checkconfig);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
         eval q{use Getopt::Long};
         error($@) if $@;
         Getopt::Long::Configure('pass_through');
@@ -38,9 +38,9 @@ sub getopt () { #{{{
                debug(gettext("done"));
                exit(0);
        });
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0,
@@ -88,9 +88,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub checkconfig { #{{{
+sub checkconfig {
        foreach my $field (qw{amazon_s3_key_id amazon_s3_key_file
                              amazon_s3_bucket}) {
                if (! exists $config{$field} || ! defined $config{$field}) {
@@ -101,11 +101,11 @@ sub checkconfig { #{{{
            ! defined $config{amazon_s3_prefix}) {
            $config{amazon_s3_prefix}="wiki/";
        }
-} #}}}
+}
 
 {
 my $bucket;
-sub getbucket { #{{{
+sub getbucket {
        return $bucket if defined $bucket;
        
        open(IN, "<", $config{amazon_s3_key_file}) || error($config{amazon_s3_key_file}.": ".$!);
@@ -138,11 +138,11 @@ sub getbucket { #{{{
        }
 
        return $bucket;
-} #}}}
+}
 }
 
 # Given a file, return any S3 keys associated with it.
-sub file2keys ($) { #{{{
+sub file2keys ($) {
        my $file=shift;
 
        my @keys;
@@ -162,14 +162,14 @@ sub file2keys ($) { #{{{
                }
        }
        return @keys;
-} #}}}
+}
 
 package IkiWiki;
 use File::MimeInfo;
 use Encode;
 
 # This is a wrapper around the real writefile.
-sub writefile ($$$;$$) { #{{{
+sub writefile ($$$;$$) {
         my $file=shift;
         my $destdir=shift;
         my $content=shift;
@@ -225,10 +225,10 @@ sub writefile ($$$;$$) { #{{{
        }
 
        return $ret;
-} #}}}
+}
 
 # This is a wrapper around the real prune.
-sub prune ($) { #{{{
+sub prune ($) {
        my $file=shift;
 
        my @keys=IkiWiki::Plugin::amazon_s3::file2keys($file);
@@ -247,6 +247,6 @@ sub prune ($) { #{{{
        }
 
        return $IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::prune'}->($file);
-} #}}}
+}
 
 1
index 2be983693d7d2d67f5cbd39a93b19c0885f6cfa6..243b9892056028ea3cd289257c70274a54a410f6 100644 (file)
@@ -3,14 +3,14 @@ package IkiWiki::Plugin::anonok;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "anonok", call => \&getsetup);
        hook(type => "canedit", id => "anonok", call => \&canedit);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -24,9 +24,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub canedit ($$$) { #{{{
+sub canedit ($$$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
@@ -45,6 +45,6 @@ sub canedit ($$$) { #{{{
        else {
                return "";
        }
-} #}}}
+}
 
 1
index dcac3e82006bf9679732727d4ed683b5b31bf8a9..087c315a9af355569921c9150c05c0ba89ec8df1 100644 (file)
@@ -3,17 +3,18 @@ package IkiWiki::Plugin::attachment;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
+       add_underlay("javascript");
        hook(type => "getsetup", id => "attachment", call => \&getsetup);
        hook(type => "checkconfig", id => "attachment", call => \&checkconfig);
        hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "attachment", call => \&formbuilder);
        IkiWiki::loadplugin("filecheck");
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -34,9 +35,9 @@ sub getsetup () { #{{{
                        safe => 0, # executed
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub check_canattach ($$;$) { #{{{
+sub check_canattach ($$;$) {
        my $session=shift;
        my $dest=shift; # where it's going to be put, under the srcdir
        my $file=shift; # the path to the attachment currently
@@ -60,36 +61,19 @@ sub check_canattach ($$;$) { #{{{
                );
        }
 
-       # XXX deprecated, should be removed eventually
-       if ($allowed) {
-               foreach my $admin (@{$config{adminuser}}) {
-                       my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments");
-                       if (defined $allowed_attachments &&
-                           length $allowed_attachments) {
-                               $allowed=pagespec_match($dest,
-                                       $allowed_attachments,
-                                       file => $file,
-                                       user => $session->param("name"),
-                                       ip => $ENV{REMOTE_ADDR},
-                               );
-                               last if $allowed;
-                       }
-               }
-       }
-
        if (! $allowed) {
                error(gettext("prohibited by allowed_attachments")." ($allowed)");
        }
        else {
                return 1;
        }
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        $config{cgi_disable_uploads}=0;
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
        my $form=$params{form};
        my $q=$params{cgi};
@@ -104,10 +88,10 @@ sub formbuilder_setup (@) { #{{{
                $form->tmpl_param("field-upload" => '<input name="_submit" type="submit" value="Upload Attachment" />');
                $form->tmpl_param("field-link" => '<input name="_submit" type="submit" value="Insert Links" />');
 
-               # Add the javascript from the toggle plugin;
-               # the attachments interface uses it to toggle visibility.
+               # Add the toggle javascript; the attachments interface uses
+               # it to toggle visibility.
                require IkiWiki::Plugin::toggle;
-               $form->tmpl_param("javascript" => $IkiWiki::Plugin::toggle::javascript);
+               $form->tmpl_param("javascript" => IkiWiki::Plugin::toggle::include_javascript($params{page}, 1));
                # Start with the attachments interface toggled invisible,
                # but if it was used, keep it open.
                if ($form->submitted ne "Upload Attachment" &&
@@ -119,42 +103,9 @@ sub formbuilder_setup (@) { #{{{
                        $form->tmpl_param("attachments-class" => "toggleable-open");
                }
        }
-       elsif ($form->title eq "preferences") {
-               # XXX deprecated, should remove eventually
-               my $session=$params{session};
-               my $user_name=$session->param("name");
-
-               $form->field(name => "allowed_attachments", size => 50,
-                       fieldset => "admin",
-                       comment => "deprecated; please move to allowed_attachments in setup file",
-               );
-               if (! IkiWiki::is_admin($user_name)) {
-                       $form->field(name => "allowed_attachments", type => "hidden");
-               }
-                if (! $form->submitted) {
-                       my $value=IkiWiki::userinfo_get($user_name, "allowed_attachments");
-                       if (length $value) {
-                               $form->field(name => "allowed_attachments", force => 1,
-                                       value => IkiWiki::userinfo_get($user_name, "allowed_attachments"));
-                       }
-                       else {
-                               $form->field(name => "allowed_attachments", type => "hidden");
-                       }
-                }
-               if ($form->submitted && $form->submitted eq 'Save Preferences') {
-                       if (defined $form->field("allowed_attachments")) {
-                               IkiWiki::userinfo_set($user_name, "allowed_attachments",
-                               $form->field("allowed_attachments")) ||
-                                       error("failed to set allowed_attachments");
-                               if (! length $form->field("allowed_attachments")) {
-                                       $form->field(name => "allowed_attachments", type => "hidden");
-                               }
-                       }
-               }
-       }
-} #}}}
+}
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
        my $form=$params{form};
        my $q=$params{cgi};
@@ -252,9 +203,9 @@ sub formbuilder (@) { #{{{
        # Generate the attachment list only after having added any new
        # attachments.
        $form->tmpl_param("attachment_list" => [attachment_list($form->field('page'))]);
-} # }}}
+}
 
-sub attachment_location ($) { #{{{
+sub attachment_location ($) {
        my $page=shift;
        
        # Put the attachment in a subdir of the page it's attached
@@ -263,9 +214,9 @@ sub attachment_location ($) { #{{{
        $page.="/" if length $page;
        
        return $page;
-} #}}}
+}
 
-sub attachment_list ($) { #{{{
+sub attachment_list ($) {
        my $page=shift;
        my $loc=attachment_location($page);
 
@@ -279,7 +230,6 @@ sub attachment_list ($) { #{{{
                                link => htmllink($page, $page, $f, noimageinline => 1),
                                size => IkiWiki::Plugin::filecheck::humansize((stat(_))[7]),
                                mtime => displaytime($IkiWiki::pagemtime{$f}),
-                               mtime_raw => $IkiWiki::pagemtime{$f},
                        };
                }
        }
@@ -287,6 +237,6 @@ sub attachment_list ($) { #{{{
        # Sort newer attachments to the top of the list, so a newly-added
        # attachment appears just before the form used to add it.
        return sort { $b->{mtime_raw} <=> $a->{mtime_raw} || $a->{link} cmp $b->{link} } @ret;
-} #}}}
+}
 
 1
index d1b3edb1f3cb6394d6bda558aed507fee627b4c3..555856b1189fe4508ac25997cad15669fb28ceea 100644 (file)
@@ -3,23 +3,23 @@ package IkiWiki::Plugin::autoindex;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "autoindex", call => \&getsetup);
        hook(type => "refresh", id => "autoindex", call => \&refresh);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub genindex ($) { #{{{
+sub genindex ($) {
        my $page=shift;
        my $file=newpagefile($page, $config{default_pageext});
        my $template=template("autoindex.tmpl");
@@ -28,9 +28,9 @@ sub genindex ($) { #{{{
        if ($config{rcs}) {
                IkiWiki::rcs_add($file);
        }
-} #}}}
+}
 
-sub refresh () { #{{{
+sub refresh () {
        eval q{use File::Find};
        error($@) if $@;
 
@@ -107,6 +107,6 @@ sub refresh () { #{{{
                        IkiWiki::enable_commit_hook();
                }
        }
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/blogspam.pm b/IkiWiki/Plugin/blogspam.pm
new file mode 100644 (file)
index 0000000..cbd9859
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::blogspam;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+my $defaulturl='http://test.blogspam.net:8888/';
+
+sub import {
+       hook(type => "getsetup", id => "blogspam",  call => \&getsetup);
+       hook(type => "checkcontent", id => "blogspam", call => \&checkcontent);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 0,
+               },
+               blogspam_pagespec => {
+                       type => 'pagespec',
+                       example => 'postcomment(*)',
+                       description => 'PageSpec of pages to check for spam',
+                       link => 'ikiwiki/PageSpec',
+                       safe => 1,
+                       rebuild => 0,
+               },
+               blogspam_options => {
+                       type => "string",
+                       example => "blacklist=1.2.3.4,blacklist=8.7.6.5,max-links=10",
+                       description => "options to send to blogspam server",
+                       link => "http://blogspam.net/api/testComment.html#options",
+                       safe => 1,
+                       rebuild => 0,
+               },
+               blogspam_server => {
+                       type => "string",
+                       default => $defaulturl,
+                       description => "blogspam server XML-RPC url",
+                       safe => 1,
+                       rebuild => 0,
+               },
+}
+
+sub checkcontent (@) {
+       my %params=@_;
+
+       eval q{
+               use RPC::XML;
+               use RPC::XML::Client;
+       };
+       if ($@) {
+               warn($@);
+               return undef;
+       }
+       
+       if (exists $config{blogspam_pagespec}) {
+               return undef
+                       if ! pagespec_match($params{page}, $config{blogspam_pagespec},
+                               location => $params{page});
+       }
+
+       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})
+               if exists $config{blogspam_options};
+
+       # Allow short comments and whitespace-only edits, unless the user
+       # has overridden min-words themselves.
+       push @options, "min-words=0"
+               unless grep /^min-words=/i, @options;
+       # Wiki pages can have a lot of urls, unless the user specifically
+       # wants to limit them.
+       push @options, "exclude=lotsaurls"
+               unless grep /^max-links/i, @options;
+       # Unless the user specified a size check, disable such checking.
+       push @options, "exclude=size"
+               unless grep /^(?:max|min)-size/i, @options;
+       # This test has absurd false positives on words like "alpha"
+       # and "buy".
+       push @options, "exclude=stopwords";
+
+       my %req=(
+               ip => $ENV{REMOTE_ADDR},
+               comment => $params{content},
+               subject => defined $params{subject} ? $params{subject} : "",
+               name => defined $params{author} ? $params{author} : "",
+               link => exists $params{url} ? $params{url} : "",
+               options => join(",", @options),
+               site => $config{url},
+               version => "ikiwiki ".$IkiWiki::version,
+       );
+       my $res = $client->send_request('testComment', \%req);
+
+       if (! ref $res || ! defined $res->value) {
+               debug("failed to get response from blogspam server ($url)");
+               return undef;
+       }
+       elsif ($res->value =~ /^SPAM:(.*)/) {
+               eval q{use Data::Dumper};
+               debug("blogspam server reports ".$res->value.": ".Dumper(\%req));
+               return gettext("Sorry, but that looks like spam to <a href=\"http://blogspam.net/\">blogspam</a>: ").$1;
+       }
+       elsif ($res->value ne 'OK') {
+               debug("blogspam server failure: ".$res->value);
+               return undef;
+       }
+       else {
+               return undef;
+       }
+}
+
+1
index 37752dd3ef9e9b4113bfcaa1a9b49bb0a4e06bab..bf0d7560dbc8a86a28b1ad694d9de326d0153f1f 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::brokenlinks;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "brokenlinks", call => \&getsetup);
        hook(type => "preprocess", id => "brokenlinks", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
@@ -61,6 +61,6 @@ sub preprocess (@) { #{{{
                        }
                        sort @broken)
                ."</ul>\n";
-} # }}}
+}
 
 1
index 101e91b930836126f9ef4a00b6a722af42cf5c50..8830073672663b77d2e21fb837a15a913b7b6c0d 100644 (file)
@@ -7,7 +7,7 @@ use IkiWiki;
 use Encode;
 use open qw{:utf8 :std};
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "bzr", call => \&checkconfig);
        hook(type => "getsetup", id => "bzr", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -20,18 +20,18 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (defined $config{bzr_wrapper} && length $config{bzr_wrapper}) {
                push @{$config{wrappers}}, {
                        wrapper => $config{bzr_wrapper},
                        wrappermode => (defined $config{bzr_wrappermode} ? $config{bzr_wrappermode} : "06755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -65,9 +65,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub bzr_log ($) { #{{{
+sub bzr_log ($) {
        my $out = shift;
        my @infos = ();
        my $key = undef;
@@ -99,20 +99,20 @@ sub bzr_log ($) { #{{{
        close $out;
 
        return @infos;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        my @cmdline = ("bzr", "update", "--quiet", $config{srcdir});
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        return "";
-} #}}}
+}
 
-sub bzr_author ($$) { #{{{
+sub bzr_author ($$) {
        my ($user, $ipaddr) = @_;
 
        if (defined $user) {
@@ -124,9 +124,9 @@ sub bzr_author ($$) { #{{{
        else {
                return "Anonymous";
        }
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
 
        $user = bzr_author($user, $ipaddr);
@@ -143,7 +143,7 @@ sub rcs_commit ($$$;$$) { #{{{
        }
 
        return undef; # success
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -164,27 +164,27 @@ sub rcs_commit_staged ($$$) {
        }
 
        return undef; # success
-} #}}}
+}
 
-sub rcs_add ($) { # {{{
+sub rcs_add ($) {
        my ($file) = @_;
 
        my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_remove ($) { # {{{
+sub rcs_remove ($) {
        my ($file) = @_;
 
        my @cmdline = ("bzr", "rm", "--force", "--quiet", "$config{srcdir}/$file");
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_rename ($$) { # {{{
+sub rcs_rename ($$) {
        my ($src, $dest) = @_;
 
        my $parent = IkiWiki::dirname($dest);
@@ -196,9 +196,9 @@ sub rcs_rename ($$) { # {{{
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        my ($num) = @_;
 
        my @cmdline = ("bzr", "log", "-v", "--show-ids", "--limit", $num, 
@@ -246,16 +246,36 @@ sub rcs_recentchanges ($) { #{{{
                        rev        => $info->{"revno"},
                        user       => $user,
                        committype => "bzr",
-                       when       => time - str2time($info->{"timestamp"}),
+                       when       => str2time($info->{"timestamp"}),
                        message    => [@message],
                        pages      => [@pages],
                };
        }
 
        return @ret;
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_diff ($) {
+       my $taintedrev=shift;
+       my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint
+
+       my $prevspec = "before:" . $rev;
+       my $revspec = "revno:" . $rev;
+       my @cmdline = ("bzr", "diff", "--old", $config{srcdir},
+               "--new", $config{srcdir},
+               "-r", $prevspec . ".." . $revspec);
+       open (my $out, "@cmdline |");
+
+       my @lines = <$out>;
+       if (wantarray) {
+               return @lines;
+       }
+       else {
+               return join("", @lines);
+       }
+}
+
+sub rcs_getctime ($) {
        my ($file) = @_;
 
        # XXX filename passes through the shell here, should try to avoid
@@ -274,6 +294,6 @@ sub rcs_getctime ($) { #{{{
        
        my $ctime = str2time($log[0]->{"timestamp"});
        return $ctime;
-} #}}}
+}
 
 1
index 6d536a91bb63a6e0a32f399844115e52208d5bdf..d473c8348234145b5dc7526584b9b7825b027e4a 100644 (file)
@@ -20,7 +20,7 @@ package IkiWiki::Plugin::calendar;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Time::Local;
 use POSIX;
 
@@ -29,13 +29,13 @@ my %linkcache;
 my $time=time;
 my @now=localtime($time);
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "calendar", call => \&getsetup);
        hook(type => "needsbuild", id => "calendar", call => \&needsbuild);
        hook(type => "preprocess", id => "calendar", call => \&preprocess);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -48,23 +48,23 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub is_leap_year (@) { #{{{
+sub is_leap_year (@) {
        my %params=@_;
        return ($params{year} % 4 == 0 && (($params{year} % 100 != 0) || $params{year} % 400 == 0));
-} #}}}
+}
 
-sub month_days { #{{{
+sub month_days {
        my %params=@_;
        my $days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)[$params{month}-1];
        if ($params{month} == 2 && is_leap_year(%params)) {
                $days_in_month++;
        }
        return $days_in_month;
-} #}}}
+}
 
-sub format_month (@) { #{{{
+sub format_month (@) {
        my %params=@_;
 
        my $pagespec = $params{pages};
@@ -215,9 +215,9 @@ EOF
         add_depends($params{page}, join(" or ", @list));
 
        return $calendar;
-} #}}}
+}
 
-sub format_year (@) { #{{{
+sub format_year (@) {
        my %params=@_;
 
        my $pagespec = $params{pages};
@@ -318,9 +318,9 @@ EOF
 EOF
 
        return $calendar;
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages} = "*"            unless defined $params{pages};
        $params{type}  = "month"        unless defined $params{type};
@@ -397,7 +397,7 @@ sub preprocess (@) { #{{{
        return "\n<div><div class=\"calendar\">$calendar</div></div>\n";
 } #}}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{calendar}{nextchange}) {
@@ -415,6 +415,6 @@ sub needsbuild (@) { #{{{
                        }
                }
        }
-} # }}}
+}
 
 1
index 7881becd5a1174f3539a93385d415a906574ada7..74a8397d7ebe33096393d4174f2975a4ce7bd03d 100644 (file)
@@ -4,7 +4,7 @@ package IkiWiki::Plugin::camelcase;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 # This regexp is based on the one in Text::WikiFormat.
 my $link_regexp=qr{
@@ -22,40 +22,52 @@ my $link_regexp=qr{
        )
 }x;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "camelcase", call => \&getsetup);
        hook(type => "linkify", id => "camelcase", call => \&linkify);
        hook(type => "scan", id => "camelcase", call => \&scan);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
-               };
-} #}}}
+               },
+               camelcase_ignore => {
+                       type => "string",
+                       example => [],
+                       description => "list of words to not turn into links",
+                       safe => 1,
+                       rebuild => undef, # might change links
+               },
+}
 
-sub linkify (@) { #{{{
+sub linkify (@) {
        my %params=@_;
        my $page=$params{page};
        my $destpage=$params{destpage};
 
        $params{content}=~s{$link_regexp}{
-               htmllink($page, $destpage, linkpage($1))
+               ignored($1) ? $1 : htmllink($page, $destpage, linkpage($1))
        }eg;
 
        return $params{content};
-} #}}}
+}
 
-sub scan (@) { #{{{
+sub scan (@) {
         my %params=@_;
         my $page=$params{page};
         my $content=$params{content};
 
        while ($content =~ /$link_regexp/g) {
-               push @{$links{$page}}, linkpage($1);
+               push @{$links{$page}}, linkpage($1) unless ignored($1)
        }
 }
 
+sub ignored ($) {
+       my $word=lc shift;
+       grep { $word eq lc $_ } @{$config{'camelcase_ignore'}}
+}
+
 1
index ac702ff026052e34b780ec380cf3cc048b7443bc..20505893b5885847370a99c84c900d6032d72ef9 100644 (file)
@@ -5,14 +5,14 @@ package IkiWiki::Plugin::color;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "preprocess", id => "color", call => \&preprocess);
        hook(type => "format",     id => "color", call => \&format);
-} #}}}
+}
 
-sub preserve_style ($$$) { #{{{
+sub preserve_style ($$$) {
        my $foreground = shift;
        my $background = shift;
        my $text       = shift;
@@ -37,18 +37,18 @@ sub preserve_style ($$$) { #{{{
        
        return $preserved;
 
-} #}}}
+}
 
-sub replace_preserved_style ($) { #{{{
+sub replace_preserved_style ($) {
        my $content = shift;
 
        $content =~ s!<span class="color">((color: ([a-z]+|\#[0-9a-f]{3,6})?)?((; )?(background-color: ([a-z]+|\#[0-9a-f]{3,6})?)?)?)</span>!<span class="color" style="$1">!g;
        $content =~ s!<span class="colorend">!!g;
 
        return $content;
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params = @_;
 
        # Preprocess the text to expand any preprocessor directives
@@ -57,13 +57,13 @@ sub preprocess (@) { #{{{
                                IkiWiki::filter($params{page}, $params{destpage}, $params{text}));
 
        return preserve_style($params{foreground}, $params{background}, $params{text});
-} #}}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
        my %params = @_;
 
        $params{content} = replace_preserved_style($params{content});
        return $params{content};        
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
new file mode 100644 (file)
index 0000000..98f9f8b
--- /dev/null
@@ -0,0 +1,840 @@
+#!/usr/bin/perl
+# Copyright © 2006-2008 Joey Hess <joey@ikiwiki.info>
+# Copyright © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+package IkiWiki::Plugin::comments;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use Encode;
+use POSIX qw(strftime);
+
+use constant PREVIEW => "Preview";
+use constant POST_COMMENT => "Post comment";
+use constant CANCEL => "Cancel";
+
+my $postcomment;
+my %commentstate;
+
+sub import {
+       hook(type => "checkconfig", id => 'comments',  call => \&checkconfig);
+       hook(type => "getsetup", id => 'comments',  call => \&getsetup);
+       hook(type => "preprocess", id => '_comment', call => \&preprocess);
+       hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi);
+       hook(type => "htmlize", id => "_comment", call => \&htmlize);
+       hook(type => "pagetemplate", id => "comments", call => \&pagetemplate);
+       hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup);
+       # Load goto to fix up user page links for logged-in commenters
+       IkiWiki::loadplugin("goto");
+       IkiWiki::loadplugin("inline");
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 1,
+               },
+               comments_pagespec => {
+                       type => 'pagespec',
+                       example => 'blog/* and !*/Discussion',
+                       description => 'PageSpec of pages where comments are allowed',
+                       link => 'ikiwiki/PageSpec',
+                       safe => 1,
+                       rebuild => 1,
+               },
+               comments_closed_pagespec => {
+                       type => 'pagespec',
+                       example => 'blog/controversial or blog/flamewar',
+                       description => 'PageSpec of pages where posting new comments is not allowed',
+                       link => 'ikiwiki/PageSpec',
+                       safe => 1,
+                       rebuild => 1,
+               },
+               comments_pagename => {
+                       type => 'string',
+                       default => 'comment_',
+                       description => 'Base name for comments, e.g. "comment_" for pages like "sandbox/comment_12"',
+                       safe => 0, # manual page moving required
+                       rebuild => undef,
+               },
+               comments_allowdirectives => {
+                       type => 'boolean',
+                       example => 0,
+                       description => 'Interpret directives in comments?',
+                       safe => 1,
+                       rebuild => 0,
+               },
+               comments_allowauthor => {
+                       type => 'boolean',
+                       example => 0,
+                       description => 'Allow anonymous commenters to set an author name?',
+                       safe => 1,
+                       rebuild => 0,
+               },
+               comments_commit => {
+                       type => 'boolean',
+                       example => 1,
+                       description => 'commit comments to the VCS',
+                       # old uncommitted comments are likely to cause
+                       # confusion if this is changed
+                       safe => 0,
+                       rebuild => 0,
+               },
+}
+
+sub checkconfig () {
+       $config{comments_commit} = 1
+               unless defined $config{comments_commit};
+       $config{comments_pagespec} = ''
+               unless defined $config{comments_pagespec};
+       $config{comments_closed_pagespec} = ''
+               unless defined $config{comments_closed_pagespec};
+       $config{comments_pagename} = 'comment_'
+               unless defined $config{comments_pagename};
+}
+
+sub htmlize {
+       my %params = @_;
+       return $params{content};
+}
+
+# FIXME: copied verbatim from meta
+sub safeurl ($) {
+       my $url=shift;
+       if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} &&
+           defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) {
+               return $url=~/$IkiWiki::Plugin::htmlscrubber::safe_url_regexp/;
+       }
+       else {
+               return 1;
+       }
+}
+
+sub preprocess {
+       my %params = @_;
+       my $page = $params{page};
+
+       my $format = $params{format};
+       if (defined $format && ! exists $IkiWiki::hooks{htmlize}{$format}) {
+               error(sprintf(gettext("unsupported page format %s"), $format));
+       }
+
+       my $content = $params{content};
+       if (! defined $content) {
+               error(gettext("comment must have content"));
+       }
+       $content =~ s/\\"/"/g;
+
+       $content = IkiWiki::filter($page, $params{destpage}, $content);
+
+       if ($config{comments_allowdirectives}) {
+               $content = IkiWiki::preprocess($page, $params{destpage},
+                       $content);
+       }
+
+       # no need to bother with htmlize if it's just HTML
+       $content = IkiWiki::htmlize($page, $params{destpage}, $format, $content)
+               if defined $format;
+
+       IkiWiki::run_hooks(sanitize => sub {
+               $content = shift->(
+                       page => $page,
+                       destpage => $params{destpage},
+                       content => $content,
+               );
+       });
+
+       # set metadata, possibly overriding [[!meta]] directives from the
+       # comment itself
+
+       my $commentuser;
+       my $commentip;
+       my $commentauthor;
+       my $commentauthorurl;
+       my $commentopenid;
+       if (defined $params{username}) {
+               $commentuser = $params{username};
+
+               my $oiduser = eval { IkiWiki::openiduser($commentuser) };
+
+               if (defined $oiduser) {
+                       # looks like an OpenID
+                       $commentauthorurl = $commentuser;
+                       $commentauthor = $oiduser;
+                       $commentopenid = $commentuser;
+               }
+               else {
+                       $commentauthorurl = IkiWiki::cgiurl(
+                               do => 'goto',
+                               page => (length $config{userdir}
+                                       ? "$config{userdir}/$commentuser"
+                                       : "$commentuser"));
+
+                       $commentauthor = $commentuser;
+               }
+       }
+       else {
+               if (defined $params{ip}) {
+                       $commentip = $params{ip};
+               }
+               $commentauthor = gettext("Anonymous");
+       }
+
+       $commentstate{$page}{commentuser} = $commentuser;
+       $commentstate{$page}{commentopenid} = $commentopenid;
+       $commentstate{$page}{commentip} = $commentip;
+       $commentstate{$page}{commentauthor} = $commentauthor;
+       $commentstate{$page}{commentauthorurl} = $commentauthorurl;
+       if (! defined $pagestate{$page}{meta}{author}) {
+               $pagestate{$page}{meta}{author} = $commentauthor;
+       }
+       if (! defined $pagestate{$page}{meta}{authorurl}) {
+               $pagestate{$page}{meta}{authorurl} = $commentauthorurl;
+       }
+
+       if ($config{comments_allowauthor}) {
+               if (defined $params{claimedauthor}) {
+                       $pagestate{$page}{meta}{author} = $params{claimedauthor};
+               }
+
+               if (defined $params{url}) {
+                       my $url=$params{url};
+
+                       eval q{use URI::Heuristic}; 
+                       if (! $@) {
+                               $url=URI::Heuristic::uf_uristr($url);
+                       }
+
+                       if (safeurl($url)) {
+                               $pagestate{$page}{meta}{authorurl} = $url;
+                       }
+               }
+       }
+       else {
+               $pagestate{$page}{meta}{author} = $commentauthor;
+               $pagestate{$page}{meta}{authorurl} = $commentauthorurl;
+       }
+
+       if (defined $params{subject}) {
+               $pagestate{$page}{meta}{title} = $params{subject};
+       }
+
+       if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) {
+               $pagestate{$page}{meta}{permalink} = urlto(IkiWiki::dirname($params{page}), undef, 1).
+                       "#".page_to_id($params{page});
+       }
+
+       eval q{use Date::Parse};
+       if (! $@) {
+               my $time = str2time($params{date});
+               $IkiWiki::pagectime{$page} = $time if defined $time;
+       }
+
+       return $content;
+}
+
+sub sessioncgi ($$) {
+       my $cgi=shift;
+       my $session=shift;
+
+       my $do = $cgi->param('do');
+       if ($do eq 'comment') {
+               editcomment($cgi, $session);
+       }
+       elsif ($do eq 'commentmoderation') {
+               commentmoderation($cgi, $session);
+       }
+}
+
+# Mostly cargo-culted from IkiWiki::plugin::editpage
+sub editcomment ($$) {
+       my $cgi=shift;
+       my $session=shift;
+
+       IkiWiki::decode_cgi_utf8($cgi);
+
+       eval q{use CGI::FormBuilder};
+       error($@) if $@;
+
+       my @buttons = (POST_COMMENT, PREVIEW, CANCEL);
+       my $form = CGI::FormBuilder->new(
+               fields => [qw{do sid page subject editcontent type author url}],
+               charset => 'utf-8',
+               method => 'POST',
+               required => [qw{editcontent}],
+               javascript => 0,
+               params => $cgi,
+               action => $config{cgiurl},
+               header => 0,
+               table => 0,
+               template => scalar IkiWiki::template_params('editcomment.tmpl'),
+       );
+
+       IkiWiki::decode_form_utf8($form);
+       IkiWiki::run_hooks(formbuilder_setup => sub {
+                       shift->(title => "comment", form => $form, cgi => $cgi,
+                               session => $session, buttons => \@buttons);
+               });
+       IkiWiki::decode_form_utf8($form);
+
+       my $type = $form->param('type');
+       if (defined $type && length $type && $IkiWiki::hooks{htmlize}{$type}) {
+               $type = IkiWiki::possibly_foolish_untaint($type);
+       }
+       else {
+               $type = $config{default_pageext};
+       }
+       my @page_types;
+       if (exists $IkiWiki::hooks{htmlize}) {
+               @page_types = grep { ! /^_/ } keys %{$IkiWiki::hooks{htmlize}};
+       }
+
+       $form->field(name => 'do', type => 'hidden');
+       $form->field(name => 'sid', type => 'hidden', value => $session->id,
+               force => 1);
+       $form->field(name => 'page', type => 'hidden');
+       $form->field(name => 'subject', type => 'text', size => 72);
+       $form->field(name => 'editcontent', type => 'textarea', rows => 10);
+       $form->field(name => "type", value => $type, force => 1,
+               type => 'select', options => \@page_types);
+
+       $form->tmpl_param(username => $session->param('name'));
+
+       if ($config{comments_allowauthor} and
+           ! defined $session->param('name')) {
+               $form->tmpl_param(allowauthor => 1);
+               $form->field(name => 'author', type => 'text', size => '40');
+               $form->field(name => 'url', type => 'text', size => '40');
+       }
+       else {
+               $form->tmpl_param(allowauthor => 0);
+               $form->field(name => 'author', type => 'hidden', value => '',
+                       force => 1);
+               $form->field(name => 'url', type => 'hidden', value => '',
+                       force => 1);
+       }
+
+       # The untaint is OK (as in editpage) because we're about to pass
+       # it to file_pruned anyway
+       my $page = $form->field('page');
+       $page = IkiWiki::possibly_foolish_untaint($page);
+       if (! defined $page || ! length $page ||
+               IkiWiki::file_pruned($page, $config{srcdir})) {
+               error(gettext("bad page name"));
+       }
+
+       my $baseurl = urlto($page, undef, 1);
+
+       $form->title(sprintf(gettext("commenting on %s"),
+                       IkiWiki::pagetitle($page)));
+
+       $form->tmpl_param('helponformattinglink',
+               htmllink($page, $page, 'ikiwiki/formatting',
+                       noimageinline => 1,
+                       linktext => 'FormattingHelp'),
+                       allowdirectives => $config{allow_directives});
+
+       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));
+               exit;
+       }
+
+       if (not exists $pagesources{$page}) {
+               error(sprintf(gettext(
+                       "page '%s' doesn't exist, so you can't comment"),
+                       $page));
+       }
+
+       if (pagespec_match($page, $config{comments_closed_pagespec},
+               location => $page)) {
+               error(sprintf(gettext(
+                       "comments on page '%s' are closed"),
+                       $page));
+       }
+
+       # Set a flag to indicate that we're posting a comment,
+       # so that postcomment() can tell it should match.
+       $postcomment=1;
+       IkiWiki::check_canedit($page, $cgi, $session);
+       $postcomment=0;
+
+       my $location=unique_comment_location($page, $config{srcdir});
+
+       my $content = "[[!_comment format=$type\n";
+
+       # FIXME: handling of double quotes probably wrong?
+       if (defined $session->param('name')) {
+               my $username = $session->param('name');
+               $username =~ s/"/&quot;/g;
+               $content .= " username=\"$username\"\n";
+       }
+       elsif (defined $ENV{REMOTE_ADDR}) {
+               my $ip = $ENV{REMOTE_ADDR};
+               if ($ip =~ m/^([.0-9]+)$/) {
+                       $content .= " ip=\"$1\"\n";
+               }
+       }
+
+       if ($config{comments_allowauthor}) {
+               my $author = $form->field('author');
+               if (defined $author && length $author) {
+                       $author =~ s/"/&quot;/g;
+                       $content .= " claimedauthor=\"$author\"\n";
+               }
+               my $url = $form->field('url');
+               if (defined $url && length $url) {
+                       $url =~ s/"/&quot;/g;
+                       $content .= " url=\"$url\"\n";
+               }
+       }
+
+       my $subject = $form->field('subject');
+       if (defined $subject && length $subject) {
+               $subject =~ s/"/&quot;/g;
+               $content .= " subject=\"$subject\"\n";
+       }
+
+       $content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
+
+       my $editcontent = $form->field('editcontent') || '';
+       $editcontent =~ s/\r\n/\n/g;
+       $editcontent =~ s/\r/\n/g;
+       $editcontent =~ s/"/\\"/g;
+       $content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n";
+
+       # This is essentially a simplified version of editpage:
+       # - the user does not control the page that's created, only the parent
+       # - it's always a create operation, never an edit
+       # - this means that conflicts should never happen
+       # - this means that if they do, rocks fall and everyone dies
+
+       if ($form->submitted eq PREVIEW) {
+               my $preview=previewcomment($content, $location, $page, time);
+               IkiWiki::run_hooks(format => sub {
+                       $preview = shift->(page => $page,
+                               content => $preview);
+               });
+               $form->tmpl_param(page_preview => $preview);
+       }
+       else {
+               $form->tmpl_param(page_preview => "");
+       }
+
+       if ($form->submitted eq POST_COMMENT && $form->validate) {
+               IkiWiki::checksessionexpiry($cgi, $session);
+               
+               $postcomment=1;
+               my $ok=IkiWiki::check_content(content => $form->field('editcontent'),
+                       subject => $form->field('subject'),
+                       $config{comments_allowauthor} ? (
+                               author => $form->field('author'),
+                               url => $form->field('url'),
+                       ) : (),
+                       page => $location,
+                       cgi => $cgi,
+                       session => $session,
+                       nonfatal => 1,
+               );
+               $postcomment=0;
+
+               if (! $ok) {
+                       my $penddir=$config{wikistatedir}."/comments_pending";
+                       $location=unique_comment_location($page, $penddir);
+                       writefile("$location._comment", $penddir, $content);
+                       IkiWiki::printheader($session);
+                       print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
+                               "<p>".
+                               gettext("Your comment will be posted after moderator review").
+                               "</p>");
+                       exit;
+               }
+
+               # FIXME: could probably do some sort of graceful retry
+               # on error? Would require significant unwinding though
+               my $file = "$location._comment";
+               writefile($file, $config{srcdir}, $content);
+
+               my $conflict;
+
+               if ($config{rcs} and $config{comments_commit}) {
+                       my $message = gettext("Added a comment");
+                       if (defined $form->field('subject') &&
+                               length $form->field('subject')) {
+                               $message = sprintf(
+                                       gettext("Added a comment: %s"),
+                                       $form->field('subject'));
+                       }
+
+                       IkiWiki::rcs_add($file);
+                       IkiWiki::disable_commit_hook();
+                       $conflict = IkiWiki::rcs_commit_staged($message,
+                               $session->param('name'), $ENV{REMOTE_ADDR});
+                       IkiWiki::enable_commit_hook();
+                       IkiWiki::rcs_update();
+               }
+
+               # Now we need a refresh
+               require IkiWiki::Render;
+               IkiWiki::refresh();
+               IkiWiki::saveindex();
+
+               # this should never happen, unless a committer deliberately
+               # breaks it or something
+               error($conflict) if defined $conflict;
+
+               # 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).
+                       "?updated#".page_to_id($location));
+
+       }
+       else {
+               IkiWiki::showform ($form, \@buttons, $session, $cgi,
+                       forcebaseurl => $baseurl);
+       }
+
+       exit;
+}
+
+sub commentmoderation ($$) {
+       my $cgi=shift;
+       my $session=shift;
+
+       IkiWiki::needsignin($cgi, $session);
+       if (! IkiWiki::is_admin($session->param("name"))) {
+               error(gettext("you are not logged in as an admin"));
+       }
+
+       IkiWiki::decode_cgi_utf8($cgi);
+       
+       if (defined $cgi->param('sid')) {
+               IkiWiki::checksessionexpiry($cgi, $session);
+
+               my $rejectalldefer=$cgi->param('rejectalldefer');
+
+               my %vars=$cgi->Vars;
+               my $added=0;
+               foreach my $id (keys %vars) {
+                       if ($id =~ /(.*)\Q._comment\E$/) {
+                               my $action=$cgi->param($id);
+                               next if $action eq 'Defer' && ! $rejectalldefer;
+
+                               # Make sure that the id is of a legal
+                               # pending comment before untainting.
+                               my ($f)= $id =~ /$config{wiki_file_regexp}/;
+                               if (! defined $f || ! length $f ||
+                                   IkiWiki::file_pruned($f, $config{srcdir})) {
+                                       error("illegal file");
+                               }
+
+                               my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1));
+                               my $file="$config{wikistatedir}/comments_pending/".
+                                       IkiWiki::possibly_foolish_untaint($id);
+
+                               if ($action eq 'Accept') {
+                                       my $content=eval { readfile($file) };
+                                       next if $@; # file vanished since form was displayed
+                                       my $dest=unique_comment_location($page, $config{srcdir})."._comment";
+                                       writefile($dest, $config{srcdir}, $content);
+                                       if ($config{rcs} and $config{comments_commit}) {
+                                               IkiWiki::rcs_add($dest);
+                                       }
+                                       $added++;
+                               }
+
+                               # This removes empty subdirs, so the
+                               # .ikiwiki/comments_pending dir will
+                               # go away when all are moderated.
+                               require IkiWiki::Render;
+                               IkiWiki::prune($file);
+                       }
+               }
+
+               if ($added) {
+                       my $conflict;
+                       if ($config{rcs} and $config{comments_commit}) {
+                               my $message = gettext("Comment moderation");
+                               IkiWiki::disable_commit_hook();
+                               $conflict=IkiWiki::rcs_commit_staged($message,
+                                       $session->param('name'), $ENV{REMOTE_ADDR});
+                               IkiWiki::enable_commit_hook();
+                               IkiWiki::rcs_update();
+                       }
+               
+                       # Now we need a refresh
+                       require IkiWiki::Render;
+                       IkiWiki::refresh();
+                       IkiWiki::saveindex();
+               
+                       error($conflict) if defined $conflict;
+               }
+       }
+
+       my @comments=map {
+               my ($id, $ctime)=@{$_};
+               my $file="$config{wikistatedir}/comments_pending/$id";
+               my $content=readfile($file);
+               my $preview=previewcomment($content, $id,
+                       IkiWiki::dirname($_), $ctime);
+               {
+                       id => $id,
+                       view => $preview,
+               } 
+       } sort { $b->[1] <=> $a->[1] } comments_pending();
+
+       my $template=template("commentmoderation.tmpl");
+       $template->param(
+               sid => $session->id,
+               comments => \@comments,
+       );
+       IkiWiki::printheader($session);
+       my $out=$template->output;
+       IkiWiki::run_hooks(format => sub {
+               $out = shift->(page => "", content => $out);
+       });
+       print IkiWiki::misctemplate(gettext("comment moderation"), $out);
+       exit;
+}
+
+sub formbuilder_setup (@) {
+       my %params=@_;
+
+       my $form=$params{form};
+       if ($form->title eq "preferences" &&
+           IkiWiki::is_admin($params{session}->param("name"))) {
+               push @{$params{buttons}}, "Comment Moderation";
+               if ($form->submitted && $form->submitted eq "Comment Moderation") {
+                       commentmoderation($params{cgi}, $params{session});
+               }
+       }
+}
+
+sub comments_pending () {
+       my $dir="$config{wikistatedir}/comments_pending/";
+       return unless -d $dir;
+
+       my @ret;
+       eval q{use File::Find};
+       error($@) if $@;
+       find({
+               no_chdir => 1,
+               wanted => sub {
+                       $_=decode_utf8($_);
+                       if (IkiWiki::file_pruned($_, $dir)) {
+                               $File::Find::prune=1;
+                       }
+                       elsif (! -l $_ && ! -d _) {
+                               $File::Find::prune=0;
+                               my ($f)=/$config{wiki_file_regexp}/; # untaint
+                               if (defined $f && $f =~ /\Q._comment\E$/) {
+                                       my $ctime=(stat($f))[10];
+                                       $f=~s/^\Q$dir\E\/?//;
+                                        push @ret, [$f, $ctime];
+                               }
+                       }
+               }
+       }, $dir);
+
+       return @ret;
+}
+
+sub previewcomment ($$$) {
+       my $content=shift;
+       my $location=shift;
+       my $page=shift;
+       my $time=shift;
+
+       my $preview = IkiWiki::htmlize($location, $page, '_comment',
+                       IkiWiki::linkify($location, $page,
+                       IkiWiki::preprocess($location, $page,
+                       IkiWiki::filter($location, $page, $content), 0, 1)));
+
+       my $template = template("comment.tmpl");
+       $template->param(content => $preview);
+       $template->param(ctime => displaytime($time));
+
+       IkiWiki::run_hooks(pagetemplate => sub {
+               shift->(page => $location,
+                       destpage => $page,
+                       template => $template);
+       });
+
+       $template->param(have_actions => 0);
+
+       return $template->output;
+}
+
+sub commentsshown ($) {
+       my $page=shift;
+
+       return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)",
+                               location => $page) &&
+              pagespec_match($page, $config{comments_pagespec},
+                             location => $page);
+}
+
+sub commentsopen ($) {
+       my $page = shift;
+
+       return length $config{cgiurl} > 0 &&
+              (! length $config{comments_closed_pagespec} ||
+               ! pagespec_match($page, $config{comments_closed_pagespec},
+                                location => $page));
+}
+
+sub pagetemplate (@) {
+       my %params = @_;
+
+       my $page = $params{page};
+       my $template = $params{template};
+       my $shown = ($template->query(name => 'commentslink') ||
+                    $template->query(name => 'commentsurl') ||
+                    $template->query(name => 'atomcommentsurl') ||
+                    $template->query(name => 'comments')) &&
+                   commentsshown($page);
+
+       if ($template->query(name => 'comments')) {
+               my $comments = undef;
+               if ($shown) {
+                       $comments = IkiWiki::preprocess_inline(
+                               pages => "internal($page/$config{comments_pagename}*)",
+                               template => 'comment',
+                               show => 0,
+                               reverse => 'yes',
+                               page => $page,
+                               destpage => $params{destpage},
+                               feedfile => 'comments',
+                               emptyfeeds => 'no',
+                       );
+               }
+
+               if (defined $comments && length $comments) {
+                       $template->param(comments => $comments);
+               }
+
+               if ($shown && commentsopen($page)) {
+                       my $addcommenturl = IkiWiki::cgiurl(do => 'comment',
+                               page => $page);
+                       $template->param(addcommenturl => $addcommenturl);
+               }
+       }
+
+       if ($template->query(name => 'commentsurl')) {
+               if ($shown) {
+                       $template->param(commentsurl =>
+                               urlto($page, undef, 1).'#comments');
+               }
+       }
+
+       if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
+               if ($shown) {
+                       # This will 404 until there are some comments, but I
+                       # think that's probably OK...
+                       $template->param(atomcommentsurl =>
+                               urlto($page, undef, 1).'comments.atom');
+               }
+       }
+
+       if ($template->query(name => 'commentslink')) {
+               # XXX Would be nice to say how many comments there are in
+               # the link. But, to update the number, blog pages
+               # would have to update whenever comments of any inlines
+               # page are added, which is not currently done.
+               if ($shown) {
+                       $template->param(commentslink =>
+                               htmllink($page, $params{destpage}, $page,
+                                       linktext => gettext("Comments"),
+                                       anchor => "comments",
+                                       noimageinline => 1));
+               }
+       }
+
+       # everything below this point is only relevant to the comments
+       # themselves
+       if (!exists $commentstate{$page}) {
+               return;
+       }
+       
+       if ($template->query(name => 'commentid')) {
+               $template->param(commentid => page_to_id($page));
+       }
+
+       if ($template->query(name => 'commentuser')) {
+               $template->param(commentuser =>
+                       $commentstate{$page}{commentuser});
+       }
+
+       if ($template->query(name => 'commentopenid')) {
+               $template->param(commentopenid =>
+                       $commentstate{$page}{commentopenid});
+       }
+
+       if ($template->query(name => 'commentip')) {
+               $template->param(commentip =>
+                       $commentstate{$page}{commentip});
+       }
+
+       if ($template->query(name => 'commentauthor')) {
+               $template->param(commentauthor =>
+                       $commentstate{$page}{commentauthor});
+       }
+
+       if ($template->query(name => 'commentauthorurl')) {
+               $template->param(commentauthorurl =>
+                       $commentstate{$page}{commentauthorurl});
+       }
+
+       if ($template->query(name => 'removeurl') &&
+           IkiWiki::Plugin::remove->can("check_canremove") &&
+           length $config{cgiurl}) {
+               $template->param(removeurl => IkiWiki::cgiurl(do => 'remove',
+                       page => $page));
+               $template->param(have_actions => 1);
+       }
+}
+
+sub unique_comment_location ($) {
+       my $page=shift;
+       my $dir=shift;
+
+       my $location;
+       my $i = 0;
+       do {
+               $i++;
+               $location = "$page/$config{comments_pagename}$i";
+       } while (-e "$dir/$location._comment");
+
+       return $location;
+}
+
+sub page_to_id ($) {
+       # Converts a comment page name into a unique, legal html id
+       # addtibute value, that can be used as an anchor to link to the
+       # comment.
+       my $page=shift;
+
+       eval q{use Digest::MD5 'md5_hex'};
+       error($@) if $@;
+
+       return "comment-".md5_hex($page);
+}
+       
+package IkiWiki::PageSpec;
+
+sub match_postcomment ($$;@) {
+       my $page = shift;
+       my $glob = shift;
+
+       if (! $postcomment) {
+               return IkiWiki::FailReason->new("not posting a comment");
+       }
+       return match_glob($page, $glob);
+}
+
+1
index e787424aaee5ca0e01c58f236a87f32c2d493e02..7445dbdad71420bb4228f573543ac673732b197c 100644 (file)
@@ -3,23 +3,23 @@ package IkiWiki::Plugin::conditional;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use UNIVERSAL;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "conditional", call => \&getsetup);
        hook(type => "preprocess", id => "if", call => \&preprocess_if);
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess_if (@) { #{{{
+sub preprocess_if (@) {
        my %params=@_;
 
        foreach my $param (qw{test then}) {
@@ -66,11 +66,11 @@ sub preprocess_if (@) { #{{{
        }
        return IkiWiki::preprocess($params{page}, $params{destpage}, 
                IkiWiki::filter($params{page}, $params{destpage}, $ret));
-} # }}}
+}
 
 package IkiWiki::PageSpec;
 
-sub match_enabled ($$;@) { #{{{
+sub match_enabled ($$;@) {
        shift;
        my $plugin=shift;
        
@@ -81,12 +81,14 @@ sub match_enabled ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("$plugin is not enabled");
        }
-} #}}}
+}
 
-sub match_sourcepage ($$;@) { #{{{
+sub match_sourcepage ($$;@) {
        shift;
        my $glob=shift;
        my %params=@_;
+       
+       $glob=derel($glob, $params{location});
 
        return IkiWiki::FailReason->new("cannot match sourcepage") unless exists $params{sourcepage};
        if (match_glob($params{sourcepage}, $glob, @_)) {
@@ -95,13 +97,15 @@ sub match_sourcepage ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("sourcepage does not match $glob");
        }
-} #}}}
+}
 
-sub match_destpage ($$;@) { #{{{
+sub match_destpage ($$;@) {
        shift;
        my $glob=shift;
        my %params=@_;
        
+       $glob=derel($glob, $params{location});
+
        return IkiWiki::FailReason->new("cannot match destpage") unless exists $params{destpage};
        if (match_glob($params{destpage}, $glob, @_)) {
                return IkiWiki::SuccessReason->new("destpage matches $glob");
@@ -109,9 +113,9 @@ sub match_destpage ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("destpage does not match $glob");
        }
-} #}}}
+}
 
-sub match_included ($$;@) { #{{{
+sub match_included ($$;@) {
        shift;
        shift;
        my %params=@_;
@@ -123,6 +127,6 @@ sub match_included ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("page $params{sourcepage} is not included");
        }
-} #}}}
+}
 
 1
index 7c729300d9a7e964a72dd137e67a6e42e3fc9991..425e71043f0133f5b855c32932bc114542c83d7d 100644 (file)
@@ -5,22 +5,22 @@ package IkiWiki::Plugin::creole;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "creole", call => \&getsetup);
        hook(type => "htmlize", id => "creole", call => \&htmlize);
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        my $content = $params{content};
 
@@ -32,6 +32,6 @@ sub htmlize (@) { #{{{
        creole_custombarelinks();
 
        return creole_parse($content);
-} # }}}
+}
 
 1
index 92667a1ef458922f6cc8e18a9df6eef4e1002937..417442f34e51d3e089186cd9f6839c001efb3bee 100644 (file)
@@ -3,26 +3,26 @@ package IkiWiki::Plugin::cutpaste;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %savedtext;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "cutpaste", call => \&getsetup);
        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);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess_cut (@) { #{{{
+sub preprocess_cut (@) {
        my %params=@_;
 
        foreach my $param (qw{id text}) {
@@ -35,9 +35,9 @@ sub preprocess_cut (@) { #{{{
        $savedtext{$params{page}}->{$params{id}} = $params{text};
 
        return "" if defined wantarray;
-} # }}}
+}
 
-sub preprocess_copy (@) { #{{{
+sub preprocess_copy (@) {
        my %params=@_;
 
        foreach my $param (qw{id text}) {
@@ -51,9 +51,9 @@ sub preprocess_copy (@) { #{{{
 
        return IkiWiki::preprocess($params{page}, $params{destpage}, 
                IkiWiki::filter($params{page}, $params{destpage}, $params{text})) if defined wantarray;
-} # }}}
+}
 
-sub preprocess_paste (@) { #{{{
+sub preprocess_paste (@) {
        my %params=@_;
 
        foreach my $param (qw{id}) {
@@ -71,6 +71,6 @@ sub preprocess_paste (@) { #{{{
 
        return IkiWiki::preprocess($params{page}, $params{destpage}, 
                IkiWiki::filter($params{page}, $params{destpage}, $savedtext{$params{page}}->{$params{id}}));
-} # }}}
+}
 
 1;
index 6c36de0a6b120b6047c44cca610bcd5e80333c29..bb77ce59f267a5c9e541a1f42f88d6eca0eee4f1 100644 (file)
@@ -2,22 +2,22 @@
 # Discordian date support fnord ikiwiki.
 package IkiWiki::Plugin::ddate;
 
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 no warnings;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "ddate", call => \&getsetup);
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub IkiWiki::displaytime ($;$) { #{{{
+sub IkiWiki::formattime ($;$) {
        my $time=shift;
        my $format=shift;
        if (! defined $format) {
@@ -36,6 +36,6 @@ sub IkiWiki::displaytime ($;$) { #{{{
        my $dt = DateTime->from_epoch(epoch => $time);
        my $dd = DateTime::Calendar::Discordian->from_object(object => $dt);
        return $dd->strftime($format);
-} #}}}
+}
 
 5
index f5d7837fc4c4712de2b693497ce3dd1b7a977b59..7df6a9ffb42f53960f4881b43b34b86f49f6e798 100644 (file)
@@ -4,25 +4,25 @@ package IkiWiki::Plugin::editdiff;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Entities;
 use IPC::Open2;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "editdiff", call => \&getsetup);
        hook(type => "formbuilder_setup", id => "editdiff",
                call => \&formbuilder_setup);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub diff ($$) { #{{{
+sub diff ($$) {
        my $orig=shift;
        my $content=shift;
 
@@ -50,9 +50,9 @@ sub diff ($$) { #{{{
        return "couldn't run diff\n" if $sigpipe;
 
        return "<pre>".encode_entities($ret)."</pre>";
-} #}}}
+}
 
-sub formbuilder_setup { #{{{
+sub formbuilder_setup {
        my %params=@_;
        my $form=$params{form};
 
@@ -72,6 +72,6 @@ sub formbuilder_setup { #{{{
                my $diff = diff(srcfile($pagesources{$page}), $content);
                $form->tmpl_param("page_preview", $diff);
        }
-} #}}}
+}
 
 1
index 30c93df20961090f0bc1e278d0bbf0e5685ecbbb..0068a6b118cd15ca7e110a51fdf81fa1ab313526 100644 (file)
@@ -6,19 +6,19 @@ use strict;
 use IkiWiki;
 use open qw{:utf8 :std};
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "editpage", call => \&getsetup);
        hook(type => "refresh", id => "editpage", call => \&refresh);
         hook(type => "sessioncgi", id => "editpage", call => \&IkiWiki::cgi_editpage);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
 sub refresh () {
        if (exists $wikistate{editpage} && exists $wikistate{editpage}{previews}) {
@@ -51,37 +51,10 @@ sub refresh () {
 
 # Back to ikiwiki namespace for the rest, this code is very much
 # internal to ikiwiki even though it's separated into a plugin,
-# and other plugins use the functions below.
+# and other plugins use the function below.
 package IkiWiki;
 
-sub check_canedit ($$$;$) { #{{{
-       my $page=shift;
-       my $q=shift;
-       my $session=shift;
-       my $nonfatal=shift;
-       
-       my $canedit;
-       run_hooks(canedit => sub {
-               return if defined $canedit;
-               my $ret=shift->($page, $q, $session);
-               if (defined $ret) {
-                       if ($ret eq "") {
-                               $canedit=1;
-                       }
-                       elsif (ref $ret eq 'CODE') {
-                               $ret->() unless $nonfatal;
-                               $canedit=0;
-                       }
-                       elsif (defined $ret) {
-                               error($ret) unless $nonfatal;
-                               $canedit=0;
-                       }
-               }
-       });
-       return $canedit;
-} #}}}
-
-sub cgi_editpage ($$) { #{{{
+sub cgi_editpage ($$) {
        my $q=shift;
        my $session=shift;
        
@@ -105,7 +78,6 @@ sub cgi_editpage ($$) { #{{{
                header => 0,
                table => 0,
                template => scalar template_params("editpage.tmpl"),
-               wikiname => $config{wikiname},
        );
        
        decode_form_utf8($form);
@@ -122,7 +94,7 @@ sub cgi_editpage ($$) { #{{{
        my $absolute=($page =~ s#^/+##);
        if (! defined $page || ! length $page ||
            file_pruned($page, $config{srcdir})) {
-               error("bad page name");
+               error(gettext("bad page name"));
        }
 
        my $baseurl = urlto($page, undef, 1);
@@ -340,16 +312,7 @@ sub cgi_editpage ($$) { #{{{
        else {
                # save page
                check_canedit($page, $q, $session);
-       
-               # The session id is stored on the form and checked to
-               # guard against CSRF. But only if the user is logged in,
-               # as anonok can allow anonymous edits.
-               if (defined $session->param("name")) {
-                       my $sid=$q->param('sid');
-                       if (! defined $sid || $sid ne $session->id) {
-                               error(gettext("Your login session has expired."));
-                       }
-               }
+               checksessionexpiry($q, $session, $q->param('sid'));
 
                my $exists=-e "$config{srcdir}/$file";
 
@@ -378,8 +341,17 @@ sub cgi_editpage ($$) { #{{{
                        showform($form, \@buttons, $session, $q, forcebaseurl => $baseurl);
                        exit;
                }
+                       
+               my $message="";
+               if (defined $form->field('comments') &&
+                   length $form->field('comments')) {
+                       $message=$form->field('comments');
+               }
                
                my $content=$form->field('editcontent');
+               check_content(content => $content, page => $page,
+                       cgi => $q, session => $session,
+                       subject => $message);
                run_hooks(editcontent => sub {
                        $content=shift->(
                                content => $content,
@@ -413,12 +385,6 @@ sub cgi_editpage ($$) { #{{{
                
                my $conflict;
                if ($config{rcs}) {
-                       my $message="";
-                       if (defined $form->field('comments') &&
-                           length $form->field('comments')) {
-                               $message=$form->field('comments');
-                       }
-                       
                        if (! $exists) {
                                rcs_add($file);
                        }
@@ -462,6 +428,6 @@ sub cgi_editpage ($$) { #{{{
        }
 
        exit;
-} #}}}
+}
 
 1
index 846b4e7c832c499a0755860b2c277b282a2b2f1d..0bafc95d06d854b860e566a8c14134119d51db17 100644 (file)
@@ -3,11 +3,11 @@ package IkiWiki::Plugin::edittemplate;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Template;
 use Encode;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "edittemplate",
                call => \&getsetup);
        hook(type => "needsbuild", id => "edittemplate",
@@ -16,17 +16,17 @@ sub import { #{{{
                call => \&preprocess);
        hook(type => "formbuilder", id => "edittemplate",
                call => \&formbuilder);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
 
        foreach my $page (keys %pagestate) {
@@ -40,9 +40,9 @@ sub needsbuild (@) { #{{{
                        }
                }
        }
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
         my %params=@_;
 
        return "" if $params{page} ne $params{destpage};
@@ -62,9 +62,9 @@ sub preprocess (@) { #{{{
        return sprintf(gettext("edittemplate %s registered for %s"),
                htmllink($params{page}, $params{destpage}, $link),
                $params{match});
-} # }}}
+}
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
        my $form=$params{form};
 
@@ -103,9 +103,9 @@ sub formbuilder (@) { #{{{
                        }
                }
        }
-} #}}}
+}
 
-sub filltemplate ($$) { #{{{
+sub filltemplate ($$) {
        my $template_page=shift;
        my $page=shift;
 
@@ -136,6 +136,6 @@ sub filltemplate ($$) { #{{{
        $template->param(name => $page);
 
        return $template->output;
-} #}}}
+}
 
 1
index 2a16373921436d78db16be6455fb59081149ecd2..a7d38358fe3ab4177c2cf6a7817f3e037f2c8e4a 100644 (file)
@@ -3,7 +3,7 @@ package IkiWiki::Plugin::embed;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my $attribr=qr/[^<>"]+/;
 
@@ -43,35 +43,35 @@ my $safehtml=qr{(
 
 my @embedded;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "embed", call => \&getsetup);
        hook(type => "filter", id => "embed", call => \&filter);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub embed ($) { #{{{
+sub embed ($) {
        hook(type => "format", id => "embed", call => \&format) unless @embedded;
        push @embedded, shift;
        return "<div class=\"embed$#embedded\"></div>";
-} #}}}
+}
 
-sub filter (@) { #{{{
+sub filter (@) {
        my %params=@_;
        $params{content} =~ s/$safehtml/embed($1)/eg;
        return $params{content};
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
         my %params=@_;
        $params{content} =~ s/<div class="embed(\d+)"><\/div>/$embedded[$1]/eg;
         return $params{content};
-} # }}}
+}
 
 1
index ba6c7d8b9f064577bcfb2c9e2716c7653da1fc72..066f15cf1b2f12ef4a027e5c9842d1b859358f23 100644 (file)
@@ -6,7 +6,7 @@ package IkiWiki::Plugin::external;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use RPC::XML;
 use RPC::XML::Parser;
 use IPC::Open2;
@@ -14,7 +14,7 @@ use IO::Handle;
 
 my %plugins;
 
-sub import { #{{{
+sub import {
        my $self=shift;
        my $plugin=shift;
        return unless defined $plugin;
@@ -32,17 +32,17 @@ sub import { #{{{
        $RPC::XML::ENCODING="utf-8";
 
        rpc_call($plugins{$plugin}, "import");
-} #}}}
+}
 
-sub rpc_write ($$) { #{{{
+sub rpc_write ($$) {
        my $fh=shift;
        my $string=shift;
 
        $fh->print($string."\n");
        $fh->flush;
-} #}}}
+}
 
-sub rpc_call ($$;@) { #{{{
+sub rpc_call ($$;@) {
        my $plugin=shift;
        my $command=shift;
 
@@ -131,12 +131,12 @@ sub rpc_call ($$;@) { #{{{
        }
 
        return undef;
-} #}}}
+}
 
 package IkiWiki::RPC::XML;
 use Memoize;
 
-sub getvar ($$$) { #{{{
+sub getvar ($$$) {
        my $plugin=shift;
        my $varname="IkiWiki::".shift;
        my $key=shift;
@@ -145,9 +145,9 @@ sub getvar ($$$) { #{{{
        my $ret=$varname->{$key};
        use strict 'refs';
        return $ret;
-} #}}}
+}
 
-sub setvar ($$$;@) { #{{{
+sub setvar ($$$;@) {
        my $plugin=shift;
        my $varname="IkiWiki::".shift;
        my $key=shift;
@@ -157,18 +157,18 @@ sub setvar ($$$;@) { #{{{
        my $ret=$varname->{$key}=$value;
        use strict 'refs';
        return $ret;
-} #}}}
+}
 
-sub getstate ($$$$) { #{{{
+sub getstate ($$$$) {
        my $plugin=shift;
        my $page=shift;
        my $id=shift;
        my $key=shift;
 
        return $IkiWiki::pagestate{$page}{$id}{$key};
-} #}}}
+}
 
-sub setstate ($$$$;@) { #{{{
+sub setstate ($$$$;@) {
        my $plugin=shift;
        my $page=shift;
        my $id=shift;
@@ -176,22 +176,22 @@ sub setstate ($$$$;@) { #{{{
        my $value=shift;
 
        return $IkiWiki::pagestate{$page}{$id}{$key}=$value;
-} #}}}
+}
 
-sub getargv ($) { #{{{
+sub getargv ($) {
        my $plugin=shift;
 
        return \@ARGV;
-} #}}}
+}
 
-sub setargv ($@) { #{{{
+sub setargv ($@) {
        my $plugin=shift;
        my $array=shift;
 
        @ARGV=@$array;
-} #}}}
+}
 
-sub inject ($@) { #{{{
+sub inject ($@) {
        # Bind a given perl function name to a particular RPC request.
        my $plugin=shift;
        my %params=@_;
@@ -202,12 +202,20 @@ sub inject ($@) { #{{{
        my $sub = sub {
                IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
        };
+       $sub=memoize($sub) if $params{memoize};
+
+       # This will add it to the symbol table even if not present.
+       no warnings;
        eval qq{*$params{name}=\$sub};
-       memoize($params{name}) if $params{memoize};
+       use warnings;
+
+       # This will ensure that everywhere it was exported to sees
+       # the injected version.
+       IkiWiki::inject(name => $params{name}, call => $sub);
        return 1;
-} #}}}
+}
 
-sub hook ($@) { #{{{
+sub hook ($@) {
        # the call parameter is a function name to call, since XML RPC
        # cannot pass a function reference
        my $plugin=shift;
@@ -219,13 +227,13 @@ sub hook ($@) { #{{{
        IkiWiki::hook(%params, call => sub {
                IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_);
        });
-} #}}}
+}
 
-sub pagespec_match ($@) { #{{{
+sub pagespec_match ($@) {
        # convert pagespec_match's return object into a XML RPC boolean
        my $plugin=shift;
 
        return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
-} #}}}
+}
 
 1
index e9204dea9fbf1841b386c87b107e33bf0bbfd603..6060914c5a59a6736971f5557d97b3efc992d953 100644 (file)
@@ -5,22 +5,22 @@ package IkiWiki::Plugin::favicon;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "favicon", call => \&getsetup);
        hook(type => "pagetemplate", id => "favicon", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
 
        my $template=$params{template};
@@ -28,6 +28,6 @@ sub pagetemplate (@) { #{{{
        if ($template->query(name => "favicon")) {
                $template->param(favicon => "favicon.ico");
        }
-} # }}}
+}
 
 1
index 27f764e3b344a344ef2d491552824c2c40e6e5f1..8575ee108eece4135c783993b718cfbb1f278c2e 100644 (file)
@@ -3,7 +3,7 @@ package IkiWiki::Plugin::filecheck;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %units=( #{{{       # size in bytes
        B               => 1,
@@ -37,9 +37,9 @@ my %units=( #{{{      # size in bytes
        # ikiwiki, if you find you need larger data quantities, either modify
        # yourself to add them, or travel back in time to 2008 and kill me.
        #   -- Joey
-); #}}}
+);
 
-sub parsesize ($) { #{{{
+sub parsesize ($) {
        my $size=shift;
 
        no warnings;
@@ -51,10 +51,10 @@ sub parsesize ($) { #{{{
                }
        }
        return $base;
-} #}}}
+}
 
 # This is provided for other plugins that want to convert back the other way.
-sub humansize ($) { #{{{
+sub humansize ($) {
        my $size=shift;
 
        foreach my $unit (reverse sort { $units{$a} <=> $units{$b} || $b cmp $a } keys %units) {
@@ -63,11 +63,11 @@ sub humansize ($) { #{{{
                }
        }
        return $size; # near zero, or negative
-} #}}}
+}
 
 package IkiWiki::PageSpec;
 
-sub match_maxsize ($$;@) { #{{{
+sub match_maxsize ($$;@) {
        my $page=shift;
        my $maxsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
        if ($@) {
@@ -86,9 +86,9 @@ sub match_maxsize ($$;@) { #{{{
        else {
                return IkiWiki::SuccessReason->new("file not too large");
        }
-} #}}}
+}
 
-sub match_minsize ($$;@) { #{{{
+sub match_minsize ($$;@) {
        my $page=shift;
        my $minsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
        if ($@) {
@@ -107,9 +107,9 @@ sub match_minsize ($$;@) { #{{{
        else {
                return IkiWiki::SuccessReason->new("file not too small");
        }
-} #}}}
+}
 
-sub match_mimetype ($$;@) { #{{{
+sub match_mimetype ($$;@) {
        my $page=shift;
        my $wanted=shift;
 
@@ -140,9 +140,9 @@ sub match_mimetype ($$;@) { #{{{
        else {
                return IkiWiki::SuccessReason->new("file MIME type is $mimetype");
        }
-} #}}}
+}
 
-sub match_virusfree ($$;@) { #{{{
+sub match_virusfree ($$;@) {
        my $page=shift;
        my $wanted=shift;
 
@@ -182,9 +182,9 @@ sub match_virusfree ($$;@) { #{{{
        else {
                return IkiWiki::SuccessReason->new("file seems virusfree ($reason)");
        }
-} #}}}
+}
 
-sub match_ispage ($$;@) { #{{{
+sub match_ispage ($$;@) {
        my $filename=shift;
 
        if (defined IkiWiki::pagetype($filename)) {
@@ -193,4 +193,4 @@ sub match_ispage ($$;@) { #{{{
        else {
                return IkiWiki::FailReason->new("file is not a wiki page");
        }
-} #}}}
+}
diff --git a/IkiWiki/Plugin/format.pm b/IkiWiki/Plugin/format.pm
new file mode 100644 (file)
index 0000000..bbe3aa9
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::format;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "preprocess", id => "format", call => \&preprocess);
+}
+
+sub preprocess (@) {
+       my $format=$_[0];
+       shift; shift;
+       my $text=$_[0];
+       shift; shift;
+       my %params=@_;
+
+       if (! defined $format || ! defined $text) {
+               error(gettext("must specify format and text"));
+       }
+       elsif (! exists $IkiWiki::hooks{htmlize}{$format}) {
+               error(sprintf(gettext("unsupported page format %s"), $format));
+       }
+
+       return IkiWiki::htmlize($params{page}, $params{destpage}, $format,
+               IkiWiki::preprocess($params{page}, $params{destpage}, $text));
+}
+
+1
index 456b63e9f341f215dba522603c20c8a005fec7a0..17e57dea14fccb4c3f9e1c21a5926ef4880033cd 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::fortune;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "fortune", call => \&getsetup);
        hook(type => "preprocess", id => "fortune", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        $ENV{PATH}="$ENV{PATH}:/usr/games:/usr/local/games";
        my $f = `fortune 2>/dev/null`;
 
@@ -29,6 +29,6 @@ sub preprocess (@) { #{{{
        else {
                return "<pre>$f</pre>\n";
        }
-} # }}}
+}
 
 1
index 14b0ab2851dc03b561e4c86e9e0c5d660a8ca3a2..68b114a7328332a54d8e66426bd09dc1eec0b030 100644 (file)
@@ -9,8 +9,9 @@ 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;
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "git", call => \&checkconfig);
        hook(type => "getsetup", id => "git", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -23,24 +24,34 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+       hook(type => "rcs", id => "rcs_receive", call => \&rcs_receive);
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! defined $config{gitorigin_branch}) {
                $config{gitorigin_branch}="origin";
        }
        if (! defined $config{gitmaster_branch}) {
                $config{gitmaster_branch}="master";
        }
-       if (defined $config{git_wrapper} && length $config{git_wrapper}) {
+       if (defined $config{git_wrapper} &&
+           length $config{git_wrapper}) {
                push @{$config{wrappers}}, {
                        wrapper => $config{git_wrapper},
                        wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
                };
        }
-} #}}}
+       if (defined $config{git_test_receive_wrapper} &&
+           length $config{git_test_receive_wrapper}) {
+               push @{$config{wrappers}}, {
+                       test_receive => 1,
+                       wrapper => $config{git_test_receive_wrapper},
+                       wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
+               };
+       }
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -60,6 +71,20 @@ sub getsetup () { #{{{
                        safe => 0,
                        rebuild => 0,
                },
+               git_test_receive_wrapper => {
+                       type => "string",
+                       example => "/git/wiki.git/hooks/pre-receive",
+                       description => "git pre-receive hook to generate",
+                       safe => 0, # file
+                       rebuild => 0,
+               },
+               untrusted_committers => {
+                       type => "string",
+                       example => [],
+                       description => "unix users whose commits should be checked by the pre-receive hook",
+                       safe => 0,
+                       rebuild => 0,
+               },
                historyurl => {
                        type => "string",
                        example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=history;f=[[file]]",
@@ -69,8 +94,8 @@ sub getsetup () { #{{{
                },
                diffurl => {
                        type => "string",
-                       example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_parent]];f=[[file]]",
-                       description => "gitweb url to show a diff ([[sha1_to]], [[sha1_from]], [[sha1_parent]], and [[file]] substituted)",
+                       example => "http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]",
+                       description => "gitweb url to show a diff ([[file]], [[sha1_to]], [[sha1_from]], [[sha1_commit]], and [[sha1_parent]] substituted)",
                        safe => 1,
                        rebuild => 1,
                },
@@ -88,9 +113,9 @@ sub getsetup () { #{{{
                        safe => 0, # paranoia
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub safe_git (&@) { #{{{
+sub safe_git (&@) {
        # Start a child process safely without resorting /bin/sh.
        # Return command output or success state (in scalar context).
 
@@ -103,15 +128,25 @@ sub safe_git (&@) { #{{{
        if (!$pid) {
                # In child.
                # Git commands want to be in wc.
-               chdir $config{srcdir}
-                   or error("Cannot chdir to $config{srcdir}: $!");
+               if (! $no_chdir) {
+                       chdir $config{srcdir}
+                           or error("Cannot chdir to $config{srcdir}: $!");
+               }
                exec @cmdline or error("Cannot exec '@cmdline': $!");
        }
        # In parent.
 
+       # git output is probably utf-8 encoded, but may contain
+       # other encodings or invalidly encoded stuff. So do not rely
+       # on the normal utf-8 IO layer, decode it by hand.
+       binmode($OUT);
+
        my @lines;
        while (<$OUT>) {
+               $_=decode_utf8($_, 0);
+
                chomp;
+
                push @lines, $_;
        }
 
@@ -125,9 +160,9 @@ sub safe_git (&@) { #{{{
 sub run_or_die ($@) { safe_git(\&error, @_) }
 sub run_or_cry ($@) { safe_git(sub { warn @_ },  @_) }
 sub run_or_non ($@) { safe_git(undef,            @_) }
-#}}}
 
-sub merge_past ($$$) { #{{{
+
+sub merge_past ($$$) {
        # Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'.
        # Git merge commands work with the committed changes, except in the
        # implicit case of '-m' of git checkout(1).  So we should invent a
@@ -219,9 +254,9 @@ sub merge_past ($$$) { #{{{
        error("Git merge failed!\n$failure\n") if $failure;
 
        return $conflict;
-} #}}}
+}
 
-sub parse_diff_tree ($@) { #{{{
+sub parse_diff_tree ($@) {
        # Parse the raw diff tree chunk and return the info hash.
        # See git-diff-tree(1) for the syntax.
 
@@ -320,6 +355,9 @@ sub parse_diff_tree ($@) { #{{{
                                        'file'      => decode("utf8", $file),
                                        'sha1_from' => $sha1_from[0],
                                        'sha1_to'   => $sha1_to,
+                                       'mode_from' => $mode_from[0],
+                                       'mode_to'   => $mode_to,
+                                       'status'    => $status,
                                };
                        }
                        next;
@@ -328,17 +366,17 @@ sub parse_diff_tree ($@) { #{{{
        }
 
        return \%ci;
-} #}}}
+}
 
-sub git_commit_info ($;$) { #{{{
-       # Return an array of commit info hashes of num commits (default: 1)
+sub git_commit_info ($;$) {
+       # Return an array of commit info hashes of num commits
        # starting from the given sha1sum.
-
        my ($sha1, $num) = @_;
 
-       $num ||= 1;
+       my @opts;
+       push @opts, "--max-count=$num" if defined $num;
 
-       my @raw_lines = run_or_die('git', 'log', "--max-count=$num", 
+       my @raw_lines = run_or_die('git', 'log', @opts,
                '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
                '-r', $sha1, '--', '.');
        my ($prefix) = run_or_die('git', 'rev-parse', '--show-prefix');
@@ -351,11 +389,10 @@ sub git_commit_info ($;$) { #{{{
        warn "Cannot parse commit info for '$sha1' commit" if !@ci;
 
        return wantarray ? @ci : $ci[0];
-} #}}}
+}
 
-sub git_sha1 (;$) { #{{{
+sub git_sha1 (;$) {
        # Return head sha1sum (of given file).
-
        my $file = shift || q{--};
 
        # Ignore error since a non-existing file might be given.
@@ -365,26 +402,25 @@ sub git_sha1 (;$) { #{{{
                ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
        } else { debug("Empty sha1sum for '$file'.") }
        return defined $sha1 ? $sha1 : q{};
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        # Update working directory.
 
        if (length $config{gitorigin_branch}) {
                run_or_cry('git', 'pull', $config{gitorigin_branch});
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        # Return the commit sha1sum of the file when editing begins.
        # This will be later used in rcs_commit if a merge is required.
-
        my ($file) = @_;
 
        return git_sha1($file);
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        # Try to commit the page; returns undef on _success_ and
        # a version of the page with the rcs's conflict markers on
        # failure.
@@ -403,7 +439,7 @@ sub rcs_commit ($$$;$$) { #{{{
 
        rcs_add($file); 
        return rcs_commit_staged($message, $user, $ipaddr);
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -413,7 +449,7 @@ sub rcs_commit_staged ($$$) {
        # Set the commit author and email to the web committer.
        my %env=%ENV;
        if (defined $user || defined $ipaddr) {
-               my $u=defined $user ? $user : $ipaddr;
+               my $u=encode_utf8(defined $user ? $user : $ipaddr);
                $ENV{GIT_AUTHOR_NAME}=$u;
                $ENV{GIT_AUTHOR_EMAIL}="$u\@web";
        }
@@ -444,29 +480,29 @@ sub rcs_commit_staged ($$$) {
        return undef; # success
 }
 
-sub rcs_add ($) { # {{{
+sub rcs_add ($) {
        # Add file to archive.
 
        my ($file) = @_;
 
        run_or_cry('git', 'add', $file);
-} #}}}
+}
 
-sub rcs_remove ($) { # {{{
+sub rcs_remove ($) {
        # Remove file from archive.
 
        my ($file) = @_;
 
        run_or_cry('git', 'rm', '-f', $file);
-} #}}}
+}
 
-sub rcs_rename ($$) { # {{{
+sub rcs_rename ($$) {
        my ($src, $dest) = @_;
 
        run_or_cry('git', 'mv', '-f', $src, $dest);
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        # List of recent changes.
 
        my ($num) = @_;
@@ -475,7 +511,7 @@ sub rcs_recentchanges ($) { #{{{
        error($@) if $@;
 
        my @rets;
-       foreach my $ci (git_commit_info('HEAD', $num)) {
+       foreach my $ci (git_commit_info('HEAD', $num || 1)) {
                # Skip redundant commits.
                next if ($ci->{'comment'} && @{$ci->{'comment'}}[0] eq $dummy_commit_msg);
 
@@ -493,6 +529,7 @@ sub rcs_recentchanges ($) { #{{{
                        $diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go;
                        $diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go;
                        $diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go;
+                       $diffurl =~ s/\[\[sha1_commit\]\]/$sha1/go;
 
                        push @pages, {
                                page => pagename($file),
@@ -533,9 +570,9 @@ sub rcs_recentchanges ($) { #{{{
        }
 
        return @rets;
-} #}}}
+}
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        my $rev=shift;
        my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
        my @lines;
@@ -550,19 +587,112 @@ sub rcs_diff ($) { #{{{
        else {
                return join("", @lines);
        }
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        my $file=shift;
        # Remove srcdir prefix
        $file =~ s/^\Q$config{srcdir}\E\/?//;
 
-       my $sha1  = git_sha1($file);
-       my $ci    = git_commit_info($sha1);
+       my @sha1s = run_or_non('git', 'rev-list', 'HEAD', '--', $file);
+       my $ci    = git_commit_info($sha1s[$#sha1s], 1);
        my $ctime = $ci->{'author_epoch'};
        debug("ctime for '$file': ". localtime($ctime));
 
        return $ctime;
-} #}}}
+}
+
+sub rcs_receive () {
+       # 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.
+       my $subdir="";
+       my $dir=$config{srcdir};
+       while (! -d "$dir/.git") {
+               $subdir=IkiWiki::basename($dir)."/".$subdir;
+               $dir=IkiWiki::dirname($dir);
+               if (! length $dir) {
+                       error("cannot determine root of git repo");
+               }
+       }
+
+       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);
+                               }
+
+                               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");
+                                       }
+                               }
+
+                               push @rets, {
+                                       file => $file,
+                                       action => $action,
+                                       path => $path,
+                               };
+                       }
+               }
+       }
+
+       return reverse @rets;
+}
 
 1
index ed1f4ddfc6cab5d88604be3fbe409ba3a573f642..451cd6f84fce568167c1d8ef045baba3513dcb80 100644 (file)
@@ -4,13 +4,12 @@ package IkiWiki::Plugin::goodstuff;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my @bundle=qw{
        brokenlinks
        img
        map
-       meta
        more
        orphans
        pagecount
@@ -23,21 +22,22 @@ my @bundle=qw{
        template
        toc
        toggle
+       repolist
 };
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "goodstuff", call => \&getsetup);
        foreach my $plugin (@bundle) {
                IkiWiki::loadplugin($plugin);
        }
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
 1
index 92b9b29eb63a86d031ed995ee08ab3b5d0a10ce0..4bba5775c2ba8583fc06504496e39792c2107bad 100644 (file)
@@ -3,26 +3,26 @@ package IkiWiki::Plugin::google;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use URI;
 
 my $host;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "google", call => \&getsetup);
        hook(type => "checkconfig", id => "google", call => \&checkconfig);
        hook(type => "pagetemplate", id => "google", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! length $config{url}) {
                error(sprintf(gettext("Must specify %s when using the google search plugin"), "url"));
        }
@@ -31,10 +31,10 @@ sub checkconfig () { #{{{
                error(gettext("Failed to parse url, cannot determine domain name"));
        }
        $host=$uri->host;
-} #}}}
+}
 
 my $form;
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $page=$params{page};
        my $template=$params{template};
@@ -49,6 +49,6 @@ sub pagetemplate (@) { #{{{
 
                $template->param(searchform => $form);
        }
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/googlecalendar.pm b/IkiWiki/Plugin/googlecalendar.pm
deleted file mode 100644 (file)
index 81a3ad6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/perl
-package IkiWiki::Plugin::googlecalendar;
-
-use warnings;
-use strict;
-use IkiWiki 2.00;
-
-sub import { #{{{
-       hook(type => "getsetup", id => "googlecalendar",
-               call => \&getsetup);
-       hook(type => "preprocess", id => "googlecalendar",
-               call => \&preprocess);
-       hook(type => "format", id => "googlecalendar",
-               call => \&format);
-} # }}}
-
-sub getsetup () { #{{{
-       return
-               plugin => {
-                       safe => 1,
-                       rebuild => undef,
-               },
-} #}}}
-
-sub preprocess (@) { #{{{
-       my %params=@_;
-
-       # Parse the html, looking for the url to embed for the calendar.
-       # Avoid XSS attacks..
-       my ($url)=$params{html}=~m#iframe\s+src="http://www\.google\.com/calendar/embed\?([^"<>]+)"#;
-       if (! defined $url || ! length $url) {
-               error gettext("failed to find url in html")
-       }
-       my ($height)=$params{html}=~m#height="(\d+)"#;
-       my ($width)=$params{html}=~m#width="(\d+)"#;
-
-       return "<div class=\"googlecalendar\" src=\"$url\" height=\"$height\" width=\"$width\"></div>";
-} # }}}
-
-sub format (@) { #{{{
-        my %params=@_;
-
-       $params{content}=~s/<div class=\"googlecalendar" src="([^"]+)" height="([^"]+)" width="([^"]+)"><\/div>/gencal($1,$2,$3)/eg;
-
-        return $params{content};
-} # }}}
-
-sub gencal ($$$) { #{{{
-       my $url=shift;
-       my $height=shift;
-       my $width=shift;
-       return qq{<iframe src="http://www.google.com/calendar/embed?$url" style=" border-width:0 " width="$width" frameborder="0" height="$height"></iframe>};
-} #}}}
-
-1
diff --git a/IkiWiki/Plugin/goto.pm b/IkiWiki/Plugin/goto.pm
new file mode 100644 (file)
index 0000000..3f40c58
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::goto;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "cgi", id => 'goto',  call => \&cgi);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 0,
+               }
+}
+
+# cgi_goto(CGI, [page])
+# Redirect to a specified page, or display "not found". If not specified,
+# the page param from the CGI object is used.
+sub cgi_goto ($;$) {
+       my $q = shift;
+       my $page = shift;
+
+       if (!defined $page) {
+               $page = IkiWiki::decode_utf8($q->param("page"));
+
+               if (!defined $page) {
+                       error("missing page parameter");
+               }
+       }
+
+       IkiWiki::loadindex();
+
+       # If the page is internal (like a comment), see if it has a
+       # permalink. Comments do.
+       if (IkiWiki::isinternal($page) &&
+           defined $pagestate{$page}{meta}{permalink}) {
+               IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
+       }
+
+       my $link = bestlink("", $page);
+
+       if (! length $link) {
+               IkiWiki::cgi_custom_failure(
+                       $q->header(-status => "404 Not Found"),
+                       IkiWiki::misctemplate(gettext("missing page"),
+                               "<p>".
+                               sprintf(gettext("The page %s does not exist."),
+                                       htmllink("", "", $page)).
+                               "</p>")
+               )
+       }
+       else {
+               IkiWiki::redirect($q, urlto($link, undef, 1));
+       }
+
+       exit;
+}
+
+sub cgi ($) {
+       my $cgi=shift;
+       my $do = $cgi->param('do');
+
+       if (defined $do && ($do eq 'goto' || $do eq 'commenter' ||
+                              $do eq 'recentchanges_link')) {
+               # goto is the preferred name for this; recentchanges_link and
+               # commenter are for compatibility with any saved URLs
+               cgi_goto($cgi);
+       }
+}
+
+1;
index 20b419413094f5f7dbbbd16ec78efca947da3e01..32e994d6b96c4d10dce2998db005ac22729a7ce5 100644 (file)
@@ -5,27 +5,27 @@ package IkiWiki::Plugin::graphviz;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use IPC::Open2;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "graphviz", call => \&getsetup);
        hook(type => "preprocess", id => "graph", call => \&graph);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
 my %graphviz_programs = (
        "dot" => 1, "neato" => 1, "fdp" => 1, "twopi" => 1, "circo" => 1
 );
 
-sub render_graph (\%) { #{{{
+sub render_graph (\%) {
        my %params = %{(shift)};
 
        my $src = "$params{type} g {\n";
@@ -45,7 +45,7 @@ sub render_graph (\%) { #{{{
 
        if (! -e "$config{destdir}/$dest") {
                my $pid;
-               my $sigpipe=0;;
+               my $sigpipe=0;
                $SIG{PIPE}=sub { $sigpipe=1 };
                $pid=open2(*IN, *OUT, "$params{prog} -Tpng");
 
@@ -84,9 +84,9 @@ sub render_graph (\%) { #{{{
        else {
                return "<img src=\"".urlto($dest, $params{destpage})."\" />\n";
        }
-} #}}}
+}
 
-sub graph (@) { #{{{
+sub graph (@) {
        my %params=@_;
        $params{src} = "" unless defined $params{src};
        $params{type} = "digraph" unless defined $params{type};
@@ -94,6 +94,6 @@ sub graph (@) { #{{{
        error gettext("prog not a valid graphviz program") unless $graphviz_programs{$params{prog}};
 
        return render_graph(%params);
-} # }}}
+}
 
 1
index eb8b786e826d0071ff41b75f08673c781db0bea6..5a062a27606be6a0cb8d9a5a4f06ce8c0ec5cd6a 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::haiku;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "haiku", call => \&getsetup);
        hook(type => "preprocess", id => "haiku", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup { #{{{
+sub getsetup {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        my $haiku;
@@ -54,6 +54,6 @@ sub preprocess (@) { #{{{
        $haiku=~s/\n/<br \/>\n/mg;
        
        return "\n\n<blockquote><p>$haiku</p></blockquote>\n\n";
-} # }}}
+}
 
 1
index 40e4f945255df2b4ae21b732cd55818b41dfc821..bd2177a06a1217de57700c40de641e9794133b5f 100644 (file)
@@ -10,23 +10,23 @@ package IkiWiki::Plugin::hnb;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use File::Temp qw(:mktemp);
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "hnb", call => \&getsetup);
        hook(type => "htmlize", id => "hnb", call => \&htmlize);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params = @_;
 
        # hnb outputs version number etc. every time to STDOUT, so
@@ -52,6 +52,6 @@ sub htmlize (@) { #{{{
        $ret =~ s/<body>.*//si;
 
        return $ret;
-} #}}}
+}
 
 1;
index b752075787801a2cc0a557ada55ba6989f67f97a..a7d5e8ce91af28d9053b9b831564e9b1fc13a7b3 100644 (file)
@@ -4,9 +4,9 @@ package IkiWiki::Plugin::html;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "html", call => \&getsetup);
        hook(type => "htmlize", id => "html", call => \&htmlize);
        hook(type => "htmlize", id => "htm", call => \&htmlize);
@@ -14,19 +14,19 @@ sub import { #{{{
        # ikiwiki defaults to skipping .html files as a security measure;
        # make it process them so this plugin can take effect
        $config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        return $params{content};
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/htmlbalance.pm b/IkiWiki/Plugin/htmlbalance.pm
new file mode 100644 (file)
index 0000000..26f8e49
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::htmlbalance;
+
+# htmlbalance: Parse and re-serialize HTML to ensure balanced tags
+#
+# Copyright 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use HTML::Entities;
+
+sub import {
+       hook(type => "getsetup", id => "htmlbalance", call => \&getsetup);
+       hook(type => "sanitize", id => "htmlbalance", call => \&sanitize);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+               },
+}
+
+sub sanitize (@) {
+       my %params=@_;
+       my $ret = '';
+
+       eval q{use HTML::TreeBuilder};
+       error $@ if $@;
+       my $tree = HTML::TreeBuilder->new();
+       $tree->ignore_unknown(0);
+       $tree->ignore_ignorable_whitespace(0);
+       $tree->no_space_compacting(1);
+       $tree->p_strict(1);
+       $tree->store_comments(0);
+       $tree->store_declarations(0);
+       $tree->store_pis(0);
+       $tree->parse_content($params{content});
+       my @nodes = $tree->disembowel();
+       foreach my $node (@nodes) {
+               if (ref $node) {
+                       $ret .= $node->as_XML();
+                       chomp $ret;
+                       $node->delete();
+               }
+               else {
+                       $ret .= encode_entities($node);
+               }
+       }
+       $tree->delete();
+       return $ret;
+}
+
+1
index 7398c84784632048c41eab1976436578a8bf7027..a249cdf7a43b2986b5ca519f88c01cc6fcf85141 100644 (file)
@@ -3,13 +3,13 @@ package IkiWiki::Plugin::htmlscrubber;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 # This regexp matches urls that are in a known safe scheme.
 # Feel free to use it from other plugins.
 our $safe_url_regexp;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "htmlscrubber", call => \&getsetup);
        hook(type => "sanitize", id => "htmlscrubber", call => \&sanitize);
 
@@ -33,9 +33,9 @@ sub import { #{{{
        # data is a special case. Allow data:image/*, but
        # disallow data:text/javascript and everything else.
        $safe_url_regexp=qr/^(?:(?:$uri_schemes):|data:image\/|[^:]+(?:$|\/))/i;
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -49,9 +49,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub sanitize (@) { #{{{
+sub sanitize (@) {
        my %params=@_;
 
        if (exists $config{htmlscrubber_skip} &&
@@ -62,10 +62,10 @@ sub sanitize (@) { #{{{
        }
 
        return scrubber()->scrub($params{content});
-} # }}}
+}
 
 my $_scrubber;
-sub scrubber { #{{{
+sub scrubber {
        return $_scrubber if defined $_scrubber;
 
        eval q{use HTML::Scrubber};
@@ -111,6 +111,6 @@ sub scrubber { #{{{
                }],
        );
        return $_scrubber;
-} # }}}
+}
 
 1
index 9ba5e9592b0c84482e01175c5881f901315a4397..6f3379ef457bddb7387c8485427ec88d51f5b0c5 100644 (file)
@@ -9,23 +9,23 @@ package IkiWiki::Plugin::htmltidy;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use IPC::Open2;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "tidy", call => \&getsetup);
        hook(type => "sanitize", id => "tidy", call => \&sanitize);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub sanitize (@) { #{{{
+sub sanitize (@) {
        my %params=@_;
 
        my $pid;
@@ -49,6 +49,6 @@ sub sanitize (@) { #{{{
        return "" if $sigpipe || ! defined $ret;
 
        return $ret;
-} # }}}
+}
 
 1
index fc0cffb1e3fa3d529baccc812b0ee77818bd6a39..1816c9d74c27aaee1e2b6114e62dd06b8fca1d4c 100644 (file)
@@ -4,28 +4,28 @@ package IkiWiki::Plugin::httpauth;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "httpauth", call => \&getsetup);
        hook(type => "auth", id => "httpauth", call => \&auth);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub auth ($$) { #{{{
+sub auth ($$) {
        my $cgi=shift;
        my $session=shift;
 
        if (defined $cgi->remote_user()) {
                $session->param("name", $cgi->remote_user());
        }
-} #}}}
+}
 
 1
index 7b89ab6730faed3693f2d0eb59afa38a5194e854..d295b833b21b57ccfef5c5d985ae91281efb466b 100644 (file)
@@ -5,24 +5,24 @@ package IkiWiki::Plugin::img;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %imgdefaults;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "img", call => \&getsetup);
        hook(type => "preprocess", id => "img", call => \&preprocess, scan => 1);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my ($image) = $_[0] =~ /$config{wiki_file_regexp}/; # untaint
        my %params=@_;
 
@@ -119,9 +119,9 @@ sub preprocess (@) { #{{{
        }
 
        my $imgtag='<img src="'.$imgurl.
-               '" alt="'.(exists $params{alt} ? $params{alt} : '').
                '" width="'.$im->Get("width").
                '" height="'.$im->Get("height").'"'.
+               (exists $params{alt} ? '" alt="'.$params{alt}.'"' : '').
                (exists $params{title} ? ' title="'.$params{title}.'"' : '').
                (exists $params{class} ? ' class="'.$params{class}.'"' : '').
                (exists $params{id} ? ' id="'.$params{id}.'"' : '').
@@ -149,6 +149,6 @@ sub preprocess (@) { #{{{
        else {
                return $imgtag;
        }
-} #}}}
+}
 
 1
index 6d88c2f15c46215f86687f5ea91eb8c9dd3e643e..9d7d4b0fd832d32aa7c00ece7ede97ca1847508f 100644 (file)
@@ -5,7 +5,7 @@ package IkiWiki::Plugin::inline;
 use warnings;
 use strict;
 use Encode;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use URI;
 
 my %knownfeeds;
@@ -13,7 +13,7 @@ my %page_numfeeds;
 my @inline;
 my $nested=0;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "inline", call => \&getopt);
        hook(type => "getsetup", id => "inline", call => \&getsetup);
        hook(type => "checkconfig", id => "inline", call => \&checkconfig);
@@ -22,15 +22,14 @@ sub import { #{{{
                call => \&IkiWiki::preprocess_inline);
        hook(type => "pagetemplate", id => "inline",
                call => \&IkiWiki::pagetemplate_inline);
-       hook(type => "format", id => "inline", call => \&format);
+       hook(type => "format", id => "inline", call => \&format, first => 1);
        # Hook to change to do pinging since it's called late.
        # This ensures each page only pings once and prevents slow
        # pings interrupting page builds.
-       hook(type => "change", id => "inline", 
-               call => \&IkiWiki::pingurl);
-} # }}}
+       hook(type => "change", id => "inline", call => \&IkiWiki::pingurl);
+}
 
-sub getopt () { #{{{
+sub getopt () {
        eval q{use Getopt::Long};
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
@@ -43,9 +42,9 @@ sub getopt () { #{{{
                        push @{$config{pingurl}}, $_[1];
                },      
        );
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -86,9 +85,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (($config{rss} || $config{atom}) && ! length $config{url}) {
                error(gettext("Must specify url to wiki with --url when using --rss or --atom"));
        }
@@ -101,9 +100,9 @@ sub checkconfig () { #{{{
        if (! exists $config{pingurl}) {
                $config{pingurl}=[];
        }
-} #}}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
         my %params=@_;
 
        # Fill in the inline content generated earlier. This is actually an
@@ -112,9 +111,9 @@ sub format (@) { #{{{
                delete @inline[$1,]
        }eg;
        return $params{content};
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -149,7 +148,7 @@ package IkiWiki;
 my %toping;
 my %feedlinks;
 
-sub preprocess_inline (@) { #{{{
+sub preprocess_inline (@) {
        my %params=@_;
        
        if (! exists $params{pages}) {
@@ -161,6 +160,7 @@ sub preprocess_inline (@) { #{{{
        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=exists $params{feeds} ? yesno($params{feeds}) : !$quick;
+       my $emptyfeeds=exists $params{emptyfeeds} ? yesno($params{emptyfeeds}) : 1;
        my $feedonly=yesno($params{feedonly});
        if (! exists $params{show} && ! $archive) {
                $params{show}=10;
@@ -194,6 +194,13 @@ sub preprocess_inline (@) { #{{{
        if (exists $params{sort} && $params{sort} eq 'title') {
                @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
        }
+       elsif (exists $params{sort} && $params{sort} eq 'title_natural') {
+               eval q{use Sort::Naturally};
+               if ($@) {
+                       error(gettext("Sort::Naturally needed for title_natural sort"));
+               }
+               @list=sort { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) } @list;
+       }
        elsif (exists $params{sort} && $params{sort} eq 'mtime') {
                @list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
        }
@@ -201,7 +208,7 @@ sub preprocess_inline (@) { #{{{
                @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
        }
        else {
-               return sprintf(gettext("unknown sort type %s"), $params{sort});
+               error sprintf(gettext("unknown sort type %s"), $params{sort});
        }
 
        if (yesno($params{reverse})) {
@@ -232,29 +239,51 @@ sub preprocess_inline (@) { #{{{
        # that if they are removed or otherwise changed, the inline will be
        # sure to be updated.
        add_depends($params{page}, join(" or ", $#list >= $#feedlist ? @list : @feedlist));
-
-       my $feednum="";
-
-       my $feedid=join("\0", map { $_."\0".$params{$_} } sort keys %params);
-       if (exists $knownfeeds{$feedid}) {
-               $feednum=$knownfeeds{$feedid};
+       
+       if ($feeds && exists $params{feedpages}) {
+               @feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist;
        }
-       else {
-               if (exists $page_numfeeds{$params{destpage}}) {
-                       if ($feeds) {
-                               $feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}};
+
+       my ($feedbase, $feednum);
+       if ($feeds) {
+               # Ensure that multiple feeds on a page go to unique files.
+               
+               # Feedfile can lead to conflicts if usedirs is not enabled,
+               # so avoid supporting it in that case.
+               delete $params{feedfile} if ! $config{usedirs};
+               # Tight limits on legal feedfiles, to avoid security issues
+               # and conflicts.
+               if (defined $params{feedfile}) {
+                       if ($params{feedfile} =~ /\// ||
+                           $params{feedfile} !~ /$config{wiki_file_regexp}/) {
+                               error("illegal feedfile");
                        }
+                       $params{feedfile}=possibly_foolish_untaint($params{feedfile});
+               }
+               $feedbase=targetpage($params{destpage}, "", $params{feedfile});
+
+               my $feedid=join("\0", $feedbase, map { $_."\0".$params{$_} } sort keys %params);
+               if (exists $knownfeeds{$feedid}) {
+                       $feednum=$knownfeeds{$feedid};
                }
                else {
-                       $feednum=$knownfeeds{$feedid}="";
-                       if ($feeds) {
-                               $page_numfeeds{$params{destpage}}=1;
+                       if (exists $page_numfeeds{$params{destpage}}{$feedbase}) {
+                               if ($feeds) {
+                                       $feednum=$knownfeeds{$feedid}=++$page_numfeeds{$params{destpage}}{$feedbase};
+                               }
+                       }
+                       else {
+                               $feednum=$knownfeeds{$feedid}="";
+                               if ($feeds) {
+                                       $page_numfeeds{$params{destpage}}{$feedbase}=1;
+                               }
                        }
                }
        }
 
-       my $rssurl=basename(rsspage($params{destpage}).$feednum) if $feeds && $rss;
-       my $atomurl=basename(atompage($params{destpage}).$feednum) if $feeds && $atom;
+       my $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $rss;
+       my $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $atom;
+
        my $ret="";
 
        if (length $config{cgiurl} && ! $params{preview} && (exists $params{rootpage} ||
@@ -285,8 +314,12 @@ sub preprocess_inline (@) { #{{{
                                gettext("Add a new post titled:"));
                }
                $ret.=$formtemplate->output;
+               
+               # The post form includes the feed buttons, so
+               # emptyfeeds cannot be hidden.
+               $emptyfeeds=1;
        }
-       elsif ($feeds && !$params{preview}) {
+       elsif ($feeds && !$params{preview} && ($emptyfeeds || @feedlist)) {
                # Add feed buttons.
                my $linktemplate=template("feedlink.tmpl", blind_cache => 1);
                $linktemplate->param(rssurl => $rssurl) if $rss;
@@ -298,7 +331,7 @@ sub preprocess_inline (@) { #{{{
                require HTML::Template;
                my @params=IkiWiki::template_params($params{template}.".tmpl", blind_cache => 1);
                if (! @params) {
-                       return sprintf(gettext("nonexistant template %s"), $params{template});
+                       error sprintf(gettext("nonexistant template %s"), $params{template});
                }
                my $template=HTML::Template->new(@params) unless $raw;
        
@@ -314,6 +347,7 @@ sub preprocess_inline (@) { #{{{
                                        $template->param(content => $content);
                                }
                                $template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
+                               $template->param(inlinepage => $page);
                                $template->param(title => pagetitle(basename($page)));
                                $template->param(ctime => displaytime($pagectime{$page}, $params{timeformat}));
                                $template->param(mtime => displaytime($pagemtime{$page}, $params{timeformat}));
@@ -363,30 +397,26 @@ sub preprocess_inline (@) { #{{{
                }
        }
        
-       if ($feeds) {
-               if (exists $params{feedpages}) {
-                       @feedlist=grep { pagespec_match($_, $params{feedpages}, location => $params{page}) } @feedlist;
-               }
-       
+       if ($feeds && ($emptyfeeds || @feedlist)) {
                if ($rss) {
-                       my $rssp=rsspage($params{destpage}).$feednum;
+                       my $rssp=$feedbase."rss".$feednum;
                        will_render($params{destpage}, $rssp);
                        if (! $params{preview}) {
                                writefile($rssp, $config{destdir},
                                        genfeed("rss",
                                                $config{url}."/".$rssp, $desc, $params{guid}, $params{destpage}, @feedlist));
                                $toping{$params{destpage}}=1 unless $config{rebuild};
-                               $feedlinks{$params{destpage}}=qq{<link rel="alternate" type="application/rss+xml" title="$desc (RSS)" href="$rssurl" />};
+                               $feedlinks{$params{destpage}}.=qq{<link rel="alternate" type="application/rss+xml" title="$desc (RSS)" href="$rssurl" />};
                        }
                }
                if ($atom) {
-                       my $atomp=atompage($params{destpage}).$feednum;
+                       my $atomp=$feedbase."atom".$feednum;
                        will_render($params{destpage}, $atomp);
                        if (! $params{preview}) {
                                writefile($atomp, $config{destdir},
                                        genfeed("atom", $config{url}."/".$atomp, $desc, $params{guid}, $params{destpage}, @feedlist));
                                $toping{$params{destpage}}=1 unless $config{rebuild};
-                               $feedlinks{$params{destpage}}=qq{<link rel="alternate" type="application/atom+xml" title="$desc (Atom)" href="$atomurl" />};
+                               $feedlinks{$params{destpage}}.=qq{<link rel="alternate" type="application/atom+xml" title="$desc (Atom)" href="$atomurl" />};
                        }
                }
        }
@@ -394,18 +424,18 @@ sub preprocess_inline (@) { #{{{
        return $ret if $raw || $nested;
        push @inline, $ret;
        return "<div class=\"inline\" id=\"$#inline\"></div>\n\n";
-} #}}}
+}
 
-sub pagetemplate_inline (@) { #{{{
+sub pagetemplate_inline (@) {
        my %params=@_;
        my $page=$params{page};
        my $template=$params{template};
 
        $template->param(feedlinks => $feedlinks{$page})
                if exists $feedlinks{$page} && $template->query(name => "feedlinks");
-} #}}}
+}
 
-sub get_inline_content ($$) { #{{{
+sub get_inline_content ($$) {
        my $page=shift;
        my $destpage=shift;
        
@@ -424,9 +454,9 @@ sub get_inline_content ($$) { #{{{
        else {
                return "";
        }
-} #}}}
+}
 
-sub date_822 ($) { #{{{
+sub date_822 ($) {
        my $time=shift;
 
        my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
@@ -434,9 +464,9 @@ sub date_822 ($) { #{{{
        my $ret=POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time));
        POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
        return $ret;
-} #}}}
+}
 
-sub date_3339 ($) { #{{{
+sub date_3339 ($) {
        my $time=shift;
 
        my $lc_time=POSIX::setlocale(&POSIX::LC_TIME);
@@ -444,9 +474,9 @@ sub date_3339 ($) { #{{{
        my $ret=POSIX::strftime("%Y-%m-%dT%H:%M:%SZ", gmtime($time));
        POSIX::setlocale(&POSIX::LC_TIME, $lc_time);
        return $ret;
-} #}}}
+}
 
-sub absolute_urls ($$) { #{{{
+sub absolute_urls ($$) {
        # sucky sub because rss sucks
        my $content=shift;
        my $baseurl=shift;
@@ -467,17 +497,9 @@ sub absolute_urls ($$) { #{{{
        $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;
-} #}}}
-
-sub rsspage ($) { #{{{
-       return targetpage(shift, "rss");
-} #}}}
-
-sub atompage ($) { #{{{
-       return targetpage(shift, "atom");
-} #}}}
+}
 
-sub genfeed ($$$$$@) { #{{{
+sub genfeed ($$$$$@) {
        my $feedtype=shift;
        my $feedurl=shift;
        my $feeddesc=shift;
@@ -504,9 +526,15 @@ sub genfeed ($$$$$@) { #{{{
                        mdate_3339 => date_3339($pagemtime{$p}),
                );
 
-               if (exists $pagestate{$p} &&
-                   exists $pagestate{$p}{meta}{guid}) {
-                       $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+               if (exists $pagestate{$p}) {
+                       if (exists $pagestate{$p}{meta}{guid}) {
+                               $itemtemplate->param(guid => $pagestate{$p}{meta}{guid});
+                       }
+
+                       if (exists $pagestate{$p}{meta}{updated}) {
+                               $itemtemplate->param(mdate_822 => date_822($pagestate{$p}{meta}{updated}));
+                               $itemtemplate->param(mdate_3339 => date_3339($pagestate{$p}{meta}{updated}));
+                       }
                }
 
                if ($itemtemplate->query(name => "enclosure")) {
@@ -562,9 +590,9 @@ sub genfeed ($$$$$@) { #{{{
        });
        
        return $template->output;
-} #}}}
+}
 
-sub pingurl (@) { #{{{
+sub pingurl (@) {
        return unless @{$config{pingurl}} && %toping;
 
        eval q{require RPC::XML::Client};
@@ -610,6 +638,6 @@ sub pingurl (@) { #{{{
        }
 
        exit 0; # daemon done
-} #}}}
+}
 
 1
index 0638d4bddd0b1d82bd54714601f80d9582d18918..b79273f96240dcfc0a66308bb3a942f6198945f0 100644 (file)
@@ -3,27 +3,27 @@ package IkiWiki::Plugin::link;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my $link_regexp;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "link", call => \&getsetup);
        hook(type => "checkconfig", id => "link", call => \&checkconfig);
        hook(type => "linkify", id => "link", call => \&linkify);
        hook(type => "scan", id => "link", call => \&scan);
        hook(type => "renamepage", id => "link", call => \&renamepage);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if ($config{prefix_directives}) {
                $link_regexp = qr{
                        \[\[(?=[^!])            # beginning of link
@@ -58,9 +58,9 @@ sub checkconfig () { #{{{
                        \]\]                    # end of link
                }x,
        }
-} #}}}
+}
 
-sub linkify (@) { #{{{
+sub linkify (@) {
        my %params=@_;
        my $page=$params{page};
        my $destpage=$params{destpage};
@@ -78,9 +78,9 @@ sub linkify (@) { #{{{
        }eg;
        
        return $params{content};
-} #}}}
+}
 
-sub scan (@) { #{{{
+sub scan (@) {
        my %params=@_;
        my $page=$params{page};
        my $content=$params{content};
@@ -88,9 +88,9 @@ sub scan (@) { #{{{
        while ($content =~ /(?<!\\)$link_regexp/g) {
                push @{$links{$page}}, linkpage($2);
        }
-} # }}}
+}
 
-sub renamepage (@) { #{{{
+sub renamepage (@) {
        my %params=@_;
        my $page=$params{page};
        my $old=$params{oldpage};
@@ -118,6 +118,6 @@ sub renamepage (@) { #{{{
        }eg;
 
        return $params{content};
-} #}}}
+}
 
 1
index 81ee665c8c5513cc5a1acdcf16a93028ad9bb141..941ed5f3672145bb6111c5a6650fb14431641297 100644 (file)
@@ -3,27 +3,27 @@ package IkiWiki::Plugin::linkmap;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use IPC::Open2;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "linkmap", call => \&getsetup);
        hook(type => "preprocess", id => "linkmap", call => \&preprocess);
        hook(type => "format", id => "linkmap", call => \&format);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
 my $mapnum=0;
 my %maps;
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        $params{pages}="*" unless defined $params{pages};
@@ -39,17 +39,17 @@ sub preprocess (@) { #{{{
        $mapnum++;
        $maps{$mapnum}=\%params;
        return "<div class=\"linkmap$mapnum\"></div>";
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
         my %params=@_;
 
        $params{content}=~s/<div class=\"linkmap(\d+)"><\/div>/genmap($1)/eg;
 
         return $params{content};
-} # }}}
+}
 
-sub genmap ($) { #{{{
+sub genmap ($) {
        my $mapnum=shift;
        return "" unless exists $maps{$mapnum};
        my %params=%{$maps{$mapnum}};
@@ -106,6 +106,6 @@ sub genmap ($) { #{{{
        error gettext("failed to run dot") if $sigpipe;
 
        return $ret;
-} #}}}
+}
 
 1
index fc8927ccb6ca4dca305b013077c1bb8a34cb3561..d2cebca342756fdbb8d9a31e34b43fe527bd4b4d 100644 (file)
@@ -4,17 +4,17 @@ package IkiWiki::Plugin::listdirectives;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        add_underlay("directives");
        hook(type => "getsetup", id => "listdirectives", call => \&getsetup);
        hook(type => "checkconfig", id => "listdirectives", call => \&checkconfig);
        hook(type => "needsbuild", id => "listdirectives", call => \&needsbuild);
        hook(type => "preprocess", id => "listdirectives", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -27,28 +27,27 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
 my @fulllist;
-my @earlylist;
+my @shortlist;
 my $pluginstring;
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! defined $config{directive_description_dir}) {
                $config{directive_description_dir} = "ikiwiki/directive";
        }
        else {
                $config{directive_description_dir} =~ s/\/+$//;
        }
+}
 
-       @earlylist = sort keys %{$IkiWiki::hooks{preprocess}};
-} #}}}
-
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
 
        @fulllist = sort keys %{$IkiWiki::hooks{preprocess}};
-       $pluginstring = join(' ', @earlylist) . " : " . join(' ', @fulllist);
+       @shortlist = grep { ! $IkiWiki::hooks{preprocess}{$_}{shortcut} } @fulllist;
+       $pluginstring = join(' ', @shortlist) . " : " . join(' ', @fulllist);
 
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{listdirectives}{shown}) {
@@ -64,9 +63,9 @@ sub needsbuild (@) { #{{{
                        }
                }
        }
-} # }}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        
        $pagestate{$params{destpage}}{listdirectives}{shown}=$pluginstring;
@@ -77,7 +76,7 @@ sub preprocess (@) { #{{{
                @pluginlist = @fulllist;
        }
        else {
-               @pluginlist = @earlylist;
+               @pluginlist = @shortlist;
        }
        
        my $result = '<ul class="listdirectives">';
@@ -93,6 +92,6 @@ sub preprocess (@) { #{{{
        $result .= "</ul>";
 
        return $result;
-} # }}}
+}
 
 1
index f6cac6cdd8c69b520824c2557d14d9a9ea3d5fdc..0fa329251f0b7eb5e6814e50f68d020eaf047eb8 100644 (file)
@@ -3,16 +3,14 @@ package IkiWiki::Plugin::lockedit;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "lockedit", call => \&getsetup);
        hook(type => "canedit", id => "lockedit", call => \&canedit);
-       hook(type => "formbuilder_setup", id => "lockedit",
-            call => \&formbuilder_setup);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -26,9 +24,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub canedit ($$) { #{{{
+sub canedit ($$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
@@ -52,63 +50,7 @@ sub canedit ($$) { #{{{
                }
        }
 
-       # XXX deprecated, should be removed eventually
-       foreach my $admin (@{$config{adminuser}}) {
-               if (pagespec_match($page, IkiWiki::userinfo_get($admin, "locked_pages"),
-                   user => $session->param("name"),
-                   ip => $ENV{REMOTE_ADDR},
-               )) {
-                       if (! defined $user ||
-                           ! IkiWiki::userinfo_get($session->param("name"), "regdate")) {
-                               return sub { IkiWiki::needsignin($cgi, $session) };
-                       }
-                       else {
-                               return sprintf(gettext("%s is locked and cannot be edited"),
-                                       htmllink("", "", $page, noimageinline => 1));
-                       }
-               }
-       }
-
        return undef;
-} #}}}
-
-sub formbuilder_setup (@) { #{{{
-       my %params=@_;
-
-       # XXX deprecated, should be removed eventually  
-       my $form=$params{form};
-       if ($form->title eq "preferences") {
-               my $session=$params{session};
-               my $cgi=$params{cgi};
-               my $user_name=$session->param("name");
-
-               $form->field(name => "locked_pages", size => 50,
-                       fieldset => "admin",
-                       comment => "deprecated; please move to locked_pages in setup file"
-               );
-               if (! IkiWiki::is_admin($user_name)) {
-                       $form->field(name => "locked_pages", type => "hidden");
-               }
-               if (! $form->submitted) {
-                       my $value=IkiWiki::userinfo_get($user_name, "locked_pages");
-                       if (length $value) {
-                               $form->field(name => "locked_pages", force => 1, value => $value);
-                       }
-                       else {
-                               $form->field(name => "locked_pages", type => "hidden");
-                       }
-               }
-               if ($form->submitted && $form->submitted eq 'Save Preferences') {
-                       if (defined $form->field("locked_pages")) {
-                               IkiWiki::userinfo_set($user_name, "locked_pages",
-                                       $form->field("locked_pages")) ||
-                                               error("failed to set locked_pages");
-                               if (! length $form->field("locked_pages")) {
-                                       $form->field(name => "locked_pages", type => "hidden");
-                               }
-                       }
-               }
-       }
-} #}}}
+}
 
 1
index 18c584a30ccba43f0fab289392c18987422ac8db..328493116e42e29125aca0353062886588e38e5f 100644 (file)
@@ -9,22 +9,22 @@ package IkiWiki::Plugin::map;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "map", call => \&getsetup);
        hook(type => "preprocess", id => "map", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
@@ -144,6 +144,6 @@ sub preprocess (@) { #{{{
        }
        $map .= "</div>\n";
        return $map;
-} # }}}
+}
 
 1
index 6c1d2ef3c3839ed95d73284292a59e1541995907..0e134c8224f470c6cc101e0b14e6106c44a541e6 100644 (file)
@@ -4,14 +4,14 @@ package IkiWiki::Plugin::mdwn;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "mdwn", call => \&getsetup);
        hook(type => "htmlize", id => "mdwn", call => \&htmlize);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -24,10 +24,10 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
 my $markdown_sub;
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        my $content = $params{content};
 
@@ -83,6 +83,6 @@ sub htmlize (@) { #{{{
        $content=Encode::decode_utf8($content);
 
        return $content;
-} # }}}
+}
 
 1
index 7aceebcdb4821ba46929df6b3245e93fa4365fe6..11fdec529373c6b430a8e77bebb2c0a3aa6972b7 100644 (file)
@@ -7,7 +7,7 @@ use IkiWiki;
 use Encode;
 use open qw{:utf8 :std};
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "mercurial", call => \&checkconfig);
        hook(type => "getsetup", id => "mercurial", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -20,18 +20,18 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (exists $config{mercurial_wrapper} && length $config{mercurial_wrapper}) {
                push @{$config{wrappers}}, {
                        wrapper => $config{mercurial_wrapper},
                        wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -65,9 +65,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub mercurial_log ($) { #{{{
+sub mercurial_log ($) {
        my $out = shift;
        my @infos;
 
@@ -111,20 +111,20 @@ sub mercurial_log ($) { #{{{
        close $out;
 
        return @infos;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update");
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        return "";
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
 
        if (defined $user) {
@@ -149,7 +149,7 @@ sub rcs_commit ($$$;$$) { #{{{
        }
 
        return undef; # success
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -159,28 +159,28 @@ sub rcs_commit_staged ($$$) {
        error("rcs_commit_staged not implemented for mercurial"); # TODO
 }
 
-sub rcs_add ($) { # {{{
+sub rcs_add ($) {
        my ($file) = @_;
 
        my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file");
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
        }
-} #}}}
+}
 
-sub rcs_remove ($) { # {{{
+sub rcs_remove ($) {
        my ($file) = @_;
 
        error("rcs_remove not implemented for mercurial"); # TODO
-} #}}}
+}
 
-sub rcs_rename ($$) { # {{{
+sub rcs_rename ($$) {
        my ($src, $dest) = @_;
 
        error("rcs_rename not implemented for mercurial"); # TODO
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        my ($num) = @_;
 
        my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num,
@@ -217,7 +217,7 @@ sub rcs_recentchanges ($) { #{{{
                push @ret, {
                        rev        => $info->{"changeset"},
                        user       => $user,
-                       committype => "mercurial",
+                       committype => "hg",
                        when       => str2time($info->{"date"}),
                        message    => [@message],
                        pages      => [@pages],
@@ -225,18 +225,18 @@ sub rcs_recentchanges ($) { #{{{
        }
 
        return @ret;
-} #}}}
+}
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        # TODO
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        my ($file) = @_;
 
        # XXX filename passes through the shell here, should try to avoid
        # that just in case
-       my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", '1', 
+       my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v",
                "--style", "default", "$config{srcdir}/$file");
        open (my $out, "@cmdline |");
 
@@ -249,8 +249,8 @@ sub rcs_getctime ($) { #{{{
        eval q{use Date::Parse};
        error($@) if $@;
        
-       my $ctime = str2time($log[0]->{"date"});
+       my $ctime = str2time($log[$#log]->{"date"});
        return $ctime;
-} #}}}
+}
 
 1
index 8d444109f68dc304d6c055df1191b3efbc2b9b60..4a22fed3057015156c27d9f8159e9f4b47e3a633 100644 (file)
@@ -4,26 +4,26 @@ package IkiWiki::Plugin::meta;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %metaheaders;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "meta", call => \&getsetup);
        hook(type => "needsbuild", id => "meta", call => \&needsbuild);
        hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
        hook(type => "pagetemplate", id => "meta", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{meta}) {
@@ -38,16 +38,17 @@ sub needsbuild (@) { #{{{
        }
 }
 
-sub scrub ($) { #{{{
+sub scrub ($$) {
        if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
-               return IkiWiki::Plugin::htmlscrubber::sanitize(content => shift);
+               return IkiWiki::Plugin::htmlscrubber::sanitize(
+                       content => shift, destpage => shift);
        }
        else {
                return shift;
        }
-} #}}}
+}
 
-sub safeurl ($) { #{{{
+sub safeurl ($) {
        my $url=shift;
        if (exists $IkiWiki::Plugin::htmlscrubber::{safe_url_regexp} &&
            defined $IkiWiki::Plugin::htmlscrubber::safe_url_regexp) {
@@ -56,9 +57,9 @@ sub safeurl ($) { #{{{
        else {
                return 1;
        }
-} #}}}
+}
 
-sub htmlize ($$$) { #{{{
+sub htmlize ($$$) {
        my $page = shift;
        my $destpage = shift;
 
@@ -67,7 +68,7 @@ sub htmlize ($$$) { #{{{
                IkiWiki::preprocess($page, $destpage, shift)));
 }
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        return "" unless @_;
        my %params=@_;
        my $key=shift;
@@ -120,6 +121,20 @@ sub preprocess (@) { #{{{
                $pagestate{$page}{meta}{authorurl}=$value if safeurl($value);
                # fallthrough
        }
+       elsif ($key eq 'date') {
+               eval q{use Date::Parse};
+               if (! $@) {
+                       my $time = str2time($value);
+                       $IkiWiki::pagectime{$page}=$time if defined $time;
+               }
+       }
+       elsif ($key eq 'updated') {
+               eval q{use Date::Parse};
+               if (! $@) {
+                       my $time = str2time($value);
+                       $pagestate{$page}{meta}{updated}=$time if defined $time;
+               }
+       }
 
        if (! defined wantarray) {
                # avoid collecting duplicate data during scan pass
@@ -127,17 +142,10 @@ sub preprocess (@) { #{{{
        }
 
        # Metadata collection that happens only during preprocessing pass.
-       if ($key eq 'date') {
-               eval q{use Date::Parse};
-               if (! $@) {
-                       my $time = str2time($value);
-                       $IkiWiki::pagectime{$page}=$time if defined $time;
-               }
-       }
-       elsif ($key eq 'permalink') {
+       if ($key eq 'permalink') {
                if (safeurl($value)) {
                        $pagestate{$page}{meta}{permalink}=$value;
-                       push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
+                       push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />', $destpage);
                }
        }
        elsif ($key eq 'stylesheet') {
@@ -206,7 +214,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);
+                       $redir=scrub($redir, $destpage);
                }
                push @{$metaheaders{$page}}, $redir;
        }
@@ -216,7 +224,7 @@ sub preprocess (@) { #{{{
                                join(" ", map {
                                        encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
                                } keys %params).
-                               " />\n");
+                               " />\n", $destpage);
                }
        }
        elsif ($key eq 'robots') {
@@ -225,13 +233,13 @@ sub preprocess (@) { #{{{
        }
        else {
                push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key).
-                       '" content="'.encode_entities($value).'" />');
+                       '" content="'.encode_entities($value).'" />', $destpage);
        }
 
        return "";
-} # }}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
         my $page=$params{page};
         my $destpage=$params{destpage};
@@ -259,9 +267,9 @@ sub pagetemplate (@) { #{{{
                        $template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field}));
                }
        }
-} # }}}
+}
 
-sub match { #{{{
+sub match {
        my $field=shift;
        my $page=shift;
        
@@ -287,28 +295,28 @@ sub match { #{{{
        else {
                return IkiWiki::FailReason->new("$page does not have a $field");
        }
-} #}}}
+}
 
 package IkiWiki::PageSpec;
 
-sub match_title ($$;@) { #{{{
+sub match_title ($$;@) {
        IkiWiki::Plugin::meta::match("title", @_);      
-} #}}}
+}
 
-sub match_author ($$;@) { #{{{
+sub match_author ($$;@) {
        IkiWiki::Plugin::meta::match("author", @_);
-} #}}}
+}
 
-sub match_authorurl ($$;@) { #{{{
+sub match_authorurl ($$;@) {
        IkiWiki::Plugin::meta::match("authorurl", @_);
-} #}}}
+}
 
-sub match_license ($$;@) { #{{{
+sub match_license ($$;@) {
        IkiWiki::Plugin::meta::match("license", @_);
-} #}}}
+}
 
-sub match_copyright ($$;@) { #{{{
+sub match_copyright ($$;@) {
        IkiWiki::Plugin::meta::match("copyright", @_);
-} #}}}
+}
 
 1
index aab60c435d271d60568f6824bcbfe684e3853ac6..737dcf767379e69819bc71c4f7d02800be5b62f6 100644 (file)
@@ -3,14 +3,14 @@ package IkiWiki::Plugin::mirrorlist;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "mirrorlist", call => \&getsetup);
        hook(type => "pagetemplate", id => "mirrorlist", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -23,9 +23,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
         my $template=$params{template};
        
@@ -34,9 +34,9 @@ sub pagetemplate (@) { #{{{
                $value.=mirrorlist($params{page});
                $template->param(extrafooter => $value);
        }
-} # }}}
+}
 
-sub mirrorlist ($) { #{{{
+sub mirrorlist ($) {
        my $page=shift;
        return "<p>".
                (keys %{$config{mirrorlist}} > 1 ? gettext("Mirrors") : gettext("Mirror")).
@@ -49,6 +49,6 @@ sub mirrorlist ($) { #{{{
                        } keys %{$config{mirrorlist}}
                ).
                "</p>";
-} # }}}
+}
 
 1
index f31a8606bb4f664b6d626c345e668bf4e884dda3..bdb564a71c30befd8d219e0796d58e5d52b7dcb3 100644 (file)
@@ -10,7 +10,7 @@ use Date::Format qw(time2str);
 
 my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate sha1sums
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "monotone", call => \&checkconfig);
        hook(type => "getsetup", id => "monotone", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -23,9 +23,9 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (!defined($config{mtnrootdir})) {
                $config{mtnrootdir} = $config{srcdir};
        }
@@ -61,9 +61,9 @@ sub checkconfig () { #{{{
                        wrappermode => (defined $config{mtn_wrappermode} ? $config{mtn_wrappermode} : "06755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -117,9 +117,9 @@ sub getsetup () { #{{{
                        safe => 0, # path
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub get_rev () { #{{{
+sub get_rev () {
        my $sha1 = `mtn --root=$config{mtnrootdir} automate get_base_revision_id`;
 
        ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
@@ -128,9 +128,9 @@ sub get_rev () { #{{{
        }
 
        return $sha1;
-} #}}}
+}
 
-sub get_rev_auto ($) { #{{{
+sub get_rev_auto ($) {
        my $automator=shift;
 
        my @results = $automator->call("get_base_revision_id");
@@ -142,9 +142,9 @@ sub get_rev_auto ($) { #{{{
        }
 
        return $sha1;
-} #}}}
+}
 
-sub mtn_merge ($$$$) { #{{{
+sub mtn_merge ($$$$) {
        my $leftRev=shift;
        my $rightRev=shift;
        my $branch=shift;
@@ -172,9 +172,9 @@ sub mtn_merge ($$$$) { #{{{
        debug("merged $leftRev, $rightRev to make $mergeRev");
 
        return $mergeRev;
-} #}}}
+}
 
-sub commit_file_to_new_rev ($$$$$$$$) { #{{{
+sub commit_file_to_new_rev ($$$$$$$$) {
        my $automator=shift;
        my $wsfilename=shift;
        my $oldFileID=shift;
@@ -219,9 +219,9 @@ sub commit_file_to_new_rev ($$$$$$$$) { #{{{
        
        debug("Added certs for rev: $newRevID");
        return $newRevID;
-} #}}}
+}
 
-sub read_certs ($$) { #{{{
+sub read_certs ($$) {
        my $automator=shift;
        my $rev=shift;
        my @results = $automator->call("certs", $rev);
@@ -239,9 +239,9 @@ sub read_certs ($$) { #{{{
        }
 
        return @ret;
-} #}}}
+}
 
-sub get_changed_files ($$) { #{{{
+sub get_changed_files ($$) {
        my $automator=shift;
        my $rev=shift;
        
@@ -261,9 +261,9 @@ sub get_changed_files ($$) { #{{{
        }
        
        return @ret;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        chdir $config{srcdir}
            or error("Cannot chdir to $config{srcdir}: $!");
 
@@ -278,9 +278,9 @@ sub rcs_update () { #{{{
        if (system("mtn", "--root=$config{mtnrootdir}", "update", "--quiet") != 0) {
                debug("monotone update failed");
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        my $file=shift;
 
        chdir $config{srcdir}
@@ -289,9 +289,9 @@ sub rcs_prepedit ($) { #{{{
        # For monotone, return the revision of the file when
        # editing begins.
        return get_rev();
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        # Tries to commit the page; returns undef on _success_ and
        # a version of the page with the rcs's conflict markers on failure.
        # The file is relative to the srcdir.
@@ -434,7 +434,7 @@ sub rcs_commit ($$$;$$) { #{{{
        }
 
        return undef # success
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -466,7 +466,7 @@ sub rcs_commit_staged ($$$) {
        }
 }
 
-sub rcs_add ($) { #{{{
+sub rcs_add ($) {
        my $file=shift;
 
        chdir $config{srcdir}
@@ -476,9 +476,9 @@ sub rcs_add ($) { #{{{
                   $file) != 0) {
                error("Monotone add failed");
        }
-} #}}}
+}
 
-sub rcs_remove ($) { # {{{
+sub rcs_remove ($) {
        my $file = shift;
 
        chdir $config{srcdir}
@@ -495,9 +495,9 @@ sub rcs_remove ($) { # {{{
                   $file) != 0) {
                error("Monotone remove failed");
        }
-} #}}}
+}
 
-sub rcs_rename ($$) { # {{{
+sub rcs_rename ($$) {
        my ($src, $dest) = @_;
 
        chdir $config{srcdir}
@@ -507,9 +507,9 @@ sub rcs_rename ($$) { # {{{
                   $src, $dest) != 0) {
                error("Monotone rename failed");
        }
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        my $num=shift;
        my @ret;
 
@@ -525,13 +525,12 @@ sub rcs_recentchanges ($) { #{{{
        my $child = open(MTNLOG, "-|");
        if (! $child) {
                exec("mtn", "log", "--root=$config{mtnrootdir}", "--no-graph",
-                    "--brief") || error("mtn log failed to run");
+                    "--brief", "--last=$num") || error("mtn log failed to run");
        }
 
-       while (($num >= 0) and (my $line = <MTNLOG>)) {
+       while (my $line = <MTNLOG>) {
                if ($line =~ m/^($sha1_pattern)/) {
                        push @revs, $1;
-                       $num -= 1;
                }
        }
        close MTNLOG || debug("mtn log exited $?");
@@ -560,7 +559,7 @@ sub rcs_recentchanges ($) { #{{{
                                        if ($cert->{key} eq $config{mtnkey}) {
                                                $committype = "web";
                                        } else {
-                                               $committype = "monotone";
+                                               $committype = "mtn";
                                        }
                                } elsif ($cert->{name} eq "date") {
                                        $when = str2time($cert->{value}, 'UTC');
@@ -615,9 +614,9 @@ sub rcs_recentchanges ($) { #{{{
        $automator->close();
 
        return @ret;
-} #}}}
+}
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        my $rev=shift;
        my ($sha1) = $rev =~ /^($sha1_pattern)$/; # untaint
        
@@ -639,9 +638,9 @@ sub rcs_diff ($) { #{{{
        else {
                return join("", @lines);
        }
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        my $file=shift;
 
        chdir $config{srcdir}
@@ -691,6 +690,6 @@ sub rcs_getctime ($) { #{{{
        $date=str2time($date, 'UTC');
        debug("found ctime ".localtime($date)." for $file");
        return $date;
-} #}}}
+}
 
 1
index 4484441c37e3fe9338cb5ab96512913da7201032..77d5fb0772846dde323fd78a809f936365224fa5 100644 (file)
@@ -3,24 +3,24 @@ package IkiWiki::Plugin::more;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my $linktext = gettext("more");
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "more", call => \&getsetup);
        hook(type => "preprocess", id => "more", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        $params{linktext} = $linktext unless defined $params{linktext};
index 58c26b63350b5ccc1540d7815ee78d0e8f2ab7cc..bfe84c0e1ebc15961986ce57a59be9fc26c53290 100644 (file)
@@ -6,7 +6,7 @@ use warnings;
 use strict;
 use IkiWiki;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "norcs", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
        hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
@@ -18,51 +18,51 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => 0,
                },
-} #}}}
+}
 
 
-sub rcs_update () { #{{{
-} #}}}
+sub rcs_update () {
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        return ""
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
        return undef # success
-} #}}}
+}
 
-sub rcs_commit_staged ($$$) { #{{{
+sub rcs_commit_staged ($$$) {
        my ($message, $user, $ipaddr)=@_;
        return undef # success
-} #}}}
+}
 
-sub rcs_add ($) { #{{{
-} #}}}
+sub rcs_add ($) {
+}
 
-sub rcs_remove ($) { #{{{
-} #}}}
+sub rcs_remove ($) {
+}
 
-sub rcs_rename ($$) { #{{{
-} #}}}
+sub rcs_rename ($$) {
+}
 
-sub rcs_recentchanges ($) { #{{{
-} #}}}
+sub rcs_recentchanges ($) {
+}
 
-sub rcs_diff ($) { #{{{
-} #}}}
+sub rcs_diff ($) {
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        error gettext("getctime not implemented");
-} #}}}
+}
 
 1
index 96a74aee832d31af0fd653a851f95b2044a56ded..3da01efee154988d1432d0ed54680525569e224c 100644 (file)
@@ -3,22 +3,22 @@ package IkiWiki::Plugin::opendiscussion;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "opendiscussion", call => \&getsetup);
        hook(type => "canedit", id => "opendiscussion", call => \&canedit);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub canedit ($$) { #{{{
+sub canedit ($$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
@@ -26,6 +26,6 @@ sub canedit ($$) { #{{{
        my $discussion=gettext("discussion");
        return "" if $page=~/(\/|^)\Q$discussion\E$/;
        return undef;
-} #}}}
+}
 
 1
index f12cbdaa37fad0c77ada865a521ff68a0d95e785..5424c57e2c6f8e8093eb56d1aba6aee696a05b39 100644 (file)
@@ -4,24 +4,24 @@ package IkiWiki::Plugin::openid;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "openid", call => \&getopt);
        hook(type => "getsetup", id => "openid", call => \&getsetup);
        hook(type => "auth", id => "openid", call => \&auth);
        hook(type => "formbuilder_setup", id => "openid",
                call => \&formbuilder_setup, last => 1);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
        eval q{use Getopt::Long};
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
        GetOptions("openidsignup=s" => \$config{openidsignup});
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -34,9 +34,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
 
        my $form=$params{form};
@@ -92,7 +92,7 @@ sub formbuilder_setup (@) { #{{{
        }
 }
 
-sub validate ($$$;$) { #{{{
+sub validate ($$$;$) {
        my $q=shift;
        my $session=shift;
        my $openid_url=shift;
@@ -121,9 +121,9 @@ sub validate ($$$;$) { #{{{
        # eventually bounce them back to auth()
        IkiWiki::redirect($q, $check_url);
        exit 0;
-} #}}}
+}
 
-sub auth ($$) { #{{{
+sub auth ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -147,9 +147,9 @@ sub auth ($$) { #{{{
                # myopenid.com affiliate support
                validate($q, $session, $q->param('openid_identifier'));
        }
-} #}}}
+}
 
-sub getobj ($$) { #{{{
+sub getobj ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -178,26 +178,28 @@ sub getobj ($$) { #{{{
                consumer_secret => sub { return shift()+$secret },
                required_root => $config{cgiurl},
        );
-} #}}}
+}
 
 package IkiWiki;
 
 # This is not used by this plugin, but this seems the best place to put it.
 # Used elsewhere to pretty-display the name of an openid user.
-sub openiduser ($) { #{{{
+sub openiduser ($) {
        my $user=shift;
 
        if ($user =~ m!^https?://! &&
            eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) {
                my $oid=Net::OpenID::VerifiedIdentity->new(identity => $user);
                my $display=$oid->display;
-               # Convert "user.somehost.com" to "user [somehost.com]".
+               # Convert "user.somehost.com" to "user [somehost.com]"
+               # (also "user.somehost.co.uk")
                if ($display !~ /\[/) {
-                       $display=~s/^(.*?)\.([^.]+\.[a-z]+)$/$1 [$2]/;
+                       $display=~s/^([-a-zA-Z0-9]+?)\.([-.a-zA-Z0-9]+\.[a-z]+)$/$1 [$2]/;
                }
                # Convert "http://somehost.com/user" to "user [somehost.com]".
+               # (also "https://somehost.com/user/")
                if ($display !~ /\[/) {
-                       $display=~s/^https?:\/\/(.+)\/([^\/]+)$/$2 [$1]/;
+                       $display=~s/^https?:\/\/(.+)\/([^\/]+)\/?$/$2 [$1]/;
                }
                $display=~s!^https?://!!; # make sure this is removed
                eval q{use CGI 'escapeHTML'};
index 32cbc5dd5508d3df58945ebef75a80704034c7ad..605e6e43ada79398afe07d1c7c07393612eeca6d 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::orphans;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "orphans", call => \&getsetup);
        hook(type => "preprocess", id => "orphans", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
@@ -58,6 +58,6 @@ sub preprocess (@) { #{{{
                                "</li>"
                        } sort @orphans).
                "</ul>\n";
-} # }}}
+}
 
 1
index ef76d621549d44dd575fda54dfa1760bb5c4febd..c68fcbbe358762127411faec18840070f5bf8bd1 100644 (file)
@@ -4,25 +4,25 @@ package IkiWiki::Plugin::otl;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use open qw{:utf8 :std};
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "otl", call => \&getsetup);
        hook(type => "filter", id => "otl", call => \&filter);
        hook(type => "htmlize", id => "otl", call => \&htmlize);
 
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
-sub filter (@) { #{{{
+sub filter (@) {
        my %params=@_;
         
        # Munge up check boxes to look a little bit better. This is a hack.
@@ -34,9 +34,9 @@ sub filter (@) { #{{{
        $params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg;
         
        return $params{content};
-} # }}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
 
        # Can't use open2 since otl2html doesn't play nice with buffering.
@@ -95,6 +95,6 @@ sub htmlize (@) { #{{{
        $ret=~s/<body>.*//s;
        $ret=~s/<div class="Footer">.*//s;
        return $ret;
-} # }}}
+}
 
 1
index e059fa61850c531083a7cfb743597ea2691f3be2..a143f24d089d3ff0d405fd0c6f1544558375600c 100644 (file)
@@ -3,22 +3,22 @@ package IkiWiki::Plugin::pagecount;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "pagecount", call => \&getsetup);
        hook(type => "preprocess", id => "pagecount", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
@@ -33,6 +33,6 @@ sub preprocess (@) { #{{{
                $count++ if pagespec_match($page, $params{pages}, location => $params{page});
        }
        return $count;
-} # }}}
+}
 
 1
index de4b7d0686f5867a3477873b88a9d6d7074d799f..dbe69539d72311d8b43c752c9ae33ebe8017a763 100644 (file)
@@ -12,25 +12,25 @@ package IkiWiki::Plugin::pagestats;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 # Names of the HTML classes to use for the tag cloud
 our @classes = ('smallestPC', 'smallPC', 'normalPC', 'bigPC', 'biggestPC' );
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "pagestats", call => \&getsetup);
        hook(type => "preprocess", id => "pagestats", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        my $style = ($params{style} or 'cloud');
@@ -73,6 +73,6 @@ sub preprocess (@) { #{{{
 
                return $res;
        }
-} # }}}
+}
 
 1
index 99a66ee96964f9750ab3d2d41a6ec87755cd31a0..1d8a84ca77726d5d8486fc632b2606b98e25b5f6 100644 (file)
@@ -3,25 +3,25 @@ package IkiWiki::Plugin::pagetemplate;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %templates;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "pagetemplate", call => \&getsetup);
        hook(type => "preprocess", id => "pagetemplate", call => \&preprocess);
        hook(type => "templatefile", id => "pagetemplate", call => \&templatefile);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        if (! exists $params{template} ||
@@ -35,9 +35,9 @@ sub preprocess (@) { #{{{
        }
 
        return "";
-} # }}}
+}
 
-sub templatefile (@) { #{{{
+sub templatefile (@) {
        my %params=@_;
 
        if (exists $templates{$params{page}}) {
@@ -45,6 +45,6 @@ sub templatefile (@) { #{{{
        }
        
        return undef;
-} # }}}
+}
 
 1
index a8b3641e922a43e51a5d295ce64c6ad042890726..ebf1d449ae50522dac1174176810c4bd3db99799 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::parentlinks;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "parentlinks", id => "parentlinks", call => \&parentlinks);
        hook(type => "pagetemplate", id => "parentlinks", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub parentlinks ($) { #{{{
+sub parentlinks ($) {
        my $page=shift;
 
        my @ret;
@@ -48,9 +48,9 @@ sub parentlinks ($) { #{{{
                $i++;
        }
        return @ret;
-} #}}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
         my $page=$params{page};
         my $template=$params{template};
@@ -58,6 +58,6 @@ sub pagetemplate (@) { #{{{
        if ($template->query(name => "parentlinks")) {
                $template->param(parentlinks => [parentlinks($page)]);
        }
-} # }}}
+}
 
 1
index e0c0a3b0e650bd001b835c1c0cc92680af42440a..90e2ca56493767f655984973dddb80af58fd1285 100644 (file)
@@ -4,16 +4,16 @@ package IkiWiki::Plugin::passwordauth;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "passwordauth", "call" => \&getsetup);
         hook(type => "formbuilder_setup", id => "passwordauth", call => \&formbuilder_setup);
         hook(type => "formbuilder", id => "passwordauth", call => \&formbuilder);
        hook(type => "sessioncgi", id => "passwordauth", call => \&sessioncgi);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -33,10 +33,10 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
 # Checks if a string matches a user's password, and returns true or false.
-sub checkpassword ($$;$) { #{{{
+sub checkpassword ($$;$) {
        my $user=shift;
        my $password=shift;
        my $field=shift || "password";
@@ -74,9 +74,9 @@ sub checkpassword ($$;$) { #{{{
        }
 
        return $ret;
-} #}}}
+}
 
-sub setpassword ($$;$) { #{{{
+sub setpassword ($$;$) {
        my $user=shift;
        my $password=shift;
        my $field=shift || "password";
@@ -94,9 +94,9 @@ sub setpassword ($$;$) { #{{{
        else {
                IkiWiki::userinfo_set($user, $field, $password);
        }
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
 
        my $form=$params{form};
@@ -222,7 +222,7 @@ sub formbuilder_setup (@) { #{{{
        }
 }
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
 
        my $form=$params{form};
@@ -313,9 +313,9 @@ sub formbuilder (@) { #{{{
                        }
                }
        }
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -335,6 +335,6 @@ sub sessioncgi ($$) { #{{{
                IkiWiki::cgi_prefs($q, $session);
                exit;
        }
-} #}}}
+}
 
 1
index c2f21b0cfaf93cabfb562009b5db53260b8dbadf..f5386d0cae4ccb638913c9d6a7ac9a8e2a3d94af 100644 (file)
@@ -3,22 +3,22 @@ package IkiWiki::Plugin::pingee;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "pingee", call => \&getsetup);
        hook(type => "cgi", id => "pingee", call => \&cgi);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub cgi ($) { #{{{
+sub cgi ($) {
        my $cgi=shift;
 
        if (defined $cgi->param('do') && $cgi->param("do") eq "ping") {
@@ -37,6 +37,6 @@ sub cgi ($) { #{{{
                IkiWiki::saveindex();
                exit 0;
        }
-} #}}}
+}
 
 1
index 043b074a7986d8e23ac3d8f0ede649f9e289c6c9..c20ecb5d4ef3a663f5496135f56ddb5369c5dd87 100644 (file)
@@ -3,20 +3,20 @@ package IkiWiki::Plugin::pinger;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %pages;
 my $pinged=0;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "pinger", call => \&getsetup);
        hook(type => "needsbuild", id => "pinger", call => \&needsbuild);
        hook(type => "preprocess", id => "ping", call => \&preprocess);
        hook(type => "delete", id => "pinger", call => \&ping);
        hook(type => "change", id => "pinger", call => \&ping);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -29,9 +29,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{pinger}) {
@@ -45,9 +45,9 @@ sub needsbuild (@) { #{{{
                        }
                }
        }
-} # }}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        if (! exists $params{from} || ! exists $params{to}) {
                error gettext("requires 'from' and 'to' parameters");
@@ -60,7 +60,7 @@ sub preprocess (@) { #{{{
        else {
                return sprintf(gettext("Ignoring ping directive for wiki %s (this wiki is %s)"), $params{from}, $config{url});
        }
-} # }}}
+}
 
 sub ping {
        if (! $pinged && %pages) {
@@ -106,7 +106,7 @@ sub ping {
                        # will still be avoided.
                        next if $url=~/^\Q$config{cgiurl}\E/;
                        
-                       $ua->head($url);
+                       $ua->get($url);
                }
                
                exit 0;
index fadc1773e66a61758d0012991e32da66d5ae0209..bc1e3501e5e6b7c9c4a0d1568367e5d60bbf61cb 100644 (file)
@@ -3,25 +3,25 @@ package IkiWiki::Plugin::poll;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "poll", call => \&getsetup);
        hook(type => "preprocess", id => "poll", call => \&preprocess);
        hook(type => "sessioncgi", id => "poll", call => \&sessioncgi);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
 my %pagenum;
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=(open => "yes", total => "yes", percent => "yes", @_);
 
        my $open=IkiWiki::yesno($params{open});
@@ -77,9 +77,9 @@ sub preprocess (@) { #{{{
                $ret.="<span>".gettext("Total votes:")." $total</span>\n";
        }
        return "<div class=poll>$ret</div>";
-} # }}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
        my $cgi=shift;
        my $session=shift;
        if (defined $cgi->param('do') && $cgi->param('do') eq "poll") {
@@ -152,6 +152,6 @@ sub sessioncgi ($$) { #{{{
                        -url => urlto($page, undef, 1));
                exit;
        }
-} #}}}
+}
 
 1
index fa564aa86d1841fd13a7e31d0db5b105e3093e3f..bc21d71c725f892d3432dfa5ac22feb1241cfd97 100644 (file)
@@ -7,23 +7,23 @@ package IkiWiki::Plugin::polygen;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use File::Find;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "polygen", call => \&getsetup);
        hook(type => "preprocess", id => "polygen", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        my $grammar = ($params{grammar} or 'polygen');
        my $symbol = ($params{symbol} or undef);
@@ -64,6 +64,6 @@ sub preprocess (@) { #{{{
        # markdown text
        $res =~ s/\s*$//;
        return $res;
-} # }}}
+}
 
 1
index 1f4c065c1e1f09ad6ba9d395ecd3c002a1bb0a25..ba43561fbc0d5f291f3eb80163dc88c9b506effe 100644 (file)
@@ -3,23 +3,23 @@ package IkiWiki::Plugin::postsparkline;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        IkiWiki::loadplugin('sparkline');
        hook(type => "getsetup", id => "postsparkline", call => \&getsetup);
        hook(type => "preprocess", id => "postsparkline", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        if (! exists $params{max}) {
@@ -78,7 +78,7 @@ sub preprocess (@) { #{{{
        delete $params{color};
        return IkiWiki::Plugin::sparkline::preprocess(%params, 
                map { $_.$color => "" } reverse @data);
-} # }}}
+}
 
 sub perfoo ($@) {
        my $sub=shift;
index e997be3ce65d94becd3061e9cff670454e56244d..e155dd39b88285837007d51cc8da9b219d63be72 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 package IkiWiki::Plugin::prettydate;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use warnings;
 no warnings 'redefine';
 use strict;
@@ -39,12 +39,12 @@ sub default_timetable {
        ];
 }
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "prettydate", call => \&getsetup);
        hook(type => "checkconfig", id => "prettydate", call => \&checkconfig);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -64,9 +64,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! defined $config{prettydateformat} ||
            $config{prettydateformat} eq '%c') {
                $config{prettydateformat}='%X, %B %o, %Y';
@@ -82,9 +82,9 @@ sub checkconfig () { #{{{
                        $config{timetable}[$h] = $config{timetable}[$h - 1];
                }
        }
-} #}}}
+}
 
-sub IkiWiki::displaytime ($;$) { #{{{
+sub IkiWiki::formattime ($;$) {
        my $time=shift;
        my $format=shift;
        if (! defined $format) {
@@ -122,6 +122,6 @@ sub IkiWiki::displaytime ($;$) { #{{{
 
        $format=~s/\%X/$t/g;
        return strftime($format, \@t);
-} #}}}
+}
 
 1
index e536f4e23370773aebd296e290d0c84b2ded83ae..76d994acc7ad0f9d49c63c32d3d5d8dd54db5554 100644 (file)
@@ -3,25 +3,25 @@ package IkiWiki::Plugin::progress;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my $percentage_pattern = qr/[0-9]+\%?/; # pattern to validate percentages
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "progress", call => \&getsetup);
        hook(type => "preprocess", id => "progress", call => \&preprocess);
        hook(type => "format",     id => "progress", call => \&format);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        
        my $fill;
@@ -64,9 +64,9 @@ sub preprocess (@) { #{{{
   <div class="progress-done" style="width: $fill">$fill</div>
 </div>
 EODIV
-} # }}}
+}
 
-sub format(@) { #{{{
+sub format(@) {
        my %params = @_;
 
        # If HTMLScrubber has removed the style attribute, then bring it back
@@ -74,6 +74,6 @@ sub format(@) { #{{{
        $params{content} =~ s!<div class="progress-done">($percentage_pattern)</div>!<div class="progress-done" style="width: $1">$1</div>!g;
 
        return $params{content};    
-} #}}}
+}
 
 1
index 74ca13f3bcac3b1041fd73a1c35ea43e1729aed8..ad8a610c1420f73a3ce0eabf30f9300afcdff5a4 100644 (file)
@@ -4,19 +4,19 @@ package IkiWiki::Plugin::rawhtml;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "rawhtml", call => \&getsetup);
        $config{wiki_file_prune_regexps} = [ grep { !m/\\\.x\?html\?\$/ } @{$config{wiki_file_prune_regexps}} ];
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 1, # changes file types
                },
-} #}}}
+}
 
 1
index eb23b184b7f151ac95513e80c5a3b8a6fd99985c..fa851e46678f208efa04def72e988366df6ea87d 100644 (file)
@@ -3,19 +3,21 @@ package IkiWiki::Plugin::recentchanges;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
+use HTML::Entities;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "recentchanges", call => \&getsetup);
        hook(type => "checkconfig", id => "recentchanges", call => \&checkconfig);
        hook(type => "refresh", id => "recentchanges", call => \&refresh);
        hook(type => "pagetemplate", id => "recentchanges", call => \&pagetemplate);
        hook(type => "htmlize", id => "_change", call => \&htmlize);
-       hook(type => "cgi", id => "recentchanges", call => \&cgi);
-} #}}}
+       # Load goto to fix up links from recentchanges
+       IkiWiki::loadplugin("goto");
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -35,14 +37,14 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        $config{recentchangespage}='recentchanges' unless defined $config{recentchangespage};
        $config{recentchangesnum}=100 unless defined $config{recentchangesnum};
-} #}}}
+}
 
-sub refresh ($) { #{{{
+sub refresh ($) {
        my %seen;
 
        # add new changes
@@ -56,10 +58,10 @@ sub refresh ($) { #{{{
                        unlink($config{srcdir}.'/'.$pagesources{$page});
                }
        }
-} #}}}
+}
 
 # Enable the recentchanges link on wiki pages.
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $template=$params{template};
        my $page=$params{page};
@@ -70,48 +72,15 @@ sub pagetemplate (@) { #{{{
                $template->param(recentchangesurl => urlto($config{recentchangespage}, $page));
                $template->param(have_actions => 1);
        }
-} #}}}
+}
 
 # Pages with extension _change have plain html markup, pass through.
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        return $params{content};
-} #}}}
-
-sub cgi ($) { #{{{
-       my $cgi=shift;
-       if (defined $cgi->param('do') && $cgi->param('do') eq "recentchanges_link") {
-               # This is a link from a change page to some
-               # other page. Since the change pages are only generated
-               # once, statically, links on them won't be updated if the
-               # page they link to is deleted, or newly created, or
-               # changes for whatever reason. So this CGI handles that
-               # dynamic linking stuff.
-               my $page=decode_utf8($cgi->param("page"));
-               if (!defined $page) {
-                       error("missing page parameter");
-               }
-
-               IkiWiki::loadindex();
-
-               my $link=bestlink("", $page);
-               if (! length $link) {
-                       print "Content-type: text/html\n\n";
-                       print IkiWiki::misctemplate(gettext(gettext("missing page")),
-                               "<p>".
-                               sprintf(gettext("The page %s does not exist."),
-                                       htmllink("", "", $page)).
-                               "</p>");
-               }
-               else {
-                       IkiWiki::redirect($cgi, urlto($link, undef, 1));
-               }
-
-               exit;
-       }
 }
 
-sub store ($$$) { #{{{
+sub store ($$$) {
        my $change=shift;
 
        my $page="$config{recentchangespage}/change_".titlepage($change->{rev});
@@ -128,10 +97,10 @@ sub store ($$$) { #{{{
                        if (length $config{cgiurl}) {
                                $_->{link} = "<a href=\"".
                                        IkiWiki::cgiurl(
-                                               do => "recentchanges_link",
+                                               do => "goto",
                                                page => $_->{page}
                                        ).
-                                       "\">".
+                                       "\" rel=\"nofollow\">".
                                        pagetitle($_->{page}).
                                        "</a>"
                        }
@@ -154,16 +123,18 @@ sub store ($$$) { #{{{
        }
        elsif (length $config{cgiurl}) {
                $change->{authorurl} = IkiWiki::cgiurl(
-                       do => "recentchanges_link",
+                       do => "goto",
                        page => (length $config{userdir} ? "$config{userdir}/" : "").$change->{author},
                );
        }
 
-       # escape wikilinks and preprocessor stuff in commit messages
        if (ref $change->{message}) {
                foreach my $field (@{$change->{message}}) {
                        if (exists $field->{line}) {
-                               $field->{line} =~ s/(?<!\\)\[\[/\\\[\[/g;
+                               # escape html
+                               $field->{line} = encode_entities($field->{line});
+                               # escape links and preprocessor stuff
+                               $field->{line} = encode_entities($field->{line}, '\[\]');
                        }
                }
        }
@@ -175,6 +146,10 @@ sub store ($$$) { #{{{
                commitdate => displaytime($change->{when}, "%X %x"),
                wikiname => $config{wikiname},
        );
+       
+       $template->param(permalink => "$config{url}/$config{recentchangespage}/#change-".titlepage($change->{rev}))
+               if exists $config{url};
+       
        IkiWiki::run_hooks(pagetemplate => sub {
                shift->(page => $page, destpage => $page,
                        template => $template, rev => $change->{rev});
@@ -185,6 +160,6 @@ sub store ($$$) { #{{{
        utime $change->{when}, $change->{when}, "$config{srcdir}/$file";
 
        return $page;
-} #}}}
+}
 
 1
index 36acef72ebccf8978c3c4e8348074ef4bca0565c..e3ba9b8d8248858689619fee48a963912c593648 100644 (file)
@@ -3,26 +3,27 @@ package IkiWiki::Plugin::recentchangesdiff;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
+use HTML::Entities;
 
 my $maxlines=200;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "recentchangesdiff",
                call => \&getsetup);
        hook(type => "pagetemplate", id => "recentchangesdiff",
                call => \&pagetemplate);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $template=$params{template};
        if ($config{rcs} && exists $params{rev} && length $params{rev} &&
@@ -38,11 +39,13 @@ sub pagetemplate (@) { #{{{
                        else {
                                $diff=join("", @lines);
                        }
+                       # escape html
+                       $diff = encode_entities($diff);
                        # escape links and preprocessor stuff
-                       $diff =~ s/(?<!\\)\[\[/\\\[\[/g;
+                       $diff = encode_entities($diff, '\[\]');
                        $template->param(diff => $diff);
                }
        }
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/relativedate.pm b/IkiWiki/Plugin/relativedate.pm
new file mode 100644 (file)
index 0000000..3e33cd5
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::relativedate;
+
+use warnings;
+no warnings 'redefine';
+use strict;
+use IkiWiki 3.00;
+use POSIX;
+use Encode;
+
+sub import {
+       add_underlay("javascript");
+       hook(type => "getsetup", id => "relativedate", call => \&getsetup);
+       hook(type => "format", id => "relativedate", call => \&format);
+       inject(name => "IkiWiki::displaytime", call => \&mydisplaytime);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 1,
+               },
+}
+
+sub format (@) {
+        my %params=@_;
+
+       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};
+       }
+       return $params{content};
+}
+
+sub include_javascript ($;$) {
+       my $page=shift;
+       my $absolute=shift;
+       
+       return '<script src="'.urlto("ikiwiki.js", $page, $absolute).
+               '" type="text/javascript" charset="utf-8"></script>'."\n".
+               '<script src="'.urlto("relativedate.js", $page, $absolute).
+               '" type="text/javascript" charset="utf-8"></script>';
+}
+
+sub mydisplaytime ($;$) {
+       my $time=shift;
+       my $format=shift;
+
+       # This needs to be in a form that can be parsed by javascript.
+       # Being fairly human readable is also nice, as it will be exposed
+       # as the title if javascript is not available.
+       my $gmtime=decode_utf8(POSIX::strftime("%a, %d %b %Y %H:%M:%S %z",
+                       localtime($time)));
+
+       return '<span class="relativedate" title="'.$gmtime.'">'.
+               IkiWiki::formattime($time, $format).'</span>';
+}
+
+1
index 68bf9d1ee27ba570736a3e424e9bca973433149e..ee5784f2026db29ac4d48041f6cd355c2356bf1a 100644 (file)
@@ -3,25 +3,25 @@ package IkiWiki::Plugin::remove;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "remove", call => \&getsetup);
        hook(type => "formbuilder_setup", id => "remove", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "remove", call => \&formbuilder);
        hook(type => "sessioncgi", id => "remove", call => \&sessioncgi);
 
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub check_canremove ($$$) { #{{{
+sub check_canremove ($$$) {
        my $page=shift;
        my $q=shift;
        my $session=shift;
@@ -41,7 +41,7 @@ sub check_canremove ($$$) { #{{{
                error(sprintf(gettext("%s is not a file"), $file));
        }
        
-       # Must be editiable.
+       # Must be editable.
        IkiWiki::check_canedit($page, $q, $session);
 
        # If a user can't upload an attachment, don't let them delete it.
@@ -54,9 +54,9 @@ sub check_canremove ($$$) { #{{{
                        error("renaming of attachments is not allowed");
                }
        }
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
        my $form=$params{form};
        my $q=$params{cgi};
@@ -67,9 +67,9 @@ sub formbuilder_setup (@) { #{{{
                push @{$params{buttons}}, "Remove" if $form->field("do") eq "edit";
                $form->tmpl_param("field-remove" => '<input name="_submit" type="submit" value="Remove Attachments" />');
        }
-} #}}}
+}
 
-sub confirmation_form ($$) { #{{{ 
+sub confirmation_form ($$) {
        my $q=shift;
        my $session=shift;
 
@@ -90,9 +90,9 @@ sub confirmation_form ($$) { #{{{
        $f->field(name => "do", type => "hidden", value => "remove", force => 1);
 
        return $f, ["Remove", "Cancel"];
-} #}}}
+}
 
-sub removal_confirm ($$@) { #{{{
+sub removal_confirm ($$@) {
        my $q=shift;
        my $session=shift;
        my $attachment=shift;
@@ -122,9 +122,9 @@ sub removal_confirm ($$@) { #{{{
 
        IkiWiki::showform($f, $buttons, $session, $q);
        exit 0;
-} #}}}
+}
 
-sub postremove ($) { #{{{
+sub postremove ($) {
        my $session=shift;
 
        # Load saved form state and return to edit form.
@@ -132,9 +132,9 @@ sub postremove ($) { #{{{
        $session->clear("postremove");
        IkiWiki::cgi_savesession($session);
        IkiWiki::cgi($postremove, $session);
-} #}}}
+}
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
        my $form=$params{form};
 
@@ -154,9 +154,9 @@ sub formbuilder (@) { #{{{
                        removal_confirm($q, $session, 1, @selected);
                }
        }
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
         my $q=shift;
 
        if ($q->param("do") eq 'remove') {
@@ -218,7 +218,7 @@ sub sessioncgi ($$) { #{{{
                        }
                }
                else {
-                       IkiWiki::showform($form, $buttons, $session, $q);
+                       removal_confirm($q, $session, 0, $q->param("page"));
                }
 
                exit 0;
index 7e55e271cbe6a403115fb38eff1f5655fbc626d6..41af3ca4d61b2495dc0e69e77da6513a2de07373 100644 (file)
@@ -3,25 +3,25 @@ package IkiWiki::Plugin::rename;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "rename", call => \&getsetup);
        hook(type => "formbuilder_setup", id => "rename", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "rename", call => \&formbuilder);
        hook(type => "sessioncgi", id => "rename", call => \&sessioncgi);
 
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return 
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub check_canrename ($$$$$$) { #{{{
+sub check_canrename ($$$$$$) {
        my $src=shift;
        my $srcfile=shift;
        my $dest=shift;
@@ -87,9 +87,9 @@ sub check_canrename ($$$$$$) { #{{{
                        IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile);
                }
        }
-} #}}}
+}
 
-sub rename_form ($$$) { #{{{ 
+sub rename_form ($$$) {
        my $q=shift;
        my $session=shift;
        my $page=shift;
@@ -111,7 +111,7 @@ sub rename_form ($$$) { #{{{
        
        $f->field(name => "do", type => "hidden", value => "rename", force => 1);
        $f->field(name => "page", type => "hidden", value => $page, force => 1);
-       $f->field(name => "new_name", value => pagetitle($page), size => 60);
+       $f->field(name => "new_name", value => pagetitle($page, 1), size => 60);
        if (!$q->param("attachment")) {
                # insert the standard extensions
                my @page_types;
@@ -145,9 +145,9 @@ sub rename_form ($$$) { #{{{
        $f->field(name => "attachment", type => "hidden");
 
        return $f, ["Rename", "Cancel"];
-} #}}}
+}
 
-sub rename_start ($$$$) { #{{{
+sub rename_start ($$$$) {
        my $q=shift;
        my $session=shift;
        my $attachment=shift;
@@ -171,9 +171,9 @@ sub rename_start ($$$$) { #{{{
        my ($f, $buttons)=rename_form($q, $session, $page);
        IkiWiki::showform($f, $buttons, $session, $q);
        exit 0;
-} #}}}
+}
 
-sub postrename ($;$$$) { #{{{
+sub postrename ($;$$$) {
        my $session=shift;
        my $src=shift;
        my $dest=shift;
@@ -204,9 +204,9 @@ sub postrename ($;$$$) { #{{{
        }
 
        IkiWiki::cgi_editpage($postrename, $session);
-} #}}}
+}
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
        my $form=$params{form};
 
@@ -229,11 +229,11 @@ sub formbuilder (@) { #{{{
                        rename_start($q, $session, 1, $selected[0]);
                }
        }
-} #}}}
+}
 
 my $renamesummary;
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
        my $form=$params{form};
        my $q=$params{cgi};
@@ -248,9 +248,9 @@ sub formbuilder_setup (@) { #{{{
                        $form->tmpl_param(message => $renamesummary);
                }
        }
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
         my $q=shift;
 
        if ($q->param("do") eq 'rename') {
@@ -390,22 +390,8 @@ sub sessioncgi ($$) { #{{{
                                $template->param(error => $rename->{error});
                                if ($rename->{src} ne $rename->{dest}) {
                                        $template->param(brokenlinks_checked => 1);
-                                       $template->param(brokenlinks => [
-                                               map {
-                                                       {
-                                                               page => htmllink($rename->{dest}, $rename->{dest}, $_,
-                                                                               noimageinline => 1)
-                                                       }
-                                               } @{$rename->{brokenlinks}}
-                                       ]);
-                                       $template->param(fixedlinks => [
-                                               map {
-                                                       {
-                                                               page => htmllink($rename->{dest}, $rename->{dest}, $_,
-                                                                               noimageinline => 1)
-                                                       }
-                                               } @{$rename->{fixedlinks}}
-                                       ]);
+                                       $template->param(brokenlinks => linklist($rename->{dest}, $rename->{brokenlinks}));
+                                       $template->param(fixedlinks => linklist($rename->{dest}, $rename->{fixedlinks}));
                                }
                                $renamesummary.=$template->output;
                        }
@@ -418,9 +404,26 @@ sub sessioncgi ($$) { #{{{
 
                exit 0;
        }
-} #}}}
+}
+                                               
+sub linklist {
+       # generates a list of links in a form suitable for FormBuilder
+       my $dest=shift;
+       my $list=shift;
+       # converts a list of pages into a list of links
+       # in a form suitable for FormBuilder.
+
+       [map {
+               {
+                       page => htmllink($dest, $dest, $_,
+                                       noimageinline => 1,
+                                       linktext => pagetitle($_),
+                               )
+               }
+       } @{$list}]
+}
 
-sub renamepage_hook ($$$$) { #{{{
+sub renamepage_hook ($$$$) {
        my ($page, $src, $dest, $content)=@_;
 
        IkiWiki::run_hooks(renamepage => sub {
@@ -433,9 +436,9 @@ sub renamepage_hook ($$$$) { #{{{
        });
 
        return $content;
-}# }}}
+}
                        
-sub do_rename ($$$) { #{{{
+sub do_rename ($$$) {
        my $rename=shift;
        my $q=shift;
        my $session=shift;
@@ -460,9 +463,9 @@ sub do_rename ($$$) { #{{{
                }
        }
 
-} # }}}
+}
 
-sub fixlinks ($$$) { #{{{
+sub fixlinks ($$$) {
        my $rename=shift;
        my $session=shift;
 
@@ -498,6 +501,6 @@ sub fixlinks ($$$) { #{{{
        }
 
        return @fixedlinks;
-} #}}}
+}
 
 1
diff --git a/IkiWiki/Plugin/repolist.pm b/IkiWiki/Plugin/repolist.pm
new file mode 100644 (file)
index 0000000..f69ec39
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::repolist;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "getsetup", id => "repolist",  call => \&getsetup);
+       hook(type => "checkconfig", id => "repolist", call => \&checkconfig);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+               },
+               repositories => {
+                       type => "string",
+                       example => ["svn://svn.example.org/wiki/trunk"],
+                       description => "URIs of repositories containing the wiki's source",
+                       safe => 1,
+                       rebuild => undef,
+               },
+}
+
+my $relvcs;
+
+sub checkconfig () {
+       if (defined $config{rcs} && $config{repositories}) {
+               $relvcs=join("\n", map {
+                       s/"//g; # avoid quotes just in case
+                       qq{<link rel="vcs-$config{rcs}" href="$_" title="wiki $config{rcs} repository" />}
+               } @{$config{repositories}});
+               
+               hook(type => "pagetemplate", id => "repolist", call => \&pagetemplate);
+       }
+}
+
+sub pagetemplate (@) {
+       my %params=@_;
+       my $page=$params{page};
+       my $template=$params{template};
+       
+        if (defined $relvcs && $template->query(name => "relvcs")) {
+               $template->param(relvcs => $relvcs);
+       }
+}
+
+1
index e40f4888c44721005ab96d9a1bb4590b13fcea89..d79e3170ec4b4e86873d64d0200357670aa0df67 100644 (file)
@@ -4,18 +4,18 @@ package IkiWiki::Plugin::search;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "search", call => \&getsetup);
        hook(type => "checkconfig", id => "search", call => \&checkconfig);
        hook(type => "pagetemplate", id => "search", call => \&pagetemplate);
        hook(type => "postscan", id => "search", call => \&index);
        hook(type => "delete", id => "search", call => \&delete);
        hook(type => "cgi", id => "search", call => \&cgi);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -28,9 +28,9 @@ sub getsetup () { #{{{
                        safe => 0, # external program
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        foreach my $required (qw(url cgiurl)) {
                if (! length $config{$required}) {
                        error(sprintf(gettext("Must specify %s when using the search plugin"), $required));
@@ -40,10 +40,10 @@ sub checkconfig () { #{{{
        if (! defined $config{omega_cgi}) {
                $config{omega_cgi}="/usr/lib/cgi-bin/omega/omega";
        }
-} #}}}
+}
 
 my $form;
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $page=$params{page};
        my $template=$params{template};
@@ -58,11 +58,11 @@ sub pagetemplate (@) { #{{{
 
                $template->param(searchform => $form);
        }
-} #}}}
+}
 
 my $scrubber;
 my $stemmer;
-sub index (@) { #{{{
+sub index (@) {
        my %params=@_;
 
        setupfiles();
@@ -146,17 +146,17 @@ sub index (@) { #{{{
 
        $doc->add_term($pageterm);
        $db->replace_document_by_term($pageterm, $doc);
-} #}}}
+}
 
-sub delete (@) { #{{{
+sub delete (@) {
        my $db=xapiandb();
        foreach my $page (@_) {
                my $pageterm=pageterm(pagename($page));
                $db->delete_document_by_term($pageterm) if defined $pageterm;
        }
-} #}}}
+}
 
-sub cgi ($) { #{{{
+sub cgi ($) {
        my $cgi=shift;
 
        if (defined $cgi->param('P')) {
@@ -169,9 +169,9 @@ sub cgi ($) { #{{{
                        noimageinline => 1, linktext => "Help");
                exec($config{omega_cgi}) || error("$config{omega_cgi} failed: $!");
        }
-} #}}}
+}
 
-sub pageterm ($) { #{{{
+sub pageterm ($) {
        my $page=shift;
 
        # 240 is the number used by omindex to decide when to hash an
@@ -190,10 +190,10 @@ sub pageterm ($) { #{{{
        else {
                return "U:".$page;
        }
-} #}}}
+}
 
 my $db;
-sub xapiandb () { #{{{
+sub xapiandb () {
        if (! defined $db) {
                eval q{
                        use Search::Xapian;
@@ -204,11 +204,11 @@ sub xapiandb () { #{{{
                        Search::Xapian::DB_CREATE_OR_OPEN());
        }
        return $db;
-} #}}}
+}
 
 {
 my $setup=0;
-sub setupfiles () { #{{{
+sub setupfiles () {
        if (! $setup and (! -e $config{wikistatedir}."/xapian" || $config{rebuild})) {
                writefile("omega.conf", $config{wikistatedir}."/xapian",
                        "database_dir .\n".
@@ -218,7 +218,7 @@ sub setupfiles () { #{{{
                                readfile(IkiWiki::template_file("searchquery.tmpl"))));
                $setup=1;
        }
-} #}}}
+}
 }
 
 1
index 7bfce586f5b7a920e7ed8020e6e0becef623b991..1840a5722a6300d7ce30d14cd4534ef2bc16a48d 100644 (file)
@@ -3,33 +3,41 @@ package IkiWiki::Plugin::shortcut;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "shortcut", call => \&getsetup);
-       hook(type => "refresh", id => "shortcut", call => \&refresh);
+       hook(type => "checkconfig", id => "shortcut", call => \&checkconfig);
        hook(type => "preprocess", id => "shortcut", call => \&preprocess_shortcut);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub refresh () { #{{{
-       # Preprocess the shortcuts page to get all the available shortcuts
-       # defined before other pages are rendered.
-       my $srcfile=srcfile("shortcuts.mdwn", 1);
-       if (! defined $srcfile) {
-               error(gettext("shortcut plugin will not work without a shortcuts.mdwn"));
+sub checkconfig () {
+       if (defined $config{srcdir} && length $config{srcdir}) {
+               # Preprocess the shortcuts page to get all the available shortcuts
+               # defined before other pages are rendered.
+               my $srcfile=srcfile("shortcuts.".$config{default_pageext}, 1);
+               if (! defined $srcfile) {
+                       $srcfile=srcfile("shortcuts.mdwn", 1);
+               }
+               if (! defined $srcfile) {
+                       print STDERR sprintf(gettext("shortcut plugin will not work without %s"),
+                               "shortcuts.".$config{default_pageext})."\n";
+               }
+               else {
+                       IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
+               }
        }
-       IkiWiki::preprocess("shortcuts", "shortcuts", readfile($srcfile));
-} # }}}
+}
 
-sub preprocess_shortcut (@) { #{{{
+sub preprocess_shortcut (@) {
        my %params=@_;
 
        if (! defined $params{name} || ! defined $params{url}) {
@@ -37,15 +45,16 @@ sub preprocess_shortcut (@) { #{{{
        }
 
        hook(type => "preprocess", no_override => 1, id => $params{name},
+               shortcut => 1,
                call => sub { shortcut_expand($params{url}, $params{desc}, @_) });
 
        #translators: This is used to display what shortcuts are defined.
        #translators: First parameter is the name of the shortcut, the second
        #translators: is an URL.
        return sprintf(gettext("shortcut %s points to <i>%s</i>"), $params{name}, $params{url});
-} # }}}
+}
 
-sub shortcut_expand ($$@) { #{{{
+sub shortcut_expand ($$@) {
        my $url=shift;
        my $desc=shift;
        my %params=@_;
@@ -82,6 +91,6 @@ sub shortcut_expand ($$@) { #{{{
        }
 
        return "<a href=\"$url\">$desc</a>";
-} #}}}
+}
 
 1
index 9697e1198d24db690cec373e9980516e077ad936..41812e1c1f671da84be1a06a5821695fc5dc6f11 100644 (file)
@@ -6,22 +6,22 @@ package IkiWiki::Plugin::sidebar;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "sidebar", call => \&getsetup);
        hook(type => "pagetemplate", id => "sidebar", call => \&pagetemplate);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub sidebar_content ($) { #{{{
+sub sidebar_content ($) {
        my $page=shift;
        
        my $sidebar_page=bestlink($page, "sidebar") || return;
@@ -42,9 +42,9 @@ sub sidebar_content ($) { #{{{
                       IkiWiki::filter($sidebar_page, $page, $content))));
        }
 
-} # }}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
 
        my $page=$params{page};
@@ -56,6 +56,6 @@ sub pagetemplate (@) { #{{{
                        $template->param(sidebar => $content);
                }
        }
-} # }}}
+}
 
 1
index ef7b9b428029f57687da3538a52b2ab75727c6ad..032a0034c0c4e3354ea8274a6259fb0478ad949e 100644 (file)
@@ -3,23 +3,23 @@ package IkiWiki::Plugin::signinedit;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "signinedit", call => \&getsetup);
        hook(type => "canedit", id => "signinedit", call => \&canedit,
             last => 1);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub canedit ($$$) { #{{{
+sub canedit ($$$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
@@ -34,6 +34,6 @@ sub canedit ($$$) { #{{{
        else {
                return "";
        }
-} #}}}
+}
 
 1
index f844ddb91ddaa96680094d792df96af2ddd4a229..ea7d6e47f576b3cb04ffeb79d9471fdab1cfa9b1 100644 (file)
@@ -6,9 +6,9 @@ package IkiWiki::Plugin::skeleton;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "skeleton",  call => \&getopt);
        hook(type => "getsetup", id => "skeleton",  call => \&getsetup);
        hook(type => "checkconfig", id => "skeleton", call => \&checkconfig);
@@ -30,17 +30,18 @@ sub import { #{{{
        hook(type => "auth", id => "skeleton", call => \&auth);
        hook(type => "sessioncgi", id => "skeleton", call => \&sessioncgi);
        hook(type => "canedit", id => "skeleton", call => \&canedit);
+       hook(type => "checkcontent", id => "skeleton", call => \&checkcontent);
        hook(type => "editcontent", id => "skeleton", call => \&editcontent);
        hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "skeleton", call => \&formbuilder);
        hook(type => "savestate", id => "skeleton", call => \&savestate);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
        debug("skeleton plugin getopt");
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -53,155 +54,161 @@ sub getsetup () { #{{{
                        safe => 0,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        debug("skeleton plugin checkconfig");
-} #}}}
+}
 
-sub refresh () { #{{{
+sub refresh () {
        debug("skeleton plugin refresh");
-} #}}}
+}
 
-sub needsbuild () { #{{{
+sub needsbuild () {
        debug("skeleton plugin needsbuild");
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        return "skeleton plugin result";
-} # }}}
+}
 
-sub filter (@) { #{{{
+sub filter (@) {
        my %params=@_;
        
        debug("skeleton plugin running as filter");
 
        return $params{content};
-} # }}}
+}
 
-sub linkify (@) { #{{{
+sub linkify (@) {
        my %params=@_;
        
        debug("skeleton plugin running as linkify");
 
        return $params{content};
-} # }}}
+}
 
-sub scan (@) { #{{{a
+sub scan (@) {
        my %params=@_;
 
        debug("skeleton plugin running as scan");
-} # }}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
 
        debug("skeleton plugin running as htmlize");
 
        return $params{content};
-} # }}}
+}
 
-sub sanitize (@) { #{{{
+sub sanitize (@) {
        my %params=@_;
        
        debug("skeleton plugin running as a sanitizer");
 
        return $params{content};
-} # }}}
+}
 
-sub postscan (@) { #{{{
+sub postscan (@) {
        my %params=@_;
        
        debug("skeleton plugin running as postscan");
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
        my %params=@_;
        
        debug("skeleton plugin running as a formatter");
 
        return $params{content};
-} # }}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $page=$params{page};
        my $template=$params{template};
        
        debug("skeleton plugin running as a pagetemplate hook");
-} # }}}
+}
 
-sub templatefile (@) { #{{{
+sub templatefile (@) {
        my %params=@_;
        my $page=$params{page};
        
        debug("skeleton plugin running as a templatefile hook");
-} # }}}
+}
 
-sub delete (@) { #{{{
+sub delete (@) {
        my @files=@_;
 
        debug("skeleton plugin told that files were deleted: @files");
-} #}}}
+}
 
-sub change (@) { #{{{
+sub change (@) {
        my @files=@_;
 
        debug("skeleton plugin told that changed files were rendered: @files");
-} #}}}
+}
 
-sub cgi ($) { #{{{
+sub cgi ($) {
        my $cgi=shift;
 
        debug("skeleton plugin running in cgi");
-} #}}}
+}
 
-sub auth ($$) { #{{{
+sub auth ($$) {
        my $cgi=shift;
        my $session=shift;
 
        debug("skeleton plugin running in auth");
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
        my $cgi=shift;
        my $session=shift;
 
        debug("skeleton plugin running in sessioncgi");
-} #}}}
+}
 
-sub canedit ($$$) { #{{{
+sub canedit ($$$) {
        my $page=shift;
        my $cgi=shift;
        my $session=shift;
 
        debug("skeleton plugin running in canedit");
-} #}}}
+}
 
-sub editcontent ($$$) { #{{{
+sub checkcontent (@) {
+       my %params=@_;
+
+       debug("skeleton plugin running in checkcontent");
+}
+
+sub editcontent ($$$) {
        my %params=@_;
 
        debug("skeleton plugin running in editcontent");
 
        return $params{content};
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
        
        debug("skeleton plugin running in formbuilder_setup");
-} # }}}
+}
 
-sub formbuilder (@) { #{{{
+sub formbuilder (@) {
        my %params=@_;
        
        debug("skeleton plugin running in formbuilder");
-} # }}}
+}
 
-sub savestate () { #{{{
+sub savestate () {
        debug("skeleton plugin running in savestate");
-} #}}}
+}
 
 1
index 2633b1ea14cf6ab247ea858e3049c977db5f54bc..0d77916d0d3d633e7656d79527cce12647089d47 100644 (file)
@@ -3,18 +3,18 @@ package IkiWiki::Plugin::smiley;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %smileys;
 my $smiley_regexp;
 
-sub import { #{{{
+sub import {
        add_underlay("smiley");
        hook(type => "getsetup", id => "smiley", call => \&getsetup);
        hook(type => "sanitize", id => "smiley", call => \&sanitize);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -22,9 +22,9 @@ sub getsetup () { #{{{
                        # removes the smileys, which would break links
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub build_regexp () { #{{{
+sub build_regexp () {
        my $list=readfile(srcfile("smileys.mdwn"));
        while ($list =~ m/^\s*\*\s+\\\\([^\s]+)\s+\[\[([^]]+)\]\]/mg) {
                my $smiley=$1;
@@ -50,9 +50,9 @@ sub build_regexp () { #{{{
        $smiley_regexp='('.join('|', map { quotemeta }
                reverse sort keys %smileys).')';
        #debug($smiley_regexp);
-} #}}}
+}
 
-sub sanitize (@) { #{{{
+sub sanitize (@) {
        my %params=@_;
 
        build_regexp() unless defined $smiley_regexp;
@@ -87,14 +87,14 @@ MATCH:      while (m{(?:^|(?<=\s|>))(\\?)$smiley_regexp(?:(?=\s|<)|$)}g) {
                }
                else {
                        # Replace the smiley with its expanded value.
-                       substr($_, $spos, length($smiley))=
-                               htmllink($params{page}, $params{destpage},
+                       my $link=htmllink($params{page}, $params{destpage},
                                         $smileys{$smiley}, linktext => $smiley);
-                       pos=$epos+1;
+                       substr($_, $spos, length($smiley))=$link;
+                       pos=$epos+length($link);
                }
        }
 
        return $_;
-} # }}}
+}
 
 1
index 901c2f6830548c9e23c8e24831666b44d6257bc5..458192695322317d5e0f69a860476758675987d5 100644 (file)
@@ -3,7 +3,7 @@ package IkiWiki::Plugin::sparkline;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use IPC::Open2;
 
 my $match_num=qr/[-+]?[0-9]+(?:\.[0-9]+)?/;
@@ -14,20 +14,20 @@ my %locmap=(
        left => 'TEXT_LEFT',
 );
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "sparkline", call => \&getsetup);
        hook(type => "preprocess", id => "sparkline", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        my $php;
@@ -130,7 +130,7 @@ sub preprocess (@) { #{{{
 
        if (! -e "$config{destdir}/$fn") {
                my $pid;
-               my $sigpipe=0;;
+               my $sigpipe=0;
                $SIG{PIPE}=sub { $sigpipe=1 };
                $pid=open2(*IN, *OUT, "php");
 
@@ -166,6 +166,6 @@ sub preprocess (@) { #{{{
        }
 
        return '<img src="'.urlto($fn, $params{destpage}).'" alt="graph" />';
-} # }}}
+}
 
 1
index d738720be655a7c2140c7cdb14ff9548dd8f6552..fe55e7d0853a8ddcb78171fc3b6ffde3b62ad675 100644 (file)
@@ -6,7 +6,7 @@ use strict;
 use IkiWiki;
 use POSIX qw(setlocale LC_CTYPE);
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "svn", call => \&checkconfig);
        hook(type => "getsetup", id => "svn", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -19,9 +19,9 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! defined $config{svnpath}) {
                $config{svnpath}="trunk";
        }
@@ -37,9 +37,9 @@ sub checkconfig () { #{{{
                        wrappermode => (defined $config{svn_wrappermode} ? $config{svn_wrappermode} : "04755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -87,7 +87,7 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
 # svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do.
 sub find_lc_ctype() {
@@ -107,27 +107,27 @@ sub find_lc_ctype() {
 
        # fallback to the current locale
        return $current;
-} # }}}
+}
 $ENV{LC_CTYPE} = $ENV{LC_CTYPE} || find_lc_ctype();
 
-sub svn_info ($$) { #{{{
+sub svn_info ($$) {
        my $field=shift;
        my $file=shift;
 
        my $info=`LANG=C svn info $file`;
        my ($ret)=$info=~/^$field: (.*)$/m;
        return $ret;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        if (-d "$config{srcdir}/.svn") {
                if (system("svn", "update", "--quiet", $config{srcdir}) != 0) {
                        warn("svn update failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        # Prepares to edit a file under revision control. Returns a token
        # that must be passed into rcs_commit when the file is ready
        # for committing.
@@ -140,9 +140,9 @@ sub rcs_prepedit ($) { #{{{
                my $rev=svn_info("Revision", "$config{srcdir}/$file");
                return defined $rev ? $rev : "";
        }
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        # Tries to commit the page; returns undef on _success_ and
        # a version of the page with the rcs's conflict markers on failure.
        # The file is relative to the srcdir.
@@ -185,7 +185,7 @@ sub rcs_commit ($$$;$$) { #{{{
                }
        }
        return undef # success
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -209,7 +209,7 @@ sub rcs_commit_staged ($$$) {
        return undef # success
 }
 
-sub rcs_add ($) { #{{{
+sub rcs_add ($) {
        # filename is relative to the root of the srcdir
        my $file=shift;
 
@@ -224,9 +224,9 @@ sub rcs_add ($) { #{{{
                        warn("svn add failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_remove ($) { #{{{
+sub rcs_remove ($) {
        # filename is relative to the root of the srcdir
        my $file=shift;
 
@@ -235,9 +235,9 @@ sub rcs_remove ($) { #{{{
                        warn("svn rm failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_rename ($$) { #{{{
+sub rcs_rename ($$) {
        # filenames relative to the root of the srcdir
        my ($src, $dest)=@_;
        
@@ -258,9 +258,9 @@ sub rcs_rename ($$) { #{{{
                        warn("svn rename failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_recentchanges ($) { #{{{
+sub rcs_recentchanges ($) {
        my $num=shift;
        my @ret;
        
@@ -341,14 +341,14 @@ sub rcs_recentchanges ($) { #{{{
        }
 
        return @ret;
-} #}}}
+}
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
        return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`;
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        my $file=shift;
 
        my $svn_log_infoline=qr/^r\d+\s+\|\s+[^\s]+\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
@@ -376,6 +376,6 @@ sub rcs_getctime ($) { #{{{
        $date=str2time($date);
        debug("found ctime ".localtime($date)." for $file");
        return $date;
-} #}}}
+}
 
 1
index e782fc238dbd40b628f8675fefa36942d9be520c..96d63f455f886e9111f0e7bd26558b020c1de61b 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::table;
 use warnings;
 use strict;
 use Encode;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "table", call => \&getsetup);
-       hook(type => "preprocess", id => "table", call => \&preprocess);
-} # }}}
+       hook(type => "preprocess", id => "table", call => \&preprocess, scan => 1);
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params =(
                format  => 'auto',
                header  => 'row',
@@ -27,13 +27,31 @@ sub preprocess (@) { #{{{
        );
 
        if (exists $params{file}) {
-               if (! $pagesources{$params{file}}) {
+               if (! exists $pagesources{$params{file}}) {
                        error gettext("cannot find file");
                }
                $params{data} = readfile(srcfile($params{file}));
                add_depends($params{page}, $params{file});
        }
 
+       if (! defined wantarray) {
+               # scan mode --  if the table uses an external file, need to
+               # scan that file too.
+               return unless exists $params{file};
+
+               IkiWiki::run_hooks(scan => sub {
+                       shift->(
+                               page => $params{page},
+                               content => $params{data},
+                       );
+               });
+
+               # Preprocess in scan-only mode.
+               IkiWiki::preprocess($params{page}, $params{page}, $params{data}, 1);
+
+               return;
+       }
+
        if (lc $params{format} eq 'auto') {
                # first try the more simple format
                if (is_dsv_data($params{data})) {
@@ -50,22 +68,18 @@ sub preprocess (@) { #{{{
                        defined $params{delimiter} ? $params{delimiter} : ",",);
                # linkify after parsing since html link quoting can
                # confuse CSV parsing
-               if (! exists $params{file}) {
-                       @data=map {
-                               [ map {
-                                       IkiWiki::linkify($params{page},
-                                               $params{destpage}, $_);
-                               } @$_ ]
-                       } @data;
-               }
+               @data=map {
+                       [ map {
+                               IkiWiki::linkify($params{page},
+                                       $params{destpage}, $_);
+                       } @$_ ]
+               } @data;
        }
        elsif (lc $params{format} eq 'dsv') {
                # linkify before parsing since wikilinks can contain the
                # delimiter
-               if (! exists $params{file}) {
-                       $params{data} = IkiWiki::linkify($params{page},
-                               $params{destpage}, $params{data});
-               }
+               $params{data} = IkiWiki::linkify($params{page},
+                       $params{destpage}, $params{data});
                @data=split_dsv($params{data},
                        defined $params{delimiter} ? $params{delimiter} : "|",);
        }
@@ -102,16 +116,16 @@ sub preprocess (@) { #{{{
        else {  
                return $html;
        }            
-} #}}}
+}
 
-sub is_dsv_data ($) { #{{{
+sub is_dsv_data ($) {
        my $text = shift;
 
        my ($line) = split(/\n/, $text);
        return $line =~ m{.+\|};
 }
 
-sub split_csv ($$) { #{{{
+sub split_csv ($$) {
        my @text_lines = split(/\n/, shift);
        my $delimiter = shift;
 
@@ -137,9 +151,9 @@ sub split_csv ($$) { #{{{
        }
 
        return @data;
-} #}}}
+}
 
-sub split_dsv ($$) { #{{{
+sub split_dsv ($$) {
        my @text_lines = split(/\n/, shift);
        my $delimiter = shift;
        $delimiter="|" unless defined $delimiter;
@@ -150,9 +164,9 @@ sub split_dsv ($$) { #{{{
        }
     
        return @data;
-} #}}}
+}
 
-sub genrow ($@) { #{{{
+sub genrow ($@) {
        my %params=%{shift()};
        my $elt = shift;
        my @data = @_;
@@ -190,6 +204,6 @@ sub genrow ($@) { #{{{
        push @ret, "\t\t</tr>";
 
        return @ret;
-} #}}}
+}
 
 1
index 158657507331e2dd538f31c91a44c4cb09aec95a..8fe9c68286cc4ff49f15372c752cd981681a3181 100644 (file)
@@ -4,26 +4,26 @@ package IkiWiki::Plugin::tag;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my %tags;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "tag", call => \&getopt);
        hook(type => "getsetup", id => "tag", call => \&getsetup);
        hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
        hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
        hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
        eval q{use Getopt::Long};
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
        GetOptions("tagbase=s" => \$config{tagbase});
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -36,35 +36,30 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub tagpage ($) { #{{{
+sub tagpage ($) {
        my $tag=shift;
                        
        if ($tag !~ m{^\.?/} &&
            defined $config{tagbase}) {
-               $tag=$config{tagbase}."/".$tag;
+               $tag="/".$config{tagbase}."/".$tag;
+               $tag=~y#/#/#s; # squash dups
        }
 
        return $tag;
-} #}}}
+}
 
-sub taglink ($$$;@) { #{{{
+sub taglink ($$$;@) {
        my $page=shift;
        my $destpage=shift;
        my $tag=shift;
        my %opts=@_;
 
-       my $link=tagpage($tag);
+       return htmllink($page, $destpage, tagpage($tag), %opts);
+}
 
-       # Force tag creation links to create the tag under /tagbase,
-       # if there is a tagbase and this tag used it.
-       $link="/".$link if $tag ne $link;
-
-       return htmllink($page, $destpage, $link, %opts);
-} #}}}
-
-sub preprocess_tag (@) { #{{{
+sub preprocess_tag (@) {
        if (! @_) {
                return "";
        }
@@ -82,9 +77,9 @@ sub preprocess_tag (@) { #{{{
        }
                
        return "";
-} # }}}
+}
 
-sub preprocess_taglink (@) { #{{{
+sub preprocess_taglink (@) {
        if (! @_) {
                return "";
        }
@@ -107,9 +102,9 @@ sub preprocess_taglink (@) { #{{{
        grep {
                $_ ne 'page' && $_ ne 'destpage' && $_ ne 'preview'
        } keys %params);
-} # }}}
+}
 
-sub pagetemplate (@) { #{{{
+sub pagetemplate (@) {
        my %params=@_;
        my $page=$params{page};
        my $destpage=$params{destpage};
@@ -128,6 +123,14 @@ sub pagetemplate (@) { #{{{
                                sort keys %{$tags{$page}}]);
                }
        }
-} # }}}
+}
+
+package IkiWiki::PageSpec;
+
+sub match_tagged ($$;@) {
+       my $page = shift;
+       my $glob = shift;
+       return match_link($page, IkiWiki::Plugin::tag::tagpage($glob));
+}
 
 1
index c980df48f4a48dfa8100fefa341740a2028244eb..b6097bb49d26133a54dc2fa27c3fc98e59d657bb 100644 (file)
@@ -4,24 +4,25 @@ package IkiWiki::Plugin::template;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Template;
 use Encode;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "template", call => \&getsetup);
-       hook(type => "preprocess", id => "template", call => \&preprocess);
-} # }}}
+       hook(type => "preprocess", id => "template", call => \&preprocess,
+               scan => 1);
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        if (! exists $params{id}) {
@@ -68,9 +69,13 @@ sub preprocess (@) { #{{{
                }
        }
 
+       # This needs to run even in scan mode, in order to process
+       # links and other metadata includes via the template.
+       my $scan=! defined wantarray;
+
        return IkiWiki::preprocess($params{page}, $params{destpage},
                IkiWiki::filter($params{page}, $params{destpage},
-               $template->output));
-} # }}}
+               $template->output), $scan);
+}
 
 1
index 9f9b50f017bb5cb75a5ed1155984531d082d200d..440fca33be02cc6cf91ff9072c725d936571b334 100644 (file)
@@ -3,22 +3,22 @@ package IkiWiki::Plugin::testpagespec;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "testpagespec", call => \&getsetup);
        hook(type => "preprocess", id => "testpagespec", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        
        foreach my $param (qw{match pagespec}) {
@@ -37,6 +37,6 @@ sub preprocess (@) { #{{{
        else {
                return "no match: $ret";
        }
-} # }}}
+}
 
 1
index 661d97b1f4fc04b86421f41baa36cd05ce021a8b..dba5372b5fee98c33cf044e3b28024c53033649a 100644 (file)
@@ -8,7 +8,7 @@ use strict;
 use Digest::MD5 qw(md5_hex);
 use File::Temp qw(tempdir);
 use HTML::Entities;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
 my $default_prefix = <<EOPREFIX;
 \\documentclass{article}
@@ -21,12 +21,12 @@ EOPREFIX
 
 my $default_postfix = '\\end{document}';
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "teximg", call => \&getsetup);
        hook(type => "preprocess", id => "teximg", call => \&preprocess);
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -52,9 +52,9 @@ sub getsetup () { #{{{
                        safe => 0, # Not sure how secure LaTeX is...
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params = @_;
        
        my $height = $params{height};
@@ -76,9 +76,9 @@ sub preprocess (@) { #{{{
        else {
                error gettext("code includes disallowed latex commands")
        }
-} #}}}
+}
 
-sub check_height ($) { #{{{
+sub check_height ($) {
        # Since latex doesn't support unlimited scaling this function
        # returns the closest supported size.
        my $height =shift;
@@ -95,9 +95,9 @@ sub check_height ($) { #{{{
                }
        }
        return $ret;
-} #}}}
+}
 
-sub create ($$$) { #{{{
+sub create ($$$) {
        # This function calls the image generating function and returns
        # the <img .. /> for the generated image.
        my $code = shift;
@@ -127,9 +127,9 @@ sub create ($$$) { #{{{
        else {
                error qq{<a href="$logurl">}.gettext("failed to generate image from code")."</a>";
        }
-} #}}}
+}
 
-sub gen_image ($$$$) { #{{{
+sub gen_image ($$$$) {
        # Actually creates the image.
        my $code = shift;
        my $height = shift;
@@ -180,18 +180,18 @@ sub gen_image ($$$$) { #{{{
 
                return 0;
        }
-} #}}}
+}
 
-sub create_tmp_dir ($) { #{{{
+sub create_tmp_dir ($) {
        # Create a temp directory, it will be removed when ikiwiki exits.
        my $base = shift;
 
        my $template = $base.".XXXXXXXXXX";
        my $tmpdir = tempdir($template, TMPDIR => 1, CLEANUP => 1);
        return $tmpdir;
-} #}}}
+}
 
-sub check ($) { #{{{
+sub check ($) {
        # Check if the code is ok
        my $code = shift;
 
@@ -219,6 +219,6 @@ sub check ($) { #{{{
                }
        }
        return 1;
-} #}}}
+}
 
 1
index bbd282f0c8dd09035f03eadc85fbd3ea0823cf7a..b604aa3c52ab1d0fe34b686a4634920ac6310dc6 100644 (file)
@@ -6,29 +6,29 @@ package IkiWiki::Plugin::textile;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "textile", call => \&getsetup);
        hook(type => "htmlize", id => "txtl", call => \&htmlize);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        my $content = decode_utf8(encode_utf8($params{content}));
 
        eval q{use Text::Textile};
        return $content if $@;
        return Text::Textile::textile($content);
-} # }}}
+}
 
 1
index 0a5c161b25e32c74bee0c14f538cc98d85375a0a..f4b20a6ec2b27681b98b92fa4d787cb9d8cb1fe1 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 use strict;
 use IkiWiki;
 
-sub import { #{{{
+sub import {
        hook(type => "checkconfig", id => "tla", call => \&checkconfig);
        hook(type => "getsetup", id => "tla", call => \&getsetup);
        hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
@@ -18,18 +18,18 @@ sub import { #{{{
        hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
        hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
        hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (defined $config{tla_wrapper} && length $config{tla_wrapper}) {
                push @{$config{wrappers}}, {
                        wrapper => $config{tla_wrapper},
                        wrappermode => (defined $config{tla_wrappermode} ? $config{tla_wrappermode} : "06755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # rcs plugin
@@ -63,9 +63,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub quiet_system (@) { #{{{
+sub quiet_system (@) {
        # See Debian bug #385939.
        open (SAVEOUT, ">&STDOUT");
        close STDOUT;
@@ -75,17 +75,17 @@ sub quiet_system (@) { #{{{
        open (STDOUT, ">&SAVEOUT");
        close SAVEOUT;
        return $ret;
-} #}}}
+}
 
-sub rcs_update () { #{{{
+sub rcs_update () {
        if (-d "$config{srcdir}/{arch}") {
                if (quiet_system("tla", "replay", "-d", $config{srcdir}) != 0) {
                        warn("tla replay failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_prepedit ($) { #{{{
+sub rcs_prepedit ($) {
        my $file=shift;
 
        if (-d "$config{srcdir}/{arch}") {
@@ -94,9 +94,9 @@ sub rcs_prepedit ($) { #{{{
                my $rev=`tla tree-id $config{srcdir}`;
                return defined $rev ? $rev : "";
        }
-} #}}}
+}
 
-sub rcs_commit ($$$;$$) { #{{{
+sub rcs_commit ($$$;$$) {
        my $file=shift;
        my $message=shift;
        my $rcstoken=shift;
@@ -135,7 +135,7 @@ sub rcs_commit ($$$;$$) { #{{{
                }
        }
        return undef # success
-} #}}}
+}
 
 sub rcs_commit_staged ($$$) {
        # Commits all staged changes. Changes can be staged using rcs_add,
@@ -145,7 +145,7 @@ sub rcs_commit_staged ($$$) {
        error("rcs_commit_staged not implemented for tla"); # TODO
 }
 
-sub rcs_add ($) { #{{{
+sub rcs_add ($) {
        my $file=shift;
 
        if (-d "$config{srcdir}/{arch}") {
@@ -153,19 +153,19 @@ sub rcs_add ($) { #{{{
                        warn("tla add failed\n");
                }
        }
-} #}}}
+}
 
-sub rcs_remove ($) { # {{{
+sub rcs_remove ($) {
        my $file = shift;
 
        error("rcs_remove not implemented for tla"); # TODO
-} #}}}
+}
 
 sub rcs_rename ($$) { # {{{a
        my ($src, $dest) = @_;
 
        error("rcs_rename not implemented for tla"); # TODO
-} #}}}
+}
 
 sub rcs_recentchanges ($) {
        my $num=shift;
@@ -239,7 +239,7 @@ sub rcs_recentchanges ($) {
        return @ret;
 }
 
-sub rcs_diff ($) { #{{{
+sub rcs_diff ($) {
        my $rev=shift;
        my $logs = `tla logs -d $config{srcdir}`;
        my @changesets = reverse split(/\n/, $logs);
@@ -251,9 +251,9 @@ sub rcs_diff ($) { #{{{
 
        my $revminusone = $changesets[$i+1];
        return `tla diff -d $config{srcdir} $revminusone`;
-} #}}}
+}
 
-sub rcs_getctime ($) { #{{{
+sub rcs_getctime ($) {
        my $file=shift;
        eval q{use Date::Parse};
        error($@) if $@;
@@ -281,6 +281,6 @@ sub rcs_getctime ($) { #{{{
        my $date=str2time($sdate, 'UTC');
        debug("found ctime ".localtime($date)." for $file");
        return $date;
-} #}}}
+}
 
 1
index dff9d9aa5356e5928de0a9ddd654217f2165af84..a585564e74761045ee8e178b6dd8262ede94ee97 100644 (file)
@@ -4,26 +4,26 @@ package IkiWiki::Plugin::toc;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Parser;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "toc", call => \&getsetup);
        hook(type => "preprocess", id => "toc", call => \&preprocess);
        hook(type => "format", id => "toc", call => \&format);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
 my %tocpages;
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
 
        if ($params{page} eq $params{destpage}) {
@@ -40,9 +40,9 @@ sub preprocess (@) { #{{{
                # right.
                return "";
        }
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
        my %params=@_;
        my $content=$params{content};
        
index 610d38e3ac0d8e39c43d56e727f098441862b5ce..aae8cdf84beeff62d54197db0e5f1e2733fe5810 100644 (file)
@@ -3,80 +3,27 @@ package IkiWiki::Plugin::toggle;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-# Here's the javascript that makes this possible. A key feature is the use
-# of css to hide toggleables, to avoid any flashing on page load. The css
-# is only emitted after the javascript tests that it's going to be able to
-# show the toggleables.
-our $javascript=<<'EOF';
-<script type="text/javascript">
-<!--
-if (document.getElementById && document.getElementsByTagName && document.createTextNode) {
-       document.write('<style type="text/css">div.toggleable { display: none; }</style>');
-       window.onload = inittoggle;
-}
-
-function inittoggle() {
-       var as = getElementsByClass('toggle');
-       for (var i = 0; i < as.length; i++) {
-               var id = as[i].href.match(/#(\w.+)/)[1];
-               if (document.getElementById(id).className == "toggleable")
-                       document.getElementById(id).style.display="none";
-               as[i].onclick = function() {
-                       toggle(this);
-                       return false;
-               }
-       }
-}
-
-function toggle(s) {
-       var id = s.href.match(/#(\w.+)/)[1];
-       style = document.getElementById(id).style;
-       if (style.display == "none")
-               style.display = "block";
-       else
-               style.display = "none";
-}
-
-function getElementsByClass(cls, node, tag) {
-       if (document.getElementsByClass)
-               return document.getElementsByClass(cls, node, tag);
-       if (! node) node = document;
-       if (! tag) tag = '*';
-       var ret = new Array();
-       var pattern = new RegExp("(^|\\s)"+cls+"(\\s|$)");
-       var els = node.getElementsByTagName(tag);
-       for (i = 0; i < els.length; i++) {
-               if ( pattern.test(els[i].className) ) {
-                       ret.push(els[i]);
-               }
-       }
-       return ret;
-}
-
-//-->
-</script>
-EOF
-
-sub import { #{{{
+sub import {
+       add_underlay("javascript");
        hook(type => "getsetup", id => "toggle", call => \&getsetup);
        hook(type => "preprocess", id => "toggle",
                call => \&preprocess_toggle);
        hook(type => "preprocess", id => "toggleable",
                call => \&preprocess_toggleable);
        hook(type => "format", id => "toggle", call => \&format);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub genid ($$) { #{{{
+sub genid ($$) {
        my $page=shift;
        my $id=shift;
 
@@ -88,16 +35,16 @@ sub genid ($$) { #{{{
                $id="id$id";
        }
        return $id;
-} #}}}
+}
 
-sub preprocess_toggle (@) { #{{{
+sub preprocess_toggle (@) {
        my %params=(id => "default", text => "more", @_);
 
        my $id=genid($params{page}, $params{id});
        return "<a class=\"toggle\" href=\"#$id\">$params{text}</a>";
-} # }}}
+}
 
-sub preprocess_toggleable (@) { #{{{
+sub preprocess_toggleable (@) {
        my %params=(id => "default", text => "", open => "no", @_);
 
        # Preprocess the text to expand any preprocessor directives
@@ -114,19 +61,29 @@ sub preprocess_toggleable (@) { #{{{
        my ($indent)=$params{text}=~/( +)$/;
        $indent="" unless defined $indent;
        return "<div class=\"$class\" id=\"$id\"></div>\n\n$params{text}\n$indent<div class=\"toggleableend\"></div>";
-} # }}}
+}
 
-sub format (@) { #{{{
+sub format (@) {
         my %params=@_;
 
        if ($params{content}=~s!(<div class="toggleable(?:-open)?" id="[^"]+">\s*)</div>!$1!g) {
                $params{content}=~s/<div class="toggleableend">//g;
-               if (! ($params{content}=~s!^<body>!<body>$javascript!m)) {
+               if (! ($params{content}=~s!^(<body>)!$1.include_javascript($params{page})!em)) {
                        # no </body> tag, probably in preview mode
-                       $params{content}=$javascript.$params{content};
+                       $params{content}=include_javascript($params{page}, 1).$params{content};
                }
        }
        return $params{content};
-} # }}}
+}
+
+sub include_javascript ($;$) {
+       my $page=shift;
+       my $absolute=shift;
+       
+       return '<script src="'.urlto("ikiwiki.js", $page, $absolute).
+               '" type="text/javascript" charset="utf-8"></script>'."\n".
+               '<script src="'.urlto("toggle.js", $page, $absolute).
+               '" type="text/javascript" charset="utf-8"></script>';
+}
 
 1
index e4c9e5d6a086ba59d0a826c0e7378e297454d734..8599bdc8ec881429472ef19f760113f27d0a678f 100644 (file)
@@ -8,7 +8,7 @@ package IkiWiki::Plugin::txt;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use HTML::Entities;
 
 my $findurl=0;
@@ -24,13 +24,13 @@ sub import {
        }
 }
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-} #}}}
+}
 
 # We use filter to convert raw text to HTML
 # (htmlize is called after other plugins insert HTML)
@@ -39,7 +39,7 @@ sub filter (@) {
        my $content = $params{content};
 
        if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.txt$/) {
-               encode_entities($content);
+               encode_entities($content, "<>&");
                if ($findurl) {
                        my $finder = URI::Find->new(sub {
                                my ($uri, $orig_uri) = @_;
index 27089b39008455b92b24e69669627bc624fbf10d..f62be82bbea849090876053a4d81ee6c558260c6 100644 (file)
@@ -4,22 +4,22 @@ package IkiWiki::Plugin::typography;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getopt", id => "typography", call => \&getopt);
        hook(type => "getsetup", id => "typography", call => \&getsetup);
        IkiWiki::hook(type => "sanitize", id => "typography", call => \&sanitize);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
        eval q{use Getopt::Long};
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
        GetOptions("typographyattributes=s" => \$config{typographyattributes});
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        eval q{use Text::Typography};
        error($@) if $@;
 
@@ -36,9 +36,9 @@ sub getsetup () { #{{{
                        safe => 1,
                        rebuild => 1,
                },
-} #}}}
+}
 
-sub sanitize (@) { #{{{
+sub sanitize (@) {
        my %params=@_;
 
        eval q{use Text::Typography};
@@ -46,6 +46,6 @@ sub sanitize (@) { #{{{
 
        my $attributes=defined $config{typographyattributes} ? $config{typographyattributes} : '3';
        return Text::Typography::typography($params{content}, $attributes);
-} # }}}
+}
 
 1
diff --git a/IkiWiki/Plugin/underlay.pm b/IkiWiki/Plugin/underlay.pm
new file mode 100644 (file)
index 0000000..380d418
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::underlay;
+# Copyright © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+# Licensed under the GNU GPL, version 2, or any later version published by the
+# Free Software Foundation
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "getsetup", id => "underlay",  call => \&getsetup);
+       hook(type => "checkconfig", id => "underlay", call => \&checkconfig);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 0,
+                       rebuild => undef,
+               },
+               add_underlays => {
+                       type => "string",
+                       default => [],
+                       description => "extra underlay directories to add",
+                       advanced => 1,
+                       safe => 0,
+                       rebuild => 1,
+               },
+}
+
+sub checkconfig () {
+       return unless exists $config{add_underlays};
+
+       foreach my $dir (@{$config{add_underlays}}) {
+               add_underlay($dir);
+       }
+}
+
+1;
index 18e9613aee76fd51e04681128af8646dab916963..587cd55fa8f608fc2309d23eaa91ad1e32539c62 100644 (file)
@@ -4,23 +4,23 @@ package IkiWiki::Plugin::version;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "version", call => \&getsetup);
        hook(type => "needsbuild", id => "version", call => \&needsbuild);
        hook(type => "preprocess", id => "version", call => \&preprocess);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => undef,
                },
-} #}}}
+}
 
-sub needsbuild (@) { #{{{
+sub needsbuild (@) {
        my $needsbuild=shift;
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{version}{shown}) {
@@ -36,11 +36,11 @@ sub needsbuild (@) { #{{{
                        }
                }
        }
-} # }}}
+}
 
-sub preprocess (@) { #{{{
+sub preprocess (@) {
        my %params=@_;
        $pagestate{$params{destpage}}{version}{shown}=$IkiWiki::version;
-} # }}}
+}
 
 1
index 827ee3099f31f0f091b6d76326842e0bfea1fd8e..95d044c08a5d46ada18308d6448efebede1732af 100644 (file)
@@ -3,17 +3,17 @@ package IkiWiki::Plugin::websetup;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "websetup", call => \&getsetup);
        hook(type => "checkconfig", id => "websetup", call => \&checkconfig);
        hook(type => "sessioncgi", id => "websetup", call => \&sessioncgi);
        hook(type => "formbuilder_setup", id => "websetup", 
             call => \&formbuilder_setup);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -33,15 +33,15 @@ sub getsetup () { #{{{
                        safe => 0,
                        rebuild => 0,
                },
-} #}}}
+}
 
-sub checkconfig () { #{{{
+sub checkconfig () {
        if (! exists $config{websetup_show_unsafe}) {
                $config{websetup_show_unsafe}=1;
        }
-} #}}}
+}
 
-sub formatexample ($$) { #{{{
+sub formatexample ($$) {
        my $example=shift;
        my $value=shift;
 
@@ -54,9 +54,9 @@ sub formatexample ($$) { #{{{
        else {
                return "";
        }
-} #}}}
+}
 
-sub showfields ($$$@) { #{{{
+sub showfields ($$$@) {
        my $form=shift;
        my $plugin=shift;
        my $enabled=shift;
@@ -139,7 +139,7 @@ sub showfields ($$$@) { #{{{
                my $value=$config{$key};
 
                if ($info{safe} && (ref $value eq 'ARRAY' || ref $info{example} eq 'ARRAY')) {
-                       $value=[@{$value}, "", ""]; # blank items for expansion
+                       $value=[(ref $value eq 'ARRAY' ? @{$value} : ""), "", ""]; # blank items for expansion
                }
 
                if ($info{type} eq "string") {
@@ -207,16 +207,16 @@ sub showfields ($$$@) { #{{{
        }
 
        return %enabledfields;
-} #}}}
+}
 
-sub enable_plugin ($) { #{{{
+sub enable_plugin ($) {
        my $plugin=shift;
 
        $config{disable_plugins}=[grep { $_ ne $plugin } @{$config{disable_plugins}}];
        push @{$config{add_plugins}}, $plugin;
 }
 
-sub disable_plugin ($) { #{{{
+sub disable_plugin ($) {
        my $plugin=shift;
 
        if (grep { $_ eq $plugin } @{$config{add_plugins}}) {
@@ -227,7 +227,7 @@ sub disable_plugin ($) { #{{{
        }
 }
 
-sub showform ($$) { #{{{
+sub showform ($$) {
        my $cgi=shift;
        my $session=shift;
 
@@ -441,9 +441,9 @@ sub showform ($$) { #{{{
        }
 
        IkiWiki::showform($form, $buttons, $session, $cgi);
-} #}}}
+}
 
-sub sessioncgi ($$) { #{{{
+sub sessioncgi ($$) {
        my $cgi=shift;
        my $session=shift;
 
@@ -451,9 +451,9 @@ sub sessioncgi ($$) { #{{{
                showform($cgi, $session);
                exit;
        }
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
 
        my $form=$params{form};
@@ -464,6 +464,6 @@ sub formbuilder_setup (@) { #{{{
                        exit;
                }
        }
-} #}}}
+}
 
 1
index c47ccb7b1aded4ea75f096122a39000bda34cdd1..accb03bbef8317cad028d95fe36a68b466d9bd0f 100644 (file)
@@ -4,29 +4,29 @@ package IkiWiki::Plugin::wikitext;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 
-sub import { #{{{
+sub import {
        hook(type => "getsetup", id => "wiki", call => \&getsetup);
        hook(type => "htmlize", id => "wiki", call => \&htmlize);
-} # }}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        return
                plugin => {
                        safe => 0, # format plugin
                        rebuild => undef,
                },
-} #}}}
+}
 
 
-sub htmlize (@) { #{{{
+sub htmlize (@) {
        my %params=@_;
        my $content = $params{content};
 
        eval q{use Text::WikiFormat};
        return $content if $@;
        return Text::WikiFormat::format($content, undef, { implicit_links => 0 });
-} # }}}
+}
 
 1
diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm
new file mode 100644 (file)
index 0000000..9ddd237
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::wmd;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+use POSIX;
+use Encode;
+
+sub import {
+       add_underlay("wmd");
+       hook(type => "getsetup", id => "wmd", call => \&getsetup);
+       hook(type => "formbuilder_setup", id => "wmd", call => \&formbuilder_setup);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+               },
+}
+
+sub formbuilder_setup (@) {
+       my %params=@_;
+       my $form=$params{form};
+
+       return if ! defined $form->field("do");
+       
+       return unless $form->field("do") eq "edit" ||
+                       $form->field("do") eq "create" ||
+                       $form->field("do") eq "comment";
+
+       $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
+               include_javascript(undef, 1));
+}
+
+sub include_javascript ($;$) {
+       my $page=shift;
+       my $absolute=shift;
+
+       my $wmdjs=urlto("wmd/wmd.js", $page, $absolute);
+       return <<"EOF"
+<script type="text/javascript">
+wmd_options = {
+       output: "Markdown"
+};
+</script>
+<script src="$wmdjs" type="text/javascript"></script>
+EOF
+}
+
+1
diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm
new file mode 100644 (file)
index 0000000..37b6f2a
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/bin/perl
+
+package IkiWiki::Receive;
+
+use warnings;
+use strict;
+use IkiWiki;
+
+sub getuser () {
+       my $user=(getpwuid(exists $ENV{CALLER_UID} ? $ENV{CALLER_UID} : $<))[0];
+       if (! defined $user) {
+               error("cannot determine username for $<");
+       }
+       return $user;
+}
+
+sub trusted () {
+       my $user=getuser();
+       return ! ref $config{untrusted_committers} ||
+               ! grep { $_ eq $user } @{$config{untrusted_committers}};
+}
+
+sub gen_wrapper () {
+       # Test for commits from untrusted committers in the wrapper, to
+       # avoid loading ikiwiki at all for trusted commits.
+
+       my $ret=<<"EOF";
+       {
+               int u=getuid();
+EOF
+       $ret.="\t\tif ( ".
+               join("&&", map {
+                       my $uid=getpwnam($_);
+                       if (! defined $uid) {
+                               error(sprintf(gettext("cannot determine id of untrusted committer %s"), $_));
+                       }
+                       "u != $uid";
+               } @{$config{untrusted_committers}}).
+               ") exit(0);\n";
+       $ret.=<<"EOF";
+               asprintf(&s, "CALLER_UID=%i", u);
+               newenviron[i++]=s;
+       }
+EOF
+       return $ret;
+}
+
+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};
+       error($@) if $@;
+       my $cgi=CGI->new;
+       $ENV{REMOTE_ADDR}='unknown' unless exists $ENV{REMOTE_ADDR};
+
+       # And dummy up a session object.
+       require IkiWiki::CGI;
+       my $session=IkiWiki::cgi_getsession($cgi);
+       $session->param("name", getuser());
+       # Make sure whatever user was authed is in the
+       # userinfo db.
+       require IkiWiki::UserInfo;
+       if (! IkiWiki::userinfo_get($session->param("name"), "regdate")) {
+               IkiWiki::userinfo_setall($session->param("name"), {
+                       email => "",
+                       password => "",
+                       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, $config{srcdir})) {
+                       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 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);
+       }
+
+       exit 0;
+}
+
+1
index bc997ffb0f0e655dd65540ba81e588ed6625e909..adae9f0d5898dee39190a29328fa7e221c82dcdc 100644 (file)
@@ -10,7 +10,7 @@ use Encode;
 my %backlinks;
 my $backlinks_calculated=0;
 
-sub calculate_backlinks () { #{{{
+sub calculate_backlinks () {
        return if $backlinks_calculated;
        %backlinks=();
        foreach my $page (keys %links) {
@@ -22,9 +22,9 @@ sub calculate_backlinks () { #{{{
                }
        }
        $backlinks_calculated=1;
-} #}}}
+}
 
-sub backlinks ($) { #{{{
+sub backlinks ($) {
        my $page=shift;
 
        calculate_backlinks();
@@ -45,9 +45,9 @@ sub backlinks ($) { #{{{
                push @links, { url => $href, page => pagetitle($p_trimmed) };
        }
        return @links;
-} #}}}
+}
 
-sub genpage ($$) { #{{{
+sub genpage ($$) {
        my $page=shift;
        my $content=shift;
 
@@ -131,9 +131,9 @@ sub genpage ($$) { #{{{
        });
 
        return $content;
-} #}}}
+}
 
-sub scan ($) { #{{{
+sub scan ($) {
        my $file=shift;
 
        my $type=pagetype($file);
@@ -165,9 +165,9 @@ sub scan ($) { #{{{
        else {
                will_render($file, $file, 1);
        }
-} #}}}
+}
 
-sub fast_file_copy (@) { #{{{
+sub fast_file_copy (@) {
        my $srcfile=shift;
        my $destfile=shift;
        my $srcfd=shift;
@@ -191,7 +191,7 @@ sub fast_file_copy (@) { #{{{
        }
 }
 
-sub render ($) { #{{{
+sub render ($) {
        my $file=shift;
        
        my $type=pagetype($file);
@@ -233,9 +233,9 @@ sub render ($) { #{{{
                        fast_file_copy($srcfile, $file, $srcfd, @_);
                });
        }
-} #}}}
+}
 
-sub prune ($) { #{{{
+sub prune ($) {
        my $file=shift;
 
        unlink($file);
@@ -243,14 +243,14 @@ sub prune ($) { #{{{
        while (rmdir($dir)) {
                $dir=dirname($dir);
        }
-} #}}}
+}
 
-sub refresh () { #{{{
+sub refresh () {
        # security check, avoid following symlinks in the srcdir path by default
        my $test=$config{srcdir};
        while (length $test) {
                if (-l $test && ! $config{allow_symlinks_before_srcdir}) {
-                       error(sprintf(gettext("symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to allow this")), $test);
+                       error(sprintf(gettext("symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to allow this"), $test));
                }
                unless ($test=~s/\/+$//) {
                        $test=dirname($test);
@@ -507,9 +507,9 @@ sub refresh () { #{{{
        if (%rendered) {
                run_hooks(change => sub { shift->(keys %rendered) });
        }
-} #}}}
+}
 
-sub commandline_render () { #{{{
+sub commandline_render () {
        lockwiki();
        loadindex();
        unlockwiki();
@@ -528,9 +528,10 @@ sub commandline_render () { #{{{
        $content=linkify($page, $page, $content);
        $content=htmlize($page, $page, $type, $content);
        $pagemtime{$page}=(stat($srcfile))[9];
+       $pagectime{$page}=$pagemtime{$page} if ! exists $pagectime{$page};
 
        print genpage($page, $content);
        exit 0;
-} #}}}
+}
 
 1
index 77afdd6084e94084ba8e6a09b8bba632f3adcbfc..6ee11209624a20a1a0080852b6f4a64dda756543 100644 (file)
@@ -10,7 +10,7 @@ use IkiWiki;
 use open qw{:utf8 :std};
 use File::Spec;
 
-sub load ($) { # {{{
+sub load ($) {
        my $setup=IkiWiki::possibly_foolish_untaint(shift);
        $config{setupfile}=File::Spec->rel2abs($setup);
 
@@ -27,7 +27,7 @@ sub load ($) { # {{{
 
        eval $code;
        error("$setup: ".$@) if $@;
-} #}}}
+}
 
 sub merge ($) {
        # Merge setup into existing config and untaint.
@@ -71,9 +71,9 @@ sub merge ($) {
                        wrappermode => (defined $config{cgi_wrappermode} ? $config{cgi_wrappermode} : "06755"),
                };
        }
-} #}}}
+}
 
-sub getsetup () { #{{{
+sub getsetup () {
        # Gets all available setup data from all plugins. Returns an
        # ordered list of [plugin, setup] pairs.
        my @ret;
@@ -105,9 +105,9 @@ sub getsetup () { #{{{
         $config{syslog}=$syslog;
 
        return @ret;
-} #}}}
+}
 
-sub dump ($) { #{{{
+sub dump ($) {
        my $file=IkiWiki::possibly_foolish_untaint(shift);
        
        require IkiWiki::Setup::Standard;
index 88e9f3d245c95a2da545b1899d0d4f2a468dbd93..7d9eca3afef7f929edfb8a1c4ddc1da2fc3be875 100644 (file)
@@ -9,21 +9,22 @@ use IkiWiki;
 use IkiWiki::UserInfo;
 use Term::ReadLine;
 use File::Path;
+use Encode;
 
-sub ask ($$) { #{{{
+sub ask ($$) {
        my ($question, $default)=@_;
 
        my $r=Term::ReadLine->new("ikiwiki");
-       $r->readline($question." ", $default);
-} #}}}
+       $r->readline(encode_utf8($question)." ", $default);
+}
 
-sub prettydir ($) { #{{{
+sub prettydir ($) {
        my $dir=shift;
        $dir=~s/^\Q$ENV{HOME}\E\//~\//;
        return $dir;
-} #}}}
+}
 
-sub import (@) { #{{{
+sub import (@) {
        my $this=shift;
        IkiWiki::Setup::merge({@_});
 
@@ -73,8 +74,18 @@ sub import (@) { #{{{
 
        print "\n\nSetting up $config{wikiname} ...\n";
 
-       # Set up the repository.
+       # Set up the srcdir.
        mkpath($config{srcdir}) || die "mkdir $config{srcdir}: $!";
+       # Copy in example wiki.
+       if (exists $config{example}) {
+               # cp -R is POSIX
+               # Another reason not to use -a is so that pages such as blog
+               # posts will not have old creation dates on this new wiki.
+               system("cp -R $IkiWiki::installdir/share/ikiwiki/examples/$config{example}/* $config{srcdir}");
+               delete $config{example};
+       }
+
+       # Set up the repository.
        delete $config{repository} if ! $config{rcs} || $config{rcs}=~/bzr|mercurial/;
        if ($config{rcs}) {
                my @params=($config{rcs}, $config{srcdir});
@@ -99,11 +110,20 @@ sub import (@) { #{{{
                next if $admin=~/^http\?:\/\//; # openid
                
                # Prompt for password w/o echo.
+               my ($password, $password2);
                system('stty -echo 2>/dev/null');
                local $|=1;
                print "\n\nCreating wiki admin $admin ...\n";
-               print "Choose a password: ";
-               chomp(my $password=<STDIN>);
+               for (;;) {
+                       print "Choose a password: ";
+                       chomp($password=<STDIN>);
+                       print "Confirm password: ";
+                       chomp($password2=<STDIN>);
+
+                       last if $password2 eq $password;
+
+                       print "Password mismatch.\n\n";
+               }
                print "\n\n\n";
                system('stty sane 2>/dev/null');
 
@@ -142,6 +162,6 @@ sub import (@) { #{{{
        print "To modify settings, edit ".prettydir($config{dumpsetup})." and then run:\n";
        print " ikiwiki -setup ".prettydir($config{dumpsetup})."\n";
        exit 0;
-} #}}}
+}
 
 1
index 92f887f0c4c1b565f1949b963e40da94e88c08be..951bcfc56febfce724d82c652f96468c227709d2 100644 (file)
@@ -9,11 +9,11 @@ use warnings;
 use strict;
 use IkiWiki;
 
-sub import { #{{{
+sub import {
        IkiWiki::Setup::merge($_[1]);
-} #}}}
+}
 
-sub dumpline ($$$$) { #{{{
+sub dumpline ($$$$) {
        my $key=shift;
        my $value=shift;
        my $type=shift;
@@ -26,6 +26,8 @@ sub dumpline ($$$$) { #{{{
        local $Data::Dumper::Pad="\t";
        local $Data::Dumper::Sortkeys=1;
        local $Data::Dumper::Quotekeys=0;
+       # only the perl version preserves utf-8 in output
+       local $Data::Dumper::Useperl=1;
        
        my $dumpedvalue;
        if (($type eq 'boolean' || $type eq 'integer') && $value=~/^[0-9]+$/) {
@@ -53,9 +55,9 @@ sub dumpline ($$$$) { #{{{
        }
        
        return "\t$prefix$key => $dumpedvalue,";
-} #}}}
+}
 
-sub dumpvalues ($@) { #{{{
+sub dumpvalues ($@) {
        my $setup=shift;
        my @ret;
        while (@_) {
@@ -78,9 +80,9 @@ sub dumpvalues ($@) { #{{{
                }
        }
        return @ret;
-} #}}}
+}
 
-sub gendump ($) { #{{{
+sub gendump ($) {
        my $description=shift;
        my %setup=(%config);
        my @ret;
@@ -110,6 +112,6 @@ sub gendump ($) { #{{{
        push @ret, "}";
 
        return @ret;
-} #}}}
+}
 
 1
index dcf99da09bda07fbb5a643f3f4fa6a9d3a436f78..0bf100a959c934d23c8f73ac1f0962f856732a35 100644 (file)
@@ -7,12 +7,12 @@ use strict;
 use Storable;
 use IkiWiki;
 
-sub userinfo_retrieve () { #{{{
+sub userinfo_retrieve () {
        my $userinfo=eval{ Storable::lock_retrieve("$config{wikistatedir}/userdb") };
        return $userinfo;
-} #}}}
+}
 
-sub userinfo_store ($) { #{{{
+sub userinfo_store ($) {
        my $userinfo=shift;
        
        my $newfile="$config{wikistatedir}/userdb.new";
@@ -26,9 +26,9 @@ sub userinfo_store ($) { #{{{
                }
        }
        return $ret;
-} #}}}
+}
 
-sub userinfo_get ($$) { #{{{
+sub userinfo_get ($$) {
        my $user=shift;
        my $field=shift;
 
@@ -39,9 +39,9 @@ sub userinfo_get ($$) { #{{{
                return "";
        }
        return $userinfo->{$user}->{$field};
-} #}}}
+}
 
-sub userinfo_set ($$$) { #{{{
+sub userinfo_set ($$$) {
        my $user=shift;
        my $field=shift;
        my $value=shift;
@@ -54,9 +54,9 @@ sub userinfo_set ($$$) { #{{{
        
        $userinfo->{$user}->{$field}=$value;
        return userinfo_store($userinfo);
-} #}}}
+}
 
-sub userinfo_setall ($$) { #{{{
+sub userinfo_setall ($$) {
        my $user=shift;
        my $info=shift;
        
@@ -66,32 +66,12 @@ sub userinfo_setall ($$) { #{{{
        }
        $userinfo->{$user}=$info;
        return userinfo_store($userinfo);
-} #}}}
+}
 
-sub is_admin ($) { #{{{
+sub is_admin ($) {
        my $user_name=shift;
 
        return grep { $_ eq $user_name } @{$config{adminuser}};
-} #}}}
-
-# XXX deprecated, should be removed eventually
-sub get_banned_users () { #{{{
-       my @ret;
-       my $userinfo=userinfo_retrieve();
-       foreach my $user (keys %{$userinfo}) {
-               push @ret, $user if $userinfo->{$user}->{banned};
-       }
-       return @ret;
-} #}}}
-
-# XXX deprecated, should be removed eventually
-sub set_banned_users (@) { #{{{
-       my %banned=map { $_ => 1 } @_;
-       my $userinfo=userinfo_retrieve();
-       foreach my $user (keys %{$userinfo}) {
-               $userinfo->{$user}->{banned} = $banned{$user};
-       }
-       return userinfo_store($userinfo);
-} #}}}
+}
 
 1
index 187314d165ff86e07e318f5861b4461d78da70cd..6555fe625f8e542e786f3b6d7d05a72772ea207f 100644 (file)
@@ -8,7 +8,7 @@ use File::Spec;
 use Data::Dumper;
 use IkiWiki;
 
-sub gen_wrapper () { #{{{
+sub gen_wrapper () {
        $config{srcdir}=File::Spec->rel2abs($config{srcdir});
        $config{destdir}=File::Spec->rel2abs($config{destdir});
        my $this=File::Spec->rel2abs($0);
@@ -28,34 +28,84 @@ sub gen_wrapper () { #{{{
        my @envsave;
        push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
                       CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
-                      HTTP_COOKIE REMOTE_USER HTTPS} if $config{cgi};
+                      HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS
+                      REDIRECT_URL} if $config{cgi};
        my $envsave="";
        foreach my $var (@envsave) {
-               $envsave.=<<"EOF"
+               $envsave.=<<"EOF";
        if ((s=getenv("$var")))
                addenv("$var", s);
 EOF
        }
-       
+
+       my $test_receive="";
+       if ($config{test_receive}) {
+               require IkiWiki::Receive;
+               $test_receive=IkiWiki::Receive::gen_wrapper();
+       }
+
+       my $check_commit_hook="";
+       my $pre_exec="";
+       if ($config{post_commit}) {
+               # Optimise checking !commit_hook_enabled() , 
+               # so that ikiwiki does not have to be started if the
+               # hook is disabled.
+               #
+               # Note that perl's flock may be implemented using fcntl
+               # or lockf on some systems. If so, and if there is no
+               # interop between the locking systems, the true C flock will
+               # always succeed, and this optimisation won't work.
+               # The perl code will later correctly check the lock,
+               # so the right thing will still happen, though without
+               # the benefit of this optimisation.
+               $check_commit_hook=<<"EOF";
+       {
+               int fd=open("$config{wikistatedir}/commitlock", O_CREAT | O_RDWR, 0666);
+               if (fd != -1) {
+                       if (flock(fd, LOCK_SH | LOCK_NB) != 0)
+                               exit(0);
+                       close(fd);
+               }
+       }
+EOF
+       }
+       elsif ($config{cgi}) {
+               # Avoid more than one ikiwiki cgi running at a time by
+               # taking a cgi lock. Since ikiwiki uses several MB of
+               # memory, a pile up of processes could cause thrashing
+               # otherwise. The fd of the lock is stored in
+               # IKIWIKI_CGILOCK_FD so unlockwiki can close it.
+               $pre_exec=<<"EOF";
+       {
+               int fd=open("$config{wikistatedir}/cgilock", O_CREAT | O_RDWR, 0666);
+               if (fd != -1 && flock(fd, LOCK_EX) == 0) {
+                       char *fd_s;
+                       asprintf(&fd_s, "%i", fd);
+                       setenv("IKIWIKI_CGILOCK_FD", fd_s, 1);
+               }
+       }
+EOF
+       }
+
        $Data::Dumper::Indent=0; # no newlines
        my $configstring=Data::Dumper->Dump([\%config], ['*config']);
        $configstring=~s/\\/\\\\/g;
        $configstring=~s/"/\\"/g;
        $configstring=~s/\n/\\n/g;
        
-       #translators: The first parameter is a filename, and the second is
-       #translators: a (probably not translated) error message.
-       open(OUT, ">$wrapper.c") || error(sprintf(gettext("failed to write %s: %s"), "$wrapper.c", $!));;
-       print OUT <<"EOF";
+       writefile(basename("$wrapper.c"), dirname($wrapper), <<"EOF");
 /* A wrapper for ikiwiki, can be safely made suid. */
 #include <stdio.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/file.h>
 
 extern char **environ;
-char *newenviron[$#envsave+5];
+char *newenviron[$#envsave+6];
 int i=0;
 
 addenv(char *var, char *val) {
@@ -67,8 +117,10 @@ addenv(char *var, char *val) {
 }
 
 int main (int argc, char **argv) {
-       /* Sanitize environment. */
        char *s;
+
+$check_commit_hook
+$test_receive
 $envsave
        newenviron[i++]="HOME=$ENV{HOME}";
        newenviron[i++]="WRAPPED_OPTIONS=$configstring";
@@ -86,6 +138,7 @@ $envsave
                exit(1);
        }
 
+$pre_exec
        execl("$this", "$this", NULL);
        perror("exec $this");
        exit(1);
@@ -118,6 +171,6 @@ EOF
        #translators: The parameter is a filename.
        printf(gettext("successfully generated %s"), $wrapper);
        print "\n";
-} #}}}
+}
 
 1
index 95e574c66f370e9ade0816fb92c6c29e03a8ab54..93f9e89e2ab3314e6cc4ed85321c7168a3f1f67d 100755 (executable)
@@ -23,6 +23,9 @@ 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:Profile"; fi)
 
@@ -39,7 +42,7 @@ extra_build: ikiwiki.out ikiwiki.setup docwiki
        ./mdwn2man ikiwiki-makerepo 1 doc/ikiwiki-makerepo.mdwn > ikiwiki-makerepo.man
        ./mdwn2man ikiwiki-transition 1 doc/ikiwiki-transition.mdwn > ikiwiki-transition.man
        ./mdwn2man ikiwiki-update-wikilist 1 doc/ikiwiki-update-wikilist.mdwn > ikiwiki-update-wikilist.man
-       $(MAKE) -C po mo
+       $(MAKE) -C po
        
 docwiki: ikiwiki.out
        $(PERL) -Iblib/lib $(extramodules) $(tflag) ikiwiki.out -libdir . -setup docwiki.setup -refresh
@@ -54,6 +57,7 @@ extra_install:
        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 \
+                       cp -aL $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir 2>/dev/null || \
                        install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
                done; \
        done
@@ -65,6 +69,15 @@ extra_install:
                        install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/directives/ikiwiki/directive; \
                fi \
        done
+       
+       # Install example sites.
+       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 \
+               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 \
                install -d $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
@@ -74,10 +87,10 @@ extra_install:
        done
        
        install -d $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins
-       for file in `find plugins -maxdepth 1 -type f ! -wholename 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 ! -wholename 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
 
@@ -93,8 +106,8 @@ extra_install:
        install -d $(DESTDIR)$(PREFIX)/sbin
        install ikiwiki-mass-rebuild $(DESTDIR)$(PREFIX)/sbin
 
-       install -d $(DESTDIR)$(PREFIX)/lib/w3m/cgi-bin
-       install ikiwiki-w3m.cgi $(DESTDIR)$(PREFIX)/lib/w3m/cgi-bin
+       install -d $(DESTDIR)$(W3M_CGI_BIN)
+       install ikiwiki-w3m.cgi $(DESTDIR)$(W3M_CGI_BIN)
 
        install -d $(DESTDIR)$(PREFIX)/bin
        install ikiwiki.out $(DESTDIR)$(PREFIX)/bin/ikiwiki
@@ -107,6 +120,7 @@ extra_install:
        -install -d $(DESTDIR)/etc/ikiwiki
        -install -m 0644 wikilist $(DESTDIR)/etc/ikiwiki
        -install -m 0644 auto.setup $(DESTDIR)/etc/ikiwiki
+       -install -m 0644 auto-blog.setup $(DESTDIR)/etc/ikiwiki
 }
 }
 
diff --git a/auto-blog.setup b/auto-blog.setup
new file mode 100644 (file)
index 0000000..3ef734b
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+# Ikiwiki setup automator -- blog version.
+# 
+# This setup file causes ikiwiki to create a wiki, containing a blog,
+# check it into revision control, generate a setup file for the new
+# wiki, and set everything up.
+#
+# Just run: ikiwiki -setup /etc/ikiwiki/auto-blog.setup
+#
+# By default, it asks a few questions, and confines itself to the user's home
+# directory. You can edit it to change what it asks questions about, or to
+# modify the values to use site-specific settings.
+
+require IkiWiki::Setup::Automator;
+
+our $wikiname=IkiWiki::Setup::Automator::ask(
+       gettext("What will the blog be named?"), gettext("blog"));
+our $rcs=IkiWiki::Setup::Automator::ask(
+       gettext("What revision control system to use?"), "git");
+our $admin=IkiWiki::Setup::Automator::ask(
+       gettext("What wiki user (or openid) will be admin?"), $ENV{USER});
+use Net::Domain q{hostfqdn};
+our $domain=hostfqdn() || ikiwiki::setup::automator::ask(
+       gettext("What is the domain name of the web server?"), "");
+
+IkiWiki::Setup::Automator->import(
+       wikiname => $wikiname,
+       adminuser => [$admin],
+       rcs => $rcs,
+       srcdir => "$ENV{HOME}/$wikiname",
+       destdir => "$ENV{HOME}/public_html/$wikiname",
+       repository => "$ENV{HOME}/$wikiname.".($rcs eq "monotone" ? "mtn" : $rcs),
+       dumpsetup => "$ENV{HOME}/$wikiname.setup",
+       url => "http://$domain/~$ENV{USER}/$wikiname",
+       cgiurl => "http://$domain/~$ENV{USER}/$wikiname/ikiwiki.cgi",
+       cgi_wrapper => "$ENV{HOME}/public_html/$wikiname/ikiwiki.cgi",
+       adminemail => "$ENV{USER}\@$domain",
+       add_plugins => [qw{goodstuff websetup comments blogspam}],
+       disable_plugins => [qw{}],
+       libdir => "$ENV{HOME}/.ikiwiki",
+       rss => 1,
+       atom => 1,
+       syslog => 1,
+       
+       example => "blog",
+       comments_pagespec => "posts/* and !*/Discussion",
+       blogspam_pagespec => "postcomment(*)",
+       discussion => 0,
+)
index ef0f1723c9e48be1937ab9e1886a6074c405b15d..3da5e3a621cc32c2b11b8a9e3d03efd953232231 100644 (file)
@@ -17,7 +17,7 @@ our $wikiname=IkiWiki::Setup::Automator::ask(
 our $rcs=IkiWiki::Setup::Automator::ask(
        gettext("What revision control system to use?"), "git");
 our $admin=IkiWiki::Setup::Automator::ask(
-       gettext("What wiki user (or openid) will be wiki admin?"), $ENV{USER});
+       gettext("What wiki user (or openid) will be admin?"), $ENV{USER});
 use Net::Domain q{hostfqdn};
 our $domain=hostfqdn() || ikiwiki::setup::automator::ask(
        gettext("What is the domain name of the web server?"), "");
@@ -40,6 +40,4 @@ IkiWiki::Setup::Automator->import(
        rss => 1,
        atom => 1,
        syslog => 1,
-       prefix_directives => 1,
-       hardlink => 1,
 )
index a7a145d9bce7ee3a1bf307d73d2473ad862631f3..22513cc4a204e88b10ad5a26861f4463cf13b5f9 100644 (file)
@@ -1,3 +1,27 @@
+ikiwiki (3.01) unstable; urgency=low
+
+  If your wiki uses git, and you have a `diffurl` configured in
+  its setup file, you should be aware that gitweb has stopped
+  supporting the url form commonly used for the `diffurl`.
+
+  You can change your setup to use the newer gitweb url form:
+
+    http://git.example.com/gitweb.cgi?p=wiki.git;a=blobdiff;f=[[file]];h=[[sha1_to]];hp=[[sha1_from]];hb=[[sha1_commit]];hpb=[[sha1_parent]]
+
+  The changes from the old form are the addition of the `hpb` parameter,
+  and the change to the value used for the `hb` parameter.
+
+ -- Joey Hess <joeyh@debian.org>  Mon, 05 Jan 2009 18:18:05 -0500
+
+ikiwiki (3.00) unstable; urgency=low
+
+  The 3.0 release of ikiwiki changes several defaults and finishes
+  some transitions. You will need to modify your wikis to work with
+  ikiwiki 3.0. A document explaining the process is available
+  in </usr/share/doc/ikiwiki/html/tips/upgrade_to_3.0.html>
+
+ -- Joey Hess <joeyh@debian.org>  Tue, 23 Dec 2008 16:14:18 -0500
+
 ikiwiki (2.62) unstable; urgency=low
 
   TexImg standard preamble changed
@@ -101,10 +125,7 @@ ikiwiki (2.40) unstable; urgency=low
   in their setup files.
 
   To convert your wiki to the new syntax, ikiwiki provides a new script
-  ikiwiki-transition.  It will convert preprocessor directives in
-  all files given on the command line.  To convert an entire wiki:
-
-  find wikidir/ -type f -name '*.mdwn' -print0 | xargs -0 ikiwiki-transition prefix_directives
+  ikiwiki-transition.
 
   Even with prefix_directives disabled, ikiwiki now allows an optional '!'
   prefix on preprocessor directives (but still requires a space).  Thus, a
index ecef4f158c6f0ae16bdfe11f744c4c034ae2b8b6..fab20985d20c5abf2179ffbdd06aa450ff56b7a2 100644 (file)
@@ -1,4 +1,295 @@
-ikiwiki (2.67) UNRELEASED; urgency=low
+ikiwiki (3.09) unstable; urgency=low
+
+  * inline: Add title_natural sort order, using Sort::Naturally
+    (chrysn)
+  * inline: Fix urls to feed when feedfile is used on an index page.
+  * git, mercurial: Fix --getctime to return file creation time,
+    not last commit time.
+  * Updated French translation (Jean-Luc Coulon). Closes: #521072
+  * css: Add clear: both to inlinefooter.
+  * comments: Fix too loose test for comments pages that matched
+    normal pages with "comment_" in their name. Closes: #521322
+  * comments: Fix anchor ids to be legal xhtml. Closes: #521339
+  * Fix documentation of anonok_pagespec. Closes: #521793
+  * Add missing suggests on libtext-textile-perl. Closes: #522039
+  * recentchanges: change to using do=goto links for user links.
+  * Fix git test suite to use a bare repo.
+
+ -- Joey Hess <joeyh@debian.org>  Sat, 04 Apr 2009 14:33:49 -0400
+
+ikiwiki (3.08) unstable; urgency=low
+
+  * git: Fix utf-8 encoding of author names.
+  * git: Manually decode git output from utf-8, avoids
+    warning messages on invalidly encoded output.
+  * Fix bug that caused weird things to appear as page types.
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 15 Mar 2009 17:54:47 -0400
+
+ikiwiki (3.07) unstable; urgency=low
+  * Updated German translation (Kai Wasserbäch). Closes: #518377
+  * Updated French translation (Jean-Luc Coulon). Closes: #518510
+  * wmd: New plugin contributed by William Uther to support the WMD
+    Wysiwym markdown editor.
+  * smiley: Avoid infinite loop in smiley expansion triggered
+    by the template scan mode change in version 3.05. Closes: #518805
+  * template: When loading a template in scan mode, let preprocess
+    know it only needs to scan.
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 08 Mar 2009 19:00:46 -0400
+
+ikiwiki (3.06) unstable; urgency=low
+
+  * Setup automator: Fix bug in password comparison. Closes: #517654
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 01 Mar 2009 15:02:30 -0500
+
+ikiwiki (3.05) unstable; urgency=low
+
+  * debhelper v7(.0.50); rules file minimisation.
+  * template: Load templates in scan mode.
+    This is potentially expensive, but is necessary so that meta and tag
+    directives, and other links on templates affect the page using the
+    template reliably.
+  * goto: Fix redirect to comments.
+  * Add noextension parameter to htmlize hooks to support, eg, Makefile.
+  * Add tagged() PageSpec.
+  * Updated German translation (Kai Wasserbäch). Closes: #516770
+  * Setup automator: Prompt for password twice. Closes: #516973
+  * bzr: Add missing rcs_diff. (liw)
+  * comments: Avoid showing comment moderation button in prefs to non-admins.
+  * goto: Fix typo that broke recentchanges_link compatibility.
+
+ -- Joey Hess <joeyh@debian.org>  Fri, 27 Feb 2009 15:48:39 -0500
+
+ikiwiki (3.04) unstable; urgency=low
+
+  * 404: New plugin which lets you use the IkiWiki CGI script as
+    an Apache 404 handler, to give the behaviour of various other wiki
+    engines where visiting a nonexistent page provides you with a link
+    to create it. (smcv)
+  * Factor out redundant code into goto plugin. (smcv)
+  * Work around XML::Atom strangeness that results in double-encoded posts.
+    (smcv) 
+  * Fix unusual --setup --post-commit command line option combo.
+  * Create any missing directory necessary to put the wrapper
+    file into. Closes: #514384
+  * shortcut: If default_pageext is set, first look for
+    shortcuts.default_pageext.
+  * Allow comments, rename, remove, and attachment plugins to be used
+    even if the editpage plugin is disabled.
+
+ -- Joey Hess <joeyh@debian.org>  Sat, 14 Feb 2009 02:27:14 -0500
+
+ikiwiki (3.03) unstable; urgency=low
+
+  * Avoid feeding decoded unicode to Term::ReadLine. Closes: 512169
+  * blogspam: Log spam info on failure in debug mode.
+  * Remove nonstandard css. Closes: #512378
+  * blogspam: Fix use of blogspam_options and blogspam_server config settings.
+  * comments: If comment content checks fail, store the comment
+    (in .ikiwiki/comments_pending) for moderator review.
+  * comments: Add a moderation web interface, which admins can
+    access via their Preferences page.
+  * git: Fix malformed utf8 received from git.
+  * meta: New "updated" metadata specifies a fake modification time for a
+    page, to be output into RSS and Atom feeds. (smcv)
+  * underlay: New plugin, allows pulling in additional files not
+    in version control. (smcv) 
+
+ -- Joey Hess <joeyh@debian.org>  Thu, 29 Jan 2009 14:36:58 -0500
+
+ikiwiki (3.02) unstable; urgency=low
+
+  * blogspam: New plugin, adding spam filtering for page editing / comment
+    posting using the BlogSpam.net API.
+  * Add auto-blog.setup, which will set up an ikiwiki instance tuned for use
+    in blogging.
+  * checkcontent: New hook, can be used to implement arbitrary content
+    filters, including spam filters.
+  * table: Fix misparsed links in external files.
+  * table: Find links in external files in scan pass.
+  * rename: Show full names of affected pages.
+  * comments: Fix cache avoidance hack.
+  * repolist: New plugin to support the rel=vcs-* microformat.
+  * goodstuff: Include repolist by default. (But it does nothing until
+    configured with the repository locations.)
+  * comments: Add support for removing comments via web interface. (smcv)
+  * Consistently allow use of relative paths in all PageSpecs
+    that take a page name parameter. Previously, match_created_before(),
+    match_created_after(), match_sourcepage(), and match_destpage()
+    did not support that, and the docs were not clear.
+  * pinger: Get whole url, don't just head, avoids problems on
+    the nostromo web server.
+  * Recommend libterm-readline-gnu-perl since that makes auto.setup
+    behave better.
+
+ -- Joey Hess <joeyh@debian.org>  Sat, 17 Jan 2009 18:19:39 -0500
+
+ikiwiki (3.01) unstable; urgency=low
+
+  * ikiwiki-makerepo: Fix injecting of empty mercurial and bzr repositories.
+    Closes: #510518
+  * Fix documentation about git hook to use right name. Closes: #510393
+  * yesno: Always accept English even when localised.
+  * yesno: Also accept 1 and 0 as input.
+  * A recent change to gitweb removed support for the form of diffurl 
+    that many ikiwiki setups use. Document how to use the new url form.
+
+ -- Joey Hess <joeyh@debian.org>  Mon, 05 Jan 2009 18:53:50 -0500
+
+ikiwiki (3.00) unstable; urgency=low
+
+  * Remove support for GlobLists.
+  * Remove support for configuring allowed attachments, locked pages,
+    and banned users from the admin preferences page. These can only be
+    controlled via the setup file now.
+  * ikiwiki-transition moveprefs can be used to move the above
+    admin preferences into a setup file.
+  * prefix_directives and aggregate_internal are now turned on by default.
+  * ikiwiki-transition prefix_directives syntax changed
+  * googlecalendar: removed this deprecated plugin. Use htmlscrubber_skip
+    instead.
+  * embed: This plugin is deprecated, use htmlscrubber_skip instead.
+    Closes: ##462970.
+  * Version 3.00 of the plugin API.
+  * Replace blank OpenID placeholder logo with an unofficial OpenID
+    logo developed by Anna Hess. The official logo does not seem destined to
+    be free.
+  * comments: Add cache avoidance.
+  * htmlbalance: Demand-load HTML::TreeBuilder to avoid failing test suite
+    if it is not present.
+  * French translation update from Philippe Batailler. Closes: #510216
+  * websetup: Avoid a crash when a new array setup item has been added in 
+    a new ikiwiki release, and is thus not present in the setup file yet.
+
+ -- Joey Hess <joeyh@debian.org>  Wed, 31 Dec 2008 15:17:47 -0500
+
+ikiwiki (2.72) unstable; urgency=low
+
+  * Avoid comments in recentchanges being broken links (smcv)
+  * Add deprecation warning for GlobLists, which will stop working in 3.0.
+  * camelcase: Add camelcase_ignore setting.
+  * googlecalendar: Add runtime deprecation warning.
+  * comments: Deal with users entering unqualified or partial urls.
+  * inline: Run format hook first, to ensure other format hooks can affect
+    inlined content.  Closes: #509710
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 28 Dec 2008 15:01:02 -0500
+
+ikiwiki (2.71) unstable; urgency=low
+
+  * comments: Blog-style comment support, contributed by Simon McVittie.
+  * htmlbalance: New plugin contributed by Simon McVittie.
+  * Change deb dependencies to list Text::Markdown before markdown (really
+    this time).
+  * Improve escaping of wikilinks and preprocessor directives in content
+    produced by aggregate and recentchanges.
+  * French translation update from Philippe Batailler. Closes: #506250
+  * Spanish translation update from Victor Moral.
+  * Fix handling of wrappergroup option.
+  * Correct --dumpsetup to include the srcdir in the setup file.
+  * German translation update from Kai Wasserbäch. Closes: #507056
+  * inline: Support emptyfeeds=no option to skip generating empty feeds.
+  * inline: Support feedfile option to change the filename of the feed
+    generated.
+  * meta: Pass info to htmlscrubber so htmlscrubber_skip can take effect.
+  * htmlbalance: don't compact whitespace, and set misc other options (smcv)
+  * rename: Fix double-escaping of page name in edit box.
+  * monotone: When getting the log, tell monotone how many entries
+    we want, rather than closing the pipe, which it dislikes. (thm)
+  * Coding style change: Remove explcit vim folding markers.
+  * aggregate: If a feed fails to be downloaded, try again immediatly
+    next time aggregation is run, even if the usual time has not passed.
+    Closes: #508622 (Michael Gold)
+  * meta: Process meta date during scan pass so that the date will always
+    affect sorting in inlines.
+  * Improve display of some openids (smcv)
+
+ -- Joey Hess <joeyh@debian.org>  Sun, 21 Dec 2008 16:22:05 -0500
+
+ikiwiki (2.70) unstable; urgency=low
+
+  * Avoid crash on malformed utf-8 discovered by intrigeri.
+
+ -- Joey Hess <joeyh@debian.org>  Wed, 12 Nov 2008 17:45:58 -0500
+
+ikiwiki (2.69) unstable; urgency=low
+
+  * Avoid multiple ikiwiki cgi processes piling up, eating all memory,
+    and thrashing, by making the cgi wrapper wait on a cgilock.
+    If you had to set apache's MaxClients low to avoid ikiwiki thrashing your
+    server, you can now turn it up to a high value.
+  * Stop busy-waiting in lockwiki, as this could delay ikiwiki from waking up
+    for up to one second. The bailout code is no longer needed after above
+    change.
+  * Remove support for unused optional wait parameter from lockwiki.
+  * aggregate: Try to query XML::Feed for the base url when derelevatising
+    links. Since this needs the just released XML::Feed 0.3, as well 
+    as a not yet released XML::RSS, it will fall back to the old method
+    if no xml:base info is available.
+  * meta: Plugin is now enabled by default since the basewiki uses it.
+  * txt: Do not encode quotes when filtering the txt, as that broke
+    later parsing of any directives on the page.
+  * Fix the link() pagespec to match links that are internally recorded as
+    absolute.
+  * Add rel=nofollow to recentchanges_links for the same (weak) reasons it
+    was earlier added to edit links.
+  * tag: Normalize tagbase so leading/trailing slashes in it don't break
+    things.
+  * bzr: Fix dates for recentchanges.
+
+ -- Joey Hess <joeyh@debian.org>  Tue, 11 Nov 2008 20:35:55 -0500
+
+ikiwiki (2.68) unstable; urgency=low
+
+  * Add support for checking pushes from untrusted git committers. This can be
+    used to set up anonymous git pushes, and other similar things.
+  * format: New plugin, allows embedding differently formatted text inside a
+    page (ie, otl inside a mdwn page, or syntax highlighted code inside a
+    page).
+  * relativedate: New javascript-alicious plugin that makes all dates display
+    relative, in a very nice way, if I say so myself.
+  * Optimise the no-op post-commit hook, to speed up web edits by a fraction
+    of a second.
+  * git: Allow [[sha1_commit]] to be used in the diffurl, to support cgit.
+  * shortcut: Fix display of shortcuts while previewing.
+  * Plugins that used to override displaytime should instead override
+    formattime. displaytime will call that, and may wrap markup around the
+    formatted time.
+  * Add an underlay for javascript, and add ikiwiki.js containing some utility
+    code.
+  * toggle: Stop embedding the full toggle code on each page using it, and
+    move it to toggle.js in the javascript underlay.
+  * recentchanges: Make feed links point back to anchors on the recentchanges
+    page. (JasonBlevins)
+  * Fix issue with utf-8 in wikiname breaking session cookies, by
+    entity-encoding the wikiname in the session cookie.
+  * Use the pure perl Data::Dumper when generating setup files to ensure that
+    utf-8 characters are written out as such, and not as the encoded perl
+    strings the C Data::Dumper produces.
+  * inline: Only the last feed link was put on the page, fix this to include
+    all feed links. So rss will be included along with atom, and pages with
+    multiple feeds will get links added for all feeds.
+  * tag: When tagbase is set, force the links created by tagging to point at
+    the toplevel tagbase, and not closer subpages. The html links already went
+    there, but internally the links were not recorded as absolute, which could
+    cause confusing backlinks etc.
+  * Add an inject function, that can be used by plugins that want to
+    replace one of ikiwiki's functions with their own version.
+    (This is a scary thing that grubs through the symbol table, and replaces
+    all exported occurances of a function with the injected version.)
+  * external: RPC functions can be injected to replace exported functions.
+  * Updated French translation. Closes: #502694
+  * Updated Spanish translation from the ever vigilant Victor Moral.
+  * Updated Danish translation from Jonas Smedegaard. Closes: #503117
+  * Preserve syslog setting when doing `ikiwiki -setup foo -dumpsetup bar`
+  * Several fixes to --render mode.
+
+ -- Joey Hess <joeyh@debian.org>  Mon, 03 Nov 2008 16:31:11 -0500
+
+ikiwiki (2.67) unstable; urgency=low
 
   * remove: Avoid $_ breakage. (Stupid, stupid perl.)
   * Updated Spanish translation from Victor Moral.
@@ -13,8 +304,10 @@ ikiwiki (2.67) UNRELEASED; urgency=low
   * inline: Allow MTIME to be used in inlinepage.tmpl.
   * inline: Use the feed's description in the rss and atom links.
     Closes: #502113
+  * aggregate: Avoid bug that caused immediate expiration of items
+    with a date in the future.
 
- -- Joey Hess <joeyh@debian.org>  Mon, 06 Oct 2008 16:07:50 -0400
+ -- Joey Hess <joeyh@debian.org>  Fri, 17 Oct 2008 13:13:41 -0400
 
 ikiwiki (2.66) unstable; urgency=low
 
index 7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69..7f8f011eb73d6043d2e6db9d2c101195ae2801f2 100644 (file)
@@ -1 +1 @@
-5
+7
index fdf2a3a36074593ce14196b57b60a1e21ed8c43f..a0769cbce7f3f0630e501a92b9267e79bd076755 100644 (file)
@@ -1,7 +1,7 @@
 Source: ikiwiki
 Section: web
 Priority: optional
-Build-Depends: perl, debhelper (>= 5)
+Build-Depends: perl, debhelper (>= 7.0.50)
 Build-Depends-Indep: dpkg-dev (>= 1.9.0), libxml-simple-perl, libtext-markdown-perl | markdown, libtimedate-perl, libhtml-template-perl, libhtml-scrubber-perl, wdg-html-validator, libhtml-parser-perl, liburi-perl, perlmagick
 Maintainer: Joey Hess <joeyh@debian.org>
 Uploaders: Josh Triplett <josh@freedesktop.org>
@@ -12,9 +12,9 @@ Vcs-Browser: http://git.ikiwiki.info/?p=ikiwiki
 
 Package: ikiwiki
 Architecture: all
-Depends: ${perl:Depends}, markdown | libtext-markdown-perl, libhtml-scrubber-perl, libhtml-template-perl, libhtml-parser-perl, liburi-perl
-Recommends: gcc | c-compiler, libc6-dev | libc-dev, subversion | git-core (>= 1:1.5.0) | tla | bzr (>= 0.91) | mercurial | monotone (>= 0.38), libxml-simple-perl, libnet-openid-consumer-perl, liblwpx-paranoidagent-perl, libtimedate-perl, libcgi-formbuilder-perl (>= 3.05), libcgi-session-perl (>= 4.14-1), libmail-sendmail-perl, libauthen-passphrase-perl
-Suggests: viewvc | gitweb | viewcvs, libsearch-xapian-perl, xapian-omega (>= 1.0.5), librpc-xml-perl, libtext-wikiformat-perl, python, python-docutils, polygen, tidy, libxml-feed-perl, libmailtools-perl, perlmagick, libfile-mimeinfo-perl, libcrypt-ssleay-perl, liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl, libtext-csv-perl, libdigest-sha1-perl, graphviz, libnet-amazon-s3-perl, sparkline-php, texlive, dvipng
+Depends: ${misc:Depends}, ${perl:Depends}, libtext-markdown-perl | markdown, libhtml-scrubber-perl, libhtml-template-perl, libhtml-parser-perl, liburi-perl
+Recommends: gcc | c-compiler, libc6-dev | libc-dev, subversion | git-core (>= 1:1.5.0) | tla | bzr (>= 0.91) | mercurial | monotone (>= 0.38), libxml-simple-perl, libnet-openid-consumer-perl, liblwpx-paranoidagent-perl, libtimedate-perl, libcgi-formbuilder-perl (>= 3.05), libcgi-session-perl (>= 4.14-1), libmail-sendmail-perl, libauthen-passphrase-perl, libterm-readline-gnu-perl
+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, liblocale-gettext-perl (>= 1.05-1), libtext-typography-perl, libtext-csv-perl, libdigest-sha1-perl, graphviz, libnet-amazon-s3-perl, sparkline-php, texlive, dvipng, libtext-wikicreole-perl, libsort-naturally-perl, libtext-textile-perl
 Conflicts: ikiwiki-plugin-table
 Replaces: ikiwiki-plugin-table
 Provides: ikiwiki-plugin-table
index f257234dd2b4cd5f65c1dc825cb2683f6f295b55..67f0ac540200c66e1456cd5388d28c537ea67d19 100644 (file)
@@ -76,6 +76,10 @@ Files: htmltidy.pm
 Copyright: © 2006 Faidon Liambotis
 License: GPL-2+
 
+Files: htmlbalance.pm, underlay.pm
+Copyright: © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+License: GPL-2+
+
 Files: polygen.pm, pagestats.pm, cutpaste.pm
 Copyright: © 2006 Enrico Zini
 License: GPL-2+
@@ -108,6 +112,20 @@ Files: google.pm
 Copyright: Copyright (C) 2008 Peter Simons <simons@cryp.to>
 License: GPL-2+
 
+Files: comments.pm
+Copyright: 
+ © 2006-2008 Joey Hess <joey@ikiwiki.info>
+ © 2008 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+License: GPL-2+
+
+Files: 404.pm
+Copyright: © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+License: GPL-2+
+
+Files: wmd.pm
+Copyright: © 2009 William Uther
+License: GPL-2+
+
 Files: doc/logo/*
 Copyright: © 2006 Recai Oktaş <roktas@debian.org>
 License: GPL-2+
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..1936cc1
--- /dev/null
@@ -0,0 +1 @@
+html
diff --git a/debian/link b/debian/link
new file mode 100644 (file)
index 0000000..cb37931
--- /dev/null
@@ -0,0 +1,2 @@
+usr/share/ikiwiki/examples usr/share/doc/ikiwiki/examples
+usr/share/common-licenses/GPL-2 usr/share/doc/ikiwiki/html/GPL
index c588901df914968a70cbb3242b883f75e518043b..4158b2ae6636667d9b86583e7720cbe4153164b0 100755 (executable)
@@ -14,3 +14,7 @@ if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt 1.2; then
                fi
        fi
 fi
+if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt 3.02; then
+       # replaced by symlink
+       rm -rf /usr/share/doc/ikiwiki/examples
+fi
index 25b1f57b6a636ffe170efaf6b208bb61346ef9b9..0a7ce7a267e43c0999d6e468f7e6844abbc8d660 100755 (executable)
@@ -1,44 +1,19 @@
 #!/usr/bin/make -f
+%:
+       dh $@
 
-build: build-stamp
-build-stamp:
-       dh_testdir
-       perl Makefile.PL PREFIX=/usr INSTALLDIRS=vendor
-       $(MAKE) -C po
-       $(MAKE)
-       $(MAKE) test
-       touch build-stamp
+override_dh_auto_configure:
+       # keeps it out of /usr/local
+       dh_auto_configure -- PREFIX=/usr
 
-clean:
-       dh_testdir
-       dh_testroot
-       rm -f build-stamp
-       perl Makefile.PL
-       if [ -e Makefile ]; then $(MAKE) realclean; fi
-       dh_clean
-
-binary-arch: build
+override_dh_compress:
+       # avoid compressing files in the doc wiki
+       dh_compress -Xhtml
 
-binary-indep: build
-       dh_testdir
-       dh_testroot
-       dh_clean -k
-       $(MAKE) pure_install DESTDIR=$(shell pwd)/debian/ikiwiki
-       dh_installdocs html
-       dh_installexamples doc/examples/*
-       dh_link usr/share/common-licenses/GPL-2 usr/share/doc/ikiwiki/html/GPL
-       dh_installchangelogs
-       dh_compress -X html
-       dh_fixperms
-       dh_perl
-       dh_installdeb
-       dh_gencontrol
-       dh_md5sums
-       dh_builddeb
+override_dh_auto_clean:
+       # distclean moans about MANIFEST, this is quieter
+       if [ -e Makefile ]; then $(MAKE) realclean; fi
 
 # Not intended for use by anyone except the author.
 announcedir:
        @echo ${HOME}/src/ikiwiki/doc/news
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary
diff --git a/doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn b/doc/bugs/Aggregated_Atom_feeds_are_double-encoded.mdwn
new file mode 100644 (file)
index 0000000..fbdc58d
--- /dev/null
@@ -0,0 +1,22 @@
+The Atom feed from <http://planet.collabora.co.uk/>
+get "double-encoded" (UTF-8 is decoded as Latin-1 and re-encoded as
+UTF-8) when aggregated with IkiWiki on Debian unstable. The RSS 1.0
+and RSS 2.0 feeds from the same Planet are fine. All three files
+are in fact correct UTF-8, but IkiWiki mis-parses the Atom.
+
+This turns out to be a bug in XML::Feed, or (depending on your point
+of view) XML::Feed failing to work around a design flaw in XML::Atom.
+When parsing RSS it returns Unicode strings, but when parsing Atom
+it delegates to XML::Atom's behaviour, which by default is to strip
+the UTF8 flag from strings that it outputs; as a result, they're
+interpreted by IkiWiki as byte sequences corresponding to the UTF-8
+encoding. IkiWiki then treats these as if they were Latin-1 and
+encodes them into UTF-8 for output.
+
+I've filed a bug against XML::Feed on CPAN requesting that it sets
+the right magical variable to change this behaviour. IkiWiki can
+also apply the same workaround (and doing so should be harmless even
+when XML::Feed is fixed); please consider merging my 'atom' branch,
+which does so. --[[smcv]]
+
+[[!tag patch done]]
index 07badd646658f05d4ece0b1973753705de1885dd..efdd9004ed95f25cf7037d33fbe3340eea27b70f 100644 (file)
@@ -34,9 +34,9 @@ Is there a huge objection to this patch?
     index 990fcaa..0fb78ba 100644
     --- a/IkiWiki/Render.pm
     +++ b/IkiWiki/Render.pm
-    @@ -260,13 +260,15 @@ sub prune ($) { #{{{
+    @@ -260,13 +260,15 @@ sub prune ($) {
      
-     sub refresh () { #{{{
+     sub refresh () {
        # security check, avoid following symlinks in the srcdir path
     -  my $test=$config{srcdir};
     -  while (length $test) {
@@ -108,7 +108,7 @@ like this being accepted before I bothered.
      use IkiWiki;
     +use File::Spec;
      
-     sub gen_wrapper () { #{{{
+     sub gen_wrapper () {
     -       $config{srcdir}=abs_path($config{srcdir});
     -       $config{destdir}=abs_path($config{destdir});
     -       my $this=abs_path($0);
diff --git a/doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn b/doc/bugs/CGI__44___formbuilder__44___non-existent_field_address.mdwn
new file mode 100644 (file)
index 0000000..ef74deb
--- /dev/null
@@ -0,0 +1,59 @@
+Error received when clicking on the "edit" link:
+
+> `Error: [CGI::FormBuilder::AUTOLOAD] Fatal: Attempt to address
+> non-existent field 'text' by name at
+> /home/tealart/bin/share/perl/5.8.4/IkiWiki/CGI.pm line 112`
+
+Error received when following a "Create New Page" (eg. ?) link: 
+
+> `Error: [CGI::FormBuilder::AUTOLOAD] Fatal: Attempt to address
+> non-existent field 'param' by name at
+> /home/tealart/bin/share/perl/5.8.4/IkiWiki/Plugin/editpage.pm line 122`
+
+I could probably find several other flavors of this error if I went
+looking, but I trust you get the idea. 
+
+The CGI starts to render (this isn't the "you forgot to set the
+permissions/turn on the CGI" error) and then fails. 
+
+Further details:
+
+- Running on shared hosting (dreamhost; but everything compiles,
+  dependencies installed, the site generates perfectly, other CGIs
+  work, the file permissions work).
+
+- It's running perl 5.8.4, but I did upgrade gettext to 0.17
+
+- the server is running gcc v3.3.5 (at this point, this is the main
+  difference between the working system and my box.)
+
+- I've removed the locale declarations from both the config file and
+  the environment variable.
+
+- I've also modified the page template and have my templates in a non
+  standard location. The wiki compiles fine, with the template, but
+  might this be an issue? The CGI script doesn't (seem) to load under
+  the new template, but I'm not sure how to address this issue.
+
+- All of the required/suggested module dependencies are installed
+  (finally) to the latest version including (relevantly)
+  CGI::FormBuilder 3.0501.
+
+- I'm running ikiwiki v3.08. Did I mention that it works perfectly in
+  nearly every other way that I've managed to test thusfar?
+
+----
+
+> I suspect that your perl is too old and is incompatible with the version of CGI::FormBuilder you have installed.
+> 
+> Is so, it seems likely that the same error message can be reproduced by running a simple command like this at the command line:
+> 
+>     perl -e 'use warnings; use strict; use CGI::FormBuilder; my $form=CGI::FormBuilder->new; $form->text("boo")'
+> 
+> --[[Joey]]
+
+> > nope, that command produces no output. :/
+> > 
+> > I considered downgrading CGI::FormBuilder but I saw evidence of previous versions being incompatible with ikiwiki so I decided against that.
+> > 
+> > -- [[tychoish]]
index 60cbcd530eabdde38c305bfb6394cb154d6bc8fc..91c2eae60a046d16c5e37aeb6689f4ed3307f40b 100644 (file)
@@ -33,7 +33,7 @@ This type of page name (with leading slash) also gets created by the aggregate p
        index 99cead6..23d9616 100644
        --- a/IkiWiki/CGI.pm
        +++ b/IkiWiki/CGI.pm
-       @@ -305,9 +305,11 @@ sub cgi_editpage ($$) { #{{{
+       @@ -305,9 +305,11 @@ sub cgi_editpage ($$) {
                my $page=$form->field('page');
                $page=possibly_foolish_untaint($page);
                if (! defined $page || ! length $page ||
@@ -46,7 +46,7 @@ This type of page name (with leading slash) also gets created by the aggregate p
         
                my $baseurl=$config{url}."/".htmlpage($page);
                
-       @@ -425,6 +427,7 @@ sub cgi_editpage ($$) { #{{{
+       @@ -425,6 +427,7 @@ sub cgi_editpage ($$) {
                                    $from ne $form->field('from') ||
                                    file_pruned($from, $config{srcdir}) ||
                                    $from=~/^\// ||
diff --git a/doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn b/doc/bugs/Comments_link_is_to_index.html_if_usedirs_is_on.mdwn
new file mode 100644 (file)
index 0000000..6df3ccd
--- /dev/null
@@ -0,0 +1,5 @@
+When a page links to its own #comments anchor you get a link like
+"index.html#comments" rather than "./#comments". Fixed in commit 0844bd0b
+on my 'comments' branch. --[[smcv]]
+
+[[!tag patch done]]
diff --git a/doc/bugs/Error:_Your_login_session_has_expired._.mdwn b/doc/bugs/Error:_Your_login_session_has_expired._.mdwn
new file mode 100644 (file)
index 0000000..046d6e1
--- /dev/null
@@ -0,0 +1,44 @@
+I keep getting:
+
+       Error: Your login session has expired.
+
+Whilst trying to edit http://hugh.vm.bytemark.co.uk/ikiwiki.cgi via OpenID. Any ideas?
+
+
+       iki@hugh:~$ dpkg -l | grep openid
+       ii  libnet-openid-consumer-perl     0.14-4                library for consumers of OpenID iden
+       tities
+       iki@hugh:~$
+
+> This error occurs if ikiwiki sees something that looks like a CSRF
+> attack. It checks for such an attack by embedding your session id on the
+> page edit form, and comparing that id with the session id used to post
+> the form.
+> 
+> So, somehow your session id has changed between opening the edit form and
+> posting it. A few ways this could happen:
+> 
+> * Genuine CSRF attack (unlikely)
+> * If you logged out and back in, in another tab, while the edit form was
+>   open.
+> * If `.ikiwiki/sessions.db` was deleted/corrupted while you were in the
+>   midst of the edit.
+> * If some bug in CGI::Session caused your session not to be saved to the
+>   database somehow.
+> * If your browser didn't preserve the session cookie across the edit
+>   process, for whatever local reason.
+> * If you were using a modified version of `editpage.tmpl`, and 
+>   it did not include `FIELD-SID`.
+> * If you upgraded from an old version of ikiwiki, before `FIELD-SID` was
+>   added (<= 2.41), and had an edit form open from that old version, and
+>   tried to save it using the new.
+>  
+> I don't see the problem editing the sandbox there myself, FWIW.
+> (BTW, shouldn't you enable the meta plugin so RecentChanges displays
+> better?)
+> --[[joey]]
+
+
+Thanks for you excellent analysis. The bug was due to old pre-3.0 **templates** laying about. After deleting them, ikiwiki defaults to its own templates. Clever. :-)
+
+[[bugs/done]]
diff --git a/doc/bugs/Git:_web_commit_message_not_utf-8.mdwn b/doc/bugs/Git:_web_commit_message_not_utf-8.mdwn
new file mode 100644 (file)
index 0000000..08247dd
--- /dev/null
@@ -0,0 +1,17 @@
+The message generated for web commits:
+
+> web commit by mädduck
+
+is not utf-8 encoded before passed to Git (which uses utf-8 as default encoding for commit messages). This causes a wrongly-encoded log entry, and makes ikiwiki spew warnings as it creates `recentchanges`:
+
+    utf8 "\xF6" does not map to Unicode at /usr/share/perl5/IkiWiki/Rcs/git.pm line 36, <$OUT> line 57.
+    Malformed UTF-8 character (unexpected non-continuation byte 0x6e, immediately after start byte 0xf6) in pattern match (m//) at /usr/share/perl5/IkiWiki/Rcs/git.pm line 393.
+    utf8 "\xF6" does not map to Unicode at /usr/share/perl5/IkiWiki/Rcs/git.pm line 36, <$OUT> line 5.
+
+(This is version 2.53.3~bpo40+1 for lack of a newer backport for sarge)
+
+Please make sure that commit messages for Git are always utf-8.
+
+This is a change by user `mädduck` to trigger the error.
+
+> [[Fixed|done]] both on the commit and log sides. --[[Joey]] 
diff --git a/doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn b/doc/bugs/INC_location_not_set_correctly_in_make_test.mdwn
new file mode 100644 (file)
index 0000000..1d396c8
--- /dev/null
@@ -0,0 +1,24 @@
+'make test' has the following errors:
+
+Can't locate Locale/gettext.pm in @INC (@INC contains: /home/turian/utils//lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /home/turian/utils//lib/perl5/site_perl/5.8.8 . /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8) at (eval 254) line 2.
+
+What's weird is that I already have gettext.pm:
+   /home/turian/utils/lib/perl5/lib/i386-linux-thread-multi/Locale/gettext.pm
+
+That directory should be part of @INC, because I have:
+  export PERL5LIB="$PERL5LIB:$UTILS/lib/perl5/lib/i386-linux-thread-multi/"
+in my .bashrc. However, /home/turian/utils/lib/perl5/lib/i386-linux-thread-multi/ does not appear in that @INC line.
+
+How do I get the proper @INC locations set?
+
+> Nothing in ikiwiki touches whatever PERL5DIR setting you may have,
+> so AFAICS, this must be some sort of local configuration problem.
+> How do
+> `/home/turian/utils//lib/perl5/site_perl/5.8.8/i386-linux-thread-multi`
+> and `/home/turian/utils//lib/perl5/site_perl/5.8.8` get into the
+> displayed `@INC`? The likely way seems to be that something in your
+> system sets PERL5LIB to contain those directories, clobbering 
+> the earlier setting in your `.bashrc`.
+> --[[Joey]] 
+
+[[!tag done]]
diff --git a/doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn b/doc/bugs/IkiWiki::Wrapper_should_use_destdir.mdwn
new file mode 100644 (file)
index 0000000..6b02c41
--- /dev/null
@@ -0,0 +1,23 @@
+In IkiWiki/Wrapper.pm, the gen_wrapper function finds out what srcdir and
+destdir are set to in the config, but does not use them.
+
+Later in the sub, when a new wiki.cgi wrapper is being created when calling
+ikiwiki --setup /path/to/setup, it will only work if cgi\_wrapper in the
+config file is set to the full path. Otherwise, it creates wiki.cgi in the
+current working directory.  It works with the other wrapper it sets up in
+my config - post\_update (using git), as that shows in the config with a
+full path.
+
+One workaround would be to mention in the setup file that cgi_wrapper has
+to be the full path, not just the file name, but that seems silly when
+destdir is also specified in that file and that's where it should go, and
+$config{destdir} is a known value in the Wrapper.pm file.
+
+> Nowhere in any documentation does
+> it say that cgi\_wrapper is relative to the destdir. 
+> As noted in [[discussion]], there are web server setups
+> that require the cgi be located elsewhere.
+> [[done]] --[[Joey]] 
+
+>> A comment in the generated setup file that all paths should be full
+>> would prevent my (admittedly dumb) error without any drawbacks.
diff --git a/doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn b/doc/bugs/IkiWiki::Wrapper_should_use_destdir/discussion.mdwn
new file mode 100644 (file)
index 0000000..870fa7a
--- /dev/null
@@ -0,0 +1,4 @@
+Just as a point of information, I do not put my cgi wrapper in the dest
+directory. Instead I configure Apache to relate a specific URI to the cgi via
+ScriptAlias. I would not like things to be changed so that the cgi was put in
+the destdir, so I'd vote instead to comment in the `setup\_file`. -- [[Jon]]
index 28b48e2c6794cd5792eb39a8d53259b0094b5dc5..c3beb82199fc581fb5704d89a4ede7036fe7a8bd 100644 (file)
@@ -53,7 +53,7 @@ I didn't apply your following old patch against `Ikiwiki.pm` file:
     +   }
     +
     +   return eval $newpagespec;
-     } #}}}
+     }
  
      package IkiWiki::PageSpec;
 
@@ -83,7 +83,7 @@ to break the code I distribute in my backport ;)
        +       my $ret=eval possibly_foolish_untaint(pagespec_translate($spec));
                return IkiWiki::FailReason->new("syntax error") if $@;
                return $ret;
-        } #}}}
+        }
 
 >> Thanks a lot, Joey! It works :)
 >>
diff --git a/doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn b/doc/bugs/Meta_plugin_does_not_respect_htmlscrubber__95__skip_setting.___40__patch__41__.mdwn
new file mode 100644 (file)
index 0000000..0e40da5
--- /dev/null
@@ -0,0 +1,11 @@
+I have been trying to include some meta info using the link setting something like the below
+
+ meta link="http://www.example.com/" rel="command" name="Example"    
+
+This gets removed by the htmlscrubber as you would expect.
+
+Setting htmlscrubber_skip to the pagespec should stop this getting scrubbed but it does not.
+
+Below is a patch to fix that. It seams to work but I am not sure of it is the correct thing to do.
+
+> [[done]], thanks for the patch --[[Joey]]
index 3d13883123bdfc8d823b311e4fd1f44e7e9be47e..8687e7983c7a506ef736082e92bfe5be44ac3e2d 100644 (file)
@@ -11,7 +11,7 @@ diff --git a/IkiWiki/Rcs/monotone.pm b/IkiWiki/Rcs/monotone.pm
 index cde6029..34f8f96 100644
 --- a/IkiWiki/Rcs/monotone.pm
 +++ b/IkiWiki/Rcs/monotone.pm
-@@ -186,8 +186,9 @@ sub rcs_update () { #{{{
+@@ -186,8 +186,9 @@ sub rcs_update () {
        check_config();
  
        if (defined($config{mtnsync}) && $config{mtnsync}) {
index 019970899e46c7f23db4c59bbbfa95a7d899fb1b..bb3f92f9c60db83efb86222135ede6d22e1ee20c 100644 (file)
@@ -38,19 +38,19 @@ At the moment I see two possible solutions:
         +++ IkiWiki.pm  2008-07-21 20:41:35.000000000 +0200
         @@ -477,13 +477,13 @@
 
-         sub titlepage ($) { #{{{
+         sub titlepage ($) {
                 my $title=shift;
         -       $title=~s/([^-[:alnum:]:+\/.])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
         +       $title=~s/([^-[:alnum:]+\/.])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
                 return $title;
-         } #}}}
+         }
 
-         sub linkpage ($) { #{{{
+         sub linkpage ($) {
                 my $link=shift;
         -       $link=~s/([^-[:alnum:]:+\/._])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
         +       $link=~s/([^-[:alnum:]+\/._])/$1 eq ' ' ? '_' : "__".ord($1)."__"/eg;
                 return $link;
-         } #}}}
+         }
 
 What do you think about that? Does the patch have any side-effects I didn't see?
 
diff --git a/doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn b/doc/bugs/PNG_triggers_UTF-8_error_in_MimeInfo.pm.mdwn
new file mode 100644 (file)
index 0000000..0a12999
--- /dev/null
@@ -0,0 +1,25 @@
+If a PNG image matches the [[ikiwiki/PageSpec]] of an [[ikiwiki/directive/inline]] directive, the page throws the following error:
+
+> \[[!inline Error: Malformed UTF-8 character (fatal) at /usr/local/lib/perl5/site_perl/5.8.8/File/MimeInfo.pm line 120.]]
+
+Individual posts display fine, and moving the offending image outside the scope of the [[ikiwiki/directive/inline]] directive's PageSpec eliminates the error.
+
+> I tried to reproduce this with a random png and File::MimeInfo 
+> version 0.15, but could not. The png was included in the generated feed
+> via an enclosure, as it should be; no warnings or errors.
+> 
+> Looking at the source to File::MimeInfo and its changelog,
+> I'm pretty sure that this problem was fixed in version
+> 0.14:
+>>       - Fixed bug with malformed utf8 chars in default() method
+> 
+> The code involved in that fix looks like this:
+>
+>>                 no warnings; # warnings can be thrown when input not ascii
+>>                if ($] < 5.008 or ! utf8::valid($line)) {
+>>                        use bytes; # avoid invalid utf8 chars
+>
+> I guess that your locally installed version of File::MimeInfo is older than
+> this. So closing this bug [[done]]. If you still see the problem with a current
+> version of File::MimeInfo, please reopen and include where I can get a png file
+> that triggers the problem. --[[Joey]] 
index 8ae347d429726835cd413e026eb0cf8039497e75..6be5f89b5b9ce62b55d0b922924d5646b435eda9 100644 (file)
@@ -9,7 +9,7 @@ Here is a patch for toc.pm for producing non-empty 'a' elements.
 
     --- IkiWiki/Plugin/toc.pm.orig     Thu Jun  7 11:53:53 2007
     +++ IkiWiki/Plugin/toc.pm  Thu Jun  7 13:00:00 2007
-    @@ -47,7 +47,7 @@ sub format (@) { #{{{
+    @@ -47,7 +47,7 @@ sub format (@) {
                if ($tagname =~ /^h(\d+)$/i) {
                        my $level=$1;
                        my $anchor="index".++$anchors{$level}."h$level";
@@ -18,7 +18,7 @@ Here is a patch for toc.pm for producing non-empty 'a' elements.
        
                        # Take the first header level seen as the topmost level,
                        # even if there are higher levels seen later on.
-    @@ -90,6 +90,16 @@ sub format (@) { #{{{
+    @@ -90,6 +90,16 @@ sub format (@) {
                                        "</a>\n";
                                $p->handler(text => undef);
                        }, "dtext");
index 9a26e505af2df9f4b9a0dd47e5d57c4da31a76f8..c9f6981589fae57958abdb774034175adb83b385 100644 (file)
@@ -15,7 +15,7 @@ It also generates image URLs relative to the page being rendered, which means th
 
     --- IkiWiki/Plugin/graphviz.pm.orig        2007-07-27 11:35:05.000000000 +0200
     +++ IkiWiki/Plugin/graphviz.pm     2007-07-27 11:36:02.000000000 +0200
-    @@ -69,7 +69,12 @@ sub render_graph (\%) { #{{{
+    @@ -69,7 +69,12 @@ sub render_graph (\%) {
                }
        }
      
@@ -26,9 +26,9 @@ It also generates image URLs relative to the page being rendered, which means th
     +  else {
     +          return "<img src=\"".urlto($dest, $params{page})."\" />\n";
     +  }
-     } #}}}
+     }
      
-     sub graph (@) { #{{{
+     sub graph (@) {
 
 
 >> --[[HenrikBrixAndersen]]
@@ -38,7 +38,7 @@ The patch below fixes these two issues.
 
     --- graphviz.pm.orig       Thu Jun  7 15:45:16 2007
     +++ graphviz.pm    Fri Jun  8 12:03:38 2007
-    @@ -41,7 +41,6 @@ sub render_graph (\%) { #{{{
+    @@ -41,7 +41,6 @@ sub render_graph (\%) {
                $pid=open2(*IN, *OUT, "$params{prog} -Tpng");
      
                # open2 doesn't respect "use open ':utf8'"
@@ -46,7 +46,7 @@ The patch below fixes these two issues.
                binmode (OUT, ':utf8');
      
                print OUT $src;
-    @@ -70,7 +69,12 @@ sub render_graph (\%) { #{{{
+    @@ -70,7 +69,12 @@ sub render_graph (\%) {
                }
        }
      
@@ -57,6 +57,6 @@ The patch below fixes these two issues.
     +  else {
     +          return "<img src=\"".urlto($dest, $params{page})."\" />\n";
     +  }
-     } #}}}
+     }
      
-     sub graph (@) { #{{{
+     sub graph (@) {
index 836c39a71da6f86c29c2b5f88488bd0087d0022d..c852df5e93e5bfdcf63aa414fe53e0206d8a8903 100644 (file)
@@ -13,7 +13,7 @@ I can not see why this check is needed in the first place, so here's a patch for
     diff -upr ikiwiki-1.49.orig/IkiWiki/Rcs/svn.pm ikiwiki-1.49/IkiWiki/Rcs/svn.pm
     --- ikiwiki-1.49.orig/IkiWiki/Rcs/svn.pm   Mon Apr 16 15:15:09 2007
     +++ ikiwiki-1.49/IkiWiki/Rcs/svn.pm        Mon Apr 16 15:15:47 2007
-    @@ -176,7 +176,6 @@ sub rcs_recentchanges ($) { #{{{
+    @@ -176,7 +176,6 @@ sub rcs_recentchanges ($) {
                }
      
                foreach (keys %{$logentry->{paths}}) {
diff --git a/doc/bugs/SVG_files_not_recognized_as_images.mdwn b/doc/bugs/SVG_files_not_recognized_as_images.mdwn
new file mode 100644 (file)
index 0000000..207edd4
--- /dev/null
@@ -0,0 +1,29 @@
+In ikiwiki 2.66, SVG images are not recognized as images. In ikiwiki.pm,
+the hardcoded list of image file extensions does not include ".svg", which
+it probably should unless there's some other issue about rendering SVGs?
+
+The 'img' plugin also seems to not support SVGs.
+
+> SVG images can only be included via an `<object>`, `<embed>`, or
+> `<iframe>` tag. Or, perhaps as [inline SVG](http://wiki.svg.org/Inline_SVG). 
+> The [[plugins/htmlscrubber]] strips all three tags since they can easily
+> be used maliciously. If doing inline SVG, I'd worry that the svg file
+> could be malformed and mess up the html, or even inject javascript. So,
+> the only options seem to be only supporting svgs on wikis that do not
+> sanitize their html, or assuming that svgs are trusted content and
+> embedding them inline. None of which seem particularly palatable.
+> 
+> I suppose the other option would be converting the svg file to a static
+> image (png). The img plugin could probably do that fairly simply.
+> --[[Joey]]
+
+>> I'm working on inline SVG and MathML support in ikiwiki and I've
+>> modified my htmlscrubber to sanitize SVG and MathML using the
+>> whitelists from html5lib.  Here's a [patch][].  I've also made some
+>> notes about this here: [[todo/svg]].
+>> 
+>> I suspect that this bug may have caught the eye of anyone interested
+>> in this sort of thing.  I'll elaborate a bit on my user page to avoid
+>> getting off-topic here. --[[JasonBlevins]], October 21, 2008
+
+ [patch]: http://xbeta.org/gitweb/?p=xbeta/ikiwiki.git;a=blobdiff;f=IkiWiki/Plugin/htmlscrubber.pm;h=3c0ddc8f25bd8cb863634a9d54b40e299e60f7df;hp=3bdaccea119ec0e1b289a0da2f6d90e2219b8d66;hb=fe333c8e5b4a5f374a059596ee698dacd755182d;hpb=be0b4f603f918444b906e42825908ddac78b7073
index f6dbacad7fe6e442622fa4133469240a15a94e67..8aea5cd29d19bd401e53ee1a27515da99cc91e30 100644 (file)
@@ -44,7 +44,7 @@ reported in [[index/discussion#index11h1]].
 >> 
 >> If there was ever a future, syntax-breaking major release of ikiwiki
 >> (similar to python3000) I'd like to see this fixed as part of that.
->> --[[JonDowland]]
+>> --[[users/Jon]]
 
 >>> You can enable `prefix_directives` and get the disambiguated behavior
 >>> and spaces in wikilinks today. It will become the default in 3.0.
index cc53c0aeaba72b312837a21bc036129f15832eee..f2c60309ba7df335c6c8f201380a20d0daaa7fac 100644 (file)
@@ -6,7 +6,7 @@ If I click on "Czars in Russia", I'd like Ikiwiki to create "Czars\_in\_Russia.m
 
 > --- a/IkiWiki.pm
 > +++ b/IkiWiki.pm
-> @@ -584,7 +584,7 @@ sub htmllink ($$$;@) { #{{{
+> @@ -584,7 +584,7 @@ sub htmllink ($$$;@) {
 >                      return "<span class=\"createlink\"><a href=\"".
 >                              cgiurl(
 >                                      do => "create",
diff --git a/doc/bugs/URLs_with_parentheses_displayed_badly.mdwn b/doc/bugs/URLs_with_parentheses_displayed_badly.mdwn
new file mode 100644 (file)
index 0000000..59b67d4
--- /dev/null
@@ -0,0 +1,19 @@
+I've noticed that Ikiwiki displays URLs with parentheses badly. The problem occurs
+in the latest version 3.00 and older versions. Please look at the link to following
+Polish entry about C programming language at Wikipedia (it seems that URLs with
+parentheses are popular there):
+
+[Język programowania C](http://pl.wikipedia.org/wiki/C_(j%C4%99zyk_programowania))
+
+I need to escape a closing parenthesis of the URL to fix the problem.
+
+[Język programowania C](http://pl.wikipedia.org/wiki/C_(j%C4%99zyk_programowania\))
+
+--[[Paweł|users/ptecza]]
+
+> This is a bug in markdown version 1. It is fixed in [[!cpan Text::Markdown]],
+> which ikiwiki will use if it's installed. [[done]] --[[Joey]] 
+
+>> Thanks a lot for the hint, Joey! I've installed `libtext-markdown-perl` package
+>> (Aptitude has removed `markdown` package to satisfy dependencies) and now
+>> I don't need to escape Wikipedia URLs with parentheses :) --[[Paweł|users/ptecza]]
index 88a187dfc220a1d5a2f8a6bc1f186df184352fa1..12c0ad07fa12e30e4add15b5ee6c57f3f701f817 100644 (file)
@@ -24,4 +24,9 @@ Here is a patch against ikiwiki-1.51 for using find(1) and install(1) instead of
 
 >> No, apparently FreeBSD `install` does not support `-D`.  See [the FreeBSD install manpage](http://www.freebsd.org/cgi/man.cgi?query=install&apropos=0&sektion=0&manpath=FreeBSD+6.2-RELEASE&format=html). --[[JoshTriplett]]
 
->> Patch applied; [[bugs/done]]. --[[JoshTriplett]]
+>> Patch applied; [[done]]. --[[JoshTriplett]]
+
+There are still/again "cp -a"s in the Makefile as of 3.00
+
+> It's a cp -a || install. Is that causing you a problem somehow?
+> --[[Joey]] 
index a30f110a412126822742e9726cfb910dc89e788d..efb5c70b868421c895e0e178d03b23d52c3179a2 100644 (file)
@@ -6,7 +6,7 @@ In `IkiWiki::preprocess`, the last capturing group in the regex used to parse di
     index 241a7c0..d2c35a2 100644
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -1167,7 +1167,8 @@ sub preprocess ($$$;$$) { #{{{
+    @@ -1167,7 +1167,8 @@ sub preprocess ($$$;$$) {
                     }sx;
             }
      
@@ -14,6 +14,6 @@ In `IkiWiki::preprocess`, the last capturing group in the regex used to parse di
     +       # $4 can be undef if the directive was \[[!foo]]
     +       $content =~ s{$regex}{$handle->($1, $2, $3, ($4 or ""))}eg;
             return $content;
-     } #}}}
+     }
  
 [[cherry-picked|done]] --[[Joey]]
diff --git a/doc/bugs/basewiki_uses_meta_directives_but_meta_is_not_enabled_by_default.mdwn b/doc/bugs/basewiki_uses_meta_directives_but_meta_is_not_enabled_by_default.mdwn
new file mode 100644 (file)
index 0000000..62931d8
--- /dev/null
@@ -0,0 +1,5 @@
+[[plugins/meta]] is not enabled by default, yet some pages in the default basewiki include [[the_meta_directive|ikiwiki/directive/meta]], notably the [[ikiwiki]] heirarchy.
+
+This means that the default output of "ikiwiki src dest", for two empty directories src and dest, result in the meta directive being displayed inline with the page text.
+
+> [[done]], meta now enabled by default.
diff --git a/doc/bugs/beautify__95__urlpath_will_add_.__47___even_if_it_is_already_present.mdwn b/doc/bugs/beautify__95__urlpath_will_add_.__47___even_if_it_is_already_present.mdwn
new file mode 100644 (file)
index 0000000..8e96b1f
--- /dev/null
@@ -0,0 +1,3 @@
+beautify_urlpath will prepend a useless "./" to the URL "./foo". Fixed in commit 5b1cf21a on my comments branch. --[[smcv]]
+
+[[!tag patch done]]
diff --git a/doc/bugs/bugfix_for:___34__mtn:_operation_canceled:_Broken_pipe__34_____40__patch__41__.mdwn b/doc/bugs/bugfix_for:___34__mtn:_operation_canceled:_Broken_pipe__34_____40__patch__41__.mdwn
new file mode 100644 (file)
index 0000000..b7f38fd
--- /dev/null
@@ -0,0 +1,24 @@
+When using monotone as revision control system, a "mtn: operation canceled: Broken pipe" message is printed. Reason is that, in a call to mtn, the pipe is closed before mtn has done all its output. This patch fixes the problem.
+
+    diff -up ikiwiki/IkiWiki/Plugin/monotone.pm.orig ikiwiki/IkiWiki/Plugin/monotone.pm
+    --- ikiwiki/IkiWiki/Plugin/monotone.pm.orig        2008-11-12 23:45:24.000000000 +0100
+    +++ ikiwiki/IkiWiki/Plugin/monotone.pm     2008-12-16 12:41:38.000000000 +0100
+    @@ -525,13 +525,12 @@ sub rcs_recentchanges ($) {
+       my $child = open(MTNLOG, "-|");
+       if (! $child) {
+               exec("mtn", "log", "--root=$config{mtnrootdir}", "--no-graph",
+    -               "--brief") || error("mtn log failed to run");
+    +               "--brief", "--last=$num") || error("mtn log failed to run");
+       }
+     
+    -  while (($num >= 0) and (my $line = <MTNLOG>)) {
+    +  while (my $line = <MTNLOG>) {
+               if ($line =~ m/^($sha1_pattern)/) {
+                       push @revs, $1;
+    -                  $num -= 1;
+               }
+       }
+       close MTNLOG || debug("mtn log exited $?");
+
+> Thanks for the patch, and for testing the monotone backend.
+> applied [[done]] --[[Joey]]
diff --git a/doc/bugs/bzr_RecentChanges_dates_start_from_1969.mdwn b/doc/bugs/bzr_RecentChanges_dates_start_from_1969.mdwn
new file mode 100644 (file)
index 0000000..fa6e45b
--- /dev/null
@@ -0,0 +1,16 @@
+Using bzr, the dates for changes on the RecentChanges page all start
+slightly before the Unix epoch.
+
+Changing line 249 of bzr.pm from
+
+`                        when       => time - str2time($info->{"timestamp"}),`
+
+to
+
+`                        when       => str2time($info->{"timestamp"}),`
+
+fixed this for me.
+
+> Weird, I wonder why it was written to return an absolute time like that
+> in the first place? Can't have ever been right. Fixed, thanks. --[[Joey]]
+> [[done]]
diff --git a/doc/bugs/bzr_plugin_does_not_define_rcs__95__diff.mdwn b/doc/bugs/bzr_plugin_does_not_define_rcs__95__diff.mdwn
new file mode 100644 (file)
index 0000000..0294ec6
--- /dev/null
@@ -0,0 +1,27 @@
+The bzr plugin does not seem to define the rcs_diff subroutine.
+I got the follow error after enabling recentchangesdiff:
+
+"Undefined subroutine &IkiWiki::Plugin::bzr::rcs_diff called at /usr/share/perl5/IkiWiki.pm line 1590."
+
+Grepping to verify absence of rcs_diff:
+
+    $ grep rcs_diff /usr/share/perl5/IkiWiki/Plugin/{git,bzr}.pm
+    /usr/share/perl5/IkiWiki/Plugin/git.pm:    hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
+    /usr/share/perl5/IkiWiki/Plugin/git.pm:sub rcs_diff ($) {
+    /usr/share/perl5/IkiWiki/Plugin/bzr.pm:    hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
+
+> I've added the minimal stub needed to avoid the crash, but for
+> recentchangesdiff to work, someone needs to implement `rcs_diff` for bzr.
+> This should be trivial if you know and use bzr. The function
+> is passed as a parameter the revno of interest and just needs
+> to ask bzr for the diff between that and the previous version. --[[Joey]] 
+
+>> I'll see if I can make a patch. The bzr command to get the revision would
+>> look like this: bzr diff -r revno:$PREV:/path/to/src..revno:$REVNO:/path/to/src
+>> (where $PREV would be $REVNO minus one). --liw
+
+>> Sorry, that was not entirely correct, for some reason. I'll add a patch below that
+>> seems to work. I am unfortunately not ready to set up a git repository that you
+>> can pull from. --liw
+
+[[done]] --[[Joey]] 
diff --git a/doc/bugs/cannot_preview_shortcuts.mdwn b/doc/bugs/cannot_preview_shortcuts.mdwn
new file mode 100644 (file)
index 0000000..d7045b2
--- /dev/null
@@ -0,0 +1,17 @@
+Shortcuts such as \[[!google foo]] do not work when previewing pages.
+--[[JasonBlevins]]
+
+> Broken during the setup dumping changes, now fixed. --[[Joey]] [[done]]
+
+>> Just a quick note that this fix interacts with the way the `listdirectives`
+>> directive gets its list of non-shortcut directives.  At the moment it
+>> still works, but it relies on the fact that the `listdirectives` `checkconfig`
+>> hook is called before the `shortcut` `checkconfig` hook.
+>> -- [[Will]]
+
+>> The order plugins are loaded is effectively random. (`keys %hooks`).
+>> So I've made shortcuts pass a 'shortcut' parameter when registering
+>> them, which listdirectives can grep out of the full list of directives.
+>> That may not be the best name to give it, especially if other plugins
+>> generate directives too. Seemed better than forcing shortcut's
+>> checkconfig hook to run last tho. --[[Joey]]
diff --git a/doc/bugs/cannot_reliably_use_meta_in_template.mdwn b/doc/bugs/cannot_reliably_use_meta_in_template.mdwn
new file mode 100644 (file)
index 0000000..de6c227
--- /dev/null
@@ -0,0 +1,18 @@
+meta title cannot reliably be put inside a template used by the
+[[plugins/template]] plugin. Since meta title info is gathered in the scan
+pass, which does not look at the template a page includes, it will not be
+seen then, and so other pages that use the page title probably won't use
+it. (Barring luck with build order.)
+
+Update: This also affects using tags from templates.
+
+There is a simple fix for this, just add `scan => 1` when registering the
+preprocess hook for the template plugin.
+
+However, the overhead of this has to be considered. It means that, on every
+scan pass, every page containing a template will cause the template to be
+loaded and filled out. This can be some serious additional overhead.
+
+--[[Joey]] 
+
+[[done]]
diff --git a/doc/bugs/comments_produce_broken_links_in_RecentChanges.mdwn b/doc/bugs/comments_produce_broken_links_in_RecentChanges.mdwn
new file mode 100644 (file)
index 0000000..dae0085
--- /dev/null
@@ -0,0 +1,9 @@
+Comments produce links like `sandbox/comment_1` in [[RecentChanges]], which,
+when clicked, redirect to a page that does not exist.
+
+The `recentchanges` branch in my repository contains one possible [[patch]],
+which causes the CGI to go to the [[ikiwiki/directive/meta]] `permalink`, if
+any, if the page is internal (comments do have a permalink).
+
+> [[done]].. I I had thought about not showing internal page changes at
+> all, but I like your approach better --[[Joey]] 
index ba96a4e2b5203e86e493a66d0162434901b2ece7..415708a504c8483563aa5572f08d97c25a214b3a 100644 (file)
@@ -28,3 +28,5 @@ auto-generated index is insufficient.
 > tagged, I think you have larger problems than tags and backlinks being
 > the same. Like keeping that list of links up to date as tags are added
 > and changed. --[[Joey]]
+
+I see your point, Joey. I need to maintain that list manually, though, because the automatically generated list is too brief. \[[!map ...]] generates just a list of titles or descriptions. I need a list that contains both. See [[this_posting|ikiwiki/directive/map/discussion]] for more details. Until \[[!map]] can do that, I'm stuck with a manually maintained list. Which means that every link shows up in the backlinks.
diff --git a/doc/bugs/dumpsetup_does_not_save_destdir.mdwn b/doc/bugs/dumpsetup_does_not_save_destdir.mdwn
new file mode 100644 (file)
index 0000000..768c3fc
--- /dev/null
@@ -0,0 +1,3 @@
+Calling ikiwiki with a bunch of options, including the --dumpsetup somefile.setup option creates somefile.setup for later reuse with the --setup option. The destination dir however is not saved in the setup file, it has destdir => ''.
+
+> that broke in version 2.64 .. fixed [[done]] --[[Joey]]
index 012fcec2c29e832d941e8f4c54513d23fa1241a2..02ce4e221093b33bf0d9e82bd32f758c49799186 100644 (file)
@@ -3,8 +3,8 @@ matches all other pages, including all internal pages. This can lead to
 unexpected results, since it will match a bunch of recentchanges pages,
 etc.
 
-Recall that internal-use pages are not matched by a glob. So "*" doesn't
-match them. So if the pagespec is "* and !foo and !bar", it won't match
+Recall that internal-use pages are not matched by a glob. So "\*" doesn't
+match them. So if the pagespec is "\* and !foo and !bar", it won't match
 them. This is the much more common style.
 
 There's an odd inconsistency with entirely negated pagespecs. If "!foo"
diff --git a/doc/bugs/feedfile_does_the_wrong_thing_from_index.mdwn2.mdwn b/doc/bugs/feedfile_does_the_wrong_thing_from_index.mdwn2.mdwn
new file mode 100644 (file)
index 0000000..6b8781a
--- /dev/null
@@ -0,0 +1,7 @@
+[[!meta title="feedfile does the wrong thing from index"]]
+
+When I put the following !inline in my index.mdwn, it generate a file called index/graphics.rss.  However, the link in the RSS button is to graphics.rss (i.e., not in the index/ directory).
+
+`\[[!inline pages="link(tags/graphics) and ./posts/* and !*/Discussion" show="10" feedfile=graphics feedonly=yes]]`
+
+[[done]] --[[Joey]] 
index 4146a5869d22d7256f13a6770b2cbf4c942b6fbe..c25ef69278215e0de14120c437b3b8eb613521bc 100644 (file)
@@ -6,7 +6,7 @@ Ikiwiki's git handling is sending a bunch of output to stderr.  The following pa
     index 425536f..5734bb2 100644
     --- a/IkiWiki/Rcs/git.pm
     +++ b/IkiWiki/Rcs/git.pm
-    @@ -24,6 +24,7 @@ sub _safe_git (&@) { #{{{
+    @@ -24,6 +24,7 @@ sub _safe_git (&@) {
             if (!$pid) {
                     # In child.
                     # Git commands want to be in wc.
index c465bdd4ab7c579aa60db318bc3d81ae83ef08a7..564982ff34e7f7f2715c7796e613c51aac57282b 100644 (file)
@@ -8,3 +8,7 @@ cases of the one which was installed directly before the current commit.
 > I don't see one, except for diffs that show all changes in the commit,
 > rather than only changes to a single file. This feels like a bug in
 > gitweb. --[[Joey]]
+
+This is fixed by using the new gitweb style urls. Which new gitweb
+requires, but is a manual change you have to make in your setup. So,
+[[done]] --[[Joey]] 
index 255d9cee774ad523d0bdbf33b75eceafbc514120..0b4d70596a2445d268db36958fb0156e1fe08dd2 100644 (file)
@@ -8,3 +8,6 @@ Going from *RecentChanges*, when viewing the diffs of newly created pages
 > I don't see any way to make gitweb do that. You can click on the filename
 > after the "diff -cc" to see the whole file output, but gitweb won't show
 > a diff for a newly added file. --[[Joey]]
+
+>> happily this, too, is fixed by using the new style gitweb urls. [[done]]
+>> --[[Joey]] 
diff --git a/doc/bugs/html5_support.mdwn b/doc/bugs/html5_support.mdwn
new file mode 100644 (file)
index 0000000..41f955e
--- /dev/null
@@ -0,0 +1,47 @@
+Some elements of [HTML5](http://www.whatwg.org/specs/web-apps/current-work/multipage/) can be safely supported by ikiwiki. There are [several differences between HTML4 and HTMl5](http://www.w3.org/TR/html5-diff/). Unsupported new elements _should degrade gracefully_.
+
+> In the `origin/html` branch, there is an old work in progress to make
+> ikiwiki use html 4 instead of xhtml. If that could be brought forward and
+> finished then the plan has been to switch ikiwiki over to doing html 4.
+> I don't think it makes sense to try to make it support both xhtml and
+> html, it would complicate the code for no benefit.
+> 
+> I think that is the best route toward supporting html 5 as well. Get
+> ikiwiki doing html 4 first and the changes needed to get to 5 from there
+> should be small. Probably just changing some doctypes and a few other
+> small changes which could be kept in a branch, or even shipped in ikiwiki
+> mainline as an alternate set of templates. Some of the changes, like
+> supporting new html 5 tags in the htmlscrubber, can be done in mainline.
+> (Like was already done for the html 5 video and audio tags.)
+>
+> This approach seems much more maintainable going foward than rolling a
+> html 5 branch immediatly and trying to keep that continually up-to-date
+> with mainline ikiwiki that is still using xhtml. --[[Joey]]
+
+However as an [early adopter](http://en.wikipedia.org/wiki/Early_adopter) I would like to start using HTML5 as much as possible. The more pragmatic solution would be to use elements supported by the browsers of your readership I guess. I'm following other early adopters like [Anne](http://annevankesteren.nl/) for clues on how to proceed.
+
+* [Initial patch](http://git.webconverger.org/?p=ikiwiki;a=commit;h=2e2bb3f74f5000b1269142d6f9bdf1bcb4075ca4)
+
+> I can't figure out how to pull from this repository.
+>> Sorry! I have fixed the cloneurl file to read `git clone git://webconverger.org/git/ikiwiki`
+
+I'm unsure how to turn off the test validation by the very old [wdg-html-validator](http://packages.qa.debian.org/w/wdg-html-validator.html). So I have been unable to test my initial patches as I can't build ikiwiki. I would like to know how to edit the rules/Makefile to temporarily disable this.
+
+> Don't run ¨make test" ... --[[Joey]] 
+>> I don't quite grok debhelper7 [rules](http://git.ikiwiki.info/?p=ikiwiki;a=blob;f=debian/rules).
+
+>>> Well, ok :-) `rm t/html.t` or, add an empty `override_dh_auto_test` rule.
+>>> --[[Joey]] 
+
+[validator.nu](http://validator.nu/) incidentally is **the** HTML5 validator, however it is almost impossible to sanely introduce as a build dependency because of its insane Java requirements. :( I test locally via [cURL](http://wiki.whatwg.org/wiki/IDE), though Debian packages cannot be built with a network dependency.
+
+# Notes
+
+* the [time element](http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-time-element) ideally needs the datatime= attribute set with iso8601 time
+* I suspect the migration to the new semantic elements of HTML5 like article, header & footer to take some time, due to browser support. Though they sure make the template code look much nicer.
+* `<br>` and too many `<div>`s usually indicates poor semantics.
+  > YMMV, but I tend to find that kind of concern counterproductive.
+  > --[[Joey]] 
+
+* Many of the header `<span>`s should be proper [header elements](http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements)
+  > See [[todo/Option_to_make_title_an_h1__63__]] for why not. --[[Joey]] 
index e8f87f9c4dc0956097be2c04b6daf4ab876cc37e..3d0c99b83bb7ecc5c484b25c2eb0ea7c76921e65 100644 (file)
@@ -6,10 +6,42 @@ I have found if I add:
 
     newenviron[i++]="HTTPS_PROXY=http://host.domain.com:3128";
 
-to IkiWiki/Wrapper.pm it solves the problem for https requests, however it obviously would be preferred if the proxy name is not configured.
+to IkiWiki/Wrapper.pm it solves the problem for https requests, however it obviously would be preferred if the proxy name is not hard coded.
 
 Also, the ability to set HTTPS\_CA\_FILE and HTTPS\_CA\_DIR might benefit some people. Then again, it I can't see any evidence that the SSL certificate of the server is being checked. See the [[bug_report|ssl_certificates_not_checked_with_openid]] I filed on this separate issue.
 
 Unfortunately, HTTP\_PROXY doesn't work for http requests, it looks like that library is different.
 
+---
+
+Update 2008-10-26:
+
+Better solution, one that works for both http and https, and uses config options. It appears to work...
+
+Note that using $ua->proxy(['https'], ...); won't work, you get a "Not Implemented" error, see <http://community.activestate.com/forum-topic/lwp-https-requests-proxy>. Also see [[!debbug 129528]].
+
+Also note that the proxy won't work with liblwpx-paranoidagent-perl, I had to remove liblwpx-paranoidagent-perl first.
+
+Please get the patch from the *.mdwn source.
+
+louie:/usr/share/perl5/IkiWiki/Plugin# diff -u openid.pm.old openid.pm
+--- openid.pm.old      2008-10-26 12:18:58.094489360 +1100
++++ openid.pm  2008-10-26 12:40:05.763429880 +1100
+@@ -165,6 +165,14 @@
+               $ua=LWP::UserAgent->new;
+       }
++      if (defined($config{"http_proxy"})) {
++              $ua->proxy(['http'], $config{"http_proxy"});
++      }
++
++      if (defined($config{"https_proxy"})) {
++              $ENV{HTTPS_PROXY} = $config{"https_proxy"};
++      }
++
+       # Store the secret in the session.
+       my $secret=$session->param("openid_secret");
+       if (! defined $secret) {
+
+
 Brian May
index 8cfd42e78f08993cafe61da1cafe33ae3aa62e27..8cda7a70fc89f65f0985c280153ce2bac05801f8 100644 (file)
@@ -11,3 +11,5 @@ If I then inline that page, the (relative) URL no longer points to the right pla
 > 
 > However, there is a simple way to avoid both problems: Use WikiLinks
 > and/or the [[img_directive|ikiwiki/directive/img]]. --[[Joey]]
+
+[[!tag done]]
index 2e67d63574788acb5736da313d3d4e9808d688aa..f72ecade2b41cfebfb6fa1f52af3552f4dca59d8 100644 (file)
@@ -26,7 +26,7 @@ And here's a patch to implement it. Will this survive markdown munging? It seems
     index 7226231..3eb1ae7 100644
     --- a/Plugin/img.pm
     +++ b/Plugin/img.pm
-    @@ -93,9 +93,15 @@ sub preprocess (@) { #{{{
+    @@ -93,9 +93,15 @@ sub preprocess (@) {
                     $imgurl="$config{url}/$imglink";
             }
      
@@ -42,7 +42,7 @@ And here's a patch to implement it. Will this survive markdown munging? It seems
     +        $result .= '/></a>';
     +
     +        return $result;
-     } #}}}
+     }
      
      1
     -- 
index 884846b32709680a6048ffaecfda49a1c5680392..ff45550673ba99cb2d41c4354b62adb614747e68 100644 (file)
@@ -23,7 +23,7 @@ And here is a [[patch]] for this.  It makes `sort=title` actually sort on the ti
     index 9c336e7..99f6de3 100644
     --- a/IkiWiki/Plugin/inline.pm
     +++ b/IkiWiki/Plugin/inline.pm
-    @@ -185,9 +185,12 @@ sub preprocess_inline (@) { #{{{
+    @@ -185,9 +185,12 @@ sub preprocess_inline (@) {
                }
        }
      
diff --git a/doc/bugs/inline_sort_order_and_meta_date_value.mdwn b/doc/bugs/inline_sort_order_and_meta_date_value.mdwn
new file mode 100644 (file)
index 0000000..d4ec8f3
--- /dev/null
@@ -0,0 +1,314 @@
+I have a directory containing two files. f1 (<http://alcopop.org/~jon/repro2/src/blog/debgtd.html>) has 
+
+    meta date="2008-07-02 14:13:17"
+
+f2 (<http://alcopop.org/~jon/repro2/src/blog/moving.html>) has
+
+    meta date="2008-07-02 21:04:21"
+
+They have both been modified recently:
+
+    >>> stat(f1)
+    (33188, 459250L, 65027L, 1, 1000, 1000, 1686L, 1227967177, 1227966706, 1227966706)
+    >>> stat(f2)
+    (33188, 458868L, 65027L, 1, 1000, 1000, 938L, 1227967187, 1227966705, 1227966705)
+
+Note that f1 is fractionally newer than f2 in terms of ctime and mtime, but f2 is much newer in terms of the meta information.
+
+Another page includes them both via inline:
+
+    inline pages="blog/*" show=5
+
+The resulting page is rendered with f1 above f2, seemingly not using the meta directive information: <http://alcopop.org/~jon/repro2/dest/blog/>. The footer in the inline pages does use the correct time e.g. <em>Posted Wed 02 Jul 2008 14:13:17 BST</em>.
+
+If I instead include them using creation_year in the pagespec, they are ordered correctly.
+
+<http://alcopop.org/~jon/repro2/> contains the src used to reproduce this, the precise ikiwiki invocation (inside Makefile) and the results (dest).
+
+-- [[users/Jon]]
+
+
+> On Ikiwiki 2.53.3 (Debian Lenny), my inlines are also sorted using mtime
+> by default -- despite what the [[documentation|/ikiwiki/directive/inline]]
+> says -- but setting the supposed default sort order manually produces the
+> correct results.  For example, the following inline sorts my blog
+> entires using their meta date or ctime:
+> 
+>     inline pages="blog/*" show="10" sort="age"
+> 
+> I'll try to look at the code this weekend and see if age is really the
+> default sort order.
+> 
+> -- [David A. Harding](http://dtrt.org), 2008-12-20
+
+Here is the code. As you can see, sort="age" is equivilant to leaving
+out the sort option. --[[Joey]] 
+
+       if (exists $params{sort} && $params{sort} eq 'title') {
+               @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
+       }
+       elsif (exists $params{sort} && $params{sort} eq 'mtime') {
+               @list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
+       }
+       elsif (! exists $params{sort} || $params{sort} eq 'age') {
+               @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
+       }
+       else {
+               return sprintf(gettext("unknown sort type %s"), $params{sort});
+       }
+
+> On further testing, I find that the bug is limited to the first time
+> creation time should be used and has nothing to do with setting the sort
+> parameter. Revised steps to reproduce: --[David A.  Harding](http://dtrt.org), 2008-12-20
+> 
+> 1. Create pages that sort different by mtime and ctime
+> 
+> 2. inline pages="somepages/*"
+> 
+> 3. ikiwiki --setup setup_file
+> 
+> 4. Pages are output incorrectly in mtime order
+> 
+> 5. ikiwiki --setup setup_file
+> 
+> 6. Pages are output correctly in ctime order
+> 
+> 7. Create new page in somepages/, set its ctime to earlier than another
+>    page in sompages/
+> 
+> 8. ikiwiki --setup setup_file
+> 
+> 9. All previously sorted pages output correctly in ctime order but new
+>    page is output incorrectly at the top as if its mtime was its ctime
+> 
+> 10. ikiwiki --setup setup_file
+> 
+> 11. All pages, including new page, are output correctly in ctime order
+
+You're confusing ctime and creation time. This is perhaps not suprising, as
+ikiwiki uses the term 'ctime' to refer to creation time. However, the unix
+ctime value is not the same thing. Unix ctime can change if a file changes
+owner, or in some cases, permissions. Unix ctime also always changes
+when the file is modified. Ikiwiki wants a first creation date of the file,
+and it accomplishes this by recording the initial ctime of a file the first
+time it processes it, and *preserving* that creation time forever, ignoring
+later ctime changes.
+
+I suspect that this, coupled with the fact that ikiwiki sorts newest pages
+first, explains everything you describe. If not, please send me a shell script
+test case I can run, as instructions like "Create pages that sort different by
+mtime and ctime" are not ones that I know how to follow (given that touch sets
+*both*). --[[Joey]] 
+
+> Sorry. I conflated Unix ctime and ikiwiki's creation time because I
+> didn't think the difference was important to this case. I'm a writer,
+> and I should have known better -- I appologize. Revised steps to
+> reproduce are below; feel free to delete this whole misunderstanding
+> to make the bug report more concise.
+>
+> 1. Create pages in the srcdir that should sort in one order by
+>    last-modification time and in a diffent order by original creation
+>    time.  For example:
+> 
+>         $ echo -e '\[[!meta date="2007-01-01"]]\nNew.' > test/new.mdwn
+>         $ echo -e '\[[!meta date="2006-01-01"]]\nOld.' > test/old.mdwn
+> 
+> 2. Create a page that includes the files.  For example:
+> 
+>
+>         $ echo '\[[!inline pages="test/*"]]' > sort-test.mdwn
+> 
+> 3. Run ikiwiki.  For example `ikiwiki --setup setup_file`
+> 
+> 4. Pages are output incorrectly in modification time order. For example,
+>    actual partial HTML of the sort-test/index.html from commands used
+>    above (whitespace-only lines removed; one whitespace-only line
+>    added):
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/old/">old</a>
+>         </span>
+>         <p>Old.</p>
+>         <span class="pagedate">
+>         Posted Sun 01 Jan 2006 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/new/">new</a>
+>         </span>
+>         <p>New.</p>
+>         <span class="pagedate">
+>         Posted Mon 01 Jan 2007 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+> 5. Run ikiwiki again with the same command line.  For example: `ikiwiki --setup setup_file`
+> 
+> 6. Pages are output correctly in creation time order. For example,
+>    actual partial HTML of the sort-test/index.html from commands used
+>    above (whitespace-only lines removed; one whitespace-only line
+>    added):
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/new/">new</a>
+>         </span>
+>         <p>New.</p>
+>         <span class="pagedate">
+>         Posted Mon 01 Jan 2007 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/old/">old</a>
+>         </span>
+>         <p>Old.</p>
+>         <span class="pagedate">
+>         Posted Sun 01 Jan 2006 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+> 7. Create a new page with the current Unix mtime and Unix ctime, but a
+>    !meta date before the most recent creation date of another page.
+>    For example:
+> 
+>         $ echo -e '\[[!meta date="2005-01-01"]]\nOlder.' > test/older.mdwn
+> 
+> 8. Run ikiwiki again with the same command line.  For example: `ikiwiki --setup setup_file`
+> 
+> 9. All previously sorted pages output correctly in order of their
+>    creation time, but the new page is output incorrectly at the top as
+>    if its modification time was its creation time.  For example,
+>    actual partial HTML of the sort-test/index.html from commands used
+>    above (whitespace-only lines removed; two whitespace-only
+>    lines added):
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/older/">older</a>
+>         </span>
+>         <p>Older.</p>
+>         <span class="pagedate">
+>         Posted Sat 01 Jan 2005 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/new/">new</a>
+>         </span>
+>         <p>New.</p>
+>         <span class="pagedate">
+>         Posted Mon 01 Jan 2007 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/old/">old</a>
+>         </span>
+>         <p>Old.</p>
+>         <span class="pagedate">
+>         Posted Sun 01 Jan 2006 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+> 10. Run ikiwiki again with the same command line.  For example: `ikiwiki --setup setup_file`
+> 
+> 11. All pages, including new page, are output correctly in creation time
+>     order. For example, actual partial HTML of the sort-test/index.html
+>     from commands used above (whitespace-only lines removed; two
+>     whitespace-only lines added): 
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/new/">new</a>
+>         </span>
+>         <p>New.</p>
+>         <span class="pagedate">
+>         Posted Mon 01 Jan 2007 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/old/">old</a>
+>         </span>
+>         <p>Old.</p>
+>         <span class="pagedate">
+>         Posted Sun 01 Jan 2006 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+>         <div class="inlinepage">
+>         <span class="header">
+>         <a href="./../test/older/">older</a>
+>         </span>
+>         <p>Older.</p>
+>         <span class="pagedate">
+>         Posted Sat 01 Jan 2005 12:00:00 AM EST
+>         </span>
+>         </div>
+> 
+> File status after all the above actions:
+> 
+>         $ stat test/*
+>           File: `test/new.mdwn'
+>           Size: 33              Blocks: 8          IO Block: 4096   regular file
+>         Device: ca20h/51744d    Inode: 684160      Links: 1
+>         Access: (0644/-rw-r--r--)  Uid: ( 1000/ harding)   Gid: ( 1000/ harding)
+>         Access: 2008-12-20 21:48:32.000000000 -0500
+>         Modify: 2008-12-20 21:27:03.000000000 -0500
+>         Change: 2008-12-20 21:27:03.000000000 -0500
+>           File: `test/older.mdwn'
+>           Size: 35              Blocks: 8          IO Block: 4096   regular file
+>         Device: ca20h/51744d    Inode: 684407      Links: 1
+>         Access: (0644/-rw-r--r--)  Uid: ( 1000/ harding)   Gid: ( 1000/ harding)
+>         Access: 2008-12-20 21:48:32.000000000 -0500
+>         Modify: 2008-12-20 21:42:10.000000000 -0500
+>         Change: 2008-12-20 21:42:10.000000000 -0500
+>           File: `test/old.mdwn'
+>           Size: 33              Blocks: 8          IO Block: 4096   regular file
+>         Device: ca20h/51744d    Inode: 684161      Links: 1
+>         Access: (0644/-rw-r--r--)  Uid: ( 1000/ harding)   Gid: ( 1000/ harding)
+>         Access: 2008-12-20 21:48:32.000000000 -0500
+>         Modify: 2008-12-20 21:27:09.000000000 -0500
+>         Change: 2008-12-20 21:27:09.000000000 -0500
+> 
+> My ikiwiki configuration file (being used to port a blog from pyblosxom
+> to ikiwiki):
+> 
+>         harding@mail:~$ sed 's/#.*//; /^[       ]*$/d' .ikiwiki/gnuisance.setup 
+>         use IkiWiki::Setup::Standard {
+>               wikiname => "HardingBlog",
+>               adminemail => 'dave@dtrt.org',
+>               srcdir => "/srv/backup/git/gnuisance.net",
+>               destdir => "/srv/test.dtrt.org",
+>               url => "http://srv.dtrt.org",
+>               wrappers => [
+>               ],
+>               atom => 1,
+>               syslog => 0,
+>               prefix_directives => 1,
+>               add_plugins => [qw{goodstuff tag}],
+>               disable_plugins => [qw{passwordauth}],
+>               tagbase => "tag",
+>         }
+>
+> --[David A. Harding](http://dtrt.org/), 2008-12-20
+
+Thank you for a textbook excellent reproduction recipe.
+
+What appears to be going on here is that meta directives are not processed
+until the leaf pages are rendered, and thus the ctime setting is not
+available at the time that they are inlined, and the newer unix ctime is
+used. On the second build, the meta data has already been recorded.
+
+This can probably be avoided by processing meta date at scan time.
+
+Verified, fix works. [[done]]
+--[[Joey]] 
diff --git a/doc/bugs/links_misparsed_in_CSV_files.mdwn b/doc/bugs/links_misparsed_in_CSV_files.mdwn
new file mode 100644 (file)
index 0000000..27d2b7b
--- /dev/null
@@ -0,0 +1,27 @@
+If a link inside a CSV file contains two or more underscores (\_), then it will get mis-parsed by the table plugin.
+
+e.g. \[[single\_track\_lines]] becomes "em>lines".
+
+Links with only one underscore are OK.
+
+Update 2008-11-24: The problem only occurs if the CSV data is in an external file. If I load it using data="""...""" then it works fine.
+
+The problem appears to be the call to htmlize inside genrow. If the data is inline, then wikilinks get expanded before they get here, and are OK. If the data is from an external file, the wikilinks aren't expanded, and htmlize will expand \[[single\_track\_lines]] into \[[single&lt;em&gt;track&lt;/em&gt;lines]].
+
+Oh, wait, I see the problem. IkiWiki::linkify is only called if the external file doesn't exist. If I remove this check and always call IkiWiki::linkify, then the problem is solved.
+
+(this is inside /usr/share/perl5/IkiWiki/Plugin/table.pm).
+
+> To reproduce this bug, I had to install the old, broken markdown 1.0,
+> instead of the now-default Text::Markdown.
+> 
+> Why is linkify not called for external files? Well, I checked the
+> history, and it's probably best to say "for historical reasons that no
+> longer apply". So, changed as you suggest. [[done]] --[[Joey]] 
+
+I am rather confused what this check does, and the fact the comments are very different for CSV and DSV when the code is the same doesn't seem to help.
+
+> The code is not the same; two operations are run in different orders for
+> CSV and DSV, as the comments note. --[[Joey]] 
+
+-- Brian May
index c835d9f986421192c8d2800a6503433757e2faaf..b8023ce87bb265220641022310b24c09f93734a4 100644 (file)
@@ -1,4 +1,4 @@
-[[plugins/lockedit]] adds the form fields for a [[pagespec]] to preferences. This pagespec should be supplied "raw"; i.e., without quotes around it. Inexperienced users (such as [[myself|jondowland]]) may provide an invalid pagespec, such as one with quotes on it. This will be merrily accepted by the form, but will cause no locking to take place.
+[[plugins/lockedit]] adds the form fields for a [[pagespec]] to preferences. This pagespec should be supplied "raw"; i.e., without quotes around it. Inexperienced users (such as [[myself|users/jon]]) may provide an invalid pagespec, such as one with quotes on it. This will be merrily accepted by the form, but will cause no locking to take place.
 
 Perhaps some validation should be performed on the pagespec and the form-submission return include "warning: this pagespec is invalid" or "warning: this pagespec does not match any existing pages" or similar.
 
@@ -15,3 +15,7 @@ Perhaps some validation should be performed on the pagespec and the form-submiss
 > There are small classes of invalid pagespecs. For example, `(foo or bar`
 > is invalid due to having unbalanced parens, while `foo or and bar` 
 > has invalid syntax. It's possible to detect these, I guess ... --[[Joey]]
+
+>> Having moved it to the .setup file makes things more obvious I think.
+>> Anyway I consider this [[done]], please de-done this if you disagree.
+>> --[[Jon]]
diff --git a/doc/bugs/login_page_should_note_cookie_requirement.mdwn b/doc/bugs/login_page_should_note_cookie_requirement.mdwn
new file mode 100644 (file)
index 0000000..9668605
--- /dev/null
@@ -0,0 +1,33 @@
+At the moment, you go through the login shuffle and then are told that cookies are needed, so you lose all your data and login again.  It would be much slicker to note by the edit link, or at least on the login page, that cookies are required.
+
+> Hmm, it seems to me to be fairly obvious, since the vast majority of
+> websites that have a login require cookies. Such warnings used to be
+> common, but few sites bother with them anymore. --[[Joey]]
+
+>> Very few websites break without cookies.  Even fewer lose data.
+>> Can ikiwiki avoid being below average by default? --[MJR](http://mjr.towers.org.uk)
+
+>>> Can we avoid engaging in hyperbole? (Hint: Your browser probably has a
+>>> back button. Hint 2: A username/password does not count as "lost data".
+>>>  Hint 3: Now we're arguing, which is pointless.) --[[Joey]]
+
+Even better would be to only display the cookie note as a warning if the login page doesn't receive a session cookie.
+
+> I considered doing this before, but it would require running the cgi once
+> to attempt to set the cookie and then redirecting to the cgi a second
+> time to check if it took, which is both complicated and probably would
+> look bad.
+
+>> Might this be possible client-side with javascript? A quick google suggests it is possible:
+>> <http://www.javascriptkit.com/javatutors/cookiedetect.shtml>. MJR, want to try adding
+>> that?  -- [[Will]]
+
+Best of all would be to use URL-based or hidden-field-based session tokens if cookies are not permitted.
+
+> This is not very doable since most of the pages the user browses are
+> static pages in a static location.
+
+>> The pages that lose data without cookies (the edit pages, primarily)
+>> don't look static. Are they really? --[MJR](http://mjr.towers.org.uk)
+
+>>> As soon as you post an edit page, you are back to a static website.
index 5c04dce03248909f615fa235b0b703520627d5d4..6fccc5c86145a587f71d69e5b1e5314fa02436a9 100644 (file)
@@ -8,7 +8,7 @@ compare:
 
 It seems putting a '+' in there throws it. Maybe it's a markdown bug, or maybe the obfuscation markdown applies to email-links is being caught by the HTML sanitizer.
 
- -- [[JonDowland]]
+ -- [[users/Jon]]
 
 > It's a markdown bug. For some reason, markdown doesn't recognize the email with a '+' as an email:
 >
index dab40d684fccec2ccb221c7b006c7d4fc4170e14..3bbf4e5fd5ffe2e5c9f68c2792b2b26c88c56e94 100644 (file)
@@ -6,7 +6,7 @@ Here is a patch that's seems to work, although I'm not quite sure what's wrong w
     --- mercurial.pm        2007-03-24 16:14:35.000000000 +0100
     +++ /home/hbernard/mercurial.pm 2007-04-19 19:05:47.000000000 +0200
     @@ -95,7 +95,7 @@
-     sub rcs_add ($) { # {{{
+     sub rcs_add ($) {
             my ($file) = @_;
      
     -       my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$file");
diff --git a/doc/bugs/messed_up_repository.mdwn b/doc/bugs/messed_up_repository.mdwn
new file mode 100644 (file)
index 0000000..e245b84
--- /dev/null
@@ -0,0 +1,21 @@
+I messed up my local clone of my repository.
+
+It appears that there is a special clone, which contains .ikiwiki, local.css, recentchanges, and the like.
+
+How can I create a new version of this clone?
+
+> No, there's the srcdir, which ikiwiki populates with some of those files
+> when run. Notably the .ikiwiki directory and all its contents, and the
+> recentchanges directory and its contents. But not local.css.
+> 
+> If you've lost .ikiwiki and it contained user registration info
+> (passwords etc), you've lost that info. Everything else can be 
+> regenerated by running `ikiwiki -setup your.setup`
+> 
+> If you still have .ikiwiki, but the git clone is messed up somehow, you
+> can just make a new clone and move .ikiwiki into it before running
+> ikiwiki. --[[Joey]]
+
+> > Great, that worked. Thanks Joey!
+
+[[!tag done]]
index 8a88f4eda4baad883c157a891cc5461b93459e13..c82b532db9c3f30e3687e7e074da0228718e16c3 100644 (file)
@@ -26,7 +26,7 @@
     index e476521..d43abd4 100644
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -471,7 +471,11 @@ sub loadplugins () { #{{{
+    @@ -471,7 +471,11 @@ sub loadplugins () {
                     unshift @INC, possibly_foolish_untaint($config{libdir});
             }
      
index 5ddfb1f6b17bad4e992e8947095780564655f255..20c38c06202c1d0b7f1fbd7f33da7f31af2cbb48 100644 (file)
@@ -28,14 +28,14 @@ Suggestions welcome.
     index 4e4da11..853f905 100644
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -618,7 +618,7 @@ sub pagename ($) { #{{{
+    @@ -618,7 +618,7 @@ sub pagename ($) {
      
        my $type=pagetype($file);
        my $page=$file;
     -  $page=~s/\Q.$type\E*$// if defined $type;
     +  $page=~s/\Q.$type\E*$// if defined $type && !$hooks{htmlize}{$type}{leavesuffix};
        return $page;
-     } #}}}
+     }
      
     diff --git a/t/pagename.t b/t/pagename.t
     index 96e6a87..58811b9 100755
@@ -61,7 +61,7 @@ I wonder if this patch will also be useful:
     index 752d176..3f1b67b 100644
     --- a/IkiWiki/Render.pm
     +++ b/IkiWiki/Render.pm
-    @@ -279,7 +279,11 @@ sub refresh () { #{{{
+    @@ -279,7 +279,11 @@ sub refresh () {
                                else {
                                        $f=~s/^\Q$config{srcdir}\E\/?//;
                                        push @files, $f;
diff --git a/doc/bugs/output_of_successful_rename_should_list_the_full_path_to_affected_pages.mdwn b/doc/bugs/output_of_successful_rename_should_list_the_full_path_to_affected_pages.mdwn
new file mode 100644 (file)
index 0000000..132d234
--- /dev/null
@@ -0,0 +1,14 @@
+I've just renamed a page and received the following as a result:
+
+<p>
+<b>Successfully renamed users/jondowland.mdwn to users/jon.mdwn.</b>
+</p>
+<p>
+
+The following pages have been automatically modified to update their links to users/jon.mdwn:
+<ul>
+<li><a href="./../../tips/convert_mediawiki_to_ikiwiki/discussion/">discussion</a></li><li><a href="./../../tips/untrusted_git_push/discussion/">discussion</a></li></ul>...
+
+In this situation I think the link to pages should be expanded to show the entire path, since there is quite likely to be a lot of things like "discussion". -- [[users/Jon]]
+
+[[done]]
index a2eba694cfe9682cc975e3247d1cb0e36c262047..78fed0e5db5eae2a9b4e73aee89bfa8910136a67 100644 (file)
@@ -54,7 +54,7 @@ case the user is given to rebuilding the wiki by hand. --Ethan
 +      }
        return IkiWiki::FailReason->new("syntax error") if $@;
        return $ret;
- } #}}}
+ }
 </pre>
 
 > Thanks, [[done]] --[[Joey]]
index a30ab0fa377508c9a0f9f9bac611980732f4672e..4a83f9ec8ab8d1f77dda156842c436281e1ea85c 100644 (file)
@@ -1,3 +1,233 @@
 The `IkiWiki::pagetitle` function does not respect title changes via `meta.title`. It really should, so that links rendered with `htmllink` get the proper title in the link text.
 
 --[[madduck]]
+
+----
+
+It is possible to set a Page-Title in the meta-plugin, but that one isn't
+reused in parentlinks. This [[patch]] may fix it.
+
+<ul>
+<li> I give pagetitle the full path to a page.
+<li> I redefine the 'pagetitle'-sub to deal with it.
+<li> to maintain compatibility for IkiWikis without the meta-plugin, i added a 'basename' to the Original-pagetitle.
+</ul>
+
+<pre>
+diff -c /usr/share/perl5/IkiWiki/Render.pm.distrib /usr/share/perl5/IkiWiki/Render.pm
+*** /usr/share/perl5/IkiWiki/Render.pm.distrib  Wed Aug  6 07:34:55 2008
+--- /usr/share/perl5/IkiWiki/Render.pm  Tue Aug 26 23:29:32 2008
+***************
+*** 102,108 ****
+        $template->param(
+                title => $page eq 'index' 
+                        ? $config{wikiname} 
+!                       : pagetitle(basename($page)),
+                wikiname => $config{wikiname},
+                content => $content,
+                backlinks => $backlinks,
+--- 102,108 ----
+        $template->param(
+                title => $page eq 'index' 
+                        ? $config{wikiname} 
+!                       : pagetitle($page),
+                wikiname => $config{wikiname},
+                content => $content,
+                backlinks => $backlinks,
+
+diff -c /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm
+*** /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib      Wed Aug  6 07:34:55 2008
+--- /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm      Tue Aug 26 23:19:43 2008
+***************
+*** 44,50 ****
+                        "height_$height" => 1,
+                };
+                $path.="/".$dir;
+!               $title=IkiWiki::pagetitle($dir);
+                $i++;
+        }
+        return @ret;
+--- 44,50 ----
+                        "height_$height" => 1,
+                };
+                $path.="/".$dir;
+!               $title=IkiWiki::pagetitle($path);
+                $i++;
+        }
+        return @ret;
+
+diff -c /usr/share/perl5/IkiWiki.pm.distrib /usr/share/perl5/IkiWiki.pm
+*** /usr/share/perl5/IkiWiki.pm.distrib Wed Aug  6 07:48:34 2008
+--- /usr/share/perl5/IkiWiki.pm Tue Aug 26 23:47:30 2008
+***************
+*** 792,797 ****
+--- 792,799 ----
+        my $page=shift;
+        my $unescaped=shift;
+  
++       $page=basename($page);
++ 
+        if ($unescaped) {
+                $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
+       }
+
+diff -c /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib /usr/share/perl5/IkiWiki/Plugin/meta.pm
+*** /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib     Wed Aug  6 07:34:55 2008
+--- /usr/share/perl5/IkiWiki/Plugin/meta.pm     Tue Aug 26 23:30:58 2008
+***************
+*** 3,8 ****
+--- 3,9 ----
+  package IkiWiki::Plugin::meta;
+  
+  use warnings;
++ no warnings 'redefine';
+  use strict;
+  use IkiWiki 2.00;
+  
+***************
+*** 289,294 ****
+--- 290,319 ----
+        }
+  }
+  
++ sub IkiWiki::pagetitle ($;$) {
++       my $page=shift;
++       my $unescaped=shift;
++ 
++       if ($page =~ m#/#) {
++               $page =~ s#^/##;
++               $page =~ s#/index$##;
++               if ($pagestate{"$page/index"}{meta}{title}) {
++                       $page = $pagestate{"$page/index"}{meta}{title};
++               } else {
++                       $page = IkiWiki::basename($page);
++               }
++       }
++ 
++       if ($unescaped) {
++               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
++       }
++       else {
++               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : "&#$2;"/eg;
++       }
++ 
++       return $page;
++ }
++ 
+  package IkiWiki::PageSpec;
+  
+  sub match_title ($$;@) {
+
+</pre>
+
+----
+
+> A few quick notes about it:
+
+> - Using <code>inline</code> would avoid the redefinition + code duplication.
+> - A few plugins would need to be upgraded.
+> - It may be necessary to adapt the testsuite in `t/pagetitle.t`, as well.
+>
+> --[[intrigeri]]
+>
+>> It was actually more complicated than expected. A working prototype is
+>> now in my `meta` branch, see my userpage for the up-to-date url.
+>> Thus tagging [[patch]]. --[[intrigeri]]
+>>
+>>> Joey, please consider merging my `meta` branch. --[[intrigeri]]
+
+So, looking at your meta branch: --[[Joey]] 
+
+* Inter-page dependencies. If page A links to page B, and page B currently
+  has no title, then A will display the link as "B". Now page B is modified
+  and a title is added. Nothing updates "A".
+  The added overhead of rebuilding every page that links to B when B is
+  changed (as the `postscan` hook of the po plugin does) is IMHO a killer.
+  That could be hundreds or thousands of pages, making interactive editing
+  way slow. This is probably the main reason I had not attempted this whole
+  thing myself. IMHO this calls for some kind of intellegent dependency
+  handler that can detect when B's title has changed and only rebuild pages
+  that link to B in that case.
+* Looks like some plugins that use `pagetitle` to format it for display
+  were not changed to use `nicepagetitle` (for example, rename).
+  But most of those callers intend to display the page name
+  as a title, but including the parent directories in the path. (Ie,
+  "renaming foo/page title to bar/page title" -- 
+  you want to know it's moved from foo to bar.) `nicepagetitle` does not
+  allow doing that since it always takes the `basename`.
+* I don't like the name `nicepagetitle`. It's not very descriptive, is it?
+  And it seems very confusing to choose whether to use the "nice" or original
+  version. My hope is that adding a second function is unnecessary.
+  As I understand it, you added a new function for two reasons: 
+  1) It needs the full page name, not basename.
+  2) `titlepage(pagetitle($page))` reversability.
+  
+  1) If you look at all the callers
+  Of `pagetitle` most of them pass a complete page name, not just the
+  basename. In most cases `pagetitle` is used to display the full name
+  of the page, including any subdirectory it's in. So why not just make
+  it consitently be given the full name of the page, with another argument
+  specifying if we want to get back just the base name.
+
+  2) I can't find any code that actually uses the reversability like that.
+  The value passed to `titlepage` always comes from some external
+  source. Unless I missed one.
+* The use of `File::Spec->rel2abs` is a bit scary.
+* Does it really make sense to call `pagetitle` on the meta title
+  in meta's `nicepagetitle`? What if the meta title is something like
+  "foo_bar" -- that would be changed to "foo bar".
+* parentlinks is changed to use `nicepagetitle(bestlink($page, $path))`.
+  Won't `bestlink` return "" if the parent page in question does not exist?
+* `backlinks()` is changed to add an additional `title` field
+  to the hash returned, but AFAICS this is not used in the template.
+* Shouldn't `Render.pm` use nicepagetitle when getting the title for the
+  page template? Then meta would not need to override the title in the
+  `pagetemplate` hook. (Although this would eliminate handling of
+  `title_overridden` -- but that is little used and would not catch
+  all the other ways titles can be overridden with this patch anyway.)
+
+> I'm not a reviewer or anything, but can I chime in on changes to pagetitle?
+> I don't think having meta-titles in wikilinks and the parentlinks path by
+> default is necessarily a good thing. I don't consider the meta-title of a page
+> as used in `<title>` to be the same thing as the short title you
+> want in those contexts - IMO, the meta-title is the "formal" title of the page,
+> enough to identify it with no other context, and frequently too long to be used
+> as a link title or a parentlink, whereas the parentlinks title in particular
+> should be some abbreviated form that's enough to identify it in context.
+> [tbm](http://www.cyrius.com/) expressed a similar opinion when I was discussing
+> ikiwiki with him at the weekend.
+>
+> It's a matter of taste whether wikilinks are "like a parentlink" or "like a
+> `<title>`"; I could be persuaded either way on that one.
+>
+> An example from my site: [this page](http://www.pseudorandom.co.uk/2004/debian/ipsec/)
+> is the parent of [this page](http://www.pseudorandom.co.uk/2004/debian/ipsec/wifi/)
+> with a title too long to use in the latter's parentlinks; I think the titles of
+> both those pages are too long to use as wikilink text too. Similarly, tbm's page
+> about [Debian on Orion devices from Buffalo](http://www.cyrius.com/debian/orion/buffalo/)
+> can simply be called "Buffalo" in context.
+>
+> Having a `\[[!meta abbrev="..."]]` that took precedence over title
+> in parentlinks and possibly wikilinks might be a good way to fix this? Or if your
+> preference goes the other way, perhaps a `\[[!meta longtitle=""]]` could take
+> precedence when generating the `<title>` and the title that comes after the
+> parentlinks. --[[smcv]]
+
+>> I think you've convinced me. (I had always had some doubt in my mind as
+>> to whether using titles in all these other places would make sense.)
+>> 
+>> Instead of meta abbrev, you could have a meta pagename that
+>> overrides the page name displayed everywhere (in turn overridden by
+>> meta title iff the page's title is being displayed). But is this complexity
+>> needed? We have meta redir, so if you want to change the name of a page,
+>> you can just rename it, and put in a stub redirection page so links
+>> still work.
+>> 
+>> This leaves the [[plugins/contrib/po]] plugin, which really does need
+>> a way to change the displayed page name everywhere, and at least a
+>> subset of the changes in the meta branch are needed to support that.
+>> 
+>> (This would also get around my concern about inter-page dependency
+>> handling, since po contains a workaround for that, and it's probably
+>> acceptable to use potentially slow methods to handle this case.)
+>> --[[Joey]] 
index 1876d912942be37eba7aed2b324ab6651cab9ac7..5fc1d8b75d379ebc71c1f2b53d6452c225b1b1ab 100644 (file)
@@ -11,7 +11,7 @@ I've no idea what's happening (hey, I'm a C programmer), but I've hacked prune()
 <pre>
 use Scalar::Util qw(tainted);
 
-sub prune ($) { #{{{
+sub prune ($) {
         my $file=shift;
 
         unlink($file);
@@ -25,7 +25,7 @@ sub prune ($) { #{{{
                         $dir = $1;
                 }
         }
-} #}}}
+}
 </pre>
 
 > Old versions of perl are known to have bugs with taint checking.
index 26f833e5f4f3e8915dcd305c163c61dbe3d67a2a..3fd75ea1b9b86ef306c28792a85a541a36806f00 100644 (file)
@@ -6,7 +6,7 @@ messages which are then taken for CGI output, causing errors and general trouble
     @@ -55,7 +55,7 @@
      }
  
-     sub rcs_update () { #{{{
+     sub rcs_update () {
     -  my @cmdline = ("hg", "-R", "$config{srcdir}", "update");
     +  my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update");
        if (system(@cmdline) != 0) {
@@ -22,7 +22,7 @@ messages which are then taken for CGI output, causing errors and general trouble
        if (system(@cmdline) != 0) {
                warn "'@cmdline' failed: $!";
     @@ -92,7 +92,7 @@
-     sub rcs_add ($) { # {{{
+     sub rcs_add ($) {
        my ($file) = @_;
      
     -  my @cmdline = ("hg", "-R", "$config{srcdir}", "add", "$file");
index 14f1c26ba632ac690ffd2bedcd6aa9592f699fe9..ef0f9d1c427933e5a78e60ec257fe5b5aadadb07 100644 (file)
@@ -92,3 +92,16 @@ to turn on? --Chapman Flack
 >>>>> required to compare `<id>`s as opaque strings.
 >>>>>
 >>>>> --[[smcv]]
+
+>>>>>> Here's my attempt at a [[patch]] for anchor-based change permalinks:
+>>>>>> <http://pastie.org/295016>.
+>>>>>> --[[JasonBlevins]], 2008-10-17
+
+[[JasonBlevins]] nailed it, [[done]] --[[Joey]]
+
+> Thanks for applying the patch (and improving it).  There's still one small issue:
+> the old opening div tag still needs to be removed (it's hard to see the removed line
+> with the pastie color scheme).
+> --[[JasonBlevins]], 2008-10-18
+
+>> Thanks, missed that when I had to hand-apply the patch. --[[Joey]]
diff --git a/doc/bugs/relative_date_weird_results.mdwn b/doc/bugs/relative_date_weird_results.mdwn
new file mode 100644 (file)
index 0000000..9f35e47
--- /dev/null
@@ -0,0 +1,4 @@
+I just submitted a new bug, and... after clicking "save", my brand new bug page displays, at the bottom: "Last edited 6 hours and 3 minutes ago". Timezone issue, I guess? (Hint: I'm in France) -- [[intrigeri]]
+
+> Yep, it wasn't including a timezone in the machine parseable time.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/remove_orphaned_sparkline-php_from_Suggests.mdwn b/doc/bugs/remove_orphaned_sparkline-php_from_Suggests.mdwn
new file mode 100644 (file)
index 0000000..b4e2a15
--- /dev/null
@@ -0,0 +1,20 @@
+Hi!
+
+How about to replace sparkline-php from Suggests by a better alternative?
+
+I would like to file a RM bug to get it out of archive. Do you have a better alternative for it? PHP has a lot of them..
+
+Thanks
+
+> sparline-php is orphaned *in Debian*. Upstream, is has seen activity as
+> recently as 11 months ago.
+>
+> I don't know of a better alternative. I looked at the perl sparkline
+> stuff in CPAN and is was bad enough that the pain of using php from this
+> perl program was a better alternative.
+> 
+> Anyway, it works great; maintaining the sparkline-php package in Debian
+> would certianly be much less work than finding some alternative and
+> rewriting the ikiwiki code to use it, *and* packaging that alternative
+> and maintaining it in Debian. So your suggestion doesn't make a lot of
+> sense; Debian should just find a maintainer for sparkline-php. --[[Joey]]
index 8c7d8134debf0818625deee9a3bd06100d7750fb..9d433e24e1a41b82a60c4b3bdae709dca66f5b25 100644 (file)
@@ -27,3 +27,17 @@ Does the Perl version of this plugin still exist?  There appears to be no "rst.p
 
 > No, only the python version exists. It does have `raw_enabled` set.
 > --[[Joey]]
+
+I am sorry, but I am confused. Does this mean that I can use Ikiwiki
+features that translate to HTML in rst files? For example, when I use a
+\[[pagename]]-style link in a rst file, the page generated by Ikiwiki's rst
+plugin says &lt;a href="./../pagename/">pagename&lt;/a> as text. The link
+is expanded correctly, but the result isn't interpreted as HTML. Is that
+what is supposed to happen? --Peter
+
+> `raw_enabled` allows you to use the
+> [raw directive](http://docutils.sourceforge.net/docs/ref/rst/directives.html),
+> but this is not used by ikiwiki for wikilinks or anything else. 
+> That's why the [[plugin_page|plugins/rst]] has its note about 
+> issues with wikilinks and directives. You'd have to put those inside
+> raw directives yourself to avoid rst escaping their result. --[[Joey]]
index 0a2b1efeaca843f788e5be7c1a5031aaf27f36fd..dace2ca1972667166d43579e91252dfbedfd4d0e 100644 (file)
@@ -2,7 +2,7 @@ It seems like gettext only searches for locale information in /usr/share/locale,
 
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -1057,6 +1057,7 @@ sub gettext { #{{{
+    @@ -1057,6 +1057,7 @@ sub gettext {
                                     $gettext_obj=undef;
                                     return shift;
                             }
diff --git a/doc/bugs/shortcut_plugin_will_not_work_without_shortcuts.mdwn.mdwn b/doc/bugs/shortcut_plugin_will_not_work_without_shortcuts.mdwn.mdwn
new file mode 100644 (file)
index 0000000..5cc6691
--- /dev/null
@@ -0,0 +1,33 @@
+On my initial ikiwiki -setup auto.setup, I get the following error:
+
+    shortcut plugin will not work without shortcuts.mdwn
+    /home/turian/utils/etc/ikiwiki/auto.setup: ikiwiki --refresh --setup /home/turian/iki.setup failed at IkiWiki/Setup/Automator.pm line 105.
+
+
+This is using the latest git pull of ikiwiki.
+I am not sure why it is not finding shortcuts.mdwn. -- [[JosephTurian]]
+
+> The error, and the weird paths suggest to me that you
+> have installed ikiwiki in a strange way, and it is failing
+> to find its basewiki underlay. The `$installdir` is
+> hardcoded into IkiWiki.pm at build time, based on the PREFIX
+> setting (see README).
+>
+> If that's not set right, you'll have other problems than just this one,
+> so I suggest you check how you installed ikiwiki.
+> 
+> Anyway, I've made the shortcut plugin only warn about this..
+> --[[Joey]] 
+
+> > I have
+> >    $installdir="/home/turian/utils/"
+> > and the underlay dir is set to:
+> >    "$installdir/share/ikiwiki/basewiki",
+> > which does contain shortcuts.mdwn. So I am not sure why it is not finding it.
+> > I am grappling with installing ikiwiki in a user account, and would like to get the directories set up correctly.
+> > How can I debug this issue further?
+
+>>>> Why don't you strace it and look at where it's looking for
+>>>> shortcuts.mdwn. --[[Joey]] 
+
+>>>>>> Hmm, so change the PERL5LIB seemed to fix this. [[Done]].
index 2dc74a984e3e088cb0e8ad9a6f6bc7ee436bf00f..04ece0ae84ee1c2a9df0c6db597703bde5213c3e 100644 (file)
@@ -65,4 +65,21 @@ significantly harder than the network based attacks."
 
 With regards to implementation, I am surprised that the libraries don't seem to
 do this checking, already, and by default. Unfortunately, I am not sure how to test
-this adequately, see <http://bugs.debian.org/466055>. -- Brian May
+this adequately, see [[!debbug 466055]]. -- Brian May
+
+--- 
+
+I think [[!cpan Crypt::SSLeay]] already supports checking the certificate. The trick
+is to get [[!cpan LWP::UserAgent]], which is used by [[!cpan LWPx::ParanoidAgent]] to
+enable this checking.
+
+I think the trick is to set one of the the following environment variables before retrieving
+the data:
+
+$ENV{HTTPS\_CA\_DIR} = "/etc/ssl/certs/";  
+$ENV{HTTPS\_CA\_FILE} = "/etc/ssl/certs/file.pem";  
+
+Unfortunately I get weird results if the certificate verification fails, see [[!debbug 503440]].
+It still seems to work though, regardless.
+
+-- Brian May
diff --git a/doc/bugs/stray___60____47__p__62___tags.mdwn b/doc/bugs/stray___60____47__p__62___tags.mdwn
new file mode 100644 (file)
index 0000000..6e508ff
--- /dev/null
@@ -0,0 +1,15 @@
+When using the [[plugins/htmltidy]] plugin (and possibly in other circumstances), ikiwiki sometimes creates more `</p>` tags than `<p>` tags, causing unbalanced markup. I've previously noticed unbalanced tags when a `\[[!map]]` matches no pages. This is part of the reason I developed [[plugins/htmlbalance]].
+
+This is particularly noticeable if htmltidy is enabled when building the docwiki: on the 'contrib' plugin pages, the title becomes `foo </p> (third-party plugin)` (with the angle-brackets escaped - it seems the text gets sanitized but is then escaped anyway).
+
+I believe that this snippet in `IkiWiki.pm` might be the reason for the imbalance:
+
+        if ($oneline) {
+                # hack to get rid of enclosing junk added by markdown
+                # and other htmlizers
+                $content=~s/^<p>//i;
+                $content=~s/<\/p>$//i;
+                chomp $content;
+        }
+
+The fact that HTML in a `\[[!meta title]]` is added but then escaped might indicate that some other bug is involved.
diff --git a/doc/bugs/support_for_openid2_logins.mdwn b/doc/bugs/support_for_openid2_logins.mdwn
new file mode 100644 (file)
index 0000000..f78d50c
--- /dev/null
@@ -0,0 +1,10 @@
+I have several complaints that users cannot contribute to my ikiwiki instances since they only have OpenID logins that support OpenID2. E.g. Yahoo!'s OpenID only supports 2.0+ 
+
+This is not the fault of ikiwiki, though the problem lies within the [perl openid consumer](http://packages.qa.debian.org/libn/libnet-openid-consumer-perl.html) in Debian which is a 1.x implementation AFAIK.
+
+I've contacted JanRain who have pointed me to:
+
+* [OpenID4Perl](http://code.sxip.com/openid4perl/)
+* Some [work](http://code.sixapart.com/svn/openid/trunk/perl/) by David Recordon
+
+However both Perl OpenID 2.x implementations have not been released and are incomplete implementations. :(
diff --git a/doc/bugs/table_external_file_links.mdwn b/doc/bugs/table_external_file_links.mdwn
new file mode 100644 (file)
index 0000000..7b35383
--- /dev/null
@@ -0,0 +1,9 @@
+If wikilinks are put in an external table file, those links are not seen at
+scan time, and so ikiwiki does not know to update the page containing the
+table when the pages the links point to change (are added, removed, etc).
+
+There seem only two solutions to that bug -- either really make wikilinks
+in an external table file not work (probably by escaping them), 
+or run the preprocess code also in scan (expensive!). --[[Joey]]
+
+[[done]]
diff --git a/doc/bugs/tags__44___backlinks_and_3.x.mdwn b/doc/bugs/tags__44___backlinks_and_3.x.mdwn
new file mode 100644 (file)
index 0000000..4fe9a47
--- /dev/null
@@ -0,0 +1,34 @@
+I think there might be an issue in the backlinks calculation in ikiwiki 3.04.
+
+I've just migrated to 3.04. In doing so, the following pagespec
+
+> "log/* and !link(tag/aggregation) and !link(tag/draft) and !*/Discussion"
+
+...started matching pages which contained
+
+> \[\[!template draft\]\]
+
+The page templates/draft.mdwn contains (amongst some markup)
+
+> \[\[!tag draft \]\]
+
+Prior to migration, the pagespec definitely took effect post-transclusion.
+
+An example: <http://jmtd.net/log/too_much_debconf_a_bad_thing/> contains the
+template inclusion, which can be seen to have worked due to markup at the
+bottom of the page. It even includes a "Tags: draft" link at the bottom.
+
+Strangely, <http://jmtd.net/tag/draft/> does not contain backlinks to pages
+which are tagged using the procedure above.
+
+After the first rebuild, it's broken, after a subsequent refresh, it is fixed.
+I've reproduced this twice (but assumed I'd done something wrong the first
+time, so went ahead and migrated live, spamming planet debian in the process
+:(). I will try and put together a testcase. -- [[users/Jon]], 2009/02/17
+
+> Looks like the same problem as
+> [[cannot_reliably_use_meta_in_template]]. AFAIK, this has never worked
+> reliably, although the linked page has a simple, though potentially
+> expensive fix. --[[Joey]] 
+
+> fix made, [[done]] --[[Joey]] 
index ac895896a6fe3f9685195d678a464849f4179628..db3917d21b16e1c543fc2394f49c01a681653ce5 100644 (file)
@@ -25,12 +25,12 @@ After some digging I found that HTML::Template is being required after the new s
                     filter => sub {
                             my $text_ref = shift;
     @@ -857,6 +856,7 @@
-     } #}}}
+     }
 
-     sub template ($;@) { #{{{
+     sub template ($;@) {
     +       require HTML::Template;
             HTML::Template->new(template_params(@_));
-     } #}}}
+     }
 
 **That** gave me:
 
index 7ec1edc4e6638611fd3d64f5e3ff32511194eeac..bdd07210ee9366ea300a18358e5ca19403a9c4ac 100644 (file)
@@ -9,6 +9,6 @@ The first two complaints happen if textile is not loaded, the third fatal one ha
 
 0x92 is "single quote" in the evil windows default codepage. It would be nice to handle this gracefully and not abort ikiwiki at this point, or alternatively, die fatally but mention which input page caused the error.
 
-Interestingly enough, in my case, the input file has several other bad windows characters (0xFC, u-umlaut) which have not caused ikiwiki to abort. ikiwiki version 2.50. -- [[JonDowland]]
+Interestingly enough, in my case, the input file has several other bad windows characters (0xFC, u-umlaut) which have not caused ikiwiki to abort. ikiwiki version 2.50. -- [[users/Jon]]
 
 > Fixed in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/txt_plugin_having_problems_with_meta_directives.mdwn b/doc/bugs/txt_plugin_having_problems_with_meta_directives.mdwn
new file mode 100644 (file)
index 0000000..2222448
--- /dev/null
@@ -0,0 +1,19 @@
+When applying my usual copyright and licensing header to a [[plugins/txt]]
+page, garbled output is created.
+
+Here is the header:
+
+    \[[meta copyright="Copyright © 2001, 2002, 2003, 2004, 2005, 2008 Free
+    Software Foundation, Inc."]]
+    
+    \[[meta license="""[[toggle id="license" text="GFDL 1.2+"]][[toggleable
+    id="license" text="Permission is granted to copy, distribute and/or modify
+    this document under the terms of the GNU Free Documentation License,
+    Version 1.2 or any later version published by the Free Software Foundation;
+    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+    A copy of the license is included in the section entitled
+    [[GNU_Free_Documentation_License|/fdl]]."]]"""]]
+
+--[[tschwinge]]
+
+> [[done]], made it less zealous about encoding html entities. --[[Joey]]
diff --git a/doc/bugs/unicode_chars_in_wikiname_break_auth.mdwn b/doc/bugs/unicode_chars_in_wikiname_break_auth.mdwn
new file mode 100644 (file)
index 0000000..472597c
--- /dev/null
@@ -0,0 +1,20 @@
+I spent hours trying to understand why my wiki suddenly refused me to log in (using passwordauth).
+The failure message was always: `login failed, perhaps you need to turn on cookies?`
+
+Inspecting the cookie information (thanks to Iceweasel's webdeveloper add-on), I realized there were some weird-looking encoded chars in the cookie name.
+
+Replacing "·" with "-" in `wikiname` fixed this login issue.
+
+> Hmm, Recai sent me a patch a long time ago to handle utf-8 here by encoding
+> the wikiname. But it doesn't seem to work, somehow the encoded utf-8
+> value still doesn't make it through. (CGI::Session seems to have underermined utf-8
+> issues too.) Seems like I will have to possibly break some sessions and
+> entity-encode the wikiname in the cookie.. [[done]]. --[[Joey]]
+
+>> I confirm it fixes the bug for me. --[[intrigeri]]
+
+(BTW, such a char was replaced by -I don't remember what encoding thingie- in my setup file, when running `ikiwiki-transition setupformat`.)
+
+> Thanks for the heads up, fixed that too. --[[Joey]]
+
+>> I confirm it fixes the bug for me. --[[intrigeri]]
diff --git a/doc/bugs/user_links_on_recentchanges_pages_problem.mdwn b/doc/bugs/user_links_on_recentchanges_pages_problem.mdwn
new file mode 100644 (file)
index 0000000..d00f681
--- /dev/null
@@ -0,0 +1,12 @@
+When I click on a linked username for commits on the recentchanges page (on
+the live ikiwiki.info) I get a link such as
+<http://ikiwiki.info/ikiwiki.cgi?page=users%2Fjoey&do=recentchanges_link>
+which returns something like
+
+    <a href="http://ikiwiki.info">ikiwiki</a>/ Error
+    <p class="error">Error: unknown do parameter
+
+-- [[Jon]]
+
+> That was fixed in 3.04 but ikiwiki.info had not been upgraded to it yet.
+> [[done]] --[[Joey]] 
index 37fb59071607e042b7476fcc738419a6ff97cd72..486a4d1864a2e731cb9d7d6cd6bc37c9f2705609 100644 (file)
@@ -7,4 +7,5 @@ developers monitor [[RecentChanges]] closely, via the webpage, email,
 [CIA](http://cia.navi.cx), and IRC, and respond in a timely fashion.
 
 You could also drop by the IRC channel `#ikiwiki` on
-[OFTC](http://www.oftc.net/) (`irc.oftc.net`).
+[OFTC](http://www.oftc.net/) (`irc.oftc.net`), or use the
+[identi.ca ikiwiki group](http://identi.ca/group/ikiwiki).
diff --git a/doc/convert.mdwn b/doc/convert.mdwn
new file mode 100644 (file)
index 0000000..871cd31
--- /dev/null
@@ -0,0 +1,7 @@
+Do you have an existing wiki or blog using other software, and would like
+to convert it to ikiwiki? Various tools and techniques have been developed
+to handle such conversions.
+
+* [[tips/convert_mediawiki_to_ikiwiki]]
+* [[tips/convert_MoinMoin_and_TWiki_to_ikiwiki]]
+* [[tips/convert_blogger_blogs_to_ikiwiki]]
index 26720196f582248919a469e741f74bb47ac71c5b..15e1475139e022f2b48c153cef6bf380de592711 100644 (file)
@@ -1,12 +1,15 @@
 [[!meta title="CSS Market"]]
 
-User contributed stylesheet files for ikiwiki. Feel free to add your own
-stylesheets here. (Upload as wiki pages; wiki gnomes will convert them to css
-files..)
+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`.
+
+Feel free to add your own stylesheets here. (Upload as wiki pages; wiki
+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 
-  [zack's blog](http://www.bononia.it/~zack/blog/)
+  [zack's blog](http://upsilon.cc/~zack/blog/)
   [[!meta stylesheet="zack"]]
 
 * **[[css_market/kirkambar.css]]**, contributed by [[Roktas]].  This far from perfect
@@ -51,6 +54,10 @@ files..)
 
 * **[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"]]
+
 If your web browser allows selecting between multiple stylesheets, this
 page can be viewed using many of the stylesheets above. For example, if
 using Epiphany with the Select Stylesheet extension enabled, use View ->
diff --git a/doc/css_market/actiontabs.css b/doc/css_market/actiontabs.css
new file mode 100644 (file)
index 0000000..a1dc47e
--- /dev/null
@@ -0,0 +1,122 @@
+/* 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 cba13132ee03bbecffc14e2816857f38476b2677..f80053e38bfe26f4083c78aefd97ed071f0d8db2 100644 (file)
@@ -5,3 +5,12 @@ What is the correct way to install the .tmpl files? -- [[JosephTurian]]
 > ikiwiki's standard templates (in, eg `/usr/share/ikiwiki/templates`)
 > --[[Joey]]
 
+----
+
+How can I update a .css file uploaded to the CSS market?
+My CSS has been updated to address comments (for the comments plugin), but I cannot find a way to update zack.css.
+The most recent version is always available at: <http://git.upsilon.cc/cgi-bin/gitweb.cgi?p=zack-homepage.git;a=blob_plain;f=local.css;hb=HEAD>
+
+-- [[StefanoZacchiroli]]
+
+> Just letting me know about the change works -- updated. --[[Joey]] 
index dbc2e5c445b3293723ab4bcc9a87bfa14f0d29b2..5a0521d54bce1e700c8531f7f27c4b2dfe7d97d6 100644 (file)
  */
 
 body {
-  font-family: sans;
-  width: 760px;
-  margin-left: 20px;
+  font-family: sans-serif;
+  font-size: medium;
 }
+h1, h2, h3, h4 {
+  font-weight: normal;
+}
+h1 { font-size: 140%; }
+h2 { font-size: 120%; }
+h3 { font-size: 110%; }
+h4 { font-size: 105% }
 
-div#content {
-  font-size: 11pt;
+a { text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+.flow {
+  float: right;
+  margin-left: 10px;
+  margin-bottom: 10px;
+  text-align: center;
 }
 
-.header span {
-  font-size: 14pt;
-  font-weight: normal;
+.attrib-caption {
+  font-size: xx-small;
+  font-style: italic;
 }
 
-div.actions ul {
-  font-size: 10pt;
+input {
+  border: solid 1px;
+  border-color: #aaa;
 }
 
-h1 {
-  font-weight: normal;
-  font-size: 17pt;
+.header { font-weight: normal; }
+
+.selflink { text-decoration: underline; }
+
+.pageheader .actions ul,
+#sitemeta {
+  border-top: solid 1px;
+  border-bottom: solid 1px;
+  font-size: small;
+  border-color: #aaa;
+  background: #eee;
 }
-h2 {
-  font-weight: normal;
-  font-size: 16pt;
+.actions ul {
+  padding: 1px;
+  margin-top: 5px;
 }
-h3 {
-  font-weight: normal;
-  font-size: 15pt;
+#sitemeta {
+  padding: 0;
+  margin-bottom: 5px;
 }
-h4 {
-  font-weight: normal;
-  font-size: 14pt;
+#backlinks,
+.tags {
+  margin-top: 0;
+  margin-bottom: 0;
 }
-h5 {
-  font-weight: normal;
-  font-size: 13pt;
+
+#pageinfo {
+  border: none;
 }
-h6 {
-  font-weight: normal;
-  font-size: 12pt;
+
+#searchform div:before {
+  font-size: small;
+  content: "search:";
+}
+#searchform input {
+  border-top: none;
+  border-bottom: none;
+  vertical-align: bottom;
+  margin-right: 7px;
 }
 
-div.inlinepage > span.header > a {
-  float: right;
-  display: block;
-  font-size: 11pt;
-  font-weight: normal;
-  margin: 0;
+#sidebar {
+  border: solid;
+  border-width: 1px;
   padding: 0;
+  margin-top: 15px;
+  border: 1px solid;
+  border-color: #aaa;
+  background: #eee;
+  width: 16ex;
 }
-div.inlinepage > span.header > a:before {
-  content: "permalink: ";
-  font-size: smaller;
-  text-decoration: none;
-  font-style: italic;
+#sidebar ul {
+  margin: 0;
+  padding-left: 1em;
+  list-style-type: none;
 }
-
-div.inlinepage {
-  margin-bottom: 10px;
+#sidebar ul ul {
+  padding-left: 1.5em;
+  font-size: 90%;
 }
 
-div.inlinepage h1 {
-  font-weight: normal;
-  font-size: 14pt;
+#pageinfo,
+#footer {
   margin: 0;
 }
-div.inlinepage h2 {
-  font-weight: normal;
-  font-size: 13pt;
-  margin: 0;
+#pageinfo {
+  font-size: small;
 }
-div.inlinepage h3 {
-  font-weight: normal;
-  font-size: 12pt;
+.pagecopyright,
+.pagelicense,
+.pagedate {
   margin: 0;
+  display: inline;
 }
-div.inlinepage h4 {
-  font-weight: normal;
-  font-size: 11pt;
-  margin: 0;
+#backlinks {
+  margin-top: 5px;
+  margin-bottom: 10px;
+  font-size: larger;
 }
-div.inlinepage h5 {
-  font-weight: normal;
-  font-size: 11pt;
-  margin: 0;
+.validation {
+  display: inline;
+  float: right;
 }
-div.inlinepage h6 {
-  font-weight: normal;
-  font-size: 11pt;
-  margin: 0;
+
+.pagecloud {
+  margin-left: 5px;
 }
 
-div#blogform {
-  padding: 0px 5px;
-  margin-bottom: 10px;
+table.identikit tr th {
+  text-align: right;
+  vertical-align: top;
+}
+table.identikit tr th:after {
+  content: ":";
+}
+table.identikit tr td {
+  text-align: left;
+  vertical-align: top;
 }
 
-pre {
-  width: 90%;
-  font-size: 10pt;
-  font-family: monospace;
-  background: #e1e1e1;
-  margin-left: 4%;
-  padding-top: 5px;
-  padding-bottom: 5px;
+.doi_logo , .doi_logo a {
+    background: #3965bd;
+    color: white !important;
+    font-size: 80%;
+    text-decoration: none;
+    font-family: times;
+    font-weight: bold;
+    padding: 0px 1px 0px 2px;
 }
 
-.pagecloud {
-  width: 25%;
-  border-top: 1px solid #aaa;
-  border-bottom: 1px solid #aaa;
-  background: #eee;
-  color: black !important;
+#comments {
+    margin-top: 5ex;
+    border-top: solid 1px;
+    border-color: #aaa;
+    font-size: small;
+}
+
+#comments #feedlink {
+    text-align: right;
+}
+#comments #feedlink:before {
+    content: "comment feeds: ";
+}
+
+.addcomment {
+    padding: 5px;
+    font-style: italic;
+}
+
+.comment {
+    border: none;
+    background-color: #eee;
+    margin: 5px;
+    margin-top: 10px;
+}
+
+.comment-subject {
+    font-style: normal;
 }
 
-.pagecloud a {
-  text-decoration: none;
+.comment-header {
+    border-top: solid 1px;
+    border-color: #aaa;
+    text-align: right;
+    font-style: normal;
 }
index 6566dc1224f65224cffedaa3993c1c52b35819e5..507b250a58efd3793eff4b673c1d6eec9c456779 100644 (file)
@@ -10,12 +10,7 @@ Installation steps and requirements are listed on the [[install]] page.
 
 ## packages
 
-To install with apt, if using Debian (since 4.0), or Ubuntu (since 6.10):
-[[!template id=note text="""
-Note that Debian 4.0 and especially Ubuntu 6.10 contain older versions of
-ikiwiki, there have been lots of enhancements and bug fixes since those
-versions.
-"""]]
+To install with apt, if using Debian or Ubuntu:
 
         apt-get install ikiwiki
 
@@ -24,7 +19,9 @@ Or download the deb from <http://packages.debian.org/unstable/web/ikiwiki>.
 There is a backport of a recent version of ikiwiki for Debian 4.0 at
 <http://packages.debian.org/etch-backports/ikiwiki>.
 
-There is also an unofficial backport of ikiwiki for Ubuntu Hardy, provided by
+Fedora versions 8 and newer have RPMs of ikiwiki available.
+
+There is also an unofficial backport of ikiwiki for Ubuntu Intrepid, provided by
 [[Paweł_Tęcza|users/ptecza]],
 at [http://gpa.net.icm.edu.pl/ubuntu/](http://gpa.net.icm.edu.pl/ubuntu/index-en.html).
 
@@ -38,6 +35,8 @@ Gentoo has an [ebuild](http://bugs.gentoo.org/show_bug.cgi?id=144453) in its bug
 IkiWiki can be installed [from macports](http://www.macports.org/ports.php?by=name&substr=ikiwiki)
 by running `sudo port install ikiwiki`.
 
+A [PKGBUILD for Arch Linux](http://aur.archlinux.org/packages.php?ID=12284) is in the AUR.
+
 ## revision control
 
 Ikiwiki is developed in a [[git_repository|git]].
index 3e89c4b99f87539fd70ce15405c36c268f025255..2155d7feab627bb733b681eb2f494678b0b8f0c5 100644 (file)
@@ -1,10 +1,11 @@
 This is an [[example_blog|index]]. Just copy the blog subdirectory into
-your wiki to quickly get started blogging with ikiwiki.
+your wiki to quickly get started blogging with ikiwiki. 
 
-Some additional configuration you might want to do:
+Or, run this command to set up a blog with ikiwiki.
+
+       % ikiwiki -setup /etc/ikiwiki/auto-blog.setup
 
-* Change the name of the blog, by editing `index.mdwn` and changing
-  the `title`.
+Some additional configuration you might want to do:
 
 * Make sure to configure ikiwiki to generate RSS or Atom feeds.
 
@@ -12,7 +13,13 @@ Some additional configuration you might want to do:
   example of how to tag a post is:
        \[[!tag tags/life]]
 
-* Enable the sidebar plugin to get a sidebar listing all the categories
-  you've tagged posts with.
+* Enable the [[sidebar|plugins/sidebar]] plugin to get a sidebar listing all
+  the categories you've tagged posts with.
+
+* Enable the [[pagestats|plugins/pagestats]] plugin to get a tag cloud
+  to display on the [[index]].
+
+* Enable the [[comments|plugins/comments]] plugin and configure it to
+  enable comments to posts to the blog:
 
-* Enable the pagestats plugin to get a tag cloud display on the [[index]].
+       comments_pagespec => 'blog/posts/* and !*/Discussion',
index 6daf9db509cede87f753f243b9f73908ce577848..84c732dd1ea24a8f63a5068e0c2c15372c25cb5f 100644 (file)
@@ -1,14 +1,13 @@
-[[!meta title="example blog"]]
-
 [[!pagestats pages="./tags/*"]]
 
-Welcome to my blog. Have a look at the most recent posts below, or
-browse the tag cloud on the right. An archive of all [[posts]] is also
-available.
+Welcome to my blog.
+
+Have a look at the most recent posts below, or browse the tag cloud on the
+right. An archive of all [[posts]] is also available.
 
 [[!inline pages="./posts/* and !*/Discussion" show="10"
 actions=yes rootpage="posts"]]
 
 ----
 
-This wiki is powered by [ikiwiki](http://ikiwiki.info).
+This blog is powered by [ikiwiki](http://ikiwiki.info).
index 3d7174ae86f3ac38e63bc50e36080264111cd9b5..d4943234109a3cef652c1303dd118772d54b0434 100644 (file)
@@ -1,4 +1,4 @@
 This is the first post to this example blog. To add new posts, just add
-files to the blog/posts/ subdirectory, or use the web form.
+files to the posts/ subdirectory, or use the web form.
 
 [[!tag tags/tech]]
index e2d180d1fc1b609c28dba237ddda74c29776a9b3..e03a969a03918f178c34f907652cc7821df0a479 100644 (file)
@@ -1,7 +1,7 @@
 FooBar is an amazing example program that does not exist. Use it for all
 your example program needs. This is its wiki.
 
-* [[download]]
+* **[[download]]**
 * [[news]]
 * [[documentation|doc]]
 * [[bugs]]
index bab65cac69e9ee5c918e8d19d3bfcb698ac37316..729540774e734bea1df5d5140ce0d6783b0a2252 100644 (file)
@@ -5,4 +5,4 @@ _This is a bold experiment by me, since I have exactly such a question. This ove
 ## Current topics ##
 
 [[!inline pages="forum/*  and !forum/discussion and !forum/*/*" 
-actions=yes rootpage="forum" postformtext="Add a new thread titled:" show=0]]
+archive=yes rootpage="forum" postformtext="Add a new thread titled:" show=0]]
diff --git a/doc/forum/Adding_new_markup_to_markdown.mdwn b/doc/forum/Adding_new_markup_to_markdown.mdwn
new file mode 100644 (file)
index 0000000..39d233a
--- /dev/null
@@ -0,0 +1,11 @@
+I'm using ikiwiki to manage my personal wiki. One of the things I'm toying with is storing my grocery list in a wiki. The way I typically grocery-shop is to make one huge master list containing all the items I typically buy in a single cycle. Then, on any given trip, I make a subset list containing only the items I need. I'd like to streamline this process by making the master list a series of checkboxes. Before each trip, I load the list page on my phone, check off all the items I already have, then check off individual items as I get them.
+
+I'm not sure if there's a convenient way of adding checkboxes to wiki pages, and after a bit of thought I decided that "( )" would be a good markup for this. Ideally I'd like to still have access to other markdown conventions so I could, say, organize the list with headings and such when it grows large, so I don't want to create an entirely separate format, or a separate copy of the markdown plugin.
+
+Is there an existing means of, say, adding supersets to wiki markup? I suppose I could use an inline directive that inserts a multisellect HTML element, but I really like ( ). :)
+
+Ideal would be some sort of filter infrastructure. Plugins could register with a larger filter plugin that adds an inline directive. I could then invoke the checkbox filter at the top of my grocery list, and all instances of ( ) would be replaced with HTML. Might also make sense for the individual filters to specify whether or not they're invoked before or after the page template, or perhaps just always invoke them after. *shrug*
+
+Does something like this exist? I'd really like to avoid messing around with raw HTML or an inline for each of 40-50 list items. :)
+
+-- [[Nolan]]
diff --git a/doc/forum/Darcs_as_the_RCS___63__.mdwn b/doc/forum/Darcs_as_the_RCS___63__.mdwn
new file mode 100644 (file)
index 0000000..2635690
--- /dev/null
@@ -0,0 +1,11 @@
+Hi,
+
+I have successfully installed and set up my first instance of [[ikiwiki]] on my dedicated server. Following [[joey]]'s screencasts made this easy (thank you).
+
+Currently, I have set up the RCS to be git but I do not like this very much. I'd rather want darcs but if I replace rcs settings, it fails.
+
+What should I put in the configuration file to use darcs ?
+
+> Darcs is not yet supported. It's being [[worked_on|todo/darcs]].
+
+> > That's good news for me then ! Thank you.
diff --git a/doc/forum/How_does_ikiwiki_remember_times__63__.mdwn b/doc/forum/How_does_ikiwiki_remember_times__63__.mdwn
new file mode 100644 (file)
index 0000000..5522cbf
--- /dev/null
@@ -0,0 +1,89 @@
+This is similar to the last post in this forum. I want to know exactly how ikiwiki remembers the times associated with pages, especially when using it for blogging, so I know whether I can trust it or not. From that last thread, I think what ikiwiki does is this:
+
+*   The created time of a file is when that file was first committed into the versioning repository (in my case git)
+
+    > If `--getctime` it used, yes. In normal operation, when new files
+    > are added, ikiwiki sets the creation time to the ctime of the file
+    > on disk, rather than bothering to ask the VCS. --[[Joey]] 
+
+*   The modified time of a file is what that file was last updated in the repository
+
+    > Almost right, the modified time is actually taken from the
+    > modification time of the file in disk. --[[Joey]] 
+
+And with a blog, by default, the posts are ordered by creation time, although an option can order them by modified time.
+
+Okay. So this should mean that the times are safe if, for example, I delete my working copy and then clone another one from the bare git repository, or otherwise mess up the creation times and mtimes stored as file metadata on the filesystem.
+
+Do I have it right?
+
+> Some VCS, like git, set the file mtimes to the current time
+> when making a new checkout, so they will be lost if you do that.
+> The creation times can be retrived using the `--getctime` option.
+> I suppose it might be nice if there were a `--getmtime` that pulled
+> true modification times out of the VCS, but I haven't found it a big
+> deal in practice for the last modification times to be updated to the
+> current time when rebuilding a wiki like this. --[[Joey]] 
+>
+> > Thanks for the clarification. I ran some tests of my own to make sure I understand it right, and I'm satisfied
+> > that the order of posts in my blog can be retrieved from the VCS using the `--getctime` option, at least if I
+> > choose to order my posts by creation time rather than modification time. But I now know that I can't rely on
+> > page modification times in ikiwiki as these can be lost permanently.
+> >
+> > I would suggest that there should at least be a `--getmtime` option like you describe, and perhaps that 
+> > `--getctime` and `--getmtime` be _on by default_. In my opinion the creation times and modification times of 
+> > pages in ikiwiki are part of the user's content and are important to protect, because the user may be relying 
+> > on them, especially if they use blogging or lists of recently modified pages, etc. Right now the modification
+> > times can be lost permanently.
+> >
+> > Is there a typo in the description of `--getctime` in the man page?
+> >
+> > > --getctime
+> > > Pull  **last  changed  time**  for each new page out of the revision
+> > > control system. This rarely used option provides a  way  to  get
+> > > the real creation times of items in weblogs, such as when build‐
+> > > ing a wiki from a new Subversion checkout. It is unoptimised and
+> > > quite  slow. It is best used with --rebuild, to force ikiwiki to
+> > > get the ctime for all pages.
+> >
+> > Surely it is not the _last changed time_ but the _first seen time_ of each page that is pulled out of the VCS?
+> > If the aim is to get the real creation times of items in weblogs, then the last times that the items were
+> > changed in the VCS is not going to help. -- [[seanh]]
+>>> Typo, fixed. --[[Joey]] 
+
+> > > If you want to preserve the date of a page, the best way to do it is to
+> > > use [[ikiwiki/directive/meta]] date="foo". This will survive checkouts,
+> > > VCS migrations, etc. -- [[Jon]]
+> > >
+> > > > That's a good tip Jon. That would also survive renaming a page by renaming its mdwn file, which would 
+> > > > normally lose the times also. (And in that case I think both times are irretrievable, even by 
+> > > > `--getctime`). I might start using a simple script to make blog posts that creates a file for
+> > > > me, puts today's date in the file as a meta, and opens the file in my editor.  -- [[seanh]]
+
+>>>>> I use a script that does that and also sets up templates and tags
+>>>>> for a new item:
+
+    #!/bin/sh
+    set -u
+    set -e
+
+    if [ $# -ne 1 ]; then
+        echo usage: $0 pagename >&2
+        exit 1
+    fi
+
+    pagename="$1"
+
+    if [ -e "$pagename" ]; then
+        echo error: "$pagename" exists >&2
+            exit 1
+    fi
+
+    date=$(date)
+    echo '\[[!template id=draft]]' >> "$pagename"
+    echo "\[[!meta date=\"$date\"]]" >> "$pagename"
+    echo "\[[!tag draft]]" >> "$pagename"
+    git add "$pagename"
+    $EDITOR "$pagename"
+
+>>>>> -- [[Jon]]
diff --git a/doc/forum/How_to_fix___34__does_not_map_to_Unicode__34___errors__63__.mdwn b/doc/forum/How_to_fix___34__does_not_map_to_Unicode__34___errors__63__.mdwn
new file mode 100644 (file)
index 0000000..0b38953
--- /dev/null
@@ -0,0 +1,20 @@
+I'm getting a number of errors like this when running ikiwiki:
+
+    utf8 "\xA2" does not map to Unicode at /usr/local/share/perl/5.10.0/IkiWiki.pm line 739, <$in> chunk 1.
+
+I think it's because some of my files contain non-utf8, non-unicode, or somehow bad characters in them, probably fancy quotes and the like that have been copy-and-pasted from my web browser. The problem is that I have hundreds of files, I transferred them all over from pyblosxom to ikiwiki at once, and the error message doesn't tell me which file the error comes from. How can I fix this?
+
+Thanks  
+-- seanh
+
+> Unfortunatly, these messages are logged by perl so there's no way to add
+> a filename to them.
+> 
+> If you run the build in --verbose mode, you should see which page ikiwiki
+> is working on, and unless it inlines some other page, you can be pretty
+> sure that page contains invalid utf-8 if the message is then printed.
+>
+> Another option is to use the `isutf8` program from 
+> moreutils](http://kitenet.net/~joey/code/moreutils/),
+> and run it on each file, it will tell you the line number
+> and character position that is invalid. --[[Joey]] 
index e88400cd427467505c7df9f9516c3118b2e68f04..53c70e50a4d14b53848e459cc8093af682498f0b 100644 (file)
@@ -17,6 +17,10 @@ Paul
 > somehow figure out that pages matched by it yesterday no longer match,
 > and that pages containing the pagespec need to be rebuilt. Which means
 > you'd also need a cron job.
->
+
+>> Thank you for the explanation.
+
 > I suspect what you're trying to accomplish is
 > [[todo/tagging_with_a_publication_date]]? --[[Joey]]
+
+>> Yeah, something like that. Thanks! --[[PaulePanter]]
diff --git a/doc/forum/Migrating_old_repository_to_new_ikiwiki_system__63__.mdwn b/doc/forum/Migrating_old_repository_to_new_ikiwiki_system__63__.mdwn
new file mode 100644 (file)
index 0000000..fe67e6a
--- /dev/null
@@ -0,0 +1,58 @@
+How do I setup an old ikiwiki repository on a new system?
+
+I have a git repository from an old ikiwiki system.
+I reformatted that hard drive, but saved the repository.
+
+I copied it the repository to my new system, which is now the "master" host.
+I installed ikiwiki on the new system.
+
+How do I set up an ikiwiki system using a pre-existing repository (instead of creating a new one)? --[[JosephTurian]]
+
+> Well, if you have:
+> * A git repository of the wiki
+> * A setup file for the wiki
+>
+> Then you should:
+> 
+> 1. Manually set up a bare git repository, and push
+>    your backed up repository to it.
+> 2. `git clone` from the bare git repository to 
+>    recreate the ikiwiki srcdir
+> 3. `git clone` from the bare git repository a second time,
+>    to create a checkout you can manually edit (optional)
+> 4. run `ikiwiki --getctime --setup your.setup`
+>    The getctime will ensure page creation times are accurate
+>    by putting the info out of the git history,
+>    and only needs to be done once.
+>
+> If you preserved your repository, but not the setup file,
+> the easiest way to make one is probably to run
+> `ikiwiki -dumpsetup` and edit the setup file. --[[Joey]] 
+
+> > I get the following errors after running ikiwiki setup:
+
+    shortcut plugin will not work without shortcuts.mdwn
+    shortcut plugin will not work without shortcuts.mdwn
+    successfully generated /home/turian/public_html/iki/ikiwiki.cgi
+    shortcut plugin will not work without shortcuts.mdwn
+    successfully generated /home/turian/repos/iki.git/hooks/post-update
+    Can't stat /usr/share/ikiwiki/basewiki/../javascript: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Plugin/autoindex.pm line 60
+    Can't stat /usr/share/ikiwiki/basewiki/../smiley: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Plugin/autoindex.pm line 60
+    Can't stat /usr/share/ikiwiki/basewiki: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Plugin/autoindex.pm line 60
+    Can't stat /usr/share/ikiwiki/basewiki/../javascript: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Render.pm line 320
+    Can't stat /usr/share/ikiwiki/basewiki/../smiley: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Render.pm line 320
+    Can't stat /usr/share/ikiwiki/basewiki: No such file or directory
+     at /home/turian/utils//lib/perl5/site_perl/5.8.8//IkiWiki/Render.pm line 320
+    internal error: smileys.mdwn cannot be found in /home/turian/iki or underlay
+
+> > How do I resolve these errors? I have my PERL5LIB location set correctly.
+
+>>> Well, that's unrelated to the original question, but
+>>> I guess you should set `underlaydir` in your setup file to
+>>> point to whereever you have installed the basewiki directory.
+>>> --[[Joey]] 
diff --git a/doc/forum/What_is_wrong_with_my_recentchange_page___63__.mdwn b/doc/forum/What_is_wrong_with_my_recentchange_page___63__.mdwn
new file mode 100644 (file)
index 0000000..4914cba
--- /dev/null
@@ -0,0 +1,13 @@
+Hi again,
+
+I have finally finished my setup *but* I still have a problem with RecentChanges page.
+
+Can somebody check it for me at [http://maillard.mobi/~xma/wiki/recentchanges/] and tell what is wrong ?
+
+Thank you.
+
+--[[xma]]
+
+> Looks to me like you don't have the meta plugin enabled. --[[Joey]]
+
+> > You are right. Now all is ok. --[[xma]]
diff --git a/doc/forum/chinese_character_problem.mdwn b/doc/forum/chinese_character_problem.mdwn
new file mode 100644 (file)
index 0000000..aea5570
--- /dev/null
@@ -0,0 +1,21 @@
+just finished setting up ikiwiki..
+
+I can type chinese, save and display it correctly in ikiwiki for the first time. However, when i try to edit the page again, the chinese character in the form is unrecognizable. you can see it here <http://ikiwiki.perlchina.org/>
+
+I am using the latest ikiwiki(manually installed as non-root user) and CGI::FormBuilder(3.0501) on Debian 4.0
+
+这个没问题 it is not a problem on ikiwiki website though.
+
+Thanks.
+
+
+> Is your system perhaps not configured with a utf-8 default locale? Or ikiwiki not configured to use it?
+> Make sure that some utf-8 locale is enabled (in /etc/locale.gen on Debian for example) and try setting `locale` in your > ikiwiki setup file. --[[Joey]]
+
+I have installed locales-all and locale -a shows that zh_CN.UTF-8 is installed(there is no /etc/local.gen file though). then I enabled this line "locale => 'zh_CN.UTF-8'" in my wiki setup and -setup again. but that generated lots error messages "Missing constant domain at (eval 30) line 3"
+
+sorry being a n00b on this thing  what else can I do?
+
+> See [[bugs/Missing_constant_domain_at_IkiWiki.pm_line_842]].
+> Looks like you need to upgrade to a newer version of 
+> [[!cpan Locale::gettext]] --[[Joey]] 
diff --git a/doc/forum/discussion.mdwn b/doc/forum/discussion.mdwn
new file mode 100644 (file)
index 0000000..93cf465
--- /dev/null
@@ -0,0 +1,7 @@
+I like the idea of this forum heirarchy -- but I think a map would be clearer than inlining the sub-pages. -- [[users/Jon]]
+
+> The easier way to accomplish this is to set archive=yes in the inline.
+> Switching to archive view can be useful when there are a lot of long
+> posts and people tend to want to scan by title to find interesting ones
+> and not necessarily read them all, which probably fits this forum pretty
+> well --[[Joey]]
diff --git a/doc/forum/ikiwiki__39__s_notion_of_time.mdwn b/doc/forum/ikiwiki__39__s_notion_of_time.mdwn
new file mode 100644 (file)
index 0000000..ee564fc
--- /dev/null
@@ -0,0 +1,35 @@
+I'm having some difficulties with ikiwiki's notion of time.
+
+For (regular) pages, the *last edited* date is the one where the file
+was indeed last modified according to the file system information.
+The *created* date (commented out in the HTML) is, at least for
+`--getctime` operation, the date, where the file was last registered
+as changed with the VCS.
+
+Now, at least with git, the thing is that when you're checking out files,
+they'll get the checkout-time's current time stamp.
+
+What I strive for is the following: *created* be the date when the file
+(under its current name) was *first* registered with the VCS (which is
+more logical in my opinion), and *last edited* be the date the file was
+last registered as changed with the VCS, which is the current
+`--getctime` *created* date.
+
+This means that I can build the HTML files from different checkouts of the
+VCS and they won't differ in the time stamps they contain in the HTML.
+
+What is the rationale for ikiwiki's current behavior with respect to these
+time stamps?
+
+--[[tschwinge]]
+
+> Presumably it's the authors of the git and mercurial backends
+> not understanding the documentation for `rcs_getctime`,
+> which states:
+> 
+>>This is used to get the page creation time for a file from the RCS, by
+>>looking it up in the history.
+> 
+> I've fixed both broken implementations to correctly look
+> up the first, not the last, commit. Other VCS do not seem
+> to have the problem. --[[Joey]] 
diff --git a/doc/forum/managing_todo_lists.mdwn b/doc/forum/managing_todo_lists.mdwn
new file mode 100644 (file)
index 0000000..0a69af8
--- /dev/null
@@ -0,0 +1,44 @@
+I keep some TODO lists on ikiwiki pages. I'm half-tempted to write a plugin
+to make ticking items off and adding items easier via the web interface. I'm
+aware though that this is not really what ikiwiki is designed for. Would
+anyone else find this useful? -- [[users/jon]]
+
+----
+
+My subsequent thoughts about how to approach this are two-fold.
+
+Firstly, a filetype for todo lists, probably OPML, but I haven't looked to see
+if there is something more suitable. A plugin that converts this source into a
+traditional page output, i.e. a DOM tree of ul or ol and li elements.
+
+Secondly, some magic javascript to make editing the list via the web page 
+more interactive: add items, strike items out, reorder items etc., without
+round-tripping to the cgi for each operation.
+
+Finally, a mechanism whereby the changes made to the page live can be
+committed back to the repository:
+
+ * ...perhaps the input → output conversion is reversible, and the HTML DOM
+   representing the list can be transformed back into the source and submitted
+   to the cgi like a regular edit: issues include the result of other
+   postprocessing: templates, wikilinks, etc.
+ * perhaps an embedded copy of the source is included in the output and the
+   javascript operates on that in tandem with the static copy
+   * perhaps the "output" is generated live by the JS at view time (with maybe
+     a plugin-generated rendered output for non JS environments)
+
+I envisage a button called "commit changes" appearing once some changes are
+made that submits the changes to the CGI, perhaps via a back channel. I'm not
+sure how to handle embeds or challenges from the CGI such as a login challenge
+(maybe the back channel would not be necessary in the first cut).
+
+> You might look at the [[plugins/hnb]] plugin. HNB supports checklists.
+> There's not a fancy web interface, but the hnb command-line program can
+> be used to edit them. --[[Joey]] 
+
+>> thanks - I'll give it a look. I spent a few hours writing some javascript to manipulate a ul/li DOM tree in an outliner-fashion the other day. I might be able to join the puzzle pieces together sometime. [[Jon]]
+
+a solution for this could be similar to a solution for [[todo/structured page data]], as todo lists are definitely a form of structured data. (in both cases, the page's current content is rendered into a html form, whose result is then saved as the page's new contents) --[[chrysn]]
+
+> Thanks for the link: yup, there's definitely some common ground there.
+> -- [[Jon]]
index d42a5c704dc55379e499ca69bfdad2b59be8a7f8..fa8b5010e38065e8d880d048d961957ad0ad6c0c 100644 (file)
@@ -43,7 +43,7 @@ In the end, I did the following. I created a directory /srv/ikiwiki/ which is ow
 
 ## cgi_wrapper
 
-I do not understand those wrappers completely. The cgi is a script, which can be called by a webserver, e. g. [[Apache_2|/tips/apache_cgi]]. But www-data is normally not allowed to write to the source directory (which is owned by gitosis or push to the repository). Therefore it should be run as the user gitosis. And because cgi scripts can not be made suid, I wrapper (in this case a C program) is created (cgi\_wrapper) which can be made suid and therefore be run as the user gitosis. Is this correct?
+I do not understand those wrappers completely. The cgi is a script, which can be called by a webserver, e. g. [[Apache_2|/tips/dot_cgi]]. But www-data is normally not allowed to write to the source directory (which is owned by gitosis or push to the repository). Therefore it should be run as the user gitosis. And because cgi scripts can not be made suid, I wrapper (in this case a C program) is created (cgi\_wrapper) which can be made suid and therefore be run as the user gitosis. Is this correct?
 
 > It seems to me like you understand the wrapper pretty well. It's main reson to exist is to safely be suid, yes.
 
diff --git a/doc/forum/usedirs___38___indexpages_using_problem.mdwn b/doc/forum/usedirs___38___indexpages_using_problem.mdwn
new file mode 100644 (file)
index 0000000..05c85e2
--- /dev/null
@@ -0,0 +1,17 @@
+My ikiwiki setup file configed like:
+
+       usedirs => 0,
+       indexpages => 1,
+
+I create a directory and some .mdwn source file  /Whatis/index.mdwn and /Whatis/OSS.mdwn . The html file ikiwiki generated is
+/Whatis/index.html and /Whatis/OSS.html . 
+
+But in the page [OSS.html](http://atoz.org.cn/Whatis/OSS.html) , the auto generated link (on the page top)
+to “Whatis” is /Whatis.html file , not to /Whatis/index.html. So the link to “Whatis” is fail .
+
+Is it a bug , and how can I do for that ?
+
+> I suggest that you name your page `Whatis.mdwn`, and not
+> `Whatis/index.mdwn`. That will make ikiwiki's links work,
+> and allows you to link to the `Whatis` page by that name.
+> --[[Joey]] 
diff --git a/doc/forum/wiki_name_in_page_titles.mdwn b/doc/forum/wiki_name_in_page_titles.mdwn
new file mode 100644 (file)
index 0000000..01ff8d8
--- /dev/null
@@ -0,0 +1,26 @@
+I'd like to have the wiki name appear in page titles as in "WikiName:
+Page Title."  If I use `<TMPL_VAR WIKINAME>: <TMPL_VAR TITLE>` in the
+template this works for all pages except the index page itself which
+will have title "WikiName: WikiName" as its title.  Does anyone know
+of a template-based solution to this or do I need to write a plugin
+that provides a `IS_HOMEPAGE` template variable? --[[JasonBlevins]]
+
+> Hmm, one way to work around this is to put a meta title directive on the
+> index page. Then TITLE will be that, rather than WIKINAME, and your
+> template should work. --[[Joey]]
+
+>> I ended up writing a [path][] plugin since I had some other
+>> path-specific conditional things to include in my templates.
+>>
+>> So now I can do things like this:
+>>
+>>     <title>
+>>     <TMPL_VAR WIKINAME><TMPL_UNLESS IS_HOMEPAGE>: <TMPL_VAR TITLE></TMPL_UNLESS>
+>>     </title>
+>>
+>> But also more complicated path-specific conditionals like
+>> `IN_DIR_SUBDIR` to indicate subpages of `/dir/subdir/`.  I've got a
+>> few other small plugins brewing so I'll try to put up some contrib
+>> pages for them soon. --[[JasonBlevins]]
+
+[path]: http://code.jblevins.org/ikiwiki/plugins.git/plain/path.pm
diff --git a/doc/freesoftware/discussion.mdwn b/doc/freesoftware/discussion.mdwn
new file mode 100644 (file)
index 0000000..e71fd29
--- /dev/null
@@ -0,0 +1,3 @@
+And where is the code, please ?
+
+> [[download]] --[[Joey]] 
index e5fef6a5adad4b449c934e62c16778b0d11ae279..8a89546cf7d3fff0d791ead8acc39e58f1530e7b 100644 (file)
@@ -1,5 +1,12 @@
-Ikiwiki is developed in a git repository and can be checked out 
-like this:
+Ikiwiki, and this documentation wiki, are developed in a git repository and
+can be checked out like this:
+
+[[!template id=note text="""
+You can push changes back to ikiwiki's git repository over the `git://`
+transport, to update this wiki, if you'd like, instead of editing it on the
+web. Changes that could not be made via the web will be automatically
+rejected.
+"""]]
 
        git clone git://git.ikiwiki.info/
 
@@ -9,16 +16,30 @@ Or like this if your firewall only passes http traffic (slow):
 
 The gitweb is [here](http://git.ikiwiki.info/?p=ikiwiki).
 
-There is also a mirror [on github](http://github.com/joeyh/ikiwiki/tree/master).
-
 Commits to this git repository are fed into [CIA](http://cia.vc), and can
 be browsed, subscribed to etc on its
-[project page](http://cia.vc/stats/project/ikiwiki).
+[project page](http://cia.vc/stats/project/ikiwiki). They're also fed into
+[twitter](http://twitter.com/ikiwiki).
 
-## branches
+## personal git repositories
 
 You are of course free to set up your own ikiwiki git repository with your
-own [[patches|patch]].
+own [[patches|patch]]. If you list it here, the `gitremotes` script will
+automatically add it to git remotes. Your repo will automatically be pulled
+into [[Joey]]'s working tree. This is recommended. :-)
+
+<!-- Machine-parsed format: * wikilink <git:url> -->
+
+* github `git://github.com/joeyh/ikiwiki.git`
+  ([browse](http://github.com/joeyh/ikiwiki/tree/master))  
+  A mirror of the main repo, automatically updated.
+* [[smcv]] `git://git.pseudorandom.co.uk/git/smcv/ikiwiki.git`
+* [[intrigeri]] `git://gaffer.ptitcanardnoir.org/ikiwiki.git`
+* [[gmcmanus]] `git://github.com/gmcmanus/ikiwiki.git`
+* [[jelmer]] `git://git.samba.org/jelmer/ikiwiki.git`
+* [[hendry]] `git://webconverger.org/git/ikiwiki`
+
+## branches
 
 Some of the branches included in the main repository include:
 
@@ -30,9 +51,9 @@ Some of the branches included in the main repository include:
 * `wikiwyg` adds [[todo/wikiwyg]] support. It is unmerged pending some
   changes.
 * `darcs` is being used to add darcs support.
-* `pristine-tar` contains deltas that
-  [pristine-tar](http://kitenet.net/~joey/code/pristine-tar)
-  can use to recreate released tarballs of ikiwiki
 * `debian-stable` is used for updates to the old version included in
   Debian's stable release, and `debian-testing` is used for updates to
   Debian's testing release.
+* `pristine-tar` contains deltas that
+  [pristine-tar](http://kitenet.net/~joey/code/pristine-tar)
+  can use to recreate released tarballs of ikiwiki
index d5034b2c724da9780890985351d1b7fc5c59b6a4..3fbfbdc827c3f0208a0cd12e5241f6fc5744bd4f 100644 (file)
@@ -6,16 +6,17 @@ ikiwiki-makerepo - check an ikiwiki srcdir into revision control
 
 ikiwiki-makerepo svn|git|monotone|darcs srcdir repository
 
-ikiwiki-makerepo mercurial|darcs srcdir
+ikiwiki-makerepo bzr|mercurial|darcs srcdir
 
 # DESCRIPTION
 
 `ikiwiki-makerepo` injects a `srcdir` directory, containing an ikiwiki wiki,
-into a `repository` that it creates. The repository can be a svn, git, or
-mercurial repository.
+into a `repository` that it creates. The repository can be created using
+any of a variety of revision control systems.
 
-Note that for mercurial, the srcdir is converted into a mercurial
-repository. There is no need to have a separate repository with mercurial.
+Note that for mercurial and bzr, the srcdir is converted into a
+repository. There is no need to have a separate repository with mercurial
+or bzr.
 
 For darcs, the second (one-argument) form turns the given srcdir into a
 darcs master repository with the (new) srcdir inside. Adjust your ikiwiki.setup
@@ -24,8 +25,8 @@ preconfigured to call a (hypothetical) ikiwiki wrapper. The command
 reports the relevant file. Adjust it as needed or remove it if you don't use
 the cgi script.
 
-Note that for monotone, you are assumed to already have run "mtn genkey" to generate
-key.
+Note that for monotone, you are assumed to already have run "mtn genkey"
+to generate key.
 
 # AUTHOR
 
index 8b7c3579fabd3c1af8cc58bb43d4a0f7b7d00985..18836d5f5745dc3f4184b857c9fdca124b92ead2 100644 (file)
@@ -8,24 +8,23 @@ ikiwiki-transition type ...
 
 # DESCRIPTION
 
-`ikiwiki-transition` aids in converting wiki pages when
-there's a major change in ikiwiki syntax. It also handles other transitions
-not involving wiki pages.
+`ikiwiki-transition` aids in converting wiki pages when there's a major
+change in ikiwiki syntax. It also handles other transitions not involving
+wiki pages.
 
-# prefix_directives
+# prefix_directives your.setup
 
-The `prefix_directives` mode converts the specified ikiwiki page from
-the old preprocessor directive syntax, requiring a space, to the new
-syntax, prefixed by '!'.
+The `prefix_directives` mode converts all pages from the old preprocessor
+directive syntax, requiring a space, to the new syntax, prefixed by '!'.
 
 Preprocessor directives which already use the new syntax will remain
 unchanged.
 
-Note that if the page contains wiki links with spaces, which some
+Note that if a page contains wiki links with spaces, which some
 older versions of ikiwiki accepted, the prefix_directives transition will
 treat these as preprocessor directives and convert them.
 
-# setupformat
+# setupformat your.setup
 
 The `setupformat` mode converts a setup file from using a single `wrappers` block
 to using `cgi_wrapper`, `git_wrapper`, etc.
@@ -33,25 +32,30 @@ to using `cgi_wrapper`, `git_wrapper`, etc.
 Note that all comments and any unusual stuff like perl code in the setup
 file will be lost, as it is entirely rewritten by the transition.
 
-# aggregateinternal
+# aggregateinternal your.setup
 
 The `aggregateinternal` mode moves pages aggregated by the aggregate plugin
 so that the `aggregateinternal` option can be enabled.
 
-# indexdb
+# moveprefs your.setup
+
+Moves values that used to be admin preferences into the setup file.
+
+Note that all comments and any unusual stuff like perl code in the setup
+file will be lost, as it is entirely rewritten by the move.
+
+# indexdb srcdir
 
 The `indexdb` mode handles converting a plain text `.ikiwiki/index` file to
-a binary `.ikiwiki/indexdb`. In this mode, you should specify the srcdir of
-the wiki as the second parameter. You do not normally need to run
+a binary `.ikiwiki/indexdb`. You do not normally need to run
 `ikiwiki-transition indexdb`; ikiwiki will automatically run it as
 necessary.
 
-# hashpassword
+# hashpassword srcdir
 
 The `hashpassword` mode forces any plaintext passwords stored in the
 `.ikiwiki/userdb` file to be replaced with password hashes. (The
-Authen::Passphrase perl module is needed to do this.) In this mode, you
-should specify the srcdir of the wiki as the second parameter. 
+Authen::Passphrase perl module is needed to do this.)
 
 If this is not done explicitly, a user's plaintext password will be
 automatically converted to a hash when a user logs in for the first time
index c4342dee8a644ff1778672a3b1ff89ca1d4c2668..fb88aa72d494df0408baa77051abf729d7b83b12 100644 (file)
@@ -28,15 +28,13 @@ of text with triple-quotes:
        3. "baz"
        """]]
 
-ikiwiki also has an older syntax for directives, which requires a
-space in directives to distinguish them from [[wikilinks|ikiwiki/wikilink]].
-This syntax has several disadvantages: it requires a space after directives
-with no parameters (such as `\[[pagecount ]]`), and it prohibits spaces in
-[[wikilinks|ikiwiki/wikilink]].  ikiwiki now provides the `!`-prefixed syntax
-shown above as the preferred alternative.  However, ikiwiki still supports
-wikis using the older syntax, if the `prefix_directives` option is not enabled.
-For backward compatibility with existing wikis, this option currently
-defaults to off, so ikiwiki supports the old syntax.
+ikiwiki also has an older syntax for directives, which requires a space in
+directives to distinguish them from [[wikilinks|ikiwiki/wikilink]]. This
+syntax has several disadvantages: it requires a space after directives with
+no parameters (such as `\[[pagecount ]]`), and it prohibits spaces in
+[[wikilinks|ikiwiki/wikilink]].  ikiwiki now provides the `!`-prefixed
+syntax shown above as default.  However, ikiwiki still supports wikis using
+the older syntax, if the `prefix_directives` option is disabled.
 
 [[!if test="enabled(listdirectives)" then="""
 Here is a list of currently available directives in this wiki:
index 012367bdf9a6f8cd8c5d941a5f7df3fd32ca8e67..ca580e54f63e51cc4844be31febedc0739ea902d 100644 (file)
@@ -17,11 +17,11 @@ follow the paste directive that uses its text.  In fact, this is quite useful
 to postpone big blocks of text like long annotations and have a more natural
 flow.  For example:
 
-       \[[!toggleable id="cut" text="\[[!paste id=cutlongdesc]]"]]
-       \[[!toggleable id="copy" text="\[[!paste id=copylongdesc]]"]]
-       \[[!toggleable id="paste" text="\[[!paste id=pastelongdesc]]"]]
+       \[[!toggleable id="cut" text="[[!paste id=cutlongdesc]]"]]
+       \[[!toggleable id="copy" text="[[!paste id=copylongdesc]]"]]
+       \[[!toggleable id="paste" text="[[!paste id=pastelongdesc]]"]]
 
-       \[...some time later...]
+       [...some time later...]
 
        \[[!cut id=cutlongdesc text="""
           blah blah blah
@@ -40,7 +40,7 @@ Since you can paste without using double quotes, copy and paste can be used to
 nest directives that require multiline parameters inside each other:
 
        \[[!toggleable id=foo text="""
-         \[[!toggleable id=bar text="\[[!paste id=baz]]"]]
+         [[!toggleable id=bar text="[[!paste id=baz]]"]]
        """]]
 
        \[[!cut id=baz text="""
diff --git a/doc/ikiwiki/directive/format.mdwn b/doc/ikiwiki/directive/format.mdwn
new file mode 100644 (file)
index 0000000..94cf1b0
--- /dev/null
@@ -0,0 +1,21 @@
+The `format` directive is supplied by the [[!iki plugins/format desc=format]]
+plugin.
+
+The directive allows formatting a chunk of text using any available page
+format. It takes two parameters. First is the type of format to use,
+ie the extension that would be used for a standalone file of this type.
+Second is the text to format.
+
+For example, this will embed an otl outline inside a page using mdwn or
+some other format:
+
+       \[[!format otl """
+       foo
+               1
+               2
+       bar
+               3
+               4
+       """]]
+
+[[!meta robots="noindex, follow"]]
index 9889cda114bfb9b12effcbf82bef91e615811981..f69d55de3dc6582bcc1dec6378813ea1774af85e 100644 (file)
@@ -73,6 +73,8 @@ Here are some less often needed parameters:
   configured to `allowatom`, set to "yes" to enable.
 * `feeds` - controls generation of all types of feeds. Set to "no" to
   disable generating any feeds.
+* `emptyfeeds` - Set to "no" to disable generation of empty feeds.
+  Has no effect if `rootpage` or `postform` is set.
 * `template` - Specifies the template to fill out to display each inlined
   page. By default the `inlinepage` template is used, while
   the `archivepage` template is used for archives. Set this parameter to
@@ -85,7 +87,10 @@ Here are some less often needed parameters:
   inlining page.
 * `sort` - Controls how inlined pages are sorted. The default, "age" is to
   sort newest created pages first. Setting it to "title" will sort pages by
-  title, and "mtime" sorts most recently modified pages first.
+  title, and "mtime" sorts most recently modified pages first. If
+  [[!cpan Sort::Naturally]] is installed, `sort` can be set to "title_natural"
+  to sort by title with numbers treated as such ("1 2 9 10 20" instead of
+  "1 10 2 20 9").
 * `reverse` - If set to "yes", causes the sort order to be reversed.
 * `feedshow` - Specify the maximum number of matching pages to include in
   the rss/atom feeds. The default is the same as the `show` value above.
@@ -97,11 +102,16 @@ Here are some less often needed parameters:
   in the blog. The format string is passed to the strftime(3) function.
 * `feedpages` - A [[PageSpec]] of inlined pages to include in the rss/atom
   feeds. The default is the same as the `pages` value above, and only pages
-  matches by that value are included, but some of those can be excluded by
+  matched by that value are included, but some of those can be excluded by
   specifying a tighter [[PageSpec]] here.
 * `guid` - If a URI is given here (perhaps a UUID prefixed with `urn:uuid:`),
   the Atom feed will have this as its `<id>`. The default is to use the URL
   of the page containing the `inline` directive.
+* `feedfile` - Can be used to change the name of the file generated for the
+  feed. This is particularly useful if a page contains multiple feeds.
+  For example, set "feedfile=feed" to cause it to generate `page/feed.atom`
+  and/or `page/feed.rss`. This option is not supported if the wiki is
+  configured not to use `usedirs`.
 
 [[!meta robots="noindex, follow"]]
 
index 91b2ff46242db91b8a21c5f9863ac1224402c0ce..e301190bf2204b8f4d1fe41162b5677dd37af8d5 100644 (file)
@@ -19,3 +19,14 @@ take it as far as implementing "replies" to other comments.
 ## More dynamic `rootpage` parameter of inline plugin?
 
 (Moved to [[todo/dynamic_rootpage]])
+
+---
+
+## Excluding Images
+
+Is there a simple way to exclude images, stylesheets, and other
+"non-page" files other than a blacklist approach like
+`pages="* and !*.png and !*.css"`?  --[[JasonBlevins]]
+
+> The [[plugins/filecheck]] plugin adds a 'ispage()' pagespec test that can do that.
+> --[[Joey]]
index 8fdf40c9ff04bd39d270d070ab028b698e8ccbd4..db79a1491c9a9d85b445a236b718fe9f67fa76c0 100644 (file)
@@ -9,7 +9,7 @@ Only links between mapped pages will be shown; links pointing to or from
 unmapped pages will be omitted. If the pages to include are not specified,
 the links between all pages (and other files) in the wiki are mapped. For
 best results, only a small set of pages should be mapped, since otherwise
-the map can become very large, unweildy, and complicated. Also, the map is
+the map can become very large, unwieldy, and complicated. Also, the map is
 rebuilt whenever one of the mapped pages is changed, which can make the
 wiki a bit slow.
 
index 74db319435b346ce8aee6854717947c72c4d389e..f29a118bfea91d9957c30022312e558bc3b8b980 100644 (file)
@@ -139,6 +139,15 @@ Supported fields:
   pages unchanged and avoid_flooding_aggregators
   (see [[!iki tips/howto_avoid_flooding_aggregators]]).
 
+* updated
+
+  Specifies a fake modification time for a page, to be output into RSS and
+  Atom feeds. This is useful to avoid flooding aggregators that sort by
+  modification time, like Planet: for instance, when editing an old blog post
+  to add tags, you could set `updated` to be one second later than the original
+  value. The date/time can be given in any format that
+  [[!cpan TimeDate]] can understand, just like the `date` field.
+
 If the field is not one of the above predefined fields, the metadata will be
 written to the generated html page as a &lt;meta&gt; header. However, this
 won't be allowed if the [[!iki plugins/htmlscrubber desc=htmlscrubber]] plugin is enabled,
diff --git a/doc/ikiwiki/directive/pagestats/discussion.mdwn b/doc/ikiwiki/directive/pagestats/discussion.mdwn
new file mode 100644 (file)
index 0000000..3c9dc71
--- /dev/null
@@ -0,0 +1,10 @@
+I am trying to create a tag cloud using:  
+           
+     \[[!pagestats  pages="tags/*"]]
+
+Nothing shows up when I first used this directive. I found that I had to create a page for the tag for it to show up in pagestats.
+I would rather not find and create a page for every tag I have created or will create. Is there an easier way to create a list of tags?
+
+Thanks
+
+----
index 267aee660d52d0c53f68aeb1cf63cbc2379c753a..64736f8cddfd0ec31ad05231a19f01e7df28dfc6 100644 (file)
@@ -21,6 +21,10 @@ located under a base directory, such as "tags/". This is a useful way to
 avoid having to write the full path to tags, if you want to keep them
 grouped together out of the way.
 
+Bear in mind that specifying a tagbase means you will need to incorporate it
+into the `link()` [[ikiwiki/PageSpec]] you use: e.g., if your tagbase is
+`tag`, you would match pages tagged "foo" with `link(tag/foo)`.
+
 If you want to override the tagbase for a particular tag, you can use
 something like this:
 
diff --git a/doc/ikiwiki/directive/testpagespec/discussion.mdwn b/doc/ikiwiki/directive/testpagespec/discussion.mdwn
new file mode 100644 (file)
index 0000000..66c9a9c
--- /dev/null
@@ -0,0 +1,6 @@
+How does one test a user identity?  I tried "pagename and user(username) for the match, and had a "no user specified" error.
+
+> You can't test them with this directive, because such pagespecs test to
+> see if logged in user, who is performing some action, matches. When the
+> page with the directive is built, the concept of a user being logged in
+> doesn't really apply. --[[Joey]] 
index a4190945f541b6a9d5b0f4236675c47f6877c7aa..68419192942abb3c25758e5d8b52f319bf8311f1 100644 (file)
@@ -4,9 +4,7 @@ is a minimal markup language that resembles plain text as used in
 email messages. It is the markup language used by this wiki by default.
 
 For documentation about the markdown syntax, see [[formatting]] and
-[Markdown: syntax](http://daringfireball.net/projects/markdown/syntax). A
-[markdown mode](http://jblevins.org/projects/markdown-mode/) for 
-emacs can help in editing.
+[Markdown: syntax](http://daringfireball.net/projects/markdown/syntax).
 
 Note that [[WikiLinks|WikiLink]] and [[directives|directive]] are not part
 of the markdown syntax, and are the only bit of markup that this wiki
index c78666c4057238035798b9c10b26a01e7f332409..b476bde1f0b1385d26db52ed943500a27199f14b 100644 (file)
@@ -25,6 +25,7 @@ match all pages except for Discussion pages and the SandBox:
 Some more elaborate limits can be added to what matches using these functions:
 
 * "`link(page)`" - match only pages that link to a given page (or glob)
+* "`tagged(tag)`" - match pages that are tagged or link to the given tag (or glob)
 * "`backlink(page)`" - match only pages that a given page links to
 * "`creation_month(month)`" - match only pages created on the given month
 * "`creation_day(mday)`" - or day of the month
@@ -47,6 +48,8 @@ Some more elaborate limits can be added to what matches using these functions:
   wiki admins.
 * "`ip(address)`" - tests whether a modification is being made from the
   specified IP address.
+* "`postcomment(glob)`" - matches only when comments are being 
+  posted to a page matching the specified glob
 
 For example, to match all pages in a blog that link to the page about music
 and were written in 2005:
@@ -63,29 +66,10 @@ More complex expressions can also be created, by using parentheses for
 grouping. For example, to match pages in a blog that are tagged with either
 of two tags, use:
 
-       blog/* and (link(tag/foo) or link(tag/bar))
+       blog/* and (tagged(foo) or tagged(bar))
 
 Note that page names in PageSpecs are matched against the absolute
 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".
-
-## Old syntax
-
-The old PageSpec syntax was called a "GlobList", and worked differently in
-two ways:
-
-1. "and" and "or" were not used; any page matching any item from the list
-   matched.
-2. If an item was prefixed with "`!`", then no page matching that item
-   matched, even if it matched an earlier list item.
-
-For example, here is the old way to match all pages except for the SandBox
-and Discussion pages:
-
-       * !SandBox !*/Discussion
-
-Using this old syntax is still supported. However, the old syntax is
-deprecated and will be removed at some point, and using the new syntax is
-recommended.
index 2d33db748ad2a5f9a35378194e0c0b497285eb08..344a4a734c6308cba4b193987dace2b8a8a95f11 100644 (file)
@@ -9,7 +9,7 @@ configuration setting.
 
 For example, to limit arbitrary files to 50 kilobytes, but allow
 larger mp3 files to be uploaded by joey into a specific directory, and
-check all attachments for virii, something like this could be used:
+check all attachments for viruses, something like this could be used:
   
        virusfree() and ((user(joey) and podcast/*.mp3 and mimetype(audio/mpeg) and maxsize(15mb)) or (!ispage() and maxsize(50kb)))
 
index 0733c90c8efd7cc8a47b55d91f3cdd10fbcc1432..4eed3722ccc744595fc8380e68e69dc9e1ad6450 100644 (file)
@@ -65,3 +65,30 @@ How can I fix this?  --[[sabr]]
 
 > I don't see why that wouldn't work. Can I download the source to your
 > wiki from somewhere to investigate? --[[Joey]]
+
+----
+
+Should negation work with user(), with locked_pages in setup?  I
+experimented with setting locked_pages => 'user(someuser)' and was able to
+edit as a different user.  However, setting locked_pages =>
+'!user(someuser)' doesn't seem to allow edits for only 'someuser' - it
+locks out all users.
+
+> Negation works with anything in any PageSpec. I tested the case you
+> describe, and a negated pagespec worked for me; all users except the
+> listed user (and except wiki admins of course) were locked out.
+> --[[Joey]] 
+
+>> It must be a local problem, then, cause I've tried it with two separate 
+>> machines.  Both are running the most recent release of ikiwiki in 
+>> pkgsrc - 2.66.  Perhaps an update to a newer version would solve the issue.
+
+----
+
+Is there a way to refer to all subpages of the current page, if  the name of the 
+current page is not known (i.e. the pagespec is used in a template)? The ./ syntax
+does not seem suitable for this, as
+
+> \[[!map pages="./*"]]
+
+also lists the current page and all its siblings.
index b5cb848edead4cfb61938286e734f4a0d8b13c13..0677ff7ded6a86be7d010dfd97affdb6b266832a 100644 (file)
@@ -51,6 +51,19 @@ simply write [[wikilink]]s like `\[[../bar]]` (or even just `\[[..]]`?), but
 this doesn't work, so I had to resort to using `\[[foo/bar]]` instead.
 --[[tschwinge]]
 
+> I believe, that doesn't entirely solve the problem. Just assume, your hierarchy is `/foo/bar/foo/bar`.
+
+> How do you access from the page `/foo/bar/foo/bar` the `/foo/bar` and not `/foo/bar/foo/bar`?
+
+> Do we have a way to implement `\[[../..]]` or `\[[/foo/bar]]`?
+
+> Even worse, trying to link from `/foo/bar` to `/foo/bar/foo/bar` ... this will probably need `\[[./foo/bar]]` --[[Jan|jwalzer]]
+
+>> There is no ".." syntax in wikilinks, but if the link begins with "/" it
+>> is rooted at the top of the wiki, as documented in
+>> [[subpage/linkingrules]]. Therefore, every example page name you listed
+>> above will work unchanged as a wikilink to that page! --[[Joey]]
+
 ----
 
 How do I make images clickable?  The obvious guess, \[[foo.png|/index]], doesn't work.  --[[sabr]]
@@ -64,3 +77,5 @@ How do I make images clickable?  The obvious guess, \[[foo.png|/index]], doesn't
 Is it possible to refer to a page, say \[[foobar]], such that the link text is taken from foobar's title [[directive/meta]] tag? --Peter
 
 > Not yet. :-) Any suggestion for a syntax for it? Maybe something like \[[|foobar]] ? --[[Joey]]
+
+I like your suggestion because it's short and conscise. However, it would be nice to be able to refer to more or less arbitrary meta tags in links, not just "title". To do that, the link needs two parameters: the page name and the tag name, i.e. \[[pagename!metatag]]. Any sufficiently weird separater can be used instead of '!', of course. I like \[[pagename->metatag]], too, because it reminds me of accessing a data member of a structure (which is what referencing a meta tag is, really). --Peter
index e5f978e12a438c311df68a4fdf380765055ff86f..94ae75046a261f36b7b3e290f2113f2f89246f55 100644 (file)
@@ -1,8 +1,7 @@
-Projects
-========
+Projects & Organizations
+========================
 
 * [This wiki](http://ikiwiki.info) (of course!)
-* [UK Software Patents info page](http://www.softwarepatents.co.uk/)
 * [Planet Debian upstream](http://updo.debian.net/)
 * The [ion window manager homepage](http://modeemi.fi/~tuomov/ion/)
 * [Debian Mentors wiki](http://jameswestby.net/mentors/)
@@ -22,7 +21,7 @@ Projects
 * The [Debian Packaging Handbook project](http://packaging-handbook.alioth.debian.org/wiki/)
 * The [libkdtree project](http://libkdtree.alioth.debian.org)
 * The [pcc](http://pcc.ludd.ltu.se/) (Portable C Compiler) project.  (Simple rcs backend)
-* [The TOVA Company](http://www.tovatest.com) public site. We also use it for internal documentation and issue tracking, all with a [[rcs/Git]] backend.
+* [The TOVA Company](http://www.tovatest.com) public site.  We also use it for internal documentation and issue tracking, all with a [[rcs/Git]] backend.
 * Technical support websites for [Homebase](http://support.homebase.dk) and [Kaospilotene](http://support.kaospilot.no) (each with [source](http://source.homebase.dk/) [provided](http://source.kaospilot.no/))
 * [CampusGrün Hamburg](http://www.campusgruen.org/)
 * The [awesome window manager homepage](http://awesome.naquadah.org/)
@@ -39,10 +38,18 @@ Projects
 * [Chaos Computer Club Düsseldorf](https://www.chaosdorf.de)
 * [monkeysphere](http://web.monkeysphere.info/)
 * [The Walden Effect](http://www.waldeneffect.org/)
+* The [Fortran Wiki](http://fortranwiki.org/)
+* [Monotone](http://monotone.ca/wiki/FrontPage/)
+* The support pages for [Trinity Centre for High Performance Computing](http://www.tchpc.tcd.ie/support/)
+* [St Hugh of Lincoln Catholic Primary School in Surrey](http://www.sthugh-of-lincoln.surrey.sch.uk/)
+* [Pigro Network](http://www.pigro.net) is running a hg based ikiwiki. (And provides ikiwiki hosting for $10/m.)
+* [Cosin Homepage](http://cosin.ch) uses an Ikiwiki with a subversion repository.
+* [Bosco Free Orienteering Software](http://bosco.durcheinandertal.ch)
 
 Personal sites and blogs
 ========================
 
+* [Skirv's Wiki](http://wiki.killfile.org) - formerly Skirv's Homepage
 * [[Joey]]'s [homepage](http://kitenet.net/~joey/), including his weblog
 * [Kyle's MacLea Genealogy wiki](http://kitenet.net/~kyle/family/wiki) and [Livingstone and MacLea Emigration Registry](http://kitenet.net/~kyle/family/registry)
 * [Ulrik's personal web page](http://kaizer.se/wiki/)
@@ -100,11 +107,23 @@ Personal sites and blogs
 * [Olivier Berger's professional homepage](http://www-public.it-sudparis.eu/~berger_o/)
 * [Andrey Tarantsov's homepage](http://www.tarantsov.com/)
 * [Don Marti's blog](http://zgp.org/~dmarti/)
-* [[JonDowland]]'s [homepage](http://jmtd.net/)
+* [[users/Jon]]'s [homepage](http://jmtd.net/)
+* [[xma]] is using ikiwiki (<http://maillard.mobi/~xma/>)
+* [[JanWalzer|jwalzer]]'s [homepage](http://wa.lzer.net/) -- Work in Progress
+* [[Adam_Trickett|ajt]]'s home intranet/sanbox system ([Internet site & blog](http://www.iredale.net/) -- not ikiwiki yet)
+* [[Simon_McVittie|smcv]]'s [website](http://www.pseudorandom.co.uk/) and
+  [blog](http://smcv.pseudorandom.co.uk/)
+* Svend's [website](http://www.ciffer.net/~svend/) and [blog](http://www.ciffer.net/~svend/blog/)
+* [muammar's site](http://muammar.me)
+* [Per Bothner's blog](http://per.bothner.com/blog/)
+* [Bernd Zeimetz (bzed)](http://bzed.de/)
+* [Gaudenz Steinlin](http://gaudenz.durcheinandertal.ch)
+* [Simon Kjika'qawej C.](http://simonraven.kisikew.org/ikiwiki/) Please note it might change location at any time (likely wiki.k.o or under /wiki/ at simonraven.k.o).
+
+
 Please feel free to add your own ikiwiki site!
 
-See also: [Debian ikiwiki popcon graph](http://people.debian.org/~igloo/popcon-graphs/index.php?packages=ikiwiki)
+See also: [Debian ikiwiki popcon graph](http://popcon.debian.org/~igloo/popcon-graphs/index.php?packages=ikiwiki)
 and [google search for ikiwiki powered sites](http://www.google.com/search?q=%22powered%20by%20ikiwiki%22).
 
 While nothing makes me happier than knowing that ikiwiki has happy users, dropping some change in the [[TipJar]] is a nice way to show extra appreciation.
index 2da3668d4aa3c700a703023c5177f8b09614dd85..39a9bb9210fc09dd15672144c9c5ab5d76c7bf9e 100644 (file)
@@ -29,3 +29,7 @@ Thanks, --[[Chao]]
 Thanks for the reply Joey! ikiwiki is a fantastic wiki complier, though I do
 not have my own machine momentarily, i will pay close attention to its development.
 Hopefully I will be one of the ikiwiki users one day :) cheers --[[Chao]]
+
+----
+
+Are there automated hosting sites for ikiwiki yet?  If you know one, can you add one in a new section on [[ikiwikiusers]] please?  If you don't know any and you're willing to pay to set one up (shouldn't be much more expensive than a single ikiwiki IMO), [contact me](http://www.ttllp.co.uk/contact.html) and let's talk. -- MJR
index 89e12e6c26ed655466bbe26fbc9f3b591e5a6756..d52cb0a2dc41a3a7742f27e1955972d842b3b6d4 100644 (file)
@@ -288,6 +288,10 @@ easily, perl is possible (but I'm not strong in perl).
 
 >>> It appears the scripts were never posted?  I recently imported my Mediawiki site into Iki.  If it helps, my notes are here: <http://iki.u32.net/Mediawiki_Conversion> --[[sabr]]
 
+>>>>> The scripts have been posted now, see [[joshtriplett]]'s user page, 
+>>>>> and I've pulled together all ways I can find to [[convert]] other
+>>>>> systems into ikiwiki. --[[Joey]]
+
 ----
 
 # LaTeX support?
diff --git a/doc/index/openid/discussion.mdwn b/doc/index/openid/discussion.mdwn
new file mode 100644 (file)
index 0000000..ae614e5
--- /dev/null
@@ -0,0 +1,29 @@
+# OpenID discussion
+
+## No return_to in OpenID server
+
+Hi, there's no return_to from a designated OpenID server page, specs requires (I think a "should" or "must", can't recall exact wording) that it redirects back to the RP, in order to complete the registration and authentication. Unless I'm missing something, and the doc is incomplete, I'd consider this a bug. I don't expect to be of much use WRT coming up with a patch, but I'm willing to test ;-) .
+
+> If this is a bug, could you please explain:
+> 
+> * What happens when the bug occurs?
+> * How can one reproduce the bug?
+>
+> PS, please file bugs under [[bugs]] in future. --[[Joey]]
+
+>> Oops, my bad, didn't know that existed at the time I wrote this.
+>>
+>> What happened is that the process wouldn't complete, therefore I couldn't login with my OpenID.
+>>
+>> reproducibility: every time
+>>
+>> Should probably move this page, eh? ;)
+>> I'd do that, but I dunno know other than using the SCM backend in question....
+
+Here's some actual output (with my OpenID URL stripped out):
+
+do=postsignin&oic.time=1238224497-1450566d93097caa707f&openid.assoc_handle=%7BHMAC-SHA1%7D%7B49cdce76%7D%7BBhuXXw%3D%3D%7D&openid.identity=|<==== MY OPENID URL GOES HERE ====>|&openid.mode=id_res&openid.op_endpoint=http%3A%2F%2Fwww.myopenid.com%2Fserver&openid.response_nonce=2009-03-28T07%3A15%3A02ZDUFmG3&openid.return_to=http%3A%2F%2Fsimonraven.kisikew.org%2Fbin%2Fikiwiki.cgi%3Fdo%3Dpostsignin%26oic.time%3D1238224497-1450566d93097caa707f&openid.sig=E51Xh6Gnjku%2B0se57qCyhHbT5QY%3D&openid.signed=assoc_handle%2Cidentity%2Cmode%2Cop_endpoint%2Cresponse_nonce%2Creturn_to%2Csigned
+
+The `return_to` arg should NOT be `signed`, it should be the originating URL where you initially logged in.
+
+Also, I dunno what the assoc_handle is doing spitting out an arg like `{HMAC-SHA1}{49cdce76}{BhuXXw%3D%3D}` it should be processed further. I have the needed perl packages installed (latest for Lenny). Hrm, would endianness matter?
index d745737aafe97f60d22652cf817c84047a7b8ce9..cc3a4c29f186ca1d0c952c28b14733dda70d0659 100644 (file)
@@ -19,15 +19,6 @@ they are available.
 Various [[plugins]] use other perl modules and utilities; see their individual
 documentation for details.
 
-### Installing dependencies with yum
-
-Here's an example of how to install ikiwiki's dependencies using yum
-on Fedora 7:
-
-       yum install perl-Text-Markdown perl-Mail-Sendmail perl-HTML-Scrubber \
-         perl-XML-Simple perl-TimeDate perl-HTML-Template perl-CGI-FormBuilder \
-         perl-CGI-Session perl-File-MimeInfo perl-gettext perl-Authen-Passphrase
-
 ### Installing dependencies by hand
 
 If you want to install by hand from the tarball, you should make sure that
index abe909a94bb278ec5677fe81e85c87467f9912c6..c1129a4358cc9a9e75364be6c3a837a54e617825 100644 (file)
@@ -169,3 +169,62 @@ good. Date::Parse was already installed. --[[vibrog]]
     usemymalloc=n, bincompat5005=undef
 
 Not sure how to provide proper version information for you.--[[vibrog]]
+
+---
+
+I've tried a couple of times and my cpan has never recognised Bundle::IkiWiki. Is that section of the page still accurate? -- [[users/Jon]]
+
+> Are you running perl with the environemnt settings specified on the page?
+> Can you show how it fails to find the bundle? --[[Joey]]
+
+>> I was not. Next time I build I will have to try that (I'll need to tweak it as I already override PERL5LIB; also I need to specify http proxies). Thanks for your help! -- [[users/Jon]]
+
+---
+
+##Further problems with Bundle::IkiWiki
+I'm also having trouble with finding Bundle::IkiWiki.  I've tried it with the environment settings and without them, and also using the interactive 
+form of the cpan command.  I've also gone to cpan.org and searched -- eg
+
+    http://search.cpan.org/search?query=ikiwiki&mode=all
+
+and no Bundle for IkiWiki comes up at all.
+
+The error I get from the various cpan attempts is basically always the same:
+
+    Warning: Cannot install Bundle::IkiWiki, don't know what it is.
+    Try the command
+
+        i /Bundle::IkiWiki/
+
+    to find objects with matching identifiers.
+
+When I try that command, BTW, it basically seems to find the same stuff I get when searching on the cpan web site.
+
+This happens both on Ubuntu 8.04 and CentOS 5.1
+
+Any help would be greatly appreciated... --kent
+
+> Bundle::IkiWiki is included in ikiwiki itself, so of course cpan.org
+> does not know about it.
+> 
+> If you can show me exactly what command you ran (the tested, working
+> commands on the parent page?) and how it failed, I can try to debug
+> your problem.
+
+Just today I noticed the "Bundle" subdirectory.  What a moron I am! :-)  Also, I misunderstood the PERL5LIB=`pwd` part -- 
+I glibly thought it indicated the sink for the installation of the modules, rather than the source, and I was running 
+the cpan command from another window in a different directory, and just spiraled down into error...
+
+> The real question in my mind is why you'd want to do this at all when
+> using Ubuntu, which incldues packages of ikiwiki and all its
+> dependencies. --[[Joey]]
+
+For ubuntu 8.04: 
+
+    $ ikiwiki --version
+    ikiwiki version 2.32.3ubuntu2.1
+    $
+
+I was just trying to get the latest version.
+
+In any case, thanks for the help, and thanks for the superb software.  I really like it a lot.
index bdc37343225897f7aabd8b2b747a963afede97cf..09b68523eaddb1932dd0a19a1e82ede32004ad2e 100644 (file)
@@ -1,7 +1,7 @@
 I've produced a [code_swarm](http://vis.cs.ucdavis.edu/~ogawa/codeswarm/)
 visualization of the first 2+ years of ikiwiki's commit history. 
 
-[[!img screenshot.png size="480x360"]]
+[[!img screenshot.png size="480x360" alt="screenshot"]]
 
 * [15 mb avi](http://kitenet.net/~joey/screencasts/ikiwiki_swarm.avi)
 * [stream on vimeo](http://vimeo.com/1324348)
diff --git a/doc/news/git_push_to_this_wiki.mdwn b/doc/news/git_push_to_this_wiki.mdwn
new file mode 100644 (file)
index 0000000..4b3fcbe
--- /dev/null
@@ -0,0 +1,3 @@
+Now you can use [[git]] to clone this wiki, and push your changes back,
+thanks to ikiwiki's new support for [[tips/untrusted_git_push]]. Enjoy
+working on the wiki while offline! --[[Joey]]
diff --git a/doc/news/git_push_to_this_wiki/discussion.mdwn b/doc/news/git_push_to_this_wiki/discussion.mdwn
new file mode 100644 (file)
index 0000000..33230c7
--- /dev/null
@@ -0,0 +1,37 @@
+Thanks, Joey!  This is awesome...I had to try it out :)
+--[[JasonBlevins]]
+
+I am really happy to hear of this new feature, that I was (more or less)
+secretly dreaming of. But - and that's why I'm still insanely editing
+this wiki inside a web browser - I wonder how I'll use it for real: my
+own master branch contains a few dozens merge commits, and one is created
+every time I `git pull` ikiwiki repository (or another clone of it, living
+on one of my other boxes that by chance had Internet access more recently).
+I do not want to clutter Joey's repository with these commits, so I guess
+I have to learn some more of Git everything-is-possible world (a nice thing
+is: I am not limited anymore to "Emacs can do it", and I'm now in a position
+to say "Git can do it" or "ikiwiki already does it", depending on the
+situation). Well, let's focus. Git wizards amongst us (let's use this wiki
+as if it were users@ikiwiki.info, ok?), what would you suggest? I was thinking
+of having a new branch in my cloned repository, dedicated to editing this wiki;
+I could use `rebase` instead of `fetch+merge` to get the new upstream commits
+into this special-purpose branch. I guess it would work nicely if I had only
+one offline box with not-yet-pushed changes at the same time, but would break
+in awful and various ways when it is not the case. Any alternative idea?
+--[[intrigeri]]
+
+> Not that I'm very careful to avoid pushing merge commits (see git log ;-), 
+> but I sometimes use `git pull --rebase` to pull changes from a repo. That
+> will rebase your local changes on top of the changes pulled, avoiding the
+> merge commits. I'm sure more involved solutions are possible. --[[Joey]]
+
+> I decided to use my local `master` branch as a copy of `origin/master`
+> (kitenet) and move my local modifications to a separate branch.  I'm using
+> `master` to edit the wiki but there is still the problem of new upstream
+> commits since the last pull.  I already had this problem as Joey had pushed
+> some changes while I was editing locally.  Not knowing about
+> `pull --rebase`, I took the long way out: branch, roll back HEAD, rebase,
+> and merge.  That was too much work...It looks like `pull --rebase` is the
+> way to go. --[[JasonBlevins]]
+
+Awesome ! --[[xma]]
diff --git a/doc/news/ikiwiki_version_3.0.mdwn b/doc/news/ikiwiki_version_3.0.mdwn
new file mode 100644 (file)
index 0000000..7ca636c
--- /dev/null
@@ -0,0 +1,42 @@
+Ikiwiki has reached version 3.0 and entered a new phase in its
+[[development_cycle|roadmap]].
+
+The 3.0 release of ikiwiki changes several defaults and finishes
+some transitions. You will need to modify your wikis to work with
+ikiwiki 3.0. A document explaining the process is available
+in [[tips/upgrade_to_3.0]].
+
+The highlights of the changes in version 3.0 include:
+
+* Support for uploading [[attachments|plugins/attachment]].
+* Can [[plugins/rename]] and [[plugins/remove]] pages and files via the web.
+* [[Web_based_setup|plugins/websetup]].
+* Blog-style [[plugins/comments]] as an alternative to Discussion pages.
+* Many other new plugins including [[plugins/htmlbalance]], [[plugins/format]],
+  [[plugins/progress]], [[plugins/color]], [[plugins/autoindex]],
+  [[plugins/cutpaste]], [[plugins/hnb]], [[plugins/creole]], [[plugins/txt]],
+  [[plugins/amazon_s3]], [[plugins/pinger]], [[plugins/pingee]],
+  [[plugins/edittemplate]]
+* The RecentChanges page is compiled statically, not generated from the CGI.
+* Support for additional revision control systems: [[rcs/bzr]],
+  [[rcs/monotone]]
+* Support for [[tips/untrusted_git_push]].
+* A new version (3.00) of the plugin API, exporting additional
+  commonly used functions from `IkiWiki.pm`.
+* Nearly everything in ikiwiki is now a plugin, from WikiLinks to
+  page editing, to RecentChanges.
+* Far too many bug fixes, features, and enhancements to list here.
+
+Thanks to the many contributors to ikiwiki 3.0, including:
+
+  Jelmer Vernooij, Recai Oktaş, William Uther, Simon McVittie, Axel Beckert,
+  Bernd Zeimetz, Gabriel McManus, Paweł Tęcza, Peter Simons, Manoj
+  Srivastava, Patrick Winnertz, Jeremie Koenig, Josh Triplett, thm, Michael
+  Gold, Jason Blevins, Alexandre Dupas, Henrik Brix Andersen, Thomas Keller,
+  Enrico Zini, intrigeri, Scott Bronson, Brian May, Adeodato Simó, Brian
+  Downing, Nis Martensen. (And anyone I missed.)
+
+Also, thanks to the users, bug submitters, and documentation wiki editors.
+Without you, ikiwiki would just be a little thing I use for my home page.
+
+--[[Joey]]
index ad76606aab0e89c12ce73b6b15acca084b3159c8..c2a871f0a4df2e707aa89950afd2684a6af93259 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 59 "Accept only OpenID for logins" 18 "Accept only password logins" 35 "Accept both"]]
+[[!poll 61 "Accept only OpenID for logins" 18 "Accept only password logins" 36 "Accept both"]]
index 3d5e9dc224fcd12ddb3b7e9065b8675951e57f2e..aa9f3f0beb6414e9baa57f01e69249c9eb4608a7 100644 (file)
@@ -42,7 +42,7 @@ only Apache/iptables rules for this? Maybe it's related to
 
 > Error: /srv/web/ikiwiki.info/todo/Configurable_minimum_length_of_log_message_for_web_edits/index.html independently created, not overwriting with version from todo/Configurable_minimum_length_of_log_message_for_web_edits
 
-[[jondowland]]
+[[users/jon]]
 
 ----
 
diff --git a/doc/news/version_2.62.1.mdwn b/doc/news/version_2.62.1.mdwn
deleted file mode 100644 (file)
index e82ccfa..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ikiwiki 2.62.1 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * filecheck: Fixed two bits broken in move from attachment."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.63.mdwn b/doc/news/version_2.63.mdwn
deleted file mode 100644 (file)
index 165f60c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-ikiwiki 2.63 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Set cookies HttpOnly.
-   * Typo. Closes: #[497003](http://bugs.debian.org/497003)
-   * Ignore failure to install files into /etc, in case install is running as
-     non-root.
-   * Work around perl $\_ scoping nonsense that caused breakage when loading
-     external plugins.
-   * style.css: Add missing semicolon. Closes: #[497176](http://bugs.debian.org/497176)
-   * filecheck: Fall back to testing for binary or plain text files
-     if no mime type is detected.
-   * table: Support header=column to make the table header be the first
-     column of the data. (AlexandreDupas)
-   * For fine control over what characters are allowed, unescaped in
-     source filenames, the wiki\_file\_chars setting is added. For example,
-     set to "-[:alnum:]+/.\_" to disable colons from being used in source files
-     (which can cause troubl om Windows).
-   * po/Makefile: update po files when the pot file has changed.
-     Closes: #[497951](http://bugs.debian.org/497951)
-   * editpage: New core plugin factoring out page editing to allow disabling it
-     if desired."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.64.mdwn b/doc/news/version_2.64.mdwn
deleted file mode 100644 (file)
index 137ca1a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-ikiwiki 2.64 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Avoid uninitialised value when --dumpsetup is used and no srcdir/destdir
-     specified.
-   * ddate: Stop clobbering timeformat when not enabled.
-   * progress: New plugin to generate progress bars (willu)
-   * Add allow\_symlinks\_before\_srcdir to config so websetup doesn't eat it.
-   * img: Support sizes like 200x. Closes: #[475149](http://bugs.debian.org/475149)
-   * goodstuff: Remove otl plugin from the bundle since it needs a significant
-     external dependency and is not commonly used. If you use otl, make sure
-     you explicitly enable it now.
-   * goodstuff: Add more, progress, and table plugins to the bundle.
-   * Improve error message if external plugin fails to load. Closes: #[498458](http://bugs.debian.org/498458)
-   * Directive documentation broken out of the plugin documentation and into
-     pages suitable to be used as an underlay. Thanks to Willu for doing most
-     of the tedious work.
-   * Move the directive documentation into its own underlay, separate from
-     basewiki, since it's sorta large compared to the rest of basewiki.
-   * listdirectives: Enable use of the directives underlay.
-   * Removed the obsolete blog page from the basewiki. ikiwiki/blog still
-     remains, but is now deprecated too.
-   * Removed old redirecton pages from basewiki (helponformatting,
-     markdown, openid, pagespec, preprocessordirective, subpage, wikilink).
-   * inline: Treat rootpage as a link, so that it can refer to a subpage
-     without hardcoding the path."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.65.mdwn b/doc/news/version_2.65.mdwn
deleted file mode 100644 (file)
index db6afd9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-ikiwiki 2.65 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * aggregate: Expire excess or old items on the same pass that adds them,
-     not only on subsequent passes.
-   * editdiff: Broken since 2.62 due to wrong syntax, now fixed.
-   * aggregate: Support atom feeds with only a summary element, and no content
-     elements.
-   * progress: Display an error if the progress cannot be parsed, and allow
-     the percent parameter to only optionally end with "%".
-   * Fix reversion in use of ikiwiki -verbose -setup with a setup file that
-     enables syslog. Setup output is once again output to stdout in this
-     case.
-   * edittemplate: Default new page file type to the same type as the template.
-     (willu)
-   * edittemplate: Add "silent" parameter. (Willu)
-   * edittemplate: Link to template, to allow creating it. (Willu)
-   * editpage: Add a missing check that the page name contains only legal
-     characters, in addition to the existing check for pruned filenames.
-   * Print a debug message if a page has multiple source files.
-   * Add keepextension parameter to htmlize hook. (Willu)
-   * rename, remove: Don't rely on a form parameter to tell whether the page
-     should be treated as an attachment.
-   * rename: Add support for moving SubPages of a page when renaming it.
-     (Sponsored by The TOVA Company.)
-   * rename: Hide type field from rename form when renaming attachments."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.66.mdwn b/doc/news/version_2.66.mdwn
deleted file mode 100644 (file)
index 029c7a1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-ikiwiki 2.66 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * recentchanges: Fix redirects to non-page files.
-   * aggregate: Avoid uninitialized value warnings for pages with no recorded
-     ctime.
-   * attachment: Add admin() pagespec to test if the uploading user is a wiki
-     admin.
-   * git: Fix handling of utf-8 filenames in recentchanges.
-   * tag: Make edit link for new tags ensure that the tags are created
-     inside tagbase, when it's set.
-   * template: Make edit link for new templates ensure the page is located
-     under toplevel templates directory.
-   * htmlscrubber: Add a config setting that can be used to disable the
-     scrubber acting on a set of pages.
-   * Expand usage message and add --help. Closes: #[500344](http://bugs.debian.org/500344)
-   * Beautify urls used in various places. (smcv)
-   * Export pagetitle, titlepage, linkpage.
-   * htmltidy: Avoid returning undef if tidy fails. Also avoid returning the
-     untidied content if tidy crashes. In either case, it seems best to tidy
-     the content to nothing.
-   * htmltidy: Avoid spewing tidy errors to stderr.
-   * Reorganize index file, add a format version field. Upgrades to the new
-     index format should be transparent.
-   * Add %wikistate, which is like %pagestate except not specific to a given
-     page, and is preserved across rebuilds.
-   * editpage: Be more aggressive (and less buggy) about cleaning up
-     temporary files rendered during page preview.
-   * Add an indexpages option, which causes foo/index.mdwn to be the source
-     for page foo when foo.mdwn doesn't exist. Also, when it's enabled,
-     creating a new page will save it to foo/index.mdwn by default.
-     Closes: #[474611](http://bugs.debian.org/474611)
-     (Sponsored by The TOVA Company.)
-   * httpauth: Document that ikiwiki.cgi has to be in a directory subject to
-     authentication. Closes: #[500524](http://bugs.debian.org/500524)
-   * inline: Fix handling of rootpage that doesn't exist.
-   * attachment: Support adding attachments to pages even as they are being
-     created.
-   * remove, rename: Allow acting on attachments as a page is being created.
-   * Updated French translation. Closes: #[500929](http://bugs.debian.org/500929)"""]]
\ No newline at end of file
diff --git a/doc/news/version_2.68.mdwn b/doc/news/version_2.68.mdwn
new file mode 100644 (file)
index 0000000..b7e6250
--- /dev/null
@@ -0,0 +1,44 @@
+ikiwiki 2.68 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Add support for checking pushes from untrusted git committers. This can be
+     used to set up anonymous git pushes, and other similar things.
+   * format: New plugin, allows embedding differently formatted text inside a
+     page (ie, otl inside a mdwn page, or syntax highlighted code inside a
+     page).
+   * relativedate: New javascript-alicious plugin that makes all dates display
+     relative, in a very nice way, if I say so myself.
+   * Optimise the no-op post-commit hook, to speed up web edits by a fraction
+     of a second.
+   * git: Allow [[sha1\_commit]] to be used in the diffurl, to support cgit.
+   * shortcut: Fix display of shortcuts while previewing.
+   * Plugins that used to override displaytime should instead override
+     formattime. displaytime will call that, and may wrap markup around the
+     formatted time.
+   * Add an underlay for javascript, and add ikiwiki.js containing some utility
+     code.
+   * toggle: Stop embedding the full toggle code on each page using it, and
+     move it to toggle.js in the javascript underlay.
+   * recentchanges: Make feed links point back to anchors on the recentchanges
+     page. (JasonBlevins)
+   * Fix issue with utf-8 in wikiname breaking session cookies, by
+     entity-encoding the wikiname in the session cookie.
+   * Use the pure perl Data::Dumper when generating setup files to ensure that
+     utf-8 characters are written out as such, and not as the encoded perl
+     strings the C Data::Dumper produces.
+   * inline: Only the last feed link was put on the page, fix this to include
+     all feed links. So rss will be included along with atom, and pages with
+     multiple feeds will get links added for all feeds.
+   * tag: When tagpage is set, force the links created by tagging to point at
+     the toplevel tagpage, and not closer subpages. The html links already went
+     there, but internally the links were not recorded as absolute, which could
+     cause confusing backlinks etc.
+   * Add an inject function, that can be used by plugins that want to
+     replace one of ikiwiki's functions with their own version.
+     (This is a scary thing that grubs through the symbol table, and replaces
+     all exported occurances of a function with the injected version.)
+   * external: RPC functions can be injected to replace exported functions.
+   * Updated French translation. Closes: #[502694](http://bugs.debian.org/502694)
+   * Updated Spanish translation from the ever vigilant Victor Moral.
+   * Updated Danish translation from Jonas Smedegaard. Closes: #[503117](http://bugs.debian.org/503117)
+   * Preserve syslog setting when doing `ikiwiki -setup foo -dumpsetup bar`
+   * Several fixes to --render mode."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.69.mdwn b/doc/news/version_2.69.mdwn
new file mode 100644 (file)
index 0000000..a277541
--- /dev/null
@@ -0,0 +1,24 @@
+ikiwiki 2.69 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Avoid multiple ikiwiki cgi processes piling up, eating all memory,
+     and thrashing, by making the cgi wrapper wait on a cgilock.
+     If you had to set apache's MaxClients low to avoid ikiwiki thrashing your
+     server, you can now turn it up to a high value.
+   * Stop busy-waiting in lockwiki, as this could delay ikiwiki from waking up
+     for up to one second. The bailout code is no longer needed after above
+     change.
+   * Remove support for unused optional wait parameter from lockwiki.
+   * aggregate: Try to query XML::Feed for the base url when derelevatising
+     links. Since this needs the just released XML::Feed 0.3, as well
+     as a not yet released XML::RSS, it will fall back to the old method
+     if no xml:base info is available.
+   * meta: Plugin is now enabled by default since the basewiki uses it.
+   * txt: Do not encode quotes when filtering the txt, as that broke
+     later parsing of any directives on the page.
+   * Fix the link() pagespec to match links that are internally recorded as
+     absolute.
+   * Add rel=nofollow to recentchanges\_links for the same (weak) reasons it
+     was earlier added to edit links.
+   * tag: Normalize tagbase so leading/trailing slashes in it don't break
+     things.
+   * bzr: Fix dates for recentchanges."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.70.mdwn b/doc/news/version_2.70.mdwn
new file mode 100644 (file)
index 0000000..f0830ef
--- /dev/null
@@ -0,0 +1,3 @@
+ikiwiki 2.70 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Avoid crash on malformed utf-8 discovered by intrigeri."""]]
\ No newline at end of file
diff --git a/doc/news/version_2.71.mdwn b/doc/news/version_2.71.mdwn
new file mode 100644 (file)
index 0000000..2c86099
--- /dev/null
@@ -0,0 +1,28 @@
+ikiwiki 2.71 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * comments: Blog-style comment support, contributed by Simon McVittie.
+   * htmlbalance: New plugin contributed by Simon McVittie.
+   * Change deb dependencies to list Text::Markdown before markdown (really
+     this time).
+   * Improve escaping of wikilinks and preprocessor directives in content
+     produced by aggregate and recentchanges.
+   * French translation update from Philippe Batailler. Closes: #[506250](http://bugs.debian.org/506250)
+   * Spanish translation update from Victor Moral.
+   * Fix handling of wrappergroup option.
+   * Correct --dumpsetup to include the srcdir in the setup file.
+   * German translation update from Kai Wasserbäch. Closes: #[507056](http://bugs.debian.org/507056)
+   * inline: Support emptyfeeds=no option to skip generating empty feeds.
+   * inline: Support feedfile option to change the filename of the feed
+     generated.
+   * meta: Pass info to htmlscrubber so htmlscrubber\_skip can take effect.
+   * htmlbalance: don't compact whitespace, and set misc other options (smcv)
+   * rename: Fix double-escaping of page name in edit box.
+   * monotone: When getting the log, tell monotone how many entries
+     we want, rather than closing the pipe, which it dislikes. (thm)
+   * Coding style change: Remove explcit vim folding markers.
+   * aggregate: If a feed fails to be downloaded, try again immediatly
+     next time aggregation is run, even if the usual time has not passed.
+     Closes: #[508622](http://bugs.debian.org/508622) (Michael Gold)
+   * meta: Process meta date during scan pass so that the date will always
+     affect sorting in inlines.
+   * Improve display of some openids (smcv)"""]]
\ No newline at end of file
diff --git a/doc/news/version_2.72.mdwn b/doc/news/version_2.72.mdwn
new file mode 100644 (file)
index 0000000..26274a3
--- /dev/null
@@ -0,0 +1,9 @@
+ikiwiki 2.72 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Avoid comments in recentchanges being broken links (smcv)
+   * Add deprecation warning for GlobLists, which will stop working in 3.0.
+   * camelcase: Add camelcase\_ignore setting.
+   * googlecalendar: Add runtime deprecation warning.
+   * comments: Deal with users entering unqualified or partial urls.
+   * inline: Run format hook first, to ensure other format hooks can affect
+     inlined content.  Closes: #[509710](http://bugs.debian.org/509710)"""]]
\ No newline at end of file
diff --git a/doc/news/version_3.09.mdwn b/doc/news/version_3.09.mdwn
new file mode 100644 (file)
index 0000000..d5e1a65
--- /dev/null
@@ -0,0 +1,16 @@
+ikiwiki 3.09 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * inline: Add title\_natural sort order, using Sort::Naturally
+     (chrysn)
+   * inline: Fix urls to feed when feedfile is used on an index page.
+   * git, mercurial: Fix --getctime to return file creation time,
+     not last commit time.
+   * Updated French translation (Jean-Luc Coulon). Closes: #[521072](http://bugs.debian.org/521072)
+   * css: Add clear: both to inlinefooter.
+   * comments: Fix too loose test for comments pages that matched
+     normal pages with "comment\_" in their name. Closes: #[521322](http://bugs.debian.org/521322)
+   * comments: Fix anchor ids to be legal xhtml. Closes: #[521339](http://bugs.debian.org/521339)
+   * Fix documentation of anonok\_pagespec. Closes: #[521793](http://bugs.debian.org/521793)
+   * Add missing suggests on libtext-textile-perl. Closes: #[522039](http://bugs.debian.org/522039)
+   * recentchanges: change to using do=goto links for user links.
+   * Fix git test suite to use a bare repo."""]]
\ No newline at end of file
index fc2a3f54386a1f4ab863f705bc350aecf61232a0..4650627366f5118e8c2eb5518cae8512a46e59c3 100644 (file)
@@ -3,3 +3,6 @@ revison history of a page. This is enabled by the `historyurl` setting,
 which is used to specify the URL to a web interface such as [[ViewVC]]
 (for Subversion) or [[Gitweb]]. In that url, "\[[file]]" is replaced with
 the name of the file to view.
+
+The [[plugins/repolist]] plugin can suppliment this information with
+urls to the underlying repository of the wiki.
diff --git a/doc/plugins/404.mdwn b/doc/plugins/404.mdwn
new file mode 100644 (file)
index 0000000..ad332ee
--- /dev/null
@@ -0,0 +1,20 @@
+[[!template id=plugin name=404 author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/useful]]
+
+This plugin lets you use the IkiWiki CGI script as an Apache 404 handler,
+to give the behaviour of various other wiki engines where visiting a
+nonexistent page provides you with a link to create it.
+
+To achieve this, put something like this in the wiki's Apache configuration
+file:
+
+    ErrorDocument 404 /ikiwiki.cgi
+
+(The path here needs to be whatever the path is to the ikiwiki.cgi from
+the root of your web server.)
+
+Or put something like this in the wiki's Lighttpd (>=1.4.17) configuration file:
+
+    server.error-handler-404 = "/ikiwiki.cgi"
+
+
index c40a6dc22e977dc98a83836fa85ade23e03ec5c3..e2efcd83f1d67dc17481f5cd2b2534329290a445 100644 (file)
@@ -5,13 +5,9 @@ This plugin allows content from other feeds to be aggregated into the
 wiki. To specify feeds to aggregate, use the
 [[ikiwiki/directive/aggregate]] [[ikiwiki/directive]].
 
-New users of aggregate should enable the `aggregateinternal => 1` option in the
-.setup file. If you don't do so, you will need to enable the [[html]] plugin
-as well as aggregate itself, since feed entries will be stored as HTML.
-
-The [[meta]] and [[tag]] plugins are also recommended. The
-[[htmltidy]] plugin is suggested, since feeds can easily contain html
-problems, some of which tidy can fix.
+The [[meta]] and [[tag]] plugins are also recommended. Either the
+[[htmltidy]] or [[htmlbalance]] plugin is suggested, since feeds can easily
+contain html problems, some of which these plugins can fix.
 
 You will need to run ikiwiki periodically from a cron job, passing it the
 --aggregate parameter, to make it check for new posts. Here's an example
@@ -27,37 +23,19 @@ visit is `http://whatever/ikiwiki.cgi?do=aggregate_webtrigger`. Anyone
 can visit the url to trigger an aggregation run, but it will only check
 each feed if its `updateinterval` has passed.
 
-## internal pages and `aggregateinternal`
+## aggregated pages
 
 This plugin creates a page for each aggregated item. 
 
 If the `aggregateinternal` option is enabled in the setup file (which is
-recommended), aggregated pages are stored in the source directory with a
+the default), aggregated pages are stored in the source directory with a
 "._aggregated" extension. These pages cannot be edited by web users, and
 do not generate first-class wiki pages. They can still be inlined into a
 blog, but you have to use `internal` in [[PageSpecs|IkiWiki/PageSpec]],
 like `internal(blog/*)`.
 
-For backward compatibility, the default is that these pages have the
-".html" extension, and are first-class wiki pages -- each one generates
-a separate HTML page in the output, and they can even be edited.
-
-That turns out to not be ideal for aggregated content, because publishing
-files for each of those pages is a waste of disk space and CPU, and you
-probably don't want to allow them to be edited. So, there is an alternative
-method that can be used (and is recommended), turned on by the
-`aggregateinternal` option in the setup file.
-
-If you are already using aggregate and want to enable `aggregateinternal`,
-you should follow this process:
-
-1. Update all [[PageSpecs|ikiwiki/PageSpec]] that refer to the aggregated
-   pages -- such as those in inlines. Put "internal()" around globs 
-   in those PageSpecs. For example, if the PageSpec was `foo/*`, it should
-   be changed to `internal(foo/*)`. This has to be done because internal
-   pages are not matched by regular globs.
-2. Turn on `aggregateinternal` in the setup file.
-3. Use [[ikiwiki-transition]] to rename all existing aggregated `.html`
-   files in the srcdir. The command to run is
-   `ikiwiki-transition aggregateinternal $setupfile`,
-4. Refresh the wiki. (`ikiwiki -setup your.setup -refresh`)
+If `aggregateinternal` is disabled, you will need to enable the [[html]]
+plugin as well as aggregate itself, since feed entries will be stored as
+HTML, and as first-class wiki pages -- each one generates
+a separate HTML page in the output, and they can even be edited. This
+option is provided only for backwards compatability.
index 1db6240d510b91a7eaec6dead9dfc9a037c40d55..1a9844577cae7c5bb54f2066205a5cdc80c8c20a 100644 (file)
@@ -35,7 +35,7 @@ Two things aren't working as I'd expect:
 > problem. You can see the feed validator complain about it here:
 > <http://feedvalidator.org/check.cgi?url=http%3A%2F%2Fwww.davidj.org%2Frss.xml>
 > 
-> It's sorta unfortunate that [[cpan XML::Feed]] doesn't just assume the
+> It's sorta unfortunate that [[!cpan XML::Feed]] doesn't just assume the
 > un-esxaped html is part of the description field. Probably other feed
 > parsers are more lenient. --[[Joey]]
 
index 2a8a922cd411704d6724c5e34f6c7fb674ccc5b3..a3fec4d8990d8bb72afd6ea155e3a3d0c66d839e 100644 (file)
@@ -7,3 +7,8 @@ by default.
 
 The plugin also has a configuration setting, `anonok_pagespec`. This
 [[PageSpec]] can be used to allow anonymous editing of matching pages.
+
+If you're using the [[comments]] plugin, you can allow anonymous comments
+to be posted by setting:
+
+       anonok_pagespec => "postcomment(*)"
diff --git a/doc/plugins/autoindex/discussion.mdwn b/doc/plugins/autoindex/discussion.mdwn
new file mode 100644 (file)
index 0000000..82e30aa
--- /dev/null
@@ -0,0 +1,7 @@
+Would it be possible to add an option to only generate the index files
+for the html output and not place the markdown files in the wiki source?
+
+The reason being that I have a lot of directories which need to be autoindexed,
+but I would prefer if the index files didn't clutter up my git repository.
+
+even without that feature the plugin is a great help, thanks
diff --git a/doc/plugins/blogspam.mdwn b/doc/plugins/blogspam.mdwn
new file mode 100644 (file)
index 0000000..1d152fa
--- /dev/null
@@ -0,0 +1,26 @@
+[[!template id=plugin name=blogspam author="[[Joey]]"]]
+[[!tag type/auth]]
+
+This plugin adds antispam support to ikiwiki, using the
+[blogspam.net](http://blogspam.net/) API. Both page edits and
+[[comment|comments]] postings can be checked for spam. Page edits that
+appear to contain spam will be rejected; comments that look spammy will be
+stored in a queue for moderation by an admin.
+
+The plugin requires the [[!cpan RPC::XML]] perl module.
+
+You can control how content is tested via the `blogspam_options` setting.
+The list of options is [here](http://blogspam.net/api/testComment.html#options).
+By default, the options are configured in a way that is appropriate for
+wiki content. This includes turning off some of the more problimatic tests.
+
+The `blogspam_pagespec` setting is a [[ikiwiki/PageSpec]] that can be
+used to configure which pages are checked for spam. The default is to check
+all edits. If you only want to check [[comments]] (not wiki page edits),
+set it to "postcomment(*)".
+
+By default, the blogspam.net server is used to do the spam checking. To
+change this, the `blogspam_server` option can be set to the url for a
+different server implementing the same API. Note that content is sent
+unencrypted over the internet to the server, and the server sees
+the full text of the content.
index c9e95ce7e1b52812679dfd7b51aa3f73bd4ef70a..d695762b7d9a7494ea1e83f2fc9c41989aacb77f 100644 (file)
@@ -6,7 +6,7 @@ The directive displays a calendar, similar to the typical calendars shown on
 some blogs.
 
 Since ikiwiki is a wiki compiler, to keep the calendar up-to-date,
-wikis that include it need to be preiodically refreshes, typically by cron
+wikis that include it need to be periodically refreshes, typically by cron
 at midnight. Example crontab:
 
        0 0 * * * ikiwiki -setup ~/ikiwiki.setup -refresh
index 65c2459c6eabf4d0e6b0a97d25a46149e264c14f..9d57b7a1e6526d12846816f71531808be10940dd 100644 (file)
@@ -1,2 +1,6 @@
 It would be nice if the "month" type calendar could collect all of the 
 matching pages on a given date in some inline type way. --[[DavidBremner]]
+
+Is it possible to get the calendar to link to pages based not on their timestamp (as I understand that it does now, or have I misunderstood this?) and instead on for example their location in a directory hierarchy. That way the calendar could be used as a planning / timeline device which I think would be great. --[[Alexander]]
+
+I would like the ability to specify relative previous months. This way I could have a sidebar with the last three months by specifying no month, then 'month="-1"' and 'month="-2"'. Negative numbers for the month would otherwise be invalid, so this shouldn't produce any conflicts with expected behavior. (Right?) -- [[StevenBlack]]
diff --git a/doc/plugins/comments.mdwn b/doc/plugins/comments.mdwn
new file mode 100644 (file)
index 0000000..c13a6da
--- /dev/null
@@ -0,0 +1,52 @@
+[[!template id=plugin name=comments author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/useful]]
+
+This plugin adds "blog-style" comments. Unlike the wiki-style freeform 
+Discussion pages, these comments are posted by a simple form, cannot later
+be edited, and rss/atom feeds are provided of each page's comments.
+
+When using this plugin, you should also enable [[htmlscrubber]] and either
+[[htmltidy]] or [[htmlbalance]]. Directives are filtered out by default, to
+avoid commenters slowing down the wiki by causing time-consuming
+processing. As long as the recommended plugins are enabled, comment
+authorship should hopefully be unforgeable by CGI users.
+
+The intention is that on a non-wiki site (like a blog) you can lock all
+pages for admin-only access, then allow otherwise unprivileged (or perhaps
+even anonymous) users to comment on posts. See the documentation of the
+[[lockedit]] and [[anonok]] pages for details on locking down a wiki so
+users can only post comments.
+
+Individual comments are stored as internal-use pages named something like
+`page/comment_1`, `page/comment_2`, etc. These pages internally use a
+`\[[!_comment]]` [[ikiwiki/directive]].
+
+There are some global options for the setup file:
+
+* `comments_pagespec`: [[ikiwiki/PageSpec]] of pages where comments are
+  allowed. The default is not to allow comments on any pages. To allow
+  comments to all posts to a blog, you could use
+  `blog/posts/* and !*/Discussion`.
+* `comments_closed_pagespec`: [[ikiwiki/PageSpec]] of pages where
+  posting of new comments is closed, but any existing comments will still
+  be displayed. Often you will list a set of individual pages here.
+  For example: `blog/controversial or blog/flamewar`
+* `comments_pagename`: if this is e.g. `comment_` (the default), then
+  comment pages will be named something like `page/comment_12`
+* `comments_allowdirectives`: if true (default false), comments may
+  contain IkiWiki [[directives|ikiwiki/directive]]
+* `comments_commit`: if true (default true), comments will be committed to
+  the version control system
+* `comments_allowauthor`: if true (default false), anonymous commenters may
+  specify a name for themselves, and the \[[!meta author]] and
+  \[[!meta authorurl]] directives will not be overridden by the comments
+  plugin
+
+## comment moderation
+
+If you enable the [[blogspam]] plugin, comments that appear spammy will be
+held for moderation. Wiki admins can access the comment moderation queue
+via a button on their Preferences page.
+
+The comments are stored in `.ikiwiki/comments_pending/`, and can be
+deleted, or moved into the wiki's srcdir to be posted.
diff --git a/doc/plugins/comments/discussion.mdwn b/doc/plugins/comments/discussion.mdwn
new file mode 100644 (file)
index 0000000..3d7452b
--- /dev/null
@@ -0,0 +1,163 @@
+## Why internal pages? (unresolved)
+
+Comments are saved as internal pages, so they can never be edited through the CGI,
+only by direct committers.
+
+> So, why do it this way, instead of using regular wiki pages in a
+> namespace, such as `$page/comments/*`? Then you could use [[plugins/lockedit]] to
+> limit editing of comments in more powerful ways. --[[Joey]]
+
+>> Er... I suppose so. I'd assumed that these pages ought to only exist as inlines
+>> rather than as individual pages (same reasoning as aggregated posts), though.
+>>
+>> lockedit is actually somewhat insufficient, since `check_canedit()`
+>> doesn't distinguish between creation and editing; I'd have to continue to use
+>> some sort of odd hack to allow creation but not editing.
+>>
+>> I also can't think of any circumstance where you'd want a user other than
+>> admins (~= git committers) and possibly the commenter (who we can't check for
+>> at the moment anyway, I don't think?) to be able to edit comments - I think
+>> user expectations for something that looks like ordinary blog comments are
+>> likely to include "others can't put words into my mouth".
+>>
+>> My other objection to using a namespace is that I'm not particularly happy about
+>> plugins consuming arbitrary pieces of the wiki namespace - /discussion is bad
+>> enough already. Indeed, this very page would accidentally get matched by rules
+>> aiming to control comment-posting... :-) --[[smcv]]
+
+>>> Thinking about it, perhaps one way to address this would be to have the suffix
+>>> (e.g. whether commenting on Sandbox creates sandbox/comment1 or sandbox/c1 or
+>>> what) be configurable by the wiki admin, in the same way that recentchanges has
+>>> recentchangespage => 'recentchanges'? I'd like to see fewer hard-coded page
+>>> names in general, really - it seems odd to me that shortcuts and smileys
+>>> hard-code the name of the page to look at. Perhaps I could add
+>>> discussionpage => 'discussion' too? --[[smcv]]
+
+>>> (I've now implemented this in my branch. --[[smcv]])
+
+>> The best reason to keep the pages internal seems to me to be that you
+>> don't want the overhead of every comment spawning its own wiki page. --[[Joey]]
+
+## Formats (resolved)
+
+The plugin now allows multiple comment formats while still using internal
+pages; each comment is saved as a page containing one `\[[!comment]]` directive,
+which has a superset of the functionality of [[ikiwiki/directives/format]].
+
+## Access control (unresolved?)
+
+By the way, I think that who can post comments should be controllable by
+the existing plugins opendiscussion, anonok, signinedit, and lockedit. Allowing
+posting comments w/o any login, while a nice capability, can lead to
+spam problems. So, use `check_canedit` as at least a first-level check?
+--[[Joey]]
+
+> This plugin already uses `check_canedit`, but that function doesn't have a concept
+> of different actions. The hack I use is that when a user comments on, say, sandbox,
+> I call `check_canedit` for the pseudo-page "sandbox[postcomment]". The
+> special `postcomment(glob)` [[ikiwiki/pagespec]] returns true if the page ends with
+> "[postcomment]" and the part before (e.g. sandbox) matches the glob. So, you can
+> have postcomment(blog/*) or something. (Perhaps instead of taking a glob, postcomment
+> should take a pagespec, so you can have postcomment(link(tags/commentable))?)
+>
+> This is why `anonok_pagespec => 'postcomment(*)'` and `locked_pages => '!postcomment(*)'`
+> are necessary to allow anonymous and logged-in editing (respectively).
+>
+>> I changed that to move the flag out of the page name, and into a variable that the `match_postcomment`
+>> function checks for. Other ugliness still applies. :-) --[[Joey]] 
+>
+> This is ugly - one alternative would be to add `check_permission()` that takes a
+> page and a verb (create, edit, rename, remove and maybe comment are the ones I
+> can think of so far), use that, and port the plugins you mentioned to use that
+> API too. This plugin could either call `check_can("$page/comment1", 'create')` or
+> call `check_can($page, 'comment')`.
+> 
+> One odd effect of the code structure I've used is that we check for the ability to
+> create the page before we actually know what page name we're going to use - when
+> posting the comment I just increment a number until I reach an unused one - so
+> either the code needs restructuring, or the permission check for 'create' would
+> always be for 'comment1' and never 'comment123'. --[[smcv]]
+
+>> Now resolved, in fact --[[smcv]]
+
+> Another possibility is to just check for permission to edit (e.g.) `sandbox/comment1`.
+> However, this makes the "comments can only be created, not edited" feature completely
+> reliant on the fact that internal pages can't be edited. Perhaps there should be a
+> `editable_pages` pagespec, defaulting to `'*'`? --[[smcv]]
+
+## comments directive vs global setting (resolved?)
+
+When comments have been enabled generally, you still need to mark which pages
+can have comments, by including the `\[[!comments]]` directive in them. By default,
+this directive expands to a "post a comment" link plus an `\[[!inline]]` with
+the comments. [This requirement has now been removed --[[smcv]]]
+
+> I don't like this, because it's hard to explain to someone why they have
+> to insert this into every post to their blog. Seems that the model used
+> for discussion pages could work -- if comments are enabled, automatically
+> add the comment posting form and comments to the end of each page.
+> --[[Joey]]
+
+>> I don't think I'd want comments on *every* page (particularly, not the
+>> front page). Perhaps a pagespec in the setup file, where the default is "*"?
+>> Then control freaks like me could use "link(tags/comments)" and tag pages
+>> as allowing comments.
+>>
+>>> Yes, I think a pagespec is the way to go. --[[Joey]]
+
+>>>> Implemented --[[smcv]]
+
+>> 
+>> The model used for discussion pages does require patching the existing
+>> page template, which I was trying to avoid - I'm not convinced that having
+>> every possible feature hard-coded there really scales (and obviously it's
+>> rather annoying while this plugin is on a branch). --[[smcv]]
+
+>>> Using the template would allow customising the html around the comments
+>>> which seems like a good thing? --[[Joey]]
+
+>>>> The \[[!comments]] directive is already template-friendly - it expands to
+>>>> the contents of the template `comments_embed.tmpl`, possibly with the
+>>>> result of an \[[!inline]] appended. I should change `comments_embed.tmpl`
+>>>> so it uses a template variable `INLINE` for the inline result rather than
+>>>> having the perl code concatenate it, which would allow a bit more
+>>>> customization (whether the "post" link was before or after the inline).
+>>>> Even if you want comments in page.tmpl, keeping the separate comments_embed.tmpl
+>>>> and having a `COMMENTS` variable in page.tmpl might be the way forward,
+>>>> since the smaller each templates is, the easier it will be for users
+>>>> to maintain a patched set of templates. (I think so, anyway, based on what happens
+>>>> with dpkg prompts in Debian packages with monolithic vs split
+>>>> conffiles.) --[[smcv]]
+
+>>>>> I've switched my branch to use page.tmpl instead; see what you think? --[[smcv]]
+
+## Raw HTML (resolved?)
+
+Raw HTML was not initially allowed by default (this was configurable).
+
+> I'm not sure that raw html should be a problem, as long as the
+> htmlsanitizer and htmlbalanced plugins are enabled. I can see filtering
+> out directives, as a special case. --[[Joey]]
+
+>> Right, if I sanitize each post individually, with htmlscrubber and either htmltidy
+>> or htmlbalance turned on, then there should be no way the user can forge a comment;
+>> I was initially wary of allowing meta directives, but I think those are OK, as long
+>> as the comment template puts the \[[!meta author]] at the *end*. Disallowing
+>> directives is more a way to avoid commenters causing expensive processing than
+>> anything else, at this point.
+>>
+>> I've rebased the plugin on master, made it sanitize individual posts' content
+>> and removed the option to disallow raw HTML. Sanitizing individual posts before
+>> they've been htmlized required me to preserve whitespace in the htmlbalance
+>> plugin, so I did that. Alternatively, we could htmlize immediately and always
+>> save out raw HTML? --[[smcv]]
+
+>>> There might be some use cases for other directives, such as img, in
+>>> comments.
+>>> 
+>>> I don't know if meta is "safe" (ie, guaranteed to be inexpensive and not
+>>> allow users to do annoying things) or if it will continue to be in the
+>>> future. Hard to predict really, all that can be said with certainty is
+>>> all directives will contine to be inexpensive and safe enough that it's
+>>> sensible to allow users to (ab)use them on open wikis.
+>>> --[[Joey]]
index 7a28edaba136ae13b8b462c9302958c240c990f6..e22b13f713b0ffc25ff2f9c56e25814789ee1154 100644 (file)
@@ -2,6 +2,6 @@ Contributed [[plugins]]:
 
 (See [[install]] for installation help.)
 
-[[!inline pages="plugins/contrib/* !*/Discussion" 
+[[!inline pages="plugins/contrib/* and !*/Discussion" 
 feedpages="created_after(plugins/contrib/navbar)" archive="yes"
 rootpage="plugins/contrib" postformtext="Add a new plugin named:" show=0]]
index b4a7cd5d6857c7de39e8b9b992cd04d70a6337ba..adb414ffb905f3c5bfdc45bbf061329e3fd9f7f3 100644 (file)
@@ -20,14 +20,14 @@ template variable somebody wants to use.
 --[[bma]]
 
 Copyright and license values are not "template values", they are values
-tracked by the meta plugin, and that various code compares and uses to fill
+tracked by the [[meta]] plugin, and that various code compares and uses to fill
 out the templates. Something like varioki cannot do that. --[[Joey]]
 
 Somewhat more detailed usage documentation would be appreciated. I tried to setup
 those plugins with a current ikiwiki release, i.e. 2.61, but they appeared to do
 nothing, really. Also, those example pages don't seem to use those plugins, even;
 they set "copyright" and "license" properties using ordinary [[meta]] tags. Maybe
-I'm missing something terribly obvious? --[[Peter]]
+I'm missing something terribly obvious? --Peter
 > Only obvious if you read the source :-). You need to put a file named "copyright.html"
 >(respectively "license.html") in your wiki. Everything underneath that (in the wikilink sense) will use that
 >content for the license or copyright. Saves putting \[[meta license="foo"]] in every page [[DavidBremner]]
index 7148de3ef7512058a7fef657966e3c8d3a9b491c..72df13bd0b06a47d05a5b79834d85d9ac32e0a77 100644 (file)
@@ -2,7 +2,7 @@
 
 This plugin would create a nice looking gallery of the images. It has been build over the img plugin in Ikiwiki
 
-SVN repository of plugin is located at <http://ned.snow-crash.org:8080/svn/ikiwiki-gallery>
+GIT repo of the plugin is located at <http://github.com/joeyh/ikiwiki/tree/gallery>
 
 
 USAGE : 
index ef2fa122abf57057b6e2df71129bcfaf6c965837..c80cc0b496e6e0c3c45acd532d6e931871d8f901 100644 (file)
@@ -12,9 +12,9 @@ rst and any other format that produces html. The code is available here:
        use strict;
        use IkiWiki 2.00;
 
-       sub import { #{{{
+       sub import {
                hook(type => "sanitize", id => "headinganchors", call => \&headinganchors);
-       } # }}}
+       }
 
        sub text_to_anchor {
                my $str = shift;
@@ -26,11 +26,11 @@ rst and any other format that produces html. The code is available here:
                return $str;
        }
 
-       sub headinganchors (@) { #{{{
+       sub headinganchors (@) {
                my %params=@_;
                my $content=$params{content};
                $content=~s{<h([0-9])>([^>]*)</h([0-9])>}{'<h'.$1.' id="'.text_to_anchor($2).'">'.$2.'</h'.$3.'>'}gie;
                return $content;
-       } # }}}
+       }
 
        1
index 9b43a106cad03bf736375faf2e4a22280ef00e1e..8abb76583b58f156986d7d00d0c3dcb15d603538 100644 (file)
@@ -1,3 +1,6 @@
+[[!template id=plugin name=highlightcode author="[[sabr]]"]]
+[[!tag type/format]]
+
 A small plugin to allow Ikiwiki to display source files complete with syntax highlighting. Files with recognized extensions (i.e. my-file.cpp) are be rendered just like any other Ikiwiki page. You can even edit your source files with Ikiwiki's editor.
 
 It uses the Syntax::Highlight::Engine::Kate Perl module to do the highlighting.
index 0c336684625a304fa08206f26d041191e1907acd..bf502606e03e3a299d98b82424374d3941e8f0ed 100644 (file)
@@ -10,7 +10,8 @@ Download: [linguas.pm](http://ettin.org/pub/ikiwiki/linguas.pm) (2006-08-21).
 
 Note that even though it is still available for download, this plugin is no
 longer actively maintained. If you are interested in multilingual wiki pages, you
-can also take a look at other approaches such as [[todo/l10n]] or Lars Wirzenius's
+can also take a look at other approaches such as [[todo/l10n]], [[plugins/contrib/po]],
+or Lars Wirzenius's
 [Static website, with translations, using IkiWiki](http://liw.iki.fi/liw/log/2007-05.html#20070528b).
 
 Usage
diff --git a/doc/plugins/contrib/mediawiki.mdwn b/doc/plugins/contrib/mediawiki.mdwn
new file mode 100644 (file)
index 0000000..c0a2325
--- /dev/null
@@ -0,0 +1,5 @@
+[[!template id=plugin name=mediawiki author="[[sabr]]"]]
+[[!tag type/format]]
+
+[The Mediawiki plugin](http://u32.net/Mediawiki_Plugin/) allows ikiwiki to
+process pages written using MediaWiki markup.
diff --git a/doc/plugins/contrib/opml.mdwn b/doc/plugins/contrib/opml.mdwn
new file mode 100644 (file)
index 0000000..3f98e80
--- /dev/null
@@ -0,0 +1,11 @@
+[[!template id=plugin name=opml author="[[JanWalzer|jwalzer]]"]]
+[[!tag type/format]]
+
+The idea of this plugin is to parse in an OPML-File and output a linklist, maybe some customization.
+OPML-Files are xml-files that most RSS-Readers write out, to summarize their subscribes feedlist.
+
+I have a "dumb" perlscript running on my website, that tries to do a opml2mdwn transformation, but its quite bad on that.
+
+This Plugin is **NOT Ready** in any way. I'm just putting this page up as a hook, to discuss it.
+
+I intend to work on this, but I'd appreciate any help on this.
diff --git a/doc/plugins/contrib/opml/discussion.mdwn b/doc/plugins/contrib/opml/discussion.mdwn
new file mode 100644 (file)
index 0000000..3a145c7
--- /dev/null
@@ -0,0 +1,4 @@
+If this is the wrong place for the development of the plugin, please mode it on to a more appropriate one. 
+
+Currently I'm quite stuck with the perl-stuff itself. I'm trying to become comfortable with the language, but it seems, the language doesn't like me. I'm lost in complex datastructures, when trying to iterate through the output of XML::Simple. --[[Jan|jwalzer]]
+
diff --git a/doc/plugins/contrib/po.mdwn b/doc/plugins/contrib/po.mdwn
new file mode 100644 (file)
index 0000000..61ec53e
--- /dev/null
@@ -0,0 +1,386 @@
+I've been working on a plugin called "po", that adds support for multi-lingual wikis,
+translated with gettext, using [po4a](http://po4a.alioth.debian.org/).
+
+More information:
+
+* It can be found in my "po" branch:
+  `git clone git://gaffer.ptitcanardnoir.org/ikiwiki.git`
+* It is self-contained, *i.e.* it does not modify ikiwiki core at all.
+* It is documented (including TODO and plans for next work steps) in
+  `doc/plugins/po.mdwn`, which can be found in the same branch.
+* No public demo site is available so far, I'm working on this.
+
+My plan is to get this plugin clean enough to be included in ikiwiki.
+
+The current version is a proof-of-concept, mature enough for me to dare submitting it here,
+but I'm prepared to hear various helpful remarks, and to rewrite parts of it as needed.
+
+Any thoughts on this?
+
+> Well, I think it's pretty stunning what you've done here. Seems very
+> complete and well thought out. I have not read the code in great detail
+> yet.
+> 
+> Just using po files is an approach I've never seen tried with a wiki. I
+> suspect it will work better for some wikis than others. For wikis that
+> just want translations that match the master language as closely as
+> possible and don't wander off and diverge, it seems perfect. (But what happens
+> if someone edits the Discussion page of a translated page?)
+> 
+> Please keep me posted, when you get closer to having all issues solved
+> and ready for merging I can do a review and hopefully help with the
+> security items you listed. --[[Joey]]
+
+>> Thanks a lot for your quick review, it's reassuring to hear such nice words
+>> from you. I did not want to design and write a full translation system, when
+>> tools such as gettext/po4a already have all the needed functionality, for cases
+>> where the master/slave languages paradigm fits.
+>> Integrating these tools into ikiwiki plugin system was a pleasure.
+>>
+>> I'll tell you when I'm ready for merging, but in the meantime,
+>> I'd like you to review the changes I did to the core (3 added hooks).
+>> Can you please do this? If not, I'll go on and hope I'm not going to far in
+>> the wrong direction.
+>>
+>>> Sure.. I'm not completly happy with any of the hooks since they're very
+>>> special purpose, and also since `run_hooks` is not the best interface
+>>> for a hook that modifies a variable, where only the last hook run will
+>>> actually do anything. It might be better to just wrap
+>>> `targetpage`, `bestlink`, and `beautify_urlpath`. But, I noticed
+>>> the other day that such wrappers around exported functions are only visible by
+>>> plugins loaded after the plugin that defines them.
+>>> 
+>>> Update: Take a look at the new "Function overriding" section of
+>>> [[plugins/write]]. I think you can just inject wrappers about a few ikiwiki
+>>> functions, rather than adding hooks. The `inject` function is pretty
+>>> insane^Wlow level, but seems to work great. --[[Joey]]
+>>>
+>>>> Thanks a lot, it seems to be a nice interface for what I was trying to achieve.
+>>>> I may be forced to wait two long weeks before I have a chance to confirm
+>>>> this. Stay tuned. --[[intrigeri]]
+>>>>
+>>>>> I've updated the plugin to use `inject`. It is now fully self-contained,
+>>>>> and does not modify the core anymore. --[[intrigeri]]
+>>
+>> The Discussion pages issue is something I am not sure about yet. But I will
+>> probably decide that "slave" pages, being only translations, don't deserve
+>> a discussion page: the discussion should happen in the language in which the
+>> pages are written for real, which is the "master" one. --[[intrigeri]]
+>> 
+>> I think that's a good decision, you don't want to translate discussion,
+>> and if the discussion page turns out multilingual, well, se la vi. ;-)
+>> 
+>> Relatedly, what happens if a translated page has a broken link, and you
+>> click on it to edit it? Seems you'd first have to create a master page
+>> and could only then translate it, right? I wonder if this will be clear
+>> though to the user.
+>>
+>>> Right: a broken link points to the URL that allows to create
+>>> a page that can either be a new master page or a non-translatable
+>>> page, depending on `po_translatable_pages` value. The best
+>>> solution I can thing of is to use [[plugins/edittemplate]] to
+>>> insert something like "Warning: this is a master page, that must
+>>> be written in $MASTER_LANGUAGE" into newly created master pages,
+>>> and maybe another warning message on newly created
+>>> non-translatable pages. It seems quite doable to me, but in order
+>>> to avoid breaking existing functionality, it implies to hack a bit
+>>> [[plugins/edittemplate]] so that multiple templates can be
+>>> inserted at page creation time. [[--intrigeri]]
+>>>
+>>>> I implemented such a warning using the formbuilder_setup hook.
+>>>> --[[intrigeri]]
+>>
+>> And also, is there any way to start a translation of a page into a new
+>> lanauge using the web interface?
+>>
+>>> When a new language is added to `po_slave_languages`, a rebuild is
+>>> triggered, and all missing PO files are created and checked into
+>>> VCS. An unpriviledged wiki user can not add a new language to
+>>> `po_slave_languages`, though. One could think of adding the needed
+>>> interface to translate a page into a yet-unsupported slave
+>>> language, and this would automagically add this new language to
+>>> `po_slave_languages`. It would probably be useful in some
+>>> usecases, but I'm not comfortable with letting unpriviledged wiki
+>>> users change the wiki configuration as a side effect of their
+>>> actions; if this were to be implemented, special care would be
+>>> needed. [[--intrigeri]]
+>>>
+>>>> Actually I meant into any of the currently supported languages.
+>>>> I guess that if the template modification is made, it will list those
+>>>> languages on the page, and if a translation to a language is missing,
+>>>> the link will allow creating it?
+>>>>
+>>>>> Any translation page always exist for every supported slave
+>>>>> language, even if no string at all have been translated yet.
+>>>>> This implies the po plugin is especially friendly to people who
+>>>>> prefer reading in their native language if available, but don't
+>>>>> mind reading in English else.
+>>>>>
+>>>>> While I'm at it, there is a remaining issue that needs to be
+>>>>> sorted out: how painful it could be for non-English speakers
+>>>>> (assuming the master language is English) to be perfectly able
+>>>>> to navigate between translation pages supposed to be written in
+>>>>> their own language, when their translation level is most
+>>>>> often low.
+>>>>>
+>>>>> (It is currently easy to display this status on the translation
+>>>>> page itself, but then it's too late, and how frustrating to load
+>>>>> a page just to realize it's actually not translated enough for
+>>>>> you. The "other languages" loop also allows displaying this
+>>>>> information, but it is generally not the primary
+>>>>> navigation tool.)
+>>>>>
+>>>>> IMHO, this is actually a social problem (i.e. it's no use adding
+>>>>> a language to the supported slave ones if you don't have the
+>>>>> manpower to actually do the translations), that can't be fully
+>>>>> solved by technical solutions, but I can think of some hacks
+>>>>> that would limit the negative impact: a given translation's
+>>>>> status (currently = percent translated) could be displayed next
+>>>>> to the link that leads to it; a color code could as well be used
+>>>>> ("just" a matter of adding a CSS id or class to the links,
+>>>>> depending on this variable). As there is already work to be done
+>>>>> to have the links text generation more customizable through
+>>>>> plugins, I could do both at the same time if we consider this
+>>>>> matter to be important enough. --[[intrigeri]]
+>>>>>
+>>>>>> The translation status in links is now implemented in my
+>>>>>> `po`branch. It requires my `meta` branch changes to
+>>>>>> work, though. I consider the latter to be mature enough to
+>>>>>> be merged. --[[intrigeri]]
+
+>> FWIW, I'm tracking your po branch in ikiwiki master git in the po
+>> branch. One thing I'd like to try in there is setting up a translated
+>> basewiki, which seems like it should be pretty easy to do, and would be
+>> a great demo! --[[Joey]]
+>>
+>>> I've merged your changes into my own branch, and made great
+>>> progress on the various todo items. Please note my repository
+>>> location has changed a few days ago, my user page was updated
+>>> accordingly, but I forgot to update this page at the same time.
+>>> Hoping it's not too complicated to relocated an existing remote...
+>>> (never done that, I'm a Git beginner as well as a Perl
+>>> newbie) --[[intrigeri]]
+>>>>
+>>>> Just a matter of editing .git/config, thanks for the heads up.
+>>>>>
+>>>>> Joey, please have a look at my branch, your help would be really
+>>>>> welcome for the security research, as I'm almost done with what
+>>>>> I am able to do myself in this area. --[[intrigeri]]
+>>>>>>
+>>>>>> I came up with a patch for the WrapI18N issue --[[Joey]]
+
+I've set this plugin development aside for a while. I will be back and
+finish it at some point in the first quarter of 2009. --[[intrigeri]]
+
+> Abstract: Joey, please have a look at my po and meta branches.
+> 
+> Detailed progress report:
+> 
+> * it seems the po branch in your repository has not been tracking my
+>   own po branch for two months. any config issue?
+> * all the plugin's todo items have been completed, robustness tests
+>   done
+> * I've finished the detailed security audit, and the fix for po4a
+>   bugs has entered upstream CVS last week
+> * I've merged your new `checkcontent` hook with the `cansave` hook
+>   I previously introduced in my own branch; blogspam plugin updated
+>   accordingly
+> * the rename hook changes we discussed elsewhere are also part of my
+>   branch
+> * I've introduced two new hooks (`canremove` and `canrename`), not
+>   a big deal; IMHO, they extend quite logically the plugin interface
+> * as highlighted on [[bugs/pagetitle_function_does_not_respect_meta_titles]],
+>   my `meta` branch contains a new feature that is really useful in a
+>   translatable wiki
+> 
+> As a conclusion, I'm feeling that my branches are ready to be
+> merged; only thing missing, I guess, are a bit of discussion and
+> subsequent adjustments.
+> 
+> --[[intrigeri]]
+
+> I've looked it over and updated my branch with some (untested)
+> changes.
+> 
+>> I've merged your changes into my branch. Only one was buggy.
+> 
+> Sorry, I'd forgotten about your cansave hook.. sorry for the duplicate
+> work there.
+> 
+> Reviewing the changes, mostly outside of `po.pm`, I have
+> the following issues.
+>  
+> * renamepage to renamelink change would break the ikiwiki
+>   3.x API, which I've promised not to do, so needs to be avoided
+>   somehow. (Sorry, I guess I dropped the ball on not getting this
+>   API change in before cutting 3.0..)
+>> 
+>> Fixed, see [[todo/need_global_renamepage_hook]].
+>>
+> * I don't understand the parentlinks code change and need to figure it
+>   out. Can you explain what is going on there?
+>> 
+>> I'm calling `bestlink` there so that po's injected `bestlink` is
+>> run. This way, the parent links of a page link to the parent page
+>> version in the proper language, depending on the
+>> `po_link_to=current` and `po_link_to=negotiated` settings.
+>> Moreover, when using my meta branch enhancements plus meta title to
+>> make pages titles translatable, this small patch is needed to get
+>> the translated titles into parentlinks.
+>> 
+> * canrename's mix of positional and named parameters is way too
+>   ugly to get into an ikiwiki API. Use named parameters
+>   entirely. Also probably should just use named parameters
+>   for canremove.
+> * `skeleton.pm.example`'s canrename needs fixing to use either
+>   the current or my suggested parameters.
+>> 
+>> Done.
+>> 
+> * I don't like the exporting of `%backlinks` and `$backlinks_calculated`
+>   (the latter is exported but not used).
+>> 
+>> The commit message for 85f865b5d98e0122934d11e3f3eb6703e4f4c620
+>> contains the rationale for this change. I guess I don't understand
+>> the subtleties of `our` use, and perldoc does not help me a lot.
+>> IIRC, I actually did not use `our` to "export" these variables, but
+>> rather to have them shared between `Render.pm` uses.
+>>
+>>> My wording was unclear, I meant exposing. --[[Joey]]
+>>>  
+>>>> I guess I still don't know Perl's `our` enough to understand clearly.
+>>>> No matter whether these variables are declared with `my` or `our`,
+>>>> any plugin can `use IkiWiki::Render` and then access
+>>>> `$IkiWiki::backlinks`, as already does e.g. the pagestat plugin.
+>>>> So I guess your problem is not with letting plugins use these
+>>>> variables, but with them being visible for every piece of
+>>>> (possibly external) code called from `Render.pm`. Am I right?
+>>>> If I understand clearly, using a brace block to lexically enclose
+>>>> these two `our` declarations, alongside with the `calculate_backlinks`
+>>>> and `backlinks` subs definitions, would be a proper solution, wouldn't
+>>>> it? --[[intrigeri]]
+>>>>
+>>>>> No, %backlinks and the backlinks() function are not the same thing.
+>>>>> The variable is lexically scoped; only accessible from inside
+>>>>> `Render.pm` --[[Joey]] 
+>>>> 
+> * What is this `IkiWiki::nicepagetitle` and why are you
+>   injecting it into that namespace when only your module uses it?
+>   Actually, I can't even find a caller of it in your module.
+>> 
+>> I guess you should have a look to my `meta` branch and to
+>> [[bugs/pagetitle_function_does_not_respect_meta_titles]] in order
+>> to understand this :)
+>>
+>>> It would probably be good if I could merge this branch without 
+>>> having to worry about also immediatly merging that one. --[[Joey]] 
+>>> 
+>>>> I removed all dependencies on my `meta` branch from the `po` one.
+>>>> This implied removing the `po_translation_status_in_links` and
+>>>> `po_strictly_refresh_backlinks` features, and every link text is now
+>>>> displayed in the master language. I believe the removed features really
+>>>> enhance user experience of a translatable wiki, that's why I was
+>>>> initially supposing the `meta` branch would be merged first.
+>>>> IMHO, we'll need to come back to this quite soon after `po` is merged.
+>>>> --[[intrigeri]]
+>>>>
+>>>> Maybe you should keep those features in a meta-po branch?
+>>>> I did a cursory review of your meta last night, have some issues with it, 
+>>>> but this page isn't the place for a detailed review. --[[Joey]] 
+>>>>
+>>>>> Done. --[[intrigeri]]
+>>> 
+> * I'm very fearful of the `add_depends` in `postscan`. 
+>   Does this make every page depend on every page that links
+>   to it? Won't this absurdly bloat the dependency pagespecs
+>   and slow everything down? And since nicepagetitle is given
+>   as the reason for doing it, and nicepagetitle isn't used,
+>   why do it?
+>> 
+>> As explained in the 85f865b5d98e0122934d11e3f3eb6703e4f4c620 log:
+>> this feature hits performance a bit. Its cost was quite small in my
+>> real-world use-cases (a few percents bigger refresh time), but
+>> could be bigger in worst cases. When using the po plugin with my
+>> meta branch changes (i.e. the `nicepagetitle` thing), and having
+>> enabled the option to display translation status in links, this
+>> maintains the translation status up-to-date in backlinks. Same when
+>> using meta title to make the pages titles translatable. It does
+>> help having a nice and consistent translated wiki, but as it can
+>> also involve problems, I just turned it into an option.
+>> 
+>>> This has been completely removed for now due to the removal of
+>>> the dependency on my `meta` branch. --[[intrigeri]]
+>> 
+> * The po4a Suggests should be versioned to the first version
+>   that can be used safely, and that version documented in 
+>   `plugins/po.mdwn`.
+>>
+>> Done.
+>> 
+>> --[[intrigeri]]
+> 
+> --[[Joey]] 
+
+I reverted the `%backlinks` and `$backlinks_calculated` exposing.
+The issue they were solving probably will arise again when I'll work
+on my meta branch again (i.e. when the simplified po one is merged),
+but the po thing is supposed to work without these ugly `our`.
+Seems like it was the last unaddressed item from Joey's review, so I'm
+daring a timid "please pull"... or rather, please review again :)
+--[[intrigeri]]
+
+> Ok, I've reviewed and merged into my own po branch. It's looking very
+> mergeable.
+> 
+> * Is it worth trying to fix compatability with `indexpages`?
+>> 
+>> Supporting `usedirs` being enabled or disabled was already quite
+>> hard IIRC, so supporting all four combinations of `usedirs` and
+>> `indexpages` settings will probably be painful. I propose we forget
+>> about it until someone reports he/she badly needs it, and then
+>> we'll see what can be done.
+>> 
+> * Would it make sense to go ahead and modify `page.tmpl` to use
+>   OTHERLANGUAGES and PERCENTTRANSLATED, instead of documenting how to modify it?
+>> 
+>> Done in my branch.
+>> 
+> * Would it be better to disable po support for pages that use unsupported
+>   or poorly-supported markup languages?
+> 
+>> I prefer keeping it enabled, as:
+>> 
+>> * most wiki markups "almost work"
+>> * when someone needs one of these to be fully supported, it's not
+>>   that hard to add dedicated support for it to po4a; if it were
+>>   disabled, I fear the ones who could do this would maybe think
+>>   it's blandly impossible and give up.
+>> 
+> * What's the reasoning behind checking that the link plugin
+>   is enabled? AFAICS, the same code in the scan hook should
+>   also work when other link plugins like camelcase are used.
+> * In `pagetemplate` there is a comment that claims the code
+>   relies on `genpage`, but I don't see how it does; it seems
+>   to always add a discussion link?
+> * Is there any real reason not to allow removing a translation?
+>   I'm imagining a spammy translation, which an admin might not
+>   be able to fix, but could remove.
+> * Re the meta title escaping issue worked around by `change`. 
+>   I suppose this does not only affect meta, but other things
+>   at scan time too. Also, handling it only on rebuild feels
+>   suspicious -- a refresh could involve changes to multiple
+>   pages and trigger the same problem, I think. Also, exposing
+>   this rebuild to the user seems really ugly, not confidence inducing.
+>   
+>   So I wonder if there's a better way. Such as making po, at scan time,
+>   re-run the scan hooks, passing them modified content (either converted
+>   from po to mdwn or with the escaped stuff cheaply de-escaped). (Of
+>   course the scan hook would need to avoid calling itself!)
+> 
+>   (This doesn't need to block the merge, but I hope it can be addressed
+>   eventually..)
+>  
+> --[[Joey]] 
+>> 
+>> --[[intrigeri]]
index 956b6728f4b7b6bbd94d9bbc9da93c2e3fefd5e6..9b09657bf0540aabc5ab4e5c8e3fcd575cde3a4a 100644 (file)
@@ -13,11 +13,11 @@ other format that produces html. The code is available here:
        use strict;
        use IkiWiki 2.00;
 
-       sub import { #{{{
+       sub import {
                hook(type => "sanitize", id => "siterel2pagerel", call => \&siterel2pagerel);
-       } # }}}
+       }
 
-       sub siterel2pagerel (@) { #{{{
+       sub siterel2pagerel (@) {
                my %params=@_;
                my $baseurl=IkiWiki::baseurl($params{page});
                my $content=$params{content};
@@ -25,6 +25,6 @@ other format that produces html. The code is available here:
                $content=~s/(<img(?:\s+(?:class|id|width|height)\s*="?\w+"?)*)\s+src=\s*"\/([^"]*)"/$1 src="$baseurl$2"/mig;
                # FIXME: do <script and everything else that can have URLs in it
                return $content;
-       } # }}}
+       }
 
        1
index 2eb22e6edd01b27778e68ee41bf81dc789ded23c..07ac2086f4cfeca1bf27c810fd19d933ac76d716 100644 (file)
@@ -10,13 +10,21 @@ where foo and bar are the (source-supported) languages you want to
 highlight
 ### Issues
 
-- I would like to have a link to the raw source; using will_render() and then copying the file should work. 
+- I would like to have a link to the raw source; using will_render() and then copying the file should work.
 
-- the common case of foo.c and foo.h breaks
-because they both generate page working/dir/foo. 
-It looks to me like ikiwiki is hardcoded to strip the extension in `pagename()` (IkiWiki.pm).
-This problem with sourcehighlight needs to be fixed before it is very useful.
+> You might also like to look at the [[todo/source_link]] todo. -- [[Will]]
 
 - Is there a way to configure the colors used by source-highlight (other than editing the globally installed "default.style" file)? It would help if I could pass the command arbitrary command-line arguments; then I could configure which config file it's supposed to use. For instance, I'm not a fan of hard-coding the colors into the HTML output. IMHO, css-style formatting should be preferred. All that can be set via the command line ... --Peter
 
 > I don't really have time right now, but it should be easy to add, if you look at how src-lang is handled.  Patches are welcome :-) --[[DavidBremner]]
+
+Note that [[Will]] wrote a plugin that uses source-highlight also. It's
+available
+[[here|todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion]].
+--[[Joey]]
+
+To be honest, [[Will]]'s version of this looks more polished.  I will try his 
+plugin and see if it can just replace mine. --[[DavidBremner]]
+
+
+*Updated* Now uses keepextension so multiple extensions should be OK
index d91ed45f1c791e7c7bf23a2912df2adae5b947fb..76a8477446f0d9d43b7db33e203604139a795c4c 100644 (file)
@@ -22,7 +22,7 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
 
     --- Wrapper.pm.orig 2008-07-29 00:09:10.000000000 -0400
     +++ Wrapper.pm
-    @@ -28,7 +28,7 @@ sub gen_wrapper () { #{{{
+    @@ -28,7 +28,7 @@ sub gen_wrapper () {
         my @envsave;
         push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
                        CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
@@ -46,16 +46,16 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
     use strict;
     use IkiWiki 2.00;
     
-    sub import { #{{{
+    sub import {
         hook(type => "getsetup", id => "unixauth", call => \&getsetup);
             hook(type => "formbuilder_setup", id => "unixauth",
                 call => \&formbuilder_setup);
             hook(type => "formbuilder", id => "unixauth",
                 call => \&formbuilder);
         hook(type => "sessioncgi", id => "unixauth", call => \&sessioncgi);
-    } # }}}
+    }
     
-    sub getsetup () { #{{{
+    sub getsetup () {
         return
         unixauth_type => {
                 type => "string",
@@ -83,10 +83,10 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
                 safe => 0,
                 rebuild => 1,
         },
-    } #}}}
+    }
     
     # Checks if a string matches a user's password, and returns true or false.
-    sub checkpassword ($$;$) { #{{{
+    sub checkpassword ($$;$) {
         my $user=shift;
         my $password=shift;
         my $field=shift || "password";
@@ -131,9 +131,9 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
         }
     
         return $ret;
-    } #}}}
+    }
     
-    sub formbuilder_setup (@) { #{{{
+    sub formbuilder_setup (@) {
         my %params=@_;
     
         my $form=$params{form};
@@ -204,7 +204,7 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
         }
     }
     
-    sub formbuilder (@) { #{{{
+    sub formbuilder (@) {
         my %params=@_;
     
         my $form=$params{form};
@@ -225,12 +225,12 @@ __Security__: [As with passwordauth](/security/#index14h2), be wary of sending u
                         my $user_name=$form->field('name');
                 }
         }
-    } #}}}
+    }
     
-    sub sessioncgi ($$) { #{{{
+    sub sessioncgi ($$) {
         my $q=shift;
         my $session=shift;
-    } #}}}
+    }
     
     1
 
index dfa4fe6cce57f042ca4bb7026d554f96bf891250..232649863c9dff898737d15c253850bac8648513 100644 (file)
@@ -32,3 +32,7 @@ I've added support for [checkpassword](http://cr.yp.to/checkpwd/interface.html),
 > to disentangle the two locks. --[[Joey]]
 
 >> Ah, ok, I misunderstood your comment. I'll see what I can figure out. --[[schmonz]]
+
+>>> My time's been limited for this, but I just saw [[todo/avoid_thrashing]]. How does that interact with pwauth or checkpassword? --[[schmonz]]
+
+>>>> The DOS still happens, it just uses less memory. --[[Joey]]
index c6491f754392090dff7b2a08e4883aa9afa085c9..6961e8d1d2e7755898c893b0d7032d17fa697f94 100644 (file)
@@ -13,4 +13,10 @@ wiki markup formats, so should be fairly easy to guess at. There is also a
 
 Links are standard [[WikiLinks|ikiwiki/WikiLink]]. Links and
 [[directives|ikiwiki/directive]] inside `{{{ }}}` blocks are still expanded,
-since this happens before the creole format is processed.
+since this happens before the creole format is processed. (You need to escape
+them manually, via \\\[[directives]], the ~ escaping of creole doesn't work on
+this.)
+
+The standard ikiwiki [[WikiLinks|ikiwiki/WikiLink]] is almost the same as Creole link, except that creole uses \[[pagename|description]] while ikiwiki uses \[[description|pagename]].
+
+
index 36b7ba869098dc1361231193ddd35514edf4b233..38ee2bd7808334356cce60b690f620260131aef6 100644 (file)
@@ -8,4 +8,8 @@ I've installed Text::WikiCreole 0.05 and enabled the plugin, but I get an error
 
 >> I've added the patch to pkgsrc as well. Thanks. --[[schmonz]]
 
+>> Currently the creole plugin is included in ikiwiki but the ikiwiki deb (3.0.3) doesn't suggests libtext-wikicreole-perl.  Why? --[[weakish]]
+
+>>> forgot, done now --[[Joey]] 
+
 I'm moving over a really stinkingly old UseMod and creole seems the nearest match. I've worked out that Bare /Subpage links need to become \[\[Subpage\]\], and Top/Sub links need to be \[\[Top/Sub\]\] (or \[\[Top/Sub|Top/Sub\]\], to display in exactly the same way), but I'm stuck on generic hyperlinks. The creole cheat sheet says I should be able to do \[\[http://url.path/foo|LinkText\]\], but that comes out as a link to create the "linktext" page, and Markdown-style \[Link Text\](http://url.path/foo) just gets rendered as is. Any suggestions? --[[schmonz]]
index 1b78e60fcd1d4348cd7882da2149bc2ac9b778b1..f74f8a269a8f0069e0c59b745bea363b4ef54230 100644 (file)
@@ -1,4 +1,4 @@
-[[!template id=plugin name=toggle author="[[Enrico]]"]]
+[[!template id=plugin name=cutpaste author="[[Enrico]]"]]
 [[!tag type/chrome]]
 
 This plugin provides the [[ikiwiki/directive/cut]],
index e82760d881ec792f6039694c2685f15b4b894c81..741606a6e71d184df8e2b5f1b8e70a56f7900848 100644 (file)
@@ -1,5 +1,6 @@
 [[!template id=plugin name=ddate author="[[Joey]]"]]
 [[!tag type/fun]]
+[[!tag type/date]]
 
 Enables use of Discordian dates. `--timeformat` can be used to change
 the date format; see `ddate(1)`.
index 70157f1e2b03b52d465adb54113bdef38d111000..854307a98ad971b7659adb271871a0dcb192e0ca 100644 (file)
@@ -34,12 +34,3 @@ Any objections to listing plugins alphabetically rather than by creation date?
 >> "recently changed" list with the 10 most recently changed plugins
 >> at the top.  That would allow what you suggested, but still allow
 >> the main list to be alphabetical. -- [[Will]]
-
-How about adding a deprecated tag in order to clean up the plugin list?
-
-> AFAIK it's currently the only one. --[[Joey]]
-For instance [[googlecalendar]] is listed as plugin but should probably be removed from Ikiwiki in a future major version (v3?).
-
--- [[AlexandreDupas]]
-
index 1d43061e0c9fc410a439d2519383dc04a68794be..85592cb722ca1bf2f185e4b64989736ae920811f 100644 (file)
@@ -13,6 +13,14 @@ In the examples below, the parts of the html that you can change are denoted
 with "XXX"; everything else must appear exactly as shown to be accepted by the
 plugin.
 
+**This plugin is deprecated.** Rather than relying on these complex lists
+of safe content, which constantly fall out of date, you're recommended to
+configure the [[htmlscrubber]] to not scrub some pages, which only trusted
+users can edit. Then you can embed anything from anywhere on those pages.
+See [[tips/embedding_content]] for details and examples.
+This plugin's lists of safe embedded content will not be maintained, and 
+the plugin will be removed in a future  release.
+
 ## google maps
 
 Use html like this to embed a map:
diff --git a/doc/plugins/format.mdwn b/doc/plugins/format.mdwn
new file mode 100644 (file)
index 0000000..91e707f
--- /dev/null
@@ -0,0 +1,9 @@
+[[!template id=plugin name=format core=0 author="[[Joey]]"]]
+[[!tag type/format]]
+
+This plugin allows mixing different page formats together, by embedding
+text formatted one way inside a page formatted another way. This is done
+using the [[ikiwiki/directive/format]] [[ikiwiki/directive]].
+
+For example, it could be used to embed an [[otl]] outline inside a page
+that is formatted as [[mdwn]].
diff --git a/doc/plugins/format/discussion.mdwn b/doc/plugins/format/discussion.mdwn
new file mode 100644 (file)
index 0000000..df8448e
--- /dev/null
@@ -0,0 +1,15 @@
+Is there any way to tell if an htmlize hook have been called from a format directive?
+
+I am currently modifying the [[contrib/highlightcode]] plugin by [[sabr]] and I wanted to have a different behavior depending on the fact that the htmlize hook is called from a format directive or not. For instance, this could disable the raw copy of the highlighted code. Since I have enabled the keepextension option, I tried to rely on the page extension to decide whenever I have to create the raw file or not but this does not seems a reliable approach.
+
+One possible solution is to add an optional parameter to the htmlize hook (and thus to htmlize function in IkiWiki.pm) which could tell if this is the format directive that called the function but I am not sure that is a good way to do this.
+
+> It's (probably) not just the format directive that has a potential problem here.
+> Imagine a syntax highlighted source code file that contains some other
+> directive, such as table or meta. Such a directive calls `htmlize` on the
+> parameters passed to it.
+> 
+> There is one way to detect this ATM. If `%IkiWiki::preprocessing` has
+> anything in it, then ikiwiki is in the middle of handling a preprocessing
+> directive. So you could check that. It's getting into internals, so not
+> ideal.. --[[Joey]]
index 83b60f4fa554f28cba4db953bb5db004c1a343cf..ee1bffcfa8f8e07f0336eff76a0ebc6fd5a0a8ca 100644 (file)
@@ -12,7 +12,6 @@ Currently included:
 * [[brokenlinks]]
 * [[img]]
 * [[map]]
-* [[meta]]
 * [[more]]
 * [[orphans]]
 * [[pagecount]]
@@ -25,5 +24,6 @@ Currently included:
 * [[template]]
 * [[toc]]
 * [[toggle]]
+* [[repolist]]
 
 New plugins will be added to this bundle from time to time.
diff --git a/doc/plugins/google/discussion.mdwn b/doc/plugins/google/discussion.mdwn
new file mode 100644 (file)
index 0000000..babc919
--- /dev/null
@@ -0,0 +1,6 @@
+This plugin uses the googleform.tmpl
+which produces valid HTML but invalid XHTML.
+This is not very good since the default ikiwiki
+templates produce XHTML instead of HTML.
+
+> Fixed, thanks for the patch! --[[Joey]] 
diff --git a/doc/plugins/googlecalendar.mdwn b/doc/plugins/googlecalendar.mdwn
deleted file mode 100644 (file)
index bca2ae7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-[[!template id=plugin name=googlecalendar author="[[Joey]]"]]
-[[!tag type/special-purpose]]
-
-*Note*: This plugin is deprecated. Please switch to the [[embed]] plugin.
-
-This plugin allows embedding a google calendar iframe in the wiki.
-Normally, if the [[htmlscrubber]] is enabled, such iframes are scrubbed out
-of the wiki content since they're not very safe if created by malicious
-users. But some iframes are legitimate, and safe, if you trust the embedded
-content. This plugin is an example of how to deal with this in ikiwiki.
-
-Example use:
-
-       \[[!googlecalendar html="""
-       <iframe src="http://www.google.com/calendar/embed?src=adkrdken8mupngh13jshlbenoc%40group.calendar.google.com&title=OSEL%20Calendar&chrome=NAVIGATION&bgcolor=%2371d873&height=588" style=" border-width:0 " width="480" frameborder="0" height="588"></iframe>
-       """]]
-
-The iframe should be the one provided by google. Note that it's used in a
-way that avoids cross-site scripting attacks, assuming you trust google's
-content.
diff --git a/doc/plugins/goto.mdwn b/doc/plugins/goto.mdwn
new file mode 100644 (file)
index 0000000..9c401c5
--- /dev/null
@@ -0,0 +1,10 @@
+[[!template id=plugin name=goto author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/useful]]
+
+This plugin adds a `do=goto` mode for the IkiWiki CGI script. It's mainly
+for internal use by the [[404]], [[comments]] and [[recentchanges]]
+plugins, which enable it automatically.
+
+With this plugin enabled you can link to `ikiwiki.cgi?do=goto&page=some/where`
+to make a link that will redirect to the page `/some/where` if it exists, or
+offer a link to create it if it doesn't.
diff --git a/doc/plugins/htmlbalance.mdwn b/doc/plugins/htmlbalance.mdwn
new file mode 100644 (file)
index 0000000..f4e2298
--- /dev/null
@@ -0,0 +1,9 @@
+[[!template id=plugin name=htmlbalance author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/html]]
+
+This plugin ensures that the HTML emitted by ikiwiki contains well-balanced
+HTML tags, by parsing it with [[!cpan HTML::TreeBuilder]] and re-serializing it. This
+acts as a lighter-weight alternative to [[plugins/htmltidy]]; it doesn't
+ensure validity, but it does at least ensure that formatting from a
+blog post pulled in by the [[ikiwiki/directive/inline]] directive doesn't
+leak into the rest of the page.
diff --git a/doc/plugins/htmlbalance/discussion.mdwn b/doc/plugins/htmlbalance/discussion.mdwn
new file mode 100644 (file)
index 0000000..c66528a
--- /dev/null
@@ -0,0 +1,10 @@
+Would it be possible to use [[!cpan HTML::Entities]] rather than
+`XML::Atom::Util` for encoding entities? The former is already an ikiwiki
+dependency (via [[!cpan HTML::Parser]]).
+
+> Now switched to HTML::Entities --[[Joey]]
+
+I also wonder if there's any benefit to using this plugin aside from with
+aggregate. Perhaps a small one but aggregate seems like the main case..
+wondering if it would be better to just have aggregate balanace the html
+automatically and do away with the separate plugin. --[[Joey]]
index 7db372e1be272b185dc735f8fb27a79ed612420c..c59b46e14e12624463881101fff3190de36061c1 100644 (file)
@@ -32,10 +32,10 @@ other HTML-related functionality, such as whether [[meta]] allows
 potentially unsafe HTML tags.
 
 The `htmlscrubber_skip` configuration setting can be used to skip scrubbing
-of some pages. Set it to a [[PageSpec]], such as "!*/Discussion", and pages
-matching that can have all the evil CSS, JavsScript, and unsafe html
-elements you like. One safe way to use this is to use [[lockedit]] to lock
-those pages, so only admins can edit them.
+of some pages. Set it to a [[ikiwiki/PageSpec]], such as "!*/Discussion",
+and pages matching that can have all the evil CSS, JavsScript, and unsafe
+html elements you like. One safe way to use this is to use [[lockedit]] to
+lock those pages, so only admins can edit them.
 
 ----
 
index f675a01aed5d0a482622077f374d0251d602dbb7..580e56f596d690e42ce10467329f05e1b07354d5 100644 (file)
@@ -7,4 +7,5 @@ emitted by ikiwiki. Besides being nicely formatted, this helps ensure that
 even if users enter suboptimal html, your wiki generates valid html.
 
 Note that since tidy is an external program, that is run each time a page
-is built, this plugin will slow ikiwiki down somewhat.
+is built, this plugin will slow ikiwiki down somewhat. [[plugins/htmlbalance]]
+might provide a faster alternative.
index 02d46e38081a1d60fb019dc445072dabb96e90e0..e1bb2d15b0b2fb1d313cd328813b54538be16500 100644 (file)
@@ -5,3 +5,8 @@ logo link to \[[hurd/logo]] / <http://www.bddebian.com/~wiki/hurd/logo/>
 instead of linking to the PNG image file.  --[[tschwinge]]
 
 > Done, use link=somepage --[[Joey]]
+
+It would be handy if the `class` and `id` tags were passed through to the surrounding `table` in the case of `caption` being present.  Would this break anything?  --[[neale]]
+
+> Seems unlikely to break *too* much. I can imagine css that styles the img
+> unexpectedly applying the table. --[[Joey]]
index 71bf232abdae7a14e48944a33cb891a0d5f3b557..c8f64ea47a6b35579bed329da4da902952920eb3 100644 (file)
@@ -4,7 +4,7 @@
 This plugin allows the administrator of a wiki to lock some pages, limiting
 who can edit them using the online interface. This doesn't prevent anyone
 who can commit to the underlying revision control system from editing the
-pages, however.
+pages, however. (Unless you set up [[tips/untrusted_git_push]].)
 
 The `locked_pages` setting configures what pages are locked. It is a
 [[ikiwiki/PageSpec]], so you have lots of control over what kind of pages
@@ -17,6 +17,10 @@ One handy thing to do if you're using ikiwiki for your blog is to lock
 posts in your blog, while still letting them comment via the Discussion
 pages.
 
+Alternatively, if you're using the [[comments]] plugin, you can lock
+"!postcomment(*)" to allow users to comment on pages, but not edit anything
+else.
+
 Wiki administrators can always edit locked pages. The [[ikiwiki/PageSpec]]
 can specify that some pages are not locked for some users. For example,
 "important_page and !user(joey)" locks `important_page` while still
diff --git a/doc/plugins/mdwn/discussion.mdwn b/doc/plugins/mdwn/discussion.mdwn
new file mode 100644 (file)
index 0000000..4b05e7f
--- /dev/null
@@ -0,0 +1,7 @@
+Unlike other format, ikiwiki is somehow depends
+on mdwn, since the underlay dir
+is written in mdwn.  If you want to disable mdwn,
+you need to overwrite the underlay
+dir (set underlaydir in ikiwiki.setup
+to your own underlay dir or replace underlay pages
+in your $SRC).
index afd55499303f42dd4284c457623bb543fd09003c..e49bdcc501bb0f3bfa91f6d18b79b0a0a2fb925b 100644 (file)
@@ -1,4 +1,4 @@
-[[!template id=plugin name=meta author="[[Joey]]"]]
+[[!template id=plugin name=meta core=1 author="[[Joey]]"]]
 [[!tag type/meta]]
 
 This plugin provides the [[ikiwiki/directive/meta]] [[ikiwiki/directive]],
index 6235963d320deba56a936d40e80d88190e84cf2c..a56027e607958364045fbc613b5bda53352fb082 100644 (file)
@@ -6,5 +6,5 @@ This plugin provides the [[ikiwiki/directive/pagecount]]
 currently in the wiki.
 
 If it is turned on it can tell us that this wiki includes
-[[!pagecount pages="* and !recentchanges"]]
-pages, of which [[!pagecount pages="*/Discussion"]] are discussion pages.
+[[!pagecount ]] pages, of which
+[[!pagecount pages="*/Discussion"]] are discussion pages.
index f4e7ae7a1225df56d0efeacd4f2c5ef8c5df087e..672970c2166a19bddf94a4970b98983c2b325a77 100644 (file)
@@ -9,3 +9,71 @@ the *Preferences -- Subscriptions*.  --[[tschwinge]]
 >> Aha, then the problem is Firefox, which is automatically filling the
 >> *Password* field with its previous value, but not filling the
 >> *Confirm Password* one.  --[[tschwinge]]
+
+## easy access to the userdb for apache auth?
+
+My use case is:
+
+* restricted ikiwiki
+* read/edit only allowed from the local network (done with apache restrictions)
+* edit only for people authenticated (done with vanilla ikiwiki passwordauth)
+
+I would like to allow people to read/edit the wiki from outside of the
+local network, if and only if they already have an ikiwiki account.
+
+[[httpauth]] doesn't fit since it doesn't allow anonymous local users
+to create their own account. I want a single, local, simple auth
+database.
+
+My (naïve?) idea would be:
+
+* keep the [[passwordauth]] system
+* provide a way for Apache to use the userdb for authentication if
+people want to connect from outside
+
+I looked at the various auth modules for apache2. It seems that none
+can use a "perl Storable data" file. So, I think some solutions could
+be:
+
+* use a sqlite database instead of a perl Storable file
+  * can be used with
+    [mod_auth_dbd](http://httpd.apache.org/docs/2.2/mod/mod_authn_dbd.html) 
+  * requires a change in ikiwiki module [[passwordauth]]
+* use an external program to read the userdb and talk with
+  [mod_auth_external](http://unixpapa.com/mod_auth_external.html)
+  * requires the maintainance of this external auth proxy over ikiwiki
+    userdb format changes
+  * (I don't know perl)
+* include this wrapper in ikiwiki
+  * something like `ikiwiki --auth user:pass:userdb` check the
+    `user:pass` pair in `userdb` and returns an Accept/Reject flag to
+    Apache 
+  * requires a change in ikiwiki core
+  * still requires
+    [mod_auth_external](http://unixpapa.com/mod_auth_external.html)
+* do it with Apache perl sections
+  * (I don't know perl)
+
+Any opinion/suggestion/solution to this is welcome and appreciated.
+
+--
+[[NicolasLimare]]
+
+For a similar use case, I've been intending to implement
+[[todo/httpauth_feature_parity_with_passwordauth]], but your idea may
+actually be the way to go. IMHO, the Perl sections idea is the
+easiest to setup, but on the long run, I'd prefer ikiwiki to optionnally
+use a userdb storage backend supported at least by Apache and lighttpd.
+--[[intrigeri]]
+
+Tons of CPAN modules may help, but most of them are specific to `mod_perl`,
+and AFAIK, ikiwiki is generally not run with `mod_perl`. It's not clear to me
+wether these modules depend on the webapp to be run with `mod_perl` set 
+as the script handler, or only on `mod_perl` to be installed and loaded.
+
+* CPAN's `Apache::AuthenHook` allows to plug arbitrary Perl handlers as
+  Apache authentication providers.
+* CPAN's `Apache::Authen::Program` (`mod_perl`)
+* [http://www.openfusion.com.au/labs/mod_auth_tkt/](mod_auth_tkt) along with CPAN's
+  `Apache::AuthTkt`
+--[[intrigeri]]
index d012004f96d697cdb09ac506fdf0cf9678ba8680..6156c235fd76e1524b30b8265a856439dd0061da 100644 (file)
@@ -3,7 +3,7 @@
 
 This plugin causes ikiwiki to listen for pings, typically delivered from
 another ikiwiki instance using the [[pinger]] plugin. When a ping is
-recieved, ikiwiki will update the wiki, the same as if `ikiwiki --refresh`
+received, ikiwiki will update the wiki, the same as if `ikiwiki --refresh`
 were ran at the command line.
 
 An url such as the following is used to trigger a ping:
index 9a67f5dca3b46dc8ef99923b9344a8a4c2a191e8..11ad4252fb16b1862b1a0bb0474de957eb5ec350 100644 (file)
@@ -1,5 +1,5 @@
 [[!template id=plugin name=prettydate author="[[Joey]]"]]
-[[!tag type/format]]
+[[!tag type/date]]
 
 Enabling this plugin changes the dates displayed on pages in the wiki to
 a format that is nice and easy to read. Examples: "late Wednesday evening, 
diff --git a/doc/plugins/relativedate.mdwn b/doc/plugins/relativedate.mdwn
new file mode 100644 (file)
index 0000000..3ada086
--- /dev/null
@@ -0,0 +1,16 @@
+[[!template id=plugin name=relativedate author="[[Joey]]"]]
+[[!tag type/date]]
+
+This plugin lets dates be displayed in relative form. Examples: "2 days ago", 
+"1 month and 3 days ago", "30 minutes ago". Hovering over the date will
+cause a tooltip to pop up with the absolute date.
+
+This only works in browsers with javascript enabled; other browsers will
+show the absolute date instead. Also, this plugin can be used with other
+plugins like [[prettydate]] that change how the absolute date is displayed.
+
+If this plugin is enabled, you may also add relative dates to pages in the
+wiki, by using html elements in the "relativedate" class. For example, this
+will display as a relative date:
+
+       <span class="relativedate">Tue Jan 20 12:00:00 EDT 2009</span>
diff --git a/doc/plugins/repolist.mdwn b/doc/plugins/repolist.mdwn
new file mode 100644 (file)
index 0000000..9b3a757
--- /dev/null
@@ -0,0 +1,17 @@
+[[!template id=plugin name=repolist author="[[Joey]]"]]
+[[!tag type/useful]]
+
+This plugin allows you to configure ikiwiki with the location of
+[[rcs]] repositories for your wiki's source. This is done via the
+"repositories" setting in the setup file. Once you tell it where the source
+to your wiki can be downloaded from, this information can be published on
+your wiki in various ways.
+
+This plugin supports the [rel-vcs-*](http://kitenet.net/~joey/rfc/rel-vcs/)
+microformat, and uses it to embed the repository location information in
+every wiki page.
+
+By using this plugin, you will make [[Joey]] very happy, as he will be able
+to easily check out the source of your wiki, for purposes of debugging and
+general curiosity. More generally, making it easy for others to find the
+repository for your wiki is just a Plain Good Idea(TM).
index 9355597ac6e9cdcc35988bde5130faf1020ebd23..5e97e2d8058391ec39cb7a493c3a4a6e1a219732 100644 (file)
@@ -11,7 +11,7 @@ ikiwiki. Limitations include:
 
 * There are issues with inserting raw html into documents, as ikiwiki 
   does with [[WikiLinks|ikiwiki/WikiLink]] and many 
-  preprocessor [[directives|ikiwiki/directive]].
+  [[directives|ikiwiki/directive]].
 
 So while you may find this useful for importing old files into your wiki,
 using this as your main markup language in ikiwiki isn't recommended at
index 8b137891791fe96927ad78e64b0aad7bded08bdc..4e11ce08c04230b8d3abdcec2980f7b2f0901c92 100644 (file)
@@ -1 +1,12 @@
+The plugin depends on [[mdwn]].  If you have
+disabled [[mdwn]], to get [[shortcut]] work, you need
+commit in a shortcuts.ext (ext is `rcs|creole|html|txt|etc`),
+and edit/patch [[shortcut]].
+
+Maybe use the `default_pageext` is better than hardcode .mdwn?
+
+--[[weakish]]
+
+> done, it will use `default_pageext` now --[[Joey]] 
+
 
index 17bb086a1eb887a1c48801352bdb8f08dcfed1da..8ff70a069ce666cc9fc909878b2a7e93518d8296 100644 (file)
@@ -5,6 +5,9 @@ This plugin provides the [[ikiwiki/directive/tag]] and
 [[ikiwiki/directive/taglink]] [[directives|ikiwiki/directive]].
 These directives allow tagging pages.
 
+It also provides the `tagged()` [[ikiwiki/PageSpec]], which can be used to
+match pages that are tagged with a specific tag.
+
 [[!if test="enabled(tag)" then="""
 This wiki has the tag plugin enabled, so you'll see a note below that this
 page is tagged with the "tags" tag.
index 7e7b88bc5a13ab4b3e14eca14ebe647af5019fc7..b6dab5358a90d14d79038e8c13bbe9a5cfe1fa1b 100644 (file)
@@ -22,3 +22,9 @@ AOLMODE=true echo "I too would really like this feature, which would make cgi fr
 better" --[[DavidBremner]]
 
 Please make the actual text used a template some way or another. I may want `map` instead of `inline`. --[[madduck]]
+
+
+See [[todo/auto-create tag pages according to a template]]
+
+-- Jeremy Schultz <jeremy.schultz@uleth.ca>
+
diff --git a/doc/plugins/textile/discussion.mdwn b/doc/plugins/textile/discussion.mdwn
deleted file mode 100644 (file)
index 945c9b4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.
\ No newline at end of file
diff --git a/doc/plugins/type/date.mdwn b/doc/plugins/type/date.mdwn
new file mode 100644 (file)
index 0000000..eae1226
--- /dev/null
@@ -0,0 +1 @@
+These plugins control how ikiwiki displays dates.
diff --git a/doc/plugins/underlay.mdwn b/doc/plugins/underlay.mdwn
new file mode 100644 (file)
index 0000000..09d096a
--- /dev/null
@@ -0,0 +1,14 @@
+[[!template id=plugin name=underlay author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/useful]]
+
+This plugin adds an `add_underlays` option to the `.setup` file.
+Its value is a list of underlay directories whose content is added to the wiki.
+
+Multiple underlays are normally set up automatically by other plugins (for
+instance, the images used by the [[plugins/smiley]] plugin), but they can also be
+used as a way to pull in external files that you don't want in revision control,
+like photos or software releases.
+
+Directories in `add_underlays` should usually be absolute. If relative, they're
+interpreted as relative to the parent directory of the basewiki underlay, which
+is probably not particularly useful in this context.
diff --git a/doc/plugins/wmd.mdwn b/doc/plugins/wmd.mdwn
new file mode 100644 (file)
index 0000000..dc9a307
--- /dev/null
@@ -0,0 +1,16 @@
+[[!template id=plugin name=wmd author="[[Will]]"]]
+[[!tag type/chrome]]
+
+[WMD](http://wmd-editor.com/) is a What You See Is What You Mean editor for
+[[mdwn]]. This plugin makes WMD be used for editing pages in the wiki.
+
+To use the plugin, you will need to install WMD. Download the [WMD
+source](http://wmd-editor.com/downloads/wmd-1.0.1.zip).  In that zip file
+you'll find a few example html files, a readme and `wmd` directory.  Create
+a 'wmd' subdirectory in the ikiwiki `underlaydir` directory (ie `sudo mkdir
+/usr/share/ikiwiki/wmd`). Move the `wmd` directory into the directory you
+made. You should now have a `wmd/wmd/wmd.js` file as well as some other
+javascript files and an images directory in the same place.
+
+Note that the WMD plugin does **not** handle ikiwiki directives.  For this
+reason the normal `preview` button remains.
index 1b78f5900b2de71ee10c4a4bd94f17c8c6d62bf1..696bc6bc37bb910af72e256b90d2250159965c7e 100644 (file)
@@ -19,7 +19,7 @@ that can be fleshed out to make a useful plugin.
 `IkiWiki::Plugin::pagecount` is another simple example. All perl plugins
 should `use IkiWiki` to import the ikiwiki plugin interface. It's a good
 idea to include the version number of the plugin interface that your plugin
-expects: `use IkiWiki 2.00`.
+expects: `use IkiWiki 3.00`.
 
 An external plugin is an executable program. It can be written in any
 language. Its interface to ikiwiki is via XML RPC, which it reads from
@@ -55,8 +55,8 @@ plugin, and a "call" parameter, which tells what function to call for the
 hook.
 
 An optional "last" parameter, if set to a true value, makes the hook run
-after all other hooks of its type. Useful if the hook depends on some other
-hook being run first.
+after all other hooks of its type, and an optional "first" parameter makes
+it run first. Useful if the hook depends on some other hook being run first.
 
 ## Types of hooks
 
@@ -107,7 +107,7 @@ adding or removing files from it.
 
 This hook is called early in the process of building the wiki, and is used
 as a first pass scan of the page, to collect metadata about the page. It's
-mostly used to scan the page for WikiLinks, and add them to `%links`.
+mostly used to scan the page for [[WikiLinks|ikiwiki/WikiLink]], and add them to `%links`.
 Present in IkiWiki 2.40 and later.
 
 The function is passed named parameters "page" and "content". Its return
@@ -168,7 +168,7 @@ htmlize the page) along with the rest of the page.
 
        hook(type => "linkify", id => "foo", call => \&linkify);
 
-This hook is called to convert [[WikiLinks|WikiLink]] on the page into html
+This hook is called to convert [[WikiLinks|ikiwiki/WikiLink]] on the page into html
 links. The function is passed named parameters "page", "destpage", and
 "content". It should return the linkified content.  Present in IkiWiki 2.40
 and later.
@@ -189,14 +189,18 @@ The function is passed named parameters: "page" and "content" and should
 return the htmlized content.
 
 If `hook` is passed an optional "keepextension" parameter, set to a true
-value, then this extension will not be stripped from the source filename when
+value, then the extension will not be stripped from the source filename when
 generating the page.
 
+If `hook` is passed an optional "noextension" parameter, set to a true
+value, then the id parameter specifies not a filename extension, but
+a whole filename that can be htmlized. This is useful for files
+like `Makefile` that have no extension.
+
 ### pagetemplate
 
        hook(type => "pagetemplate", id => "foo", call => \&pagetemplate);
 
-
 [[Templates|wikitemplates]] are filled out for many different things in
 ikiwiki, like generating a page, or part of a blog page, or an rss feed, or
 a cgi. This hook allows modifying the variables available on those
@@ -304,7 +308,7 @@ can check if the session object has a "name" parameter set.
 
 ### canedit
 
-       hook(type => "canedit", id => "foo", call => \&pagelocked);
+       hook(type => "canedit", id => "foo", call => \&canedit);
 
 This hook can be used to implement arbitrary access methods to control when
 a page can be edited using the web interface (commits from revision control
@@ -322,6 +326,26 @@ This hook should avoid directly redirecting the user to a signin page,
 since it's sometimes used to test to see which pages in a set of pages a
 user can edit.
 
+### checkcontent
+       
+       hook(type => "checkcontent", id => "foo", call => \&checkcontent);
+
+This hook is called to check the content a user has entered on a page,
+before it is saved, and decide if it should be allowed.
+
+It is passed named parameters: `content`, `page`, `cgi`, and `session`. If
+the content the user has entered is a comment, it may also be passed some
+additional parameters: `author`, `url`, and `subject`. The `subject`
+parameter may also be filled with the user's comment about the change.
+
+Note: When the user edits an existing wiki page, the passed `content` will
+include only the lines that they added to the page, or modified.
+
+The hook should return `undef` on success. If the content is disallowed, it
+should return a message stating what the problem is, or a function
+that can be run to perform whatever action is necessary to allow the user
+to post the content.
+
 ### editcontent
 
        hook(type => "editcontent", id => "foo", call => \&editcontent);
@@ -415,7 +439,7 @@ describes the plugin as a whole. For example:
 * `example` can be set to an example value.
 * `description` is a short description of the option.
 * `link` is a link to further information about the option. This can either
-  be a wikilink, or an url.
+  be a [[ikiwiki/WikiLink]], or an url.
 * `advanced` can be set to true if the option is more suitable for advanced
   users.
 * `safe` should be false if the option should not be displayed in unsafe
@@ -432,7 +456,7 @@ describes the plugin as a whole. For example:
 
 To import the ikiwiki plugin interface:
 
-       use IkiWiki '2.00';
+       use IkiWiki '3.00';
 
 This will import several variables and functions into your plugin's
 namespace. These variables and functions are the ones most plugins need,
@@ -487,7 +511,7 @@ use the following hashes, using a page name as the key:
   destination file.
 * `%pagesources` contains the name of the source file for each page.
 
-Also, the %IkiWiki::version variable contains the version number for the
+Also, the `%IkiWiki::version` variable contains the version number for the
 ikiwiki program.
 
 ### Library functions
@@ -610,6 +634,16 @@ A failure to write the file will result in it dying with an error.
 
 If the destination directory doesn't exist, it will first be created.
 
+The filename and directory are separate parameters because of
+some security checks done to avoid symlink attacks. Before writing a file,
+it checks to make sure there's not a symlink with its name, to avoid
+following the symlink. If the filename parameter includes a subdirectory
+to put the file in, it also checks if that subdirectory is a symlink, etc.
+The directory parameter, however, is not checked for symlinks. So,
+generally the directory parameter is a trusted toplevel directory like
+the srcdir or destdir, and any subdirectories of this are included in the
+filename parameter.
+
 #### `will_render($$)`
 
 Given a page name and a destination file name (not including the base
@@ -651,7 +685,7 @@ a wiki page name.
 #### `linkpage($)`
 
 This converts text that could have been entered by the user as a
-[[WikiLink]] into a wiki page name.
+[[ikiwiki/WikiLink]] into a wiki page name.
 
 #### `srcfile($;$)`
 
@@ -697,11 +731,15 @@ This can be called when creating a new page, to determine what filename
 to save the page to. It's passed a page name, and its type, and returns
 the name of the file to create, relative to the srcdir.
 
-#### `targetpage($$)`
+#### `targetpage($$;$)`
 
 Passed a page and an extension, returns the filename that page will be
 rendered to.
 
+Optionally, a third parameter can be passed, to specify the preferred
+filename of the page. For example, `targetpage("foo", "rss", "feed")`
+will yield something like `foo/feed.rss`.
+
 ## Miscellaneous
 
 ### Internal use pages
@@ -712,7 +750,7 @@ are collected together to form the RecentChanges page, for example.
 
 To make an internal use page, register a filename extension that starts
 with "_". Internal use pages cannot be edited with the web interface,
-generally shouldn't contain wikilinks or preprocessor directives (use
+generally shouldn't contain [[WikiLinks|ikiwiki/WikiLink]] or preprocessor directives (use
 either on them with extreme caution), and are not matched by regular
 PageSpecs glob patterns, but instead only by a special `internal()`
 [[ikiwiki/PageSpec]].
@@ -821,6 +859,30 @@ it up in the history.
 
 It's ok if this is not implemented, and throws an error.
 
+#### `rcs_receive()`
+
+This is called when ikiwiki is running as a pre-receive hook (or
+equivalent), and is testing if changes pushed into the RCS from an
+untrusted user should be accepted. This is optional, and doesn't make
+sense to implement for all RCSs.
+
+It should examine the incoming changes, and do any sanity 
+checks that are appropriate for the RCS to limit changes to safe file adds,
+removes, and changes. If something bad is found, it should exit
+nonzero, to abort the push. Otherwise, it should return a list of
+files that were changed, in the form:
+
+       {
+               file => # name of file that was changed
+               action => # either "add", "change", or "remove"
+               path => # temp file containing the new file content, only
+                       # needed for "add"/"change", and only if the file
+                       # is an attachment, not a page
+       }
+
+The list will then be checked to make sure that each change is one that
+is allowed to be made via the web interface.
+
 ### PageSpec plugins
 
 It's also possible to write plugins that add new functions to
@@ -847,3 +909,82 @@ to a hash containing all the config items. They should also implement a
 By the way, to parse a ikiwiki setup file and populate `%config`, a
 program just needs to do something like:
 `use IkiWiki::Setup; IkiWiki::Setup::load($filename)`
+
+### Function overriding
+
+Sometimes using ikiwiki's pre-defined hooks is not enough. Your plugin
+may need to replace one of ikiwiki's own functions with a modified version,
+or wrap one of the functions.
+
+For example, your plugin might want to override `displaytime`, to change
+the html markup used when displaying a date. Or it might want to override
+`IkiWiki::formattime`, to change how a date is formatted. Or perhaps you
+want to override `bestlink` and change how ikiwiki deals with [[WikiLinks|ikiwiki/WikiLink]].
+
+By venturing into this territory, your plugin is becoming tightly tied to
+ikiwiki's internals. And it might break if those internals change. But
+don't let that stop you, if you're brave.
+
+Ikiwiki provides an `inject()` function, that is a powerful way to replace
+any function with one of your own. This even allows you to inject a
+replacement for an exported function, like `bestlink`. Everything that
+imports that function will get your version instead. Pass it the name of
+the function to replace, and a new function to call. 
+
+For example, here's how to replace `displaytime` with a version using HTML 5
+markup:
+
+       inject(name => 'IkiWiki::displaytime', call => sub {
+               return "<time>".formattime(@_)."</time>";
+       });
+
+Here's how to wrap `bestlink` with a version that tries to handle
+plural words:
+
+       my $origbestlink=\&bestlink;
+       inject(name => 'IkiWiki::bestlink', call => \&mybestlink);
+
+       sub deplural ($) {
+               my $word=shift;
+               $word =~ s/e?s$//; # just an example :-)
+               return $word;
+       }
+
+       sub mybestlink ($$) {
+               my $page=shift;
+               my $link=shift;
+               my $ret=$origbestlink->($page, $link);
+               if (! length $ret) {
+                       $ret=$origbestlink->($page, deplural($link));
+               }
+               return $ret;
+       }
+
+### Javascript
+
+Some plugins use javascript to make ikiwiki look a bit more web-2.0-ish.
+
+All javascript code should be put in `.js` files in the `javascript`
+underlay, and plugins using those files can enable use of the underlay by
+calling `add_underlay("javascript");` in their `import` function.
+
+You'll have to arrange for `<script>` tags to be added to the pages that
+use your javascript. This can be done using a `format` hook.
+
+Ikiwiki provides some utility functions in `ikiwiki.js`, for use by other
+javascript code. These include:
+
+#### `getElementsByClass(cls, node, tag)` 
+
+Returns an array of elements with the given class. The node and tag are
+optional and define what document node and element names to search.
+
+#### `hook(name, call)`
+
+The function `call` will be run as part of the hook named `name`.
+
+Note that to hook into `window.onload`, you can use the `onload' hook.
+
+#### `run_hooks(name)`
+
+Runs the hooks with the specified name.
index 039775b792308adf304e508fb5398c092cc44c78..24a556ffe82953ac312d8ca8543291e9db3596cc 100644 (file)
@@ -40,3 +40,7 @@ distributed wiki.
 >
 > OTOH, if something can be added to the documentation that encourages
 > good behavior, that'd be a good thing ... --[[Joey]]
+
+---
+
+I would find this page clearer split up into sub-pages. Does anyone agree/disagree? -- [[users/Jon]]
index 272f74a7c9d76d59bb7df14cdfcfd04bcffd0a3b..e30bf2ff3d8d4f3e0cf1054fba7a136dbf9910a3 100644 (file)
@@ -96,14 +96,13 @@ the sentinal.
 
 ## Function injection
 
-Some parts of ikiwiki are extensible by adding functions. For example, the
-RCS interface relies on plugins providing several IkiWiki::rcs_* functions.
+Some parts of ikiwiki are extensible by adding or overriding functions.
 It's actually possible to do this from an external plugin too. 
 
-To make your external plugin provide an `IkiWiki::rcs_update` function, for
+To make your external plugin override the `IkiWiki::formattime` function, for
 example, make an RPC call to `inject`. Pass it named parameters "name" and
 "call", where "name" is the name of the function to inject into perl (here
-"Ikiwiki::rcs_update" and "call" is the RPC call ikiwiki will make whenever
+"Ikiwiki::formattime" and "call" is the RPC call ikiwiki will make whenever
 that function is run.
 
 If the RPC call is memoizable, you can also pass a "memoize" parameter, set
index e1b34b8000ebefcabedef8aabbfe1c1a4a9cb249..5345f71f257c2979065189942ac77ce1074fa1e6 100644 (file)
@@ -27,7 +27,7 @@ important one is the IkiWiki module.
 
        use warnings;
        use strict;
-       use IkiWiki 2.00;
+       use IkiWiki 3.00;
 
 Ok, boilerplate is out of the way. Now to add the one function that ikiwiki
 expects to find in any module: `import`. The import function is called when
index e62f3ef49fb2127c78e32686d97e2a267441d904..089221caba26027cb013ea69fd4650cb0ae8c44b 100644 (file)
@@ -280,6 +280,9 @@ Here is a how a commit from a remote repository works:
 
 * git-commit in the remote repository
 * git-push, pushes the commit to the master repo on the server
+* (Optionally, the master repo's pre-receive hook runs, and checks that the
+  update only modifies files that the pushing user is allowed to update. 
+  If not, it aborts the receive.)
 * the master repo's post-update hook notices this update, and runs ikiwiki
 * ikiwiki notices the modifies page source, and compiles it
 
index b210af825f47b94f6f5d5be0b3d0ee0f2f55cba7..000eb0b3cd6282b78c56cbec462782b74c116679 100644 (file)
@@ -20,9 +20,9 @@ working clones (with working directories) as leaf nodes.  The root
 working clones.
 
 One of the leaf node clone repositories is special; it has working
-directory which is used to compile the wiki from, and is also used by the
+directory which is used to compile the wiki, and is also used by the
 [[cgi]] to commit changes made via the web interface. It is special
-since the `post-commit` hook for the bare root repository is used to
+since the `post-update` hook for the bare root repository is used to
 trigger an update of this repository, and then an ikiwiki refresh
 updates the published  wiki itself.
 
@@ -43,9 +43,9 @@ repositories:
   repositories will push to/pull from.  It is a bare repository, since
   there are problems pushing to a repository that has a working
   directory. This is called _repository_ in [[ikiwiki-makerepo]]'s
-  manual page. Nominally, this bare repository has a `post-commit` hook
+  manual page. Nominally, this bare repository has a `post-update` hook
   that either is or calls ikiwiki's git wrapper, which changes to the
-  working directory for ikiwiki, does a _git pull_, and refreshes ikiwiki
+  working directory for ikiwiki, does a `git pull`, and refreshes ikiwiki
   to regenerate the wiki with any new content. The [[setup]] page describes
   how to do this.
 
@@ -64,7 +64,7 @@ repositories:
   hack on your wiki. you can commit local changes to the version on
   the laptop, perhaps while offline. Any new content should be pushed to the
   bare master repository when you are ready to publish it, and then
-  the post-commit hook of the bare repository will ensure that the
+  the post-update hook of the bare repository will ensure that the
   ikiwiki's source directory is updated, and the ikiwiki refreshed
   with the new content.
 
@@ -79,7 +79,7 @@ It is **paramount** that you **never** push to the non-bare repository
 Instead, clone the bare repository as mentioned above, and push
 **only** to the bare repository.
 
-The ikiwiki `post-commit` hook should be put in the bare repository.
+The ikiwiki `post-update` hook should be put in the bare repository.
 
 ## git repository with multiple committers
 
@@ -100,6 +100,33 @@ repository, should only be writable by the wiki's admin, and *not* by the
 group. Take care that ikiwiki uses a umask that does not cause files in
 the srcdir to become group writable. (umask 022 will work.)
 
+## git repository with untrusted committers
+
+By default, anyone who can commit to the git repository can modify any file
+on the wiki however they like. A `pre-receive` hook can be set up to limit
+incoming commits from untrusted users. Then the same limits that are placed
+on edits via the web will be in effect for commits to git for the users.
+They will not be allowed to edit locked pages, they will only be able to
+delete pages that the [[plugins/remove]] configuration allows them to
+remove, and they will only be allowed to add non-page attachments that the
+[[plugins/attachment]] configuration allows.
+
+To enable this, you need to set up the git repository to have multiple
+committers. Trusted committers, including the user that ikiwiki runs as, 
+will not have their commits checked by the `pre-receive` hook. Untrusted
+committers will have their commits checked. The configuration settings to
+enable are `git_test_receive_wrapper`, which enables generation of a
+`pre-receive` hook, and `untrusted_committers`, which is a list of
+usernames of the untrusted committers.
+
+Note that when the `pre-receive` hook is checking incoming changes, it
+ignores the git authorship information, and uses the username of the unix
+user who made the commit. Then tests including the `locked_pages` [[PageSpec]]
+are checked to see if that user can edit the pages in the commit.
+
+You can even set up an [[anonymous_user|tips/untrusted_git_push]], to allow
+anyone to push changes in via git rather than using the web interface.
+
 ## Optionally using a local wiki to preview changes
 
 When working on the "working clones" to add content to your wiki,
@@ -120,7 +147,7 @@ is the normal behaviour of ikiwiki, set the configuration of the local wiki:
 
       gitorigin_branch => "",
       ## git post-commit wrapper
-      wrapper => "/working/dir/.git/hooks/post-commit",
+      git_wrapper => "/working/dir/.git/hooks/post-commit",
 
 Then just committing should refresh the private ikiwiki on the local
 host.  Now just run `ikiwiki -setup localwiki.setup -getctime` and
index b4baf07f4a32ba4af0bdfd40e3cd0d3f2657d80e..ebfc352025d6e4c46e1dc4020faf512be6b4ce27 100644 (file)
@@ -10,9 +10,9 @@ commits edited pages, and uses the Mercurial history to generate the
 Example for a `.hg/hgrc` file in `$SRCDIR`:
 
     [hooks]
-    post-commit = /home/abe/bin/rebuildwiki
-    incoming = /home/abe/bin/rebuildwiki
+    post-commit = ikiwiki --setup /path/to/ikiwiki.setup --post-commit
+    incoming = ikiwiki --setup /path/to/ikiwiki.setup --post-commit
 
-Do not use `commit` or `precommit` hooks or ikiwiki will run into a dead lock when committing in `$SRCDIR`
+Do not use `commit` or `precommit` hooks or ikiwiki will run into a dead lock when committing in `$SRCDIR`. Also note that `--post-commit` and not `--refresh` must be used to avoid dead locking when editing the pages via CGI interface.
 
 See also [[todo/mercurial|todo/mercurial]]
index babd5cf01726afbb29033763f69c1e3fc7e8cac9..2cfcdfbf54a113d4c06971aaf63233f39780872e 100644 (file)
@@ -17,3 +17,8 @@ There is also a mismatch between the way Ikiwiki handles conflicts and the
 way Monotone handles conflicts.  At present, if there is a conflict, then
 Ikiwiki will commit a revision with conflict markers before presenting it
 to the user.  This is ugly, but there is no clean way to fix it at present.
+
+Also note that not all recent ikiwiki features have been implemented in the
+monotone plugin.  At the moment we're missing:
+
+  * [[todo/Untrusted_push_in_Monotone]]
index 488e2dec827150f9e21f5a42b23f36b4af18ef59..2f79f79784ef0efc73c5db8a52a9ff3250dad7f0 100644 (file)
@@ -7,10 +7,7 @@ This is the roadmap for ikiwiki development.
 
 Released 29 April 2006.
 
-The 1.x series changed a great deal over the more than 50 releases in its
-lifetime. It is now in maintenance mode, only security issues or really bad
-bugs will be fixed in 1.x going forward. 1.x will stop being supported with
-the release of 3.0.
+The 1.x series is no longer supported.
 
 ----
 
@@ -32,27 +29,43 @@ the release of 3.0.
 
 Released 30 April 2007.
 
-The 2.x series is expected to undergo continuing development for some time,
-adding improvements and new features, but avoiding changes that break
-backwards compatability.
+The 2.x series is now in maintenance mode. Only security fixes and fixes for
+really bad bugs will be applied going forward.
 
 ----
 
 # 3.0
 
-Version 3.0 will be an opportunity to make significant transitions.
-
-* Default to using `prefix_directives`.
-* Default to using `aggregateinternal`.
-* Remove deprecated prefs form settings for `allowed_attachments` and
-  `locked_pages`.
-* Finalise a new version of the plugin API, exporting additional commonly
-  used functions from IkiWiki.pm. See [[todo/firm_up_plugin_interface]]
-
-It will include a vast number of new features, bugfixes, and other
-improvements, far too many to list here.
-
-Release is planned for fall, 2008.
+Version 3.0 is an opportunity to make significant transitions.
+Read [[tips/upgrade_to_3.0]] for the steps you will need to
+follow when upgrading your wiki to this version.
+
+The highlights of the changes in version 3.0 include:
+
+* Support for uploading [[attachments|plugins/attachment]].
+* Can [[plugins/rename]] and [[plugins/remove]] pages and files via the web.
+* [[Web_based_setup|plugins/websetup]].
+* Blog-style [[plugins/comments]] as an alternative to Discussion pages.
+* Many other new plugins including [[plugins/htmlbalance]], [[plugins/format]],
+  [[plugins/progress]], [[plugins/color]], [[plugins/autoindex]],
+  [[plugins/cutpaste]], [[plugins/hnb]], [[plugins/creole]], [[plugins/txt]],
+  [[plugins/amazon_s3]], [[plugins/pinger]], [[plugins/pingee]],
+  [[plugins/edittemplate]]
+* The RecentChanges page is compiled statically, not generated from the CGI.
+* Support for additional revision control systems: [[rcs/bzr]],
+  [[rcs/monotone]]
+* Support for [[tips/untrusted_git_push]].
+* A new version (3.00) of the plugin API, exporting additional
+  commonly used functions from `IkiWiki.pm`.
+* Nearly everything in ikiwiki is now a plugin, from WikiLinks to page
+  editing, to RecentChanges.
+* Far too many bug fixes, features, and enhancements to list here.
+
+Released 31 December, 2008.
+
+The 3.x series is expected to undergo continuing development for some time,
+adding improvements and new features, but avoiding changes that break
+backwards compatability.
 
 ----
 
diff --git a/doc/robots.txt b/doc/robots.txt
new file mode 100644 (file)
index 0000000..7be87f9
--- /dev/null
@@ -0,0 +1,2 @@
+User-Agent: *
+Disallow: /ikiwiki.cgi
index 9e709172a900f0e23f1defe91e298814489fdbf1..1e5fba3041eeb829762158147000d38b4e14109c 100644 (file)
@@ -1,8 +1,12 @@
-This is the SandBox, a page anyone can edit to try out ikiwiki.
+This is the [[SandBox]], a page anyone can edit to try out ikiwiki (version [[!version  ]]).
 
 ----
+misc test
 
-Here's a paragraph. สวัสดี
+test more test
+[[中文显示]]
+
+Here's a paragraph.
 
 The following code block is pre-formatted:
 
@@ -51,10 +55,6 @@ Bulleted list
        * four
         * five
 
-* a new list
- * with sub heads
- * like this
-
 ----
 
 [[!template id=note text="this is generated by the [[plugins/haiku]] plugin"]]
@@ -74,12 +74,26 @@ The haiku will change after every save, mind you.
 * [![ikiwiki logo](http://ikiwiki.info/logo/ikiwiki.png)](http://ikiwiki.info)
 * <a href="http://www.google.com/">plain old html link</a>
 * [[foo]]
-* WikiLink
-
-Test
 
 -----
 
 This SandBox is also a [[blog]]!
 
 [[!inline pages="sandbox/* and !*/Discussion" rootpage="sandbox" show="4" archive="yes"]]
+
+--------
+
+This gives an example of inline code: `tar | netcat` is a nice way to transfer bulk files over the net
+
+But, of course, rsync is better.
+
+----
+
+Let's see what happens... ~~
+
+測試的啦
+
+----
+
+
+testing
diff --git a/doc/sandbox/Omgwtf_a_blof_post__33____33____33____33____33__1__33__1__33__11111__33____33____33__1__33__1__33____33__1five.html b/doc/sandbox/Omgwtf_a_blof_post__33____33____33____33____33__1__33__1__33__11111__33____33____33__1__33__1__33____33__1five.html
new file mode 100644 (file)
index 0000000..fc1757d
--- /dev/null
@@ -0,0 +1,31 @@
+<math xmlns="http://www.w3.org/1998/Math/MathML">
+  <mrow>
+    <msup>
+      <mfenced open="(" close=")">
+        <mrow>
+          <mi>a</mi>
+          <mo>+</mo>
+
+          <mi>b</mi>
+        </mrow>
+      </mfenced>
+      <mn>2</mn>
+    </msup>
+    <mo>-</mo>
+    <msub>
+
+      <mfenced open="{" close="}">
+        <mrow>
+          <mi>x</mi>
+          <mo>+</mo>
+          <mi>y</mi>
+        </mrow>
+      </mfenced>
+
+      <mi>i</mi>
+    </msub>
+  </mrow>
+</math>
+<br>
+test <b>test</b><abbr title="test">T.</abbr> <h1>test</h1>
+<a href="https://bugzilla.mozilla.org">øđ</a>
index 864f38c0d4e864425e571689ba6cf2fab67bac01..bc051b008e5be69ff07091ef2dc3abe6f712cb45 100644 (file)
@@ -1,3 +1,3 @@
-I recall testing this too, but I'm not sure where the test went. Let's try again. -- [[JonDowland]]
+I recall testing this too, but I'm not sure where the test went. Let's try again. -- [[users/Jon]]
 
 Context: [[todo/discussion_page_as_blog/discussion/castle]]
diff --git a/doc/sandbox/foobak.mdwn b/doc/sandbox/foobak.mdwn
new file mode 100644 (file)
index 0000000..c0b526f
--- /dev/null
@@ -0,0 +1 @@
+Foobaka bakfoo.
diff --git a/doc/sandbox/한글.mdwn b/doc/sandbox/한글.mdwn
new file mode 100644 (file)
index 0000000..e0ba326
--- /dev/null
@@ -0,0 +1 @@
+~를 어떻게 할까~
diff --git a/doc/sandbox/한글페이지.mdwn b/doc/sandbox/한글페이지.mdwn
new file mode 100644 (file)
index 0000000..4fac797
--- /dev/null
@@ -0,0 +1,2 @@
+
+Wow test
index 0841abf495a3d62580bfa849bbc8bafe13d58497..939d65d01e23830a597ec18c27290295be6735f7 100644 (file)
@@ -407,3 +407,13 @@ discovered on 30 May 2008 and fixed the same day. ([[!cve CVE-2008-0169]])
 
 I recommend upgrading to 2.48 immediatly if your wiki allows both password
 and openid logins.
+
+## Malformed UTF-8 DOS
+
+Feeding ikiwiki page sources containing certian forms of malformed UTF-8
+can cause it to crash. This can potentially be used for a denial of service
+attack.
+
+intrigeri discovered this problem on 12 Nov 2008 and a patch put in place
+later that day, in version 2.70. The fix was backported to testing as version
+2.53.3, and to stable as version 1.33.7.
index 1b8e4b12a723797876c01e598f2d881927834cc7..89444c9a861e35f5067994bd5b760670db6acce6 100644 (file)
@@ -2,205 +2,132 @@ This tutorial will walk you through setting up a wiki with ikiwiki.
 
 [[!toc ]]
 
-## [[Download]] and [[install]] ikiwiki.
+## Install ikiwiki
 
 If you're using Debian or Ubuntu, ikiwiki is an `apt-get install ikiwiki` away.
 If you're not, see the [[download]] and [[install]] pages.
 
-## Quick start
+## Create your wiki
 
-If you'd like to set up a wiki now, and learn more later, and you have
-ikiwiki 2.60 or better installed, just run this command and answer a couple
-of questions.
+All it takes to create a fully functional wiki using ikiwiki is running
+one command.
+[[!template id=note text="""
+For more control, advanced users may prefer to set up a wiki
+[[by_hand|byhand]].
+"""]]
 
        % ikiwiki -setup /etc/ikiwiki/auto.setup
-       What will the wiki be named? mywiki
-       What revision control system to use? git
-       What wiki user (or openid) will be wiki admin? joey
 
-Wait for it to tell you an url for your new wiki.. Done!
+Or, set up a blog with ikiwiki, run this command instead.
 
-(If the CGI doesn't seem to let you edit pages, you might need to
-[[configure_apache|tips/apache_cgi]] or [[configure_lighttpd|tips/lighttpd_cgi]].)
+       % ikiwiki -setup /etc/ikiwiki/auto-blog.setup
 
-## Decide where your wiki's files will go.
-
-As a wiki compiler, ikiwiki builds a wiki from files in a source directory,
-and outputs the files to a destination directory.  If you keep your wiki in
-a version control system, the source directory will contain a working copy
-checked out from the version control system.
+Either way, it will ask you a couple of questions.
 
-For the purposes of this tutorial, we'll set shell variables
-for these locations, and use those variables in the commands that follow.
+       What will the wiki be named? foo
+       What revision control system to use? git
+       What wiki user (or openid) will be admin? joey
+       Choose a password:
 
-       SRCDIR=~/wikiwc
-       DESTDIR=~/public_html/wiki/
+Then, wait for it to tell you an url for your new site..
 
-Note that ikiwiki owns the working copy directory; do not perform your own
-edits in ikiwiki's working copy.
+       Successfully set up foo:
+               url:         http://example.com/~joey/foo
+               srcdir:      ~/foo
+               destdir:     ~/public_html/foo
+               repository:  ~/foo.git
+       To modify settings, edit ~/foo.setup and then run:
+               ikiwiki -setup ~/foo.setup
 
-## Create the beginnings of your wiki.
+Done! 
 
-This will create a simple main page for the wiki.
+## Using the web interface
 
-       mkdir $SRCDIR
-       cd $SRCDIR
-       $EDITOR index.mdwn
+Now you can go to the url it told you, and edit pages in your new wiki
+using the web interface.
 
-In the editor, you could start by entering a simple page like
-[[!toggle id=page text="this one"]].
-[[!toggleable id=page text="""
-       Welcome to your new wiki.
+(If the web interface doesn't seem to allow editing or login, you may
+need to configure [[configure_the_web_server|tips/dot_cgi]].)
 
-       All wikis are supposed to have a \[[SandBox]],
-       so this one does too.
+## Checkout and edit wiki source
 
-       ----
+Part of the fun of using ikiwiki is not being limited to using the
+web for editing pages, and instead using your favorite text editor and
+[[Revision_Control_System|rcs]]. 
 
-       This wiki is powered by [ikiwiki](http://ikiwiki.info).
-"""]]
-   
-See [[ikiwiki/formatting]] for details about the markup language.
+To do this, you need to check out a copy of the source to your wiki.
+(You should avoid making changes directly to the `srcdir`, as that
+checkout is reserved for use by ikiwiki itself.)
 
-Note that several [[standard_wiki_pages|basewiki]] will be added to your
-wiki, from files in `/usr/share/ikiwiki/basewiki/`, so your wiki will
-automatically get a [[SandBox]], and some other useful pages.
+Depending on which [[Revision_Control_System|rcs]] you chose to use,
+you can run one of these commands to check out your own copy of your wiki's
+source. (Remember to replace "foo" with the real directory name.)
 
-## Build your wiki for the first time.
+       git clone foo.git foo.src
+       svn checkout file://`pwd`/foo.svn/trunk foo.src
+       bzr clone foo foo.src
+       hg clone foo foo.src
+       # TODO monotone, tla
 
-       ikiwiki --verbose $SRCDIR $DESTDIR --url=http://example.org/~you/wiki/
+Now to edit pages by hand, go into the directory you checked out (ie,
+"foo.src"), and fire up your text editor to edit `index.mdwn` or whatever
+other page you want to edit. If you chose to set up a blog, there is even a
+sample first post in `posts/first_post.mdwn` that you can edit.
 
-Replace the url with the real url to your wiki. You should now
-be able to visit the url and see your wiki.
+Once you've edited a page, use your revision control system to commit
+the changes. For distributed revision control systems, don't forget to push
+your commit.
 
-## Add content to your wiki.
+Once the commit reaches the repository, ikiwiki will notice it, and
+automatically update the wiki with your changes.
 
-Continue editing or adding pages and rebuilding the wiki.
-   
-To quickly get started on a common task like blogging with ikiwiki, you
-can copy in files from the [[examples]]. The examples are located in
-`doc/examples/` in the ikiwiki source package.
+## Customizing the wiki
 
-You can experiment with other ikiwiki parameters such as `--wikiname`
-and `--rebuild` too. Get comfortable with its command line (see
-[[usage]]).
+There are lots of things you can configure to customize your wiki.
+These range from changing the wiki's name, to enabling [[plugins]],
+to banning users and locking pages.
 
-## Add a setup file.
+If you log in as the admin user you configured earlier, and go to
+your Preferences page, you can click on "Wiki Setup" to customize many
+wiki settings and plugins.
 
-By now you should be getting tired of typing in all the command line
-options each time you change something in your wiki's setup. Time to
-introduce setup files.
+Some settings cannot be configured on the web, for security reasons or
+because misconfiguring them could break the wiki. To change these settings,
+you can manually edit the setup file, which is named something like
+"foo.setup". The file lists all available configuration settings
+and gives a brief description of each.
 
-To generate a setup file, use `ikiwiki --dumpsetup`. You can pass
-all the options have you been including at the command line, and they
-will be stored in the setup file.
+After making changes to this file, you need to tell ikiwiki to use it:
 
-       ikiwiki $SRCDIR $DESTDIR --url=http://example.org/~you/wiki/ --dumpsetup ikiwiki.setup
+       % ikiwiki -setup foo.setup
 
-Note that this file should *not* be put in your wiki's directory with
-the rest of the files. A good place to put it is in a ~/.ikiwiki/
-subdirectory.
-   
-Most of the options, like `wikiname` in the setup file are the same as
-ikiwiki's command line options (documented in [[usage]]. `srcdir` and
-`destdir` are the two directories you specify when running ikiwiki by
-hand. Make sure that these are pointing to the right directories, and
-read through and configure the rest of the file to your liking.
+## Customizing file locations
 
-When you're satisfied, run `ikiwiki --setup ikiwiki.setup`, and it
-will set everything up.
+As a wiki compiler, ikiwiki builds a wiki from files in a source directory,
+and outputs the files to a destination directory. The source directory is
+a working copy checked out from the version control system repository.
 
-## Turn on additional features.
+When you used `auto.setup`, ikiwiki put the source directory, destination
+directory, and repository in your home directory, and told you the location
+of each. Those locations were chosen to work without customization, but you
+might want to move them to different directories.
 
-Now you have a basic wiki with a setup file. Time to experiment
-with ikiwiki's many features. 
+First, move the destination directory and repository around.
    
-Let's first enable a key wiki feature and set up [[CGI]] to allow
-editing the wiki from the web. Just edit ikiwiki.setup, uncomment the
-settings for the `cgi_wrapper`, make sure the filename for the cgi wrapper
-is ok, run `ikiwiki --setup ikiwiki.setup`, and you're done!
-
-There are lots of other configuration options in ikiwiki.setup that you
-can uncomment, configure, and enable by re-running
-`ikiwiki --setup ikiwiki.setup`. Be sure to browse through all the
-[[plugins]]..
-
-## Put your wiki in revision control.
-
-At this point you might want to check your wiki in to a revision control
-system so you can keep track of changes and revert edits. Depending
-on the revision control system you choose, the way this is done varies.
-
-Note that the .ikiwiki subdirectory is where ikiwiki keeps its state, and
-should be preserved, but not checked into revision control.
+       % mv public_html/foo /srv/web/foo.com
+       % mv foo.git /srv/git/foo.git
 
-The [[ikiwiki-makerepo]] command automates setting up a wiki in
-revision control.
-
-[[!toggle id=subversion text="Subversion"]]
-[[!toggleable id=subversion text="""
-       REPOSITORY=~/wikirepo
-       ikiwiki-makerepo svn $SRCDIR $REPOSITORY
-"""]]
-
-[[!toggle id=git text="Git"]]
-[[!toggleable id=git text="""
-       REPOSITORY=~/wiki.git
-       ikiwiki-makerepo git $SRCDIR $REPOSITORY
-
-Please see [[rcs/git]] for detailed documentation about how
-ikiwiki uses git repositories, and some important caveats
-about using the git repositories.
-"""]]
-
-[[!toggle id=mercurial text="Mercurial"]]
-[[!toggleable id=mercurial text="""
-       REPOSITORY=$SRCDIR
-       ikiwiki-makerepo mercurial $SRCDIR
-"""]]
-
-[[!toggle id=bazaar text="Bazaar"]]
-[[!toggleable id=bazaar text="""
-       REPOSITORY=$SRCDIR
-       ikiwiki-makerepo bzr $SRCDIR
-"""]]
-
-[[!toggle id=tla text="TLA"]]
-[[!toggleable id=tla text="""
-       REPOSITORY=~/wikirepo
-       tla make-archive me@localhost--wiki $REPOSITORY
-       tla my-id "<me@localhost>"
-       cd $SRCDIR
-       tla archive-setup me@localhost--wiki/wiki--0
-       tla init-tree me@localhost--wiki/wiki--0
-       # Edit {arch}/=tagging-method and change the precious
-       # line to add the .ikiwiki directory to the regexp.
-       tla add *
-       tla import
-"""]]
-
-[[!toggle id=monotone text="Monotone"]]
-[[!toggleable id=monotone text="""
-       # This assumes that you have already used "mtn genkey you@hostname".
-       REPOSITORY=~/wiki.monotone
-       ikiwiki-makerepo monotone $SRCDIR $REPOSITORY
-"""]]
+If you moved the repository to a new location, checkouts pointing at the
+old location won't work, and the easiest way to deal with this is to delete
+them and re-checkout from the new repository location.
+   
+       % rm -rf foo
+       % git clone /src/git/foo.git
 
-## Configure ikiwiki to use revision control.
-
-Once your wiki is checked in to the revision control system, you should
-configure ikiwiki to use revision control. Edit your ikiwiki.setup, set
-`rcs` to the the revision control system you chose to use. Be sure to set
-`svnrepo` to the directory for your repository, if using subversion.
-Uncomment the configuration for the wrapper for your revision control
-system, and configure the wrapper path appropriately (for Git, it should be
-the path to `hooks/post-update` inside the bare git repository).
-
-Once it's all set up, run `ikiwiki --setup ikiwiki.setup` once more.
-Now you should be able to edit files in $SRCDIR, and use your revision
-control system to commit them, and the wiki will automatically update.
-And in the web interface, RecentChanges should work, and files changed
-by web users will also be committed using revision control.
+Finally, edit the setup file. Modify the settings for `srcdir`, `destdir`,
+`url`, `cgiurl`, `cgi_wrapper`, `git_wrapper`, etc to reflect where
+you moved things. Remember to run `ikiwiki -setup` after editing the
+setup file.
 
 ## Enjoy your new wiki!
 
diff --git a/doc/setup/byhand.mdwn b/doc/setup/byhand.mdwn
new file mode 100644 (file)
index 0000000..0184d3d
--- /dev/null
@@ -0,0 +1,190 @@
+This tutorial will walk you through setting up a wiki with ikiwiki,
+doing everything by hand. [[Setup]] has an easier method, but with less
+control.
+
+[[!toc ]]
+
+## Decide where your wiki's files will go.
+
+As a wiki compiler, ikiwiki builds a wiki from files in a source directory,
+and outputs the files to a destination directory.  If you keep your wiki in
+a version control system, the source directory will contain a working copy
+checked out from the version control system.
+
+For the purposes of this tutorial, we'll set shell variables
+for these locations, and use those variables in the commands that follow.
+
+       SRCDIR=~/wikiwc
+       DESTDIR=~/public_html/wiki/
+
+Note that ikiwiki owns the working copy directory; do not perform your own
+edits in ikiwiki's working copy.
+
+## Create the beginnings of your wiki.
+
+This will create a simple main page for the wiki.
+
+       mkdir $SRCDIR
+       cd $SRCDIR
+       $EDITOR index.mdwn
+
+In the editor, you could start by entering a simple page like
+[[!toggle id=page text="this one"]].
+[[!toggleable id=page text="""
+       Welcome to your new wiki.
+
+       All wikis are supposed to have a \[[SandBox]],
+       so this one does too.
+
+       ----
+
+       This wiki is powered by [ikiwiki](http://ikiwiki.info).
+"""]]
+   
+See [[ikiwiki/formatting]] for details about the markup language.
+
+Note that several [[standard_wiki_pages|basewiki]] will be added to your
+wiki, from files in `/usr/share/ikiwiki/basewiki/`, so your wiki will
+automatically get a [[SandBox]], and some other useful pages.
+
+## Build your wiki for the first time.
+
+       ikiwiki --verbose $SRCDIR $DESTDIR --url=http://example.org/~you/wiki/
+
+Replace the url with the real url to your wiki. You should now
+be able to visit the url and see your wiki.
+
+## Add content to your wiki.
+
+Continue editing or adding pages and rebuilding the wiki.
+   
+To quickly get started on a common task like blogging with ikiwiki, you
+can copy in files from the [[examples]]. The examples are located in
+`doc/examples/` in the ikiwiki source package.
+
+You can experiment with other ikiwiki parameters such as `--wikiname`
+and `--rebuild` too. Get comfortable with its command line (see
+[[usage]]).
+
+## Add a setup file.
+
+By now you should be getting tired of typing in all the command line
+options each time you change something in your wiki's setup. Time to
+introduce setup files.
+
+To generate a setup file, use `ikiwiki --dumpsetup`. You can pass
+all the options have you been including at the command line, and they
+will be stored in the setup file.
+
+       ikiwiki $SRCDIR $DESTDIR --url=http://example.org/~you/wiki/ --dumpsetup ikiwiki.setup
+
+Note that this file should *not* be put in your wiki's directory with
+the rest of the files. A good place to put it is in a ~/.ikiwiki/
+subdirectory.
+   
+Most of the options, like `wikiname` in the setup file are the same as
+ikiwiki's command line options (documented in [[usage]]. `srcdir` and
+`destdir` are the two directories you specify when running ikiwiki by
+hand. Make sure that these are pointing to the right directories, and
+read through and configure the rest of the file to your liking.
+
+When you're satisfied, run `ikiwiki --setup ikiwiki.setup`, and it
+will set everything up.
+
+## Turn on additional features.
+
+Now you have a basic wiki with a setup file. Time to experiment
+with ikiwiki's many features. 
+   
+Let's first enable a key wiki feature and set up [[CGI]] to allow
+editing the wiki from the web. Just edit ikiwiki.setup, uncomment the
+settings for the `cgi_wrapper`, make sure the filename for the cgi wrapper
+is ok, run `ikiwiki --setup ikiwiki.setup`, and you're done!
+
+There are lots of other configuration options in ikiwiki.setup that you
+can uncomment, configure, and enable by re-running
+`ikiwiki --setup ikiwiki.setup`. Be sure to browse through all the
+[[plugins]]..
+
+## Put your wiki in revision control.
+
+At this point you might want to check your wiki in to a revision control
+system so you can keep track of changes and revert edits. Depending
+on the revision control system you choose, the way this is done varies.
+
+Note that the .ikiwiki subdirectory is where ikiwiki keeps its state, and
+should be preserved, but not checked into revision control.
+
+The [[ikiwiki-makerepo]] command automates setting up a wiki in
+revision control.
+
+[[!toggle id=subversion text="Subversion"]]
+[[!toggleable id=subversion text="""
+       REPOSITORY=~/wikirepo
+       ikiwiki-makerepo svn $SRCDIR $REPOSITORY
+"""]]
+
+[[!toggle id=git text="Git"]]
+[[!toggleable id=git text="""
+       REPOSITORY=~/wiki.git
+       ikiwiki-makerepo git $SRCDIR $REPOSITORY
+
+Please see [[rcs/git]] for detailed documentation about how
+ikiwiki uses git repositories, and some important caveats
+about using the git repositories.
+"""]]
+
+[[!toggle id=mercurial text="Mercurial"]]
+[[!toggleable id=mercurial text="""
+       REPOSITORY=$SRCDIR
+       ikiwiki-makerepo mercurial $SRCDIR
+"""]]
+
+[[!toggle id=bazaar text="Bazaar"]]
+[[!toggleable id=bazaar text="""
+       REPOSITORY=$SRCDIR
+       ikiwiki-makerepo bzr $SRCDIR
+"""]]
+
+[[!toggle id=tla text="TLA"]]
+[[!toggleable id=tla text="""
+       REPOSITORY=~/wikirepo
+       tla make-archive me@localhost--wiki $REPOSITORY
+       tla my-id "<me@localhost>"
+       cd $SRCDIR
+       tla archive-setup me@localhost--wiki/wiki--0
+       tla init-tree me@localhost--wiki/wiki--0
+       # Edit {arch}/=tagging-method and change the precious
+       # line to add the .ikiwiki directory to the regexp.
+       tla add *
+       tla import
+"""]]
+
+[[!toggle id=monotone text="Monotone"]]
+[[!toggleable id=monotone text="""
+       # This assumes that you have already used "mtn genkey you@hostname".
+       REPOSITORY=~/wiki.monotone
+       ikiwiki-makerepo monotone $SRCDIR $REPOSITORY
+"""]]
+
+## Configure ikiwiki to use revision control.
+
+Once your wiki is checked in to the revision control system, you should
+configure ikiwiki to use revision control. Edit your ikiwiki.setup, set
+`rcs` to the the revision control system you chose to use.  Be careful, 
+you may need to use the 'fullname'.  For example, 'hg' doesn't work, you
+should use mercurial.  Be sure to set `svnrepo` to the directory for your
+repository, if using subversion. Uncomment the configuration for the wrapper
+for your revision control system, and configure the wrapper path appropriately 
+(for Git, it should be the path to `hooks/post-update` inside the bare git repository).
+
+Once it's all set up, run `ikiwiki --setup ikiwiki.setup` once more.
+Now you should be able to edit files in $SRCDIR, and use your revision
+control system to commit them, and the wiki will automatically update.
+And in the web interface, RecentChanges should work, and files changed
+by web users will also be committed using revision control.
+
+## Enjoy your new wiki!
+
+Add yourself to [[IkiWikiUsers]]. And check out
+the [[tips]] to find out how to get more out of ikiwiki.
index 7d8c525e767f1cd6e38f74c515e7bb843451fdb8..89114d7a2c159ef7df3513db092fe84841e1fe51 100644 (file)
@@ -138,3 +138,30 @@ Thanks for your response. You're right. Ubuntu does have ikiwiki, except that it
 Anyway, I think I might be able to install it from the tarball I downloaded. I've been reading the discussions, had a look at your screencasts, etc. I will give it another bash. -- [[WillDioneda]]
 
 ----
+
+How do I set up cgi editing?  In setup I have:
+
+ * cgiurl => 'http://wiki.had.co.nz/edit.cgi'
+ * cgi_wrapper => 'edit.cgi'
+
+But I don't get an edit link on my pages?  What am I doing wrong?
+
+> Assuming you don't have the editpage plugin disabled, all you should need
+> to so is re-run `ikiwiki -setup` with the above config and it should
+> rebuild your wiki and add the edit links to pages. --[[Joey]]
+
+----
+
+I setup ikiwiki on a fedora 10 machine and I am using apache as my http server. Faced a few difficulties while setting it up as the default setup program left some suid files and group writeable directories on the system. It took some time to get it working and documented what I did at http://flyingtux.blogspot.com/2009/03/installing-ikiwiki.html. Thought it might be useful to someone here. (The version installed is 2.72)
+
+> ikiwiki makes wrappers suid by default, because this ensures that when
+> the ikiwiki.cgi is run by your web server, it runs as the user who owns
+> your wiki, and can thus write to it. ikiwiki is designed to run securely
+> suid. If your webserver uses some
+> mechanism to run the ikiwiki.cgi as the user who owns it, without the
+> suid bit being set, you *could* modify `cgi_wrappermode` in your setup
+> file to drop the suid bit. 
+> 
+> ikiwiki respects the umask, so if your umask is one that causes things to
+> be group writable, they will by. If you want to override that, there is
+> also a `umask        ` setting in your setup file. --[[Joey]] 
index 5787ef65e46096e763f3d3f522b5ea3f14b41933..98a28f34769d34d43feb2a8d73f37fddd10442be 100644 (file)
@@ -12,7 +12,7 @@
        display: block;
 }
 
-.author {
+.inlineheader .author {
        margin: 0;
        font-size: 18px;
        font-weight: bold;
@@ -23,6 +23,8 @@
        margin: 0;
        padding: 6px;
        list-style-type: none;
+}
+.pageheader .actions ul {
        border-bottom: 1px solid #000;
 }
 
@@ -42,6 +44,9 @@ div.inlinecontent {
 .pagefooter {
        clear: both;
 }
+.inlinefooter {
+       clear: both;
+}
 
 .tags {
 }
@@ -339,11 +344,6 @@ input#searchbox {
        border: 2px solid;
        background-color: #dee;
        color: black;
-       
-       /* Nonstandard, but very nice. */
-       opacity: 0.95;
-       -moz-opacity: 0.95;
-       filter: alpha(opacity=95);
 }
 
 /* Formbuilder styling */
@@ -372,3 +372,18 @@ legend {
 span.color {
        padding: 2px;
 }
+
+.comment-header {
+       font-style: italic;
+       margin-top: .3em;
+}
+.comment .author {
+       font-weight: bold;
+}
+.comment-subject {
+       font-weight: bold;
+}
+.comment {
+       border: 1px solid #aaa;
+       padding: 3px;
+}
index 6670f80906652e76d5c3d09cc6bff9475e1908f5..070638e3e41a947f5717f92f26365459cd673bb9 100644 (file)
@@ -150,6 +150,8 @@ Next, add your installed Perl module directory to the *libdir* parameter.  It sh
         libdir => "/home/.server/user/site/perl/lib/perl5/",
 
 # CGI Wrapper
+The CGI wrapper file will be created automatically by "ikiwiki --setup path/to/setup", as long as you have inserted a valid filename to be created into the setup file.  On DreamHost, be careful not to put the ikiwiki.cgi file in a directory that has different owner/group than the file itself (such as the main site.domain.tld/ directory): this will cause suexec to fail.
+
 The wrapper mode of "06755" doesn't seem to work.  "755" appears to.  However, this may be completely insecure and/or buggy, so if you know better than I, edit this doc and add it here.
 
 # Pre-created SVN repository
diff --git a/doc/tips/Git_repository_and_web_server_on_different_hosts.mdwn b/doc/tips/Git_repository_and_web_server_on_different_hosts.mdwn
new file mode 100644 (file)
index 0000000..58940b8
--- /dev/null
@@ -0,0 +1,61 @@
+One may want to provide ikiwiki hosting with [[rcs/git]]+ssh access and web
+server located at different hosts. Here's a description for such
+a setup, using password-less SSH as a way of communication between
+these two hosts.
+
+Git server
+==========
+
+Let's create a user called `ikiwiki_example`. This user gets SSH
+access restricted to GIT pull/push, using `git-shell` as a shell.
+
+The root (bare) repository:
+
+- is stored in `~ikiwki_example/ikiwiki_example.git`
+- is owned by `ikiwiki_example:ikiwiki_example`
+- has permissions 0700
+
+The master repository's post-update hook connects via SSH to
+`webserver` as user `ikiwiki_example`, in order to run
+`~/bin/ikiwiki.update` on `webserver`; this post-update hook, located
+in `~ikiwki_example/ikiwiki_example.git/hooks/post-update`, is
+executable and contains:
+
+       #!/bin/sh
+       /usr/bin/ssh ikiwiki_example@webserver bin/ikiwiki.update
+
+Password-less SSH must be setup to make this possible; one can
+restrict `gitserver:ikiwiki_example` to be able to run only the needed
+command on the web server, using such a line in
+`webserver:~ikiwiki_example/.ssh/authorized_keys`:
+
+       command="bin/ikiwiki.update",from="gitserver.example.com",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ...
+
+Web server
+==========
+
+Let's create a user called `ikiwiki_example` on `webserver`. She needs
+to have write permission to the destination directory.
+
+The working tree repository (`srcdir`):
+
+- is stored in `~ikiwki_example/src`
+- is owned by `ikiwiki_example:ikiwiki_example`
+- has permissions 0700
+- has the following origin: `ikiwiki_example@gitserver:ikiwiki_example.git`
+
+The CGI wrapper is generated with ownership set to
+`ikiwiki_example:ikiwiki_example` and permissions `06755`.
+
+Password-less SSH must be setup so that `ikiwiki_example@webserver` is
+allowed to push to the master repository. As told earlier, SSH access
+to `ikiwiki_example@gitserver` is restricted to GIT pull/push, which
+is just what we need.
+
+The Git wrapper is generated in `~ikiwiki_example/bin/ikiwiki.update`:
+
+       git_wrapper => '/home/ikiwiki_example/bin/ikiwiki.update'
+
+As previously explained, this wrapper is run over SSH by the master
+repository's post-update hook; it pulls updates from the master
+repository and triggers a wiki refresh.
index 7e8ac951c9055262d97270ed1f8ebfc8c6732f34..1093029f55659cb47f5b1c31699b79092410bb75 100644 (file)
@@ -5,3 +5,8 @@ Instead of the [[plugins/search]] plugin you could embed [Google Custom Search](
 Once you've created your "custom search engine", just drop in the search box html like I've done in my [Debian tips and tricks](http://dabase.com/tips/) [source](http://git.webconverger.org/?p=faq.git;a=blob;f=tips.mdwn).
 
 If you have odd "save failed" error messages in Google's CSE's control panel, try `/usr/lib/WebKit/GtkLauncher` from [webkit](http://packages.qa.debian.org/w/webkit.html).
+
+
+# Alternatively
+
+You could use the [[Google_plugin|plugins/google]] from version 2.67.
diff --git a/doc/tips/apache_cgi.mdwn b/doc/tips/apache_cgi.mdwn
deleted file mode 100644 (file)
index f10baed..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-Many ikiwiki examples name the [[cgi]] "ikiwiki.cgi", and put it somewhere
-like `~/public_html/ikiwiki.cgi`, or `/var/www/wiki/ikiwiki.cgi`.
-
-If you follow those examples, you may find that when trying to edit a page
-in your wiki, you see the raw contents of the ikiwiki.cgi program. Or get a
-permission denied problem.
-
-This is because apache is generally not configured to run cgi scripts
-unless they're in `/usr/lib/cgi-bin/`. While you can put ikiwiki.cgi in
-there if you like, here's how to configure apache (version 2) to run `.cgi`
-programs from anywhere.
-
-These instructions are for Debian systems, but the basic apache
-configuration should work anywhere.
-
-* Edit /etc/apache2/apache2.conf and add a line like this:
-
-       AddHandler cgi-script .cgi
-
-* Find the "Options" line for the directory where you've put the
-  ikiwiki.cgi, and add "ExecCGI" to the list of options. For example, if
-  ikiwiki.cgi is in /var/www/, edit `/etc/apache2/sites-enabled/000-default`
-  and add it to the "Options" line in the "Directory /var/www/" stanza.
-  Or, if you've put it in a `~/public_html`, edit
-  `/etc/apache2/mods-available/userdir.conf`.
diff --git a/doc/tips/comments_feed.mdwn b/doc/tips/comments_feed.mdwn
new file mode 100644 (file)
index 0000000..6f81372
--- /dev/null
@@ -0,0 +1,10 @@
+You've enabled the [[plugins/comments]] plugin, so a set of pages on your
+blog can have comments added to them. Pages with comments even have special
+feeds that can be used to subscribe to those comments. But you'd like to
+add a feed that contains all the comments posted to any page. Here's how:
+
+       \[[!inline pages="internal(*/comment_*)" template=comment]]
+
+The special [[ikiwiki/PageSpec]] matches all comments. The
+[[template|wikitemplates]] causes the comments to be displayed formatted
+nicely.
diff --git a/doc/tips/convert_MoinMoin_and_TWiki_to_ikiwiki.mdwn b/doc/tips/convert_MoinMoin_and_TWiki_to_ikiwiki.mdwn
new file mode 100644 (file)
index 0000000..5565dbd
--- /dev/null
@@ -0,0 +1,3 @@
+[[JoshTriplett]] has developed scripts to convert MoinMoin and TWiki wikis
+to ikiwikis backed by a git repository, including full history. For
+details, see [[his_user_page|JoshTriplett]].
diff --git a/doc/tips/convert_mediawiki_to_ikiwiki.mdwn b/doc/tips/convert_mediawiki_to_ikiwiki.mdwn
new file mode 100644 (file)
index 0000000..f03703b
--- /dev/null
@@ -0,0 +1,4 @@
+[[sabr]] explains how to [import MediaWiki content into
+git](http://u32.net/Mediawiki_Conversion/index.html?updated), including
+full edit hostory. The [[plugins/contrib/mediawiki]] plugin can then be
+used by ikiwiki to build the wiki.
diff --git a/doc/tips/convert_mediawiki_to_ikiwiki/discussion.mdwn b/doc/tips/convert_mediawiki_to_ikiwiki/discussion.mdwn
new file mode 100644 (file)
index 0000000..15ddccb
--- /dev/null
@@ -0,0 +1,612 @@
+The u32 page is excellent, but I wonder if documenting the procedure here
+would be worthwhile. Who knows, the remote site might disappear. But also
+there are some variations on the approach that might be useful:
+
+ * using a python script and the dom library to extract the page names from
+   Special:Allpages (such as
+   <http://www.staff.ncl.ac.uk/jon.dowland/unix/docs/get_pagenames.py>)
+ * Or, querying the mysql back-end to get the names
+ * using WWW::MediaWiki for importing/exporting pages from the wiki, instead
+   of Special::Export
+
+Also, some detail on converting mediawiki transclusion to ikiwiki inlines...
+
+-- [[users/Jon]]
+
+> "Who knows, the remote site might disappear.". Right now, it appears to
+> have done just that. -- [[users/Jon]]
+
+
+The iki-fast-load ruby script from the u32 page is given below:
+
+        #!/usr/bin/env ruby
+
+        # This script is called on the final sorted, de-spammed revision
+        # XML file.
+        #
+        # It doesn't currently check for no-op revisions...  I believe
+        # that git-fast-load will dutifully load them even though nothing
+        # happened.  I don't care to solve this by adding a file cache
+        # to this script.  You can run iki-diff-next.rb to highlight any
+        # empty revisions that need to be removed.
+        #
+        # This turns each node into an equivalent file.
+        #    It does not convert spaces to underscores in file names.
+        #       This would break wikilinks.
+        #       I suppose you could fix this with mod_speling or mod_rewrite.
+        #
+        # It replaces nodes in the Image: namespace with the files themselves.
+
+
+        require 'rubygems'
+        require 'node-callback'
+        require 'time'
+        require 'ostruct'
+
+
+        # pipe is the stream to receive the git-fast-import commands
+        # putfrom is true if this branch has existing commits on it, false if not.
+        def format_git_commit(pipe, f)
+           # Need to escape backslashes and double-quotes for git?
+           # No, git breaks when I do this. 
+           # For the filename "path with \\", git sez: bad default revision 'HEAD'
+           # filename = '"' + filename.gsub('\\', '\\\\\\\\').gsub('"', '\\"') + '"'
+
+           # In the calls below, length must be the size in bytes!!
+           # TODO: I haven't figured out how this works in the land of UTF8 and Ruby 1.9.
+           pipe.puts "commit #{f.branch}"
+           pipe.puts "committer #{f.username} <#{f.email}> #{f.timestamp.rfc2822}"
+           pipe.puts "data #{f.message.length}\n#{f.message}\n"
+           pipe.puts "from #{f.branch}^0" if f.putfrom
+           pipe.puts "M 644 inline #{f.filename}"
+           pipe.puts "data #{f.content.length}\n#{f.content}\n"
+           pipe.puts
+        end
+
+
+Mediawiki.pm - A plugin which supports mediawiki format.
+
+       #!/usr/bin/perl
+       # By Scott Bronson.  Licensed under the GPLv2+ License.
+       # Extends Ikiwiki to be able to handle Mediawiki markup.
+       #
+       # To use the Mediawiki Plugin:
+       # - Install Text::MediawikiFormat
+       # - Turn of prefix_directives in your setup file.
+       #     (TODO: we probably don't need to do this anymore?)
+       #        prefix_directives => 1,
+       # - Add this plugin on Ikiwiki's path (perl -V, look for @INC)
+       #       cp mediawiki.pm something/IkiWiki/Plugin
+       # - And enable it in your setup file
+       #        add_plugins => [qw{mediawiki}],
+       # - Finally, turn off the link plugin in setup (this is important)
+       #        disable_plugins => [qw{link}],
+       # - Rebuild everything (actually, this should be automatic right?)
+       # - Now all files with a .mediawiki extension should be rendered properly.
+       
+       
+       package IkiWiki::Plugin::mediawiki;
+       
+       use warnings;
+       use strict;
+       use IkiWiki 2.00;
+       use URI;
+       
+       
+       # This is a gross hack...  We disable the link plugin so that our
+       # linkify routine is always called.  Then we call the link plugin
+       # directly for all non-mediawiki pages.  Ouch...  Hopefully Ikiwiki
+       # will be updated soon to support multiple link plugins.
+       require IkiWiki::Plugin::link;
+       
+       # Even if T:MwF is not installed, we can still handle all the linking.
+       # The user will just see Mediawiki markup rather than formatted markup.
+       eval q{use Text::MediawikiFormat ()};
+       my $markup_disabled = $@;
+       
+       # Work around a UTF8 bug in Text::MediawikiFormat
+       # http://rt.cpan.org/Public/Bug/Display.html?id=26880
+       unless($markup_disabled) {
+          no strict 'refs';
+          no warnings;
+          *{'Text::MediawikiFormat::uri_escape'} = \&URI::Escape::uri_escape_utf8;
+       }
+       
+       my %metaheaders;    # keeps track of redirects for pagetemplate.
+       my %tags;      # keeps track of tags for pagetemplate.
+       
+       
+       sub import { #{{{
+          hook(type => "checkconfig", id => "mediawiki", call => \&checkconfig);
+          hook(type => "scan", id => "mediawiki", call => \&scan);
+          hook(type => "linkify", id => "mediawiki", call => \&linkify);
+          hook(type => "htmlize", id => "mediawiki", call => \&htmlize);
+          hook(type => "pagetemplate", id => "mediawiki", call => \&pagetemplate);
+       } # }}}
+       
+       
+       sub checkconfig
+       {
+          return IkiWiki::Plugin::link::checkconfig(@_);
+       }
+       
+       
+       my $link_regexp = qr{
+           \[\[(?=[^!])        # beginning of link
+           ([^\n\r\]#|<>]+)      # 1: page to link to
+           (?:
+               \#              # '#', beginning of anchor
+               ([^|\]]+)       # 2: anchor text
+           )?                  # optional
+       
+           (?:
+               \|              # followed by '|'
+               ([^\]\|]*)      # 3: link text
+           )?                  # optional
+           \]\]                # end of link
+               ([a-zA-Z]*)   # optional trailing alphas
+       }x;
+       
+       
+       # Convert spaces in the passed-in string into underscores.
+       # If passed in undef, returns undef without throwing errors.
+       sub underscorize
+       {
+          my $var = shift;
+          $var =~ tr{ }{_} if $var;
+          return $var;
+       }
+       
+       
+       # Underscorize, strip leading and trailing space, and scrunch
+       # multiple runs of spaces into one underscore.
+       sub scrunch
+       {
+          my $var = shift;
+          if($var) {
+             $var =~ s/^\s+|\s+$//g;      # strip leading and trailing space
+             $var =~ s/\s+/ /g;      # squash multiple spaces to one
+          }
+          return $var;
+       }
+       
+       
+       # Translates Mediawiki paths into Ikiwiki paths.
+       # It needs to be pretty careful because Mediawiki and Ikiwiki handle
+       # relative vs. absolute exactly opposite from each other.
+       sub translate_path
+       {
+          my $page = shift;
+          my $path = scrunch(shift);
+       
+          # always start from root unless we're doing relative shenanigans.
+          $page = "/" unless $path =~ /^(?:\/|\.\.)/;
+       
+          my @result = ();
+          for(split(/\//, "$page/$path")) {
+             if($_ eq '..') {
+                pop @result;
+             } else {
+                push @result, $_ if $_ ne "";
+             }
+          }
+       
+          # temporary hack working around http://ikiwiki.info/bugs/Can__39__t_create_root_page/index.html?updated
+          # put this back the way it was once this bug is fixed upstream.
+          # This is actually a major problem because now Mediawiki pages can't link from /Git/git-svn to /git-svn.  And upstream appears to be uninterested in fixing this bug.  :(
+          # return "/" . join("/", @result);
+          return join("/", @result);
+       }
+       
+       
+       # Figures out the human-readable text for a wikilink
+       sub linktext
+       {
+          my($page, $inlink, $anchor, $title, $trailing) = @_;
+          my $link = translate_path($page,$inlink);
+       
+          # translate_path always produces an absolute link.
+          # get rid of the leading slash before we display this link.
+          $link =~ s#^/##;
+       
+          my $out = "";
+          if($title) {
+              $out = IkiWiki::pagetitle($title);
+          } else {
+             $link = $inlink if $inlink =~ /^\s*\//;
+              $out = $anchor ? "$link#$anchor" : $link;
+             if(defined $title && $title eq "") {
+                # a bare pipe appeared in the link...
+                # user wants to strip namespace and trailing parens.
+                $out =~ s/^[A-Za-z0-9_-]*://;
+                $out =~ s/\s*\(.*\)\s*$//;
+             }
+             # A trailing slash suppresses the leading slash
+             $out =~ s#^/(.*)/$#$1#;
+          }
+          $out .= $trailing if defined $trailing;
+          return $out;
+       }
+       
+       
+       sub tagpage ($)
+       {
+          my $tag=shift;
+       
+          if (exists $config{tagbase} && defined $config{tagbase}) {
+             $tag=$config{tagbase}."/".$tag;
+          }
+       
+          return $tag;
+       }
+       
+       
+       # Pass a URL and optional text associated with it.  This call turns
+       # it into fully-formatted HTML the same way Mediawiki would.
+       # Counter is used to number untitled links sequentially on the page.
+       # It should be set to 1 when you start parsing a new page.  This call
+       # increments it automatically.
+       sub generate_external_link
+       {
+          my $url = shift;
+          my $text = shift;
+          my $counter = shift;
+       
+          # Mediawiki trims off trailing commas.
+          # And apparently it does entity substitution first.
+          # Since we can't, we'll fake it.
+       
+          # trim any leading and trailing whitespace
+          $url =~ s/^\s+|\s+$//g;
+       
+          # url properly terminates on > but must special-case &gt;
+          my $trailer = "";
+          $url =~ s{(\&(?:gt|lt)\;.*)$}{ $trailer = $1, ''; }eg;
+       
+          # Trim some potential trailing chars, put them outside the link.
+          my $tmptrail = "";
+          $url =~ s{([,)]+)$}{ $tmptrail .= $1, ''; }eg;
+          $trailer = $tmptrail . $trailer;
+       
+          my $title = $url;
+          if(defined $text) {
+             if($text eq "") {
+                $text = "[$$counter]";
+                $$counter += 1;
+             }
+             $text =~ s/^\s+|\s+$//g;
+             $text =~ s/^\|//;
+          } else {
+             $text = $url;
+          }
+       
+          return "<a href='$url' title='$title'>$text</a>$trailer";
+       }
+       
+       
+       # Called to handle bookmarks like [[#heading]] or <span class="createlink"><a href="http://u32.net/cgi-bin/ikiwiki.cgi?page=%20text%20&amp;from=Mediawiki_Plugin%2Fmediawiki&amp;do=create" rel="nofollow">?</a>#a</span>
+       sub generate_fragment_link
+       {
+          my $url = shift;
+          my $text = shift;
+       
+          my $inurl = $url;
+          my $intext = $text;
+          $url = scrunch($url);
+       
+          if(defined($text) && $text ne "") {
+             $text = scrunch($text);
+          } else {
+             $text = $url;
+          }
+       
+          $url = underscorize($url);
+       
+          # For some reason Mediawiki puts blank titles on all its fragment links.
+          # I don't see why we would duplicate that behavior here.
+          return "<a href='$url'>$text</a>";
+       }
+       
+       
+       sub generate_internal_link
+       {
+          my($page, $inlink, $anchor, $title, $trailing, $proc) = @_;
+       
+          # Ikiwiki's link link plugin wrecks this line when displaying on the site.
+          # Until the code highlighter plugin can turn off link finding,
+          # always escape double brackets in double quotes: [[
+          if($inlink eq '..') {
+             # Mediawiki doesn't touch links like [[..#hi|ho]].
+             return "[[" . $inlink . ($anchor?"#$anchor":"") .
+                ($title?"|$title":"") . "]]" . $trailing;
+          }
+       
+          my($linkpage, $linktext);
+          if($inlink =~ /^ (:?) \s* Category (\s* \: \s*) ([^\]]*) $/x) {
+             # Handle category links
+             my $sep = $2;
+             $inlink = $3;
+             $linkpage = IkiWiki::linkpage(translate_path($page, $inlink));
+             if($1) {
+                # Produce a link but don't add this page to the given category.
+                $linkpage = tagpage($linkpage);
+                $linktext = ($title ? '' : "Category$sep") .
+                   linktext($page, $inlink, $anchor, $title, $trailing);
+                $tags{$page}{$linkpage} = 1;
+             } else {
+                # Add this page to the given category but don't produce a link.
+                $tags{$page}{$linkpage} = 1;
+                &$proc(tagpage($linkpage), $linktext, $anchor);
+                return "";
+             }
+          } else {
+             # It's just a regular link
+             $linkpage = IkiWiki::linkpage(translate_path($page, $inlink));
+             $linktext = linktext($page, $inlink, $anchor, $title, $trailing);
+          }
+       
+          return &$proc($linkpage, $linktext, $anchor);
+       }
+       
+       
+       sub check_redirect
+       {
+          my %params=@_;
+       
+          my $page=$params{page};
+          my $destpage=$params{destpage};
+          my $content=$params{content};
+       
+          return "" if $page ne $destpage;
+       
+          if($content !~ /^ \s* \#REDIRECT \s* \[\[ ( [^\]]+ ) \]\]/x) {
+             # this page isn't a redirect, render it normally.
+             return undef;
+          }
+       
+          # The rest of this function is copied from the redir clause
+          # in meta::preprocess and actually handles the redirect.
+       
+          my $value = $1;
+          $value =~ s/^\s+|\s+$//g;
+       
+          my $safe=0;
+          if ($value !~ /^\w+:\/\//) {
+             # it's a local link
+             my ($redir_page, $redir_anchor) = split /\#/, $value;
+       
+             add_depends($page, $redir_page);
+             my $link=bestlink($page, underscorize(translate_path($page,$redir_page)));
+             if (! length $link) {
+                return "<b>Redirect Error:</b> <nowiki>[[$redir_page]] not found.</nowiki>";
+             }
+       
+             $value=urlto($link, $page);
+             $value.='#'.$redir_anchor if defined $redir_anchor;
+             $safe=1;
+       
+             # redir cycle detection
+             $pagestate{$page}{mediawiki}{redir}=$link;
+             my $at=$page;
+             my %seen;
+             while (exists $pagestate{$at}{mediawiki}{redir}) {
+                if ($seen{$at}) {
+                   return "<b>Redirect Error:</b> cycle found on <nowiki>[[$at]]</nowiki>";
+                }
+                $seen{$at}=1;
+                $at=$pagestate{$at}{mediawiki}{redir};
+             }
+          } else {
+             # it's an external link
+             $value = encode_entities($value);
+          }
+       
+          my $redir="<meta http-equiv=\"refresh\" content=\"0; URL=$value\" />";
+          $redir=scrub($redir) if !$safe;
+          push @{$metaheaders{$page}}, $redir;
+       
+          return "Redirecting to $value ...";
+       }
+       
+       
+       # Feed this routine a string containing <nowiki>...</nowiki> sections,
+       # this routine calls your callback for every section not within nowikis,
+       # collecting its return values and returning the rewritten string.
+       sub skip_nowiki
+       {
+          my $content = shift;
+          my $proc = shift;
+       
+          my $result = "";
+          my $state = 0;
+       
+          for(split(/(<nowiki[^>]*>.*?<\/nowiki\s*>)/s, $content)) {
+             $result .= ($state ? $_ : &$proc($_));
+             $state = !$state;
+          }
+       
+          return $result;
+       }
+       
+       
+       # Converts all links in the page, wiki and otherwise.
+       sub linkify (@)
+       {
+          my %params=@_;
+       
+          my $page=$params{page};
+          my $destpage=$params{destpage};
+          my $content=$params{content};
+       
+          my $file=$pagesources{$page};
+          my $type=pagetype($file);
+          my $counter = 1;
+       
+          if($type ne 'mediawiki') {
+             return IkiWiki::Plugin::link::linkify(@_);
+          }
+       
+          my $redir = check_redirect(%params);
+          return $redir if defined $redir;
+       
+          # this code was copied from MediawikiFormat.pm.
+          # Heavily changed because MF.pm screws up escaping when it does
+          # this awful hack: $uricCheat =~ tr/://d;
+          my $schemas = [qw(http https ftp mailto gopher)];
+          my $re = join "|", map {qr/\Q$_\E/} @$schemas;
+          my $schemes = qr/(?:$re)/;
+          # And this is copied from URI:
+          my $reserved   = q(;/?@&=+$,);   # NOTE: no colon or [] !
+          my $uric       = quotemeta($reserved) . $URI::unreserved . "%#";
+       
+          my $result = skip_nowiki($content, sub {
+             $_ = shift;
+       
+             # Escape any anchors
+             #s/<(a[\s>\/])/&lt;$1/ig;
+             # Disabled because this appears to screw up the aggregate plugin.
+             # I guess we'll rely on Iki to post-sanitize this sort of stuff.
+       
+             # Replace external links, http://blah or [http://blah]
+             s{\b($schemes:[$uric][:$uric]+)|\[($schemes:[$uric][:$uric]+)([^\]]*?)\]}{
+                generate_external_link($1||$2, $3, \$counter)
+             }eg;
+       
+             # Handle links that only contain fragments.
+             s{ \[\[ \s* (\#[^|\]'"<>&;]+) (?:\| ([^\]'"<>&;]*))? \]\] }{
+                generate_fragment_link($1, $2)
+             }xeg;
+       
+             # Match all internal links
+             s{$link_regexp}{
+                generate_internal_link($page, $1, $2, $3, $4, sub {
+                   my($linkpage, $linktext, $anchor) = @_;
+                   return htmllink($page, $destpage, $linkpage,
+                      linktext => $linktext,
+                      anchor => underscorize(scrunch($anchor)));
+                });
+             }eg;
+          
+             return $_;
+          });
+       
+          return $result;
+       }
+       
+       
+       # Find all WikiLinks in the page.
+       sub scan (@)
+       {
+          my %params = @_;
+          my $page=$params{page};
+          my $content=$params{content};
+       
+          my $file=$pagesources{$page};
+          my $type=pagetype($file);
+       
+          if($type ne 'mediawiki') {
+             return IkiWiki::Plugin::link::scan(@_);
+          }
+       
+          skip_nowiki($content, sub {
+             $_ = shift;
+             while(/$link_regexp/g) {
+                generate_internal_link($page, $1, '', '', '', sub {
+                   my($linkpage, $linktext, $anchor) = @_;
+                   push @{$links{$page}}, $linkpage;
+                   return undef;
+                });
+             }
+             return '';
+          });
+       }
+       
+       
+       # Convert the page to HTML.
+       sub htmlize (@)
+       {
+          my %params=@_;
+          my $page = $params{page};
+          my $content = $params{content};
+       
+       
+          return $content if $markup_disabled;
+       
+          # Do a little preprocessing to babysit Text::MediawikiFormat
+          # If a line begins with tabs, T:MwF won't convert it into preformatted blocks.
+          $content =~ s/^\t/    /mg;
+       
+          my $ret = Text::MediawikiFormat::format($content, {
+       
+              allowed_tags    => [#HTML
+                       # MediawikiFormat default
+                       qw(b big blockquote br caption center cite code dd
+                          div dl dt em font h1 h2 h3 h4 h5 h6 hr i li ol p
+                          pre rb rp rt ruby s samp small strike strong sub
+                          sup table td th tr tt u ul var),
+                        # Mediawiki Specific
+                        qw(nowiki),
+                        # Our additions
+                        qw(del ins),   # These should have been added all along.
+                        qw(span),   # Mediawiki allows span but that's rather scary...?
+                        qw(a),      # this is unfortunate; should handle links after rendering the page.
+                      ],
+       
+              allowed_attrs   => [
+                       qw(title align lang dir width height bgcolor),
+                       qw(clear), # BR
+                       qw(noshade), # HR
+                       qw(cite), # BLOCKQUOTE, Q
+                       qw(size face color), # FONT
+                       # For various lists, mostly deprecated but safe
+                       qw(type start value compact),
+                       # Tables
+                       qw(summary width border frame rules cellspacing
+                          cellpadding valign char charoff colgroup col
+                          span abbr axis headers scope rowspan colspan),
+                       qw(id class name style), # For CSS
+                       # Our additions
+                       qw(href),
+                      ],
+       
+             }, {
+             extended => 0,
+             absolute_links => 0,
+             implicit_links => 0
+             });
+       
+          return $ret;
+       }
+       
+       
+       # This is only needed to support the check_redirect call.
+       sub pagetemplate (@)
+       {
+          my %params = @_;
+          my $page = $params{page};
+          my $destpage = $params{destpage};
+          my $template = $params{template};
+       
+          # handle metaheaders for redirects
+          if (exists $metaheaders{$page} && $template->query(name => "meta")) {
+          # avoid duplicate meta lines
+             my %seen;
+             $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
+          }
+       
+          $template->param(tags => [
+             map {
+                link => htmllink($page, $destpage, tagpage($_), rel => "tag")
+             }, sort keys %{$tags{$page}}
+          ]) if exists $tags{$page} && %{$tags{$page}} && $template->query(name => "tags");
+       
+          # It's an rss/atom template. Add any categories.
+          if ($template->query(name => "categories")) {
+             if (exists $tags{$page} && %{$tags{$page}}) {
+                $template->param(categories => [map { category => $_ },
+                   sort keys %{$tags{$page}}]);
+             }
+          }
+       }
+       
+       1
diff --git a/doc/tips/dot_cgi.mdwn b/doc/tips/dot_cgi.mdwn
new file mode 100644 (file)
index 0000000..04d7a97
--- /dev/null
@@ -0,0 +1,57 @@
+It's common to name the [[cgi]] "ikiwiki.cgi", and put it somewhere
+like `~/public_html/ikiwiki.cgi`, or `/var/www/wiki/ikiwiki.cgi`.
+
+If you do that, you may find that when trying to edit a page in your wiki,
+you see the raw contents of the ikiwiki.cgi program. Or get a permission
+denied problem.
+
+This is because web servers are generally not configured to run cgi scripts
+unless they're in `/usr/lib/cgi-bin/`. While you can put ikiwiki.cgi in
+there if you like, it's better to configure your web server to 
+run `.cgi`  programs from anywhere.
+
+These instructions are for Debian systems, but the basic
+configuration changes should work anywhere.
+
+## apache 2
+
+* Edit /etc/apache2/apache2.conf and add a line like this:
+
+       AddHandler cgi-script .cgi
+
+* Find the "Options" line for the directory where you've put the
+  ikiwiki.cgi, and add "ExecCGI" to the list of options. For example, if
+  ikiwiki.cgi is in /var/www/, edit `/etc/apache2/sites-enabled/000-default`
+  and add it to the "Options" line in the "Directory /var/www/" stanza.
+  Or, if you've put it in a `~/public_html`, edit
+  `/etc/apache2/mods-available/userdir.conf`.
+
+* You may also want to enable the [[plugins/404]] plugin.
+  To make apache use it, the apache config file will need a further
+  modification to make it use ikiwiki's CGI as the apache 404 handler.
+  Something like this, with the path adjusted to where you've put the CGI:
+
+       ErrorDocument 404 /cgi-bin/ikiwiki.cgi
+
+## lighttpd
+
+Here is how to enable cgi on [lighttpd](http://www.lighttpd.net/) and
+configure it in order to execute ikiwiki.cgi wherever it is located. 
+
+* Activate cgi by linking `/etc/lighttpd/conf-available/10-cgi.conf` into `/etc/lighttpd/conf-enabled` ([doc](http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI)). 
+
+* Create `/etc/lighttpd/conf-available/90-ikiwiki-cgi.conf` and add a line like this:
+
+    cgi.assign = ( "ikiwiki.cgi"  => "", )
+
+* Activate ikiwiki-cgi by linking `/etc/lighttpd/conf-available/90-ikiwiki-cgi.conf` into `/etc/lighttpd/conf-enabled`. 
+
+* Restart lighttpd server with something like `/etc/init.d/lighttpd restart`.
+
+Note that the first part enables cgi server wide but depending on default
+configuration, it may be not enough. The second part creates a specific
+rule that allow `ikiwiki.cgi` to be executed.
+
+**Warning:** I only use this on my development server (offline). I am not
+sure of how secure this approach is. If you have any thought about it, feel
+free to let me know.
diff --git a/doc/tips/emacs_syntax_highlighting.mdwn b/doc/tips/emacs_syntax_highlighting.mdwn
new file mode 100644 (file)
index 0000000..941cf54
--- /dev/null
@@ -0,0 +1,3 @@
+A [markdown mode](http://jblevins.org/projects/markdown-mode/) for 
+emacs can help in editing of ikiwiki
+[[ikiwiki/markdown]] files.
diff --git a/doc/tips/embedding_content.mdwn b/doc/tips/embedding_content.mdwn
new file mode 100644 (file)
index 0000000..142acd1
--- /dev/null
@@ -0,0 +1,35 @@
+Content from sites such as YouTube can be embedded into a web page. Maybe
+you want to do this. But you'll find that the [[plugins/htmlscrubber]]
+doesn't let you. It blocks the tags used to embed such content, because
+they can be abused in many evil ways.
+
+Some plugins have been written to try to work around this problem, by
+whitelisting the html needed to embed things from a few sites like Google
+maps, calendar, videos, and YouTube. The problem with these plugins is that
+they have to be kept up to date to add new sites, and follow changes to the
+html such sites use for embedding.
+
+(Digression: The real problem with the plugins is that they hide the
+underlying trust relationship. If you decide to embed html from a site,
+you'd better trust that site. And if ikiwiki lets you enter such html, it
+needs to trust you.)
+
+The [[plugins/htmlscrubber]] offers a different way around this problem.
+You can configure it to skip scrubbing certian pages, so that content from
+elsewhere can be embedded on those pages. Then use [[plugins/lockedit]]
+to limit who can edit those unscrubbed pages.
+
+For example, suppose your blog is all under `blog/*`, and you want
+only yourself to be able to post there, and you'd like to be able to embed
+youtube videos etc in your blog. Other users can edit some pages in the
+wiki (Discussion pages, say), but not your blog posts. Then you could configure
+ikiwiki as follows:
+
+       htmlscrubber_skip => 'blog/* and !*/Discussion',
+       locked_pages => '!*/Discussion',
+
+More simply, you might want to allow yourself to embed content anywhere
+on the wiki, but scrub content written on Discussion pages:
+       
+       htmlscrubber_skip => '!*/Discussion',
+       locked_pages => '!*/Discussion',
diff --git a/doc/tips/github.mdwn b/doc/tips/github.mdwn
new file mode 100644 (file)
index 0000000..c3fdab7
--- /dev/null
@@ -0,0 +1,64 @@
+Here's how to set up a static wiki or blog using ikiwiki with no hosting
+fees. Everything is hosted on github, both the git repository and the web
+site. Your laptop is used to generate and publish changes to it.
+
+This is possible because github now supports
+[github pages](http://github.com/blog/272-github-pages).
+
+Note that github limits free accounts to 100 mb of git storage. It's
+unlikely that a small wiki or blog will outgrow this, but we are keeping
+two copies of the website in git (source and the compiled site), and all
+historical versions too. So it could happen. If it does, you can pay github
+for more space, or you can migrate your site elsewhere.
+
+## Github Setup
+
+* Go to [github](http://github.com/) and sign up for an account, if you haven't already. 
+* Be sure to add your laptop's ssh key to it so you can push to github.
+* Create a repository on github named `$YOU.github.com`, substituting your
+  *username*. This repository will be used to publish your compiled website.
+* Create a repository on github named `$YOU` (or anything else you like).
+  This repository will be used to publish the source of your website.
+  This is actually optional.
+
+## Local Setup
+
+* On your laptop, create two empty git repositories to correspond to the github repositories: <br />
+       `YOU = your github username here` <br />
+       `mkdir ~/$YOU.github.com` <br />
+       `cd ~/$YOU.github.com` <br />
+       `git init` <br />
+       `git remote add origin git@github.com:$YOU/$YOU.github.com.git` <br />
+       `mkdir ~/$YOU` <br />
+       `cd ~/$YOU` <br />
+       `git init` <br />
+       `git remote add origin git@github.com:$YOU/$YOU.git` <br />
+* Add some wiki pages, such as an `index.mdwn`, to `~/$YOU`, and check them
+  in and commit them to git. You need something to push to github. Run
+  `git push origin master` to push the source pages to github.
+
+## Publishing to Github
+
+* Now build your wiki with a command such as: <br />
+       `ikiwiki ~/$YOU ~/$YOU.github.com --refresh`
+* Each time you build the wiki you will need to commit the changes
+  to git, and push the compiled pages to github: <br />
+       `cd ~/YOU.github.com` <br />
+       `git add .` <br />
+       `git commit -a -m update` <br />
+       `git push origin master` <br />
+
+Your wiki will show up at `http://$YOU.github.com/` within ten
+minutes after the first push, and changes you push to it from then on
+should show up immediately.
+
+## Enhancements
+
+You can follow the instructions in [[laptop_wiki_with_git]] to set up an
+editable version of your wiki on your laptop. Then you can use the web
+interface for editing. You'll still need to follow the instructions above
+to publish your changes to github.
+
+It would also be possible to teach ikiwiki to push compiled pages to github
+itself via a plugin, as was done with the [[plugins/amazon_s3]] plugin. Not
+done yet!
index 98cef92496845c76595a6662e99614be7f1013e7..e45b966897cb1b42b9a500ba89a25eb3b95bce5e 100644 (file)
@@ -1,27 +1,27 @@
 If you have a [[blog]] that is aggregated, either on a site like Planet
 Debian, or just through user subscriptions, one common problem is that
-changes to the guids of items in the blog can "flood" the aggregator,
+changes to the guids of items in the blog can “flood” the aggregator,
 causing all recent blog entries to be posted to the top of it. 
 
 This can happen in a lot of situations:
 
-* Perhaps you've just switched to ikiwiki from some other blog engine and
+* Perhaps youve just switched to ikiwiki from some other blog engine and
   imported your data.
-* Perhaps you've turned on the `usedirs` setting, which changes all the
+* Perhaps youve turned on the `usedirs` setting, which changes all the
   urls in your wiki. Even if you set up
   [[redirections|redirections_for_usedirs]] for the old urls, you still face
   the issue of flooding aggregators.
-* Perhaps you've just moved stuff around in your wiki.
+* Perhaps youve just moved stuff around in your wiki.
 
-To avoid annoying readers in these situations, it's a good idea to remove
-any existing items from your blog's news feed. That way only new items will
+To avoid annoying readers in these situations, its a good idea to remove
+any existing items from your blogs news feed. That way only new items will
 show up in the aggregator. The best way to do this is to add a `feedpages`
 parameter to the `inline` directive for your blog, with a condition such as:
 
        feedpages=created_after(blog/posts/old_post)
 
-Where "old_post" is the name of the last post you made to the blog before
-making the change. This will limit the feed to only newer posts, while stil
+Where “old_post” is the name of the last post you made to the blog before
+making the change. This will limit the feed to only newer posts, while still
 displaying the old posts in the blog page.
 
 Alternatively, you can add the [[plugins/meta]] guid directives to pages,
index b649636dccaaa6cb10eaf052eb33429363d15b97..b81ffae8d74c8008d3b519047014b73d8932bba4 100644 (file)
@@ -63,3 +63,28 @@ To remove that user:
 I've not written actual utilities to do this yet because I've only needed
 to do it rarely, and the data I've wanted has been different each time.
 --[[Joey]]
+
+## the session database
+
+`.ikiwiki/sessions.db` is the session database. See the [[!cpan CGI::Session]]
+documentation for more details.
+
+## lockfiles
+
+In case you're curious, here's what the various lock files do.
+
+* `.ikiwiki/lockfile` is the master ikiwiki lock file. Ikiwiki takes this 
+  lock before reading/writing state.
+* `.ikiwiki/commitlock` is locked as a semophore, to disable the commit hook
+  from doing anything.
+* `.ikiwiki/cgilock` is locked by the cgi wrapper, to ensure that only 
+  one ikiwiki process is run at a time to handle cgi requests.
+
+## plugin state files
+
+Some plugins create other files to store their state. 
+
+* `.ikiwiki/aggregate` is a plain text database used by the aggregate plugin
+  to record feeds and known posts.
+* `.ikiwiki/xapian/` is created by the search plugin, and contains xapian-omega
+  configuration and the xapian database.
index c05e7a3e02cf3ff70fd75314ff5be8d6801c8cbd..34d5b92520e0c40bfccf9357769ae8f8e6e848b4 100644 (file)
@@ -16,3 +16,50 @@ No idea how this happened.  I've blown it away and recreated it but, for future
 >>> --getctime does. --[[Joey]]
 
 >> Alas, I seem to have lost the bad index file to periodic /tmp wiping; I'll send it to you if it happens again.  --[[sabr]]
+
+<!-- Add by Blanko -->
+
+## Lost password for an user
+
+This morning, a person has lost its password. I was able to do something to make another password. This is the way I take : 
+
+> You can certianly do that, but do note that ikiwiki will offer to mail a
+> user a password reset link if they lost their password. --[[Joey]]
+
+### Locate the user database
+
+As tips show us, the user database is in the source file, for an example : 
+
+    src/.ikiwiki/userdb
+
+### See which user to modify
+
+Because I don't know the real login of the user, I have to read all the database : 
+
+    perl -le 'use Storable; my $index=Storable::retrieve("userdb"); use Data::Dumper; print Dumper $index'
+
+Then I was able to find this : 
+
+    'Utilisateur' => {
+                 'email' => 'user@pl.fr',
+                 'cryptresettoken' => '$2a$10$cfVeOoVbFw9VzMlgEbPMsu34pwHIFP84mWlkrs2RCKknZYPZkPffm',
+                 'password' => '',
+                 'resettoken' => '',
+                 'cryptpassword' => '$2a$10$H8bYq.dlb68wpnfJgVZQhOdsF9JQ06cteRfhPQPB5eHKnD5Y3u7au',
+                 'regdate' => '1226574052'
+               },
+
+Let's have a look to modify lines.
+
+### Modify the line
+
+When you have found the line to modify, take the user name, and change its password to **sc** (for an example) :
+
+    perl -le 'use Storable; my $userinfo=Storable::retrieve("userdb"); $userinfo->{"Utilisateur"}->{cryptpassword}=q{$2a$10$7viOHCrUkdAVL135Kr6one1mpZQ/FWYC773G1yZ0EtQciI11sSDRS}; Storable::lock_nstore($userinfo, "userdb")'
+    perl -le 'use Storable; my $userinfo=Storable::retrieve("userdb"); $userinfo->{"Utilisateur"}->{cryptresettoken}=q{}; Storable::lock_nstore($userinfo, "userdb")'
+
+Because I don't know how suppress cryptresettoken and resettoken fields, I change their content with *null*.
+
+After all these modifications, the user *Utilisateur* could connect to its account with the password **sc**, and go to Preferences, then change its password.
+
+<!-- End of Blanko's modifications -->
index 998ac74430344fc78df2928c3c3e3e9dae40454b..9758beb80d4da3cad214a48307ea27bd1a24d827 100644 (file)
@@ -15,7 +15,7 @@ for setting up ikiwiki with git.
 Next, `git clone` the source (`$REPOSITORY`, not `$SRCDIR`)
 from the server to the laptop.
 
-Now, set up a [[web_server|apache_cgi]] on your laptop, if it doesn't
+Now, set up a [[web_server|dot_cgi]] on your laptop, if it doesn't
 already have one.
 
 Now you need to write a setup file for ikiwiki on the laptop. Mostly this
index 234833ca7c12ee537e9a9a63783a8c2cf074a569..6ce72ae7b8cd749a1d2ad2d8fba1977f55bc1635 100644 (file)
@@ -5,3 +5,8 @@ Or, was this last remark about rebuilding after pulling meant to apply to rebuil
 [[DavidBremner]]
 
 * *Updated*  Now that I play with this a bit, this seems not so important.  Having a seperate sync operation that I run from the laptop is no big deal, and lets me update the parts of my site not yet managed by ikiwiki at the same time.
+
+* Ok, I have finally finished to set this up. I have a question for you :) Is it mandatory to have a locally running webserver on the laptop ? I mean, do I need to setup the CGI wrapper on the laptop ? Is it possible to just add/edit/delete/whatever, git commit all the stuff and git push back to the server ? Thank you. --[[xma]]
+
+> Of course you don't need a web server on the laptop. It is useful for
+> previewing pages before publishing them though. --[[Joey]]
diff --git a/doc/tips/lighttpd_cgi.mdwn b/doc/tips/lighttpd_cgi.mdwn
deleted file mode 100644 (file)
index 5504b06..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Here is how to enable cgi on [lighttpd](http://www.lighttpd.net/) and configure it in order to execute ikiwiki.cgi wherever it is located. 
-
-* Activate cgi by linking `/etc/lighttpd/conf-available/10-cgi.conf` into `/etc/lighttpd/conf-enabled` ([doc](http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI)). 
-
-* Create `/etc/lighttpd/conf-available/90-ikiwiki-cgi.conf` and add a line like this:
-
-    cgi.assign = ( "ikiwiki.cgi"  => "", )
-
-* Activate ikiwiki-cgi by linking `/etc/lighttpd/conf-available/90-ikiwiki-cgi.conf` into `/etc/lighttpd/conf-enabled`. 
-
-* Restart lighttpd server with something like `/etc/init.d/lighttpd restart`.
-
-Note that the first part enables cgi server wide but depending on default configuration, it may be not enough. The second part creates a specific rule that allow `ikiwiki.cgi` to be executed.
-
-**Warning:** I only use this on my development server (offline). I am not sure of how secure this approach is. If you have any thought about it, feel free to let me know.
diff --git a/doc/tips/markdown_and_eclipse.mdwn b/doc/tips/markdown_and_eclipse.mdwn
new file mode 100644 (file)
index 0000000..9e8e9bf
--- /dev/null
@@ -0,0 +1,4 @@
+For people that were not born with GNU emacs fingers, 
+there is a markdown editor (with preview and outline)
+for [eclipse](http://www.eclipse.org) available 
+[here](http://www.winterwell.com/software/markdown-editor.php).
index 6715f0c29b44a4a37f8f620b41c0b1ce2cd9eade..4b3b02eac8acbb2e35cfa4c930c9b5c7808f0bac 100644 (file)
@@ -81,7 +81,8 @@ Here is an example of how I set up a wiki:
        nano ikiwiki.setup
        # Set destdir to /home/htdocs
        # Set srcdir to /home/private/wiki
-       # Set url to http://yoursite.nfshost.com/ , set cgiurl likewise
+       # Set url to http://yoursite.nfshost.com/
+       # Set cgiurl to http://yoursite.nfshost.com/ikiwiki.cgi
        # Uncomment the `rcs => "git"` line.
        # Set the cgi_wrapper path to /home/htdocs/ikiwiki.cgi
        # Set the git_wrapper path to /home/private/wiki.git/hooks/post-update
diff --git a/doc/tips/untrusted_git_push.mdwn b/doc/tips/untrusted_git_push.mdwn
new file mode 100644 (file)
index 0000000..aef67a3
--- /dev/null
@@ -0,0 +1,122 @@
+This tip will describe how to allow anyone on the planet to `git push`
+changes into your wiki, without needing a special account. All a user needs
+to know is:
+
+       git clone git://your.wiki/path
+       # now modify any of the files the wiki would let you modify on the web
+       git push
+
+This is a wonderful thing to set up for users, because then they can work
+on the wiki while offline, and they don't need to mess around with web
+browsers.
+
+## security
+
+But, you might be wondering, how can this possibly be secure. Won't users
+upload all sorts of garbage, change pages you don't want them to edit, and so
+on.
+
+The key to making it secure is configuring ikiwiki to run as your git
+repository's `pre-receive` hook. There it will examine every change that
+untrusted users push into the wiki, and reject pushes that contain changes
+that cannot be made using the web interface.
+
+So, unless you have the [[plugins/attachment]] plugin turned on,
+non-page files cannot be added. And if it's turned on, whatever
+`allowed_attachments` checks you have configured will also check files
+pushed into git.
+
+And, unless you have the [[plugins/remove]] plugin turned on, no
+files can be deleted.
+
+And if you have `locked_pages` configured, then it will also affect what's
+pushed into git.
+
+Untrusted committers will also not be able to upload files with strange
+modes, or push to any branch except for the configured `gitorigin_branch`,
+or manipulate tags.
+
+One thing to keep an eye on is uploading large files. It may be easier to
+do this via git push than using the web, and that could be abused.
+
+Also, no checking is done that the authors of commits are right, so people
+can make a commit that pretends to be done by someone else.
+
+## user setup
+
+Add a dedicated user who will push in untrusted commits. This user should have
+a locked password, and `git-shell` as its shell.
+
+       root@bluebird:/home/joey>adduser --shell=/usr/bin/git-shell --disabled-password anon
+       Adding user `anon' ...
+
+## ikiwiki setup
+
+You should set up ikiwiki before turning on anonymous push in git. 
+
+Edit your wiki's setup file, and uncomment the lines for
+`git_test_receive_wrapper` and `untrusted_committers`.
+
+       # git pre-receive hook to generate
+       git_test_receive_wrapper => '/srv/git/ikiwiki.info/.git/hooks/pre-receive',
+       # unix users whose commits should be checked by the pre-receive hook
+       untrusted_committers => ['anon'],
+
+The `git_test_receive_wrapper` will become the git `pre-receive` hook. The
+`untrusted_committers` list is the list of unix users who will be pushing in
+untrusted changes. It should *not* include the user that ikiwiki normally runs
+as.
+
+Once you're done modifying the setup file, don't forget to run
+`ikiwiki -setup --refresh --wrappers` on it.
+
+## git setup
+
+You'll need to arrange the permissions on your bare git repository so that
+user anon can write to it. One way to do it is to create a group, and put
+both anon and your regular user in that group. Then make make the bare git
+repository owned and writable by the group. See [[rcs/git]] for some more
+tips on setting up a git repository with multiple committers.
+
+Note that anon should *not* be able to write to the `srcdir`, *only* to the bare git
+repository for your wiki.
+
+If you want to allow git over `ssh`, generate a ssh key for anon, and
+publish the *private* key for other people to use. This is optional; you
+can use `git-daemon` instead and not worry about keys.
+
+Now set up `git-daemon`. It will need to run as user `anon`, and be
+configured to export your wiki's bare git repository. I set it up as
+follows in `/etc/inetd.conf`, and ran `/etc/init.d/openbsd-inetd restart`.
+
+       git     stream  tcp     nowait  anon          /usr/bin/git-daemon git-daemon --inetd --export-all --interpolated-path=/srv/git/%H%D /srv/git
+
+At this point you should be able to `git clone git://your.wiki/path` from
+anywhere, and check out the source to your wiki. But you won't be able to
+push to it yet, one more change is needed to turn that on. Edit the
+`config` file of your bare git repository, and allow `git-daemon` to
+receive pushes:
+
+       [daemon]
+               receivepack = true
+
+Now pushes should be accepted, and your wiki immediatly be updated. If it
+doesn't, check your git repo's permissions, and make sure that the
+`post-update` and `pre-receive` hooks are suid so they run as the user who
+owns the `srcdir`.
+
+## infelicities
+
+If a user tries to push a changeset that ikiwiki doesn't like, it will
+abort the push before refs are updated. However, the changeset will still
+be present in your repository, wasting space. Since nothing refers to it,
+it will be expired eventually. You can speed up the expiry by running `git
+prune`.
+
+When aborting a push, ikiwiki displays an error message about why it didn't
+accept it. If using git over ssh, the user will see this error message,
+which is probably useful to them. But `git-daemon` is buggy, and hides this
+message from the user. This can make it hard for users to figure out why
+their push was rejected. (If this happens to you, look at "'git log --stat
+origin/master..`" and think about whether your changes would be accepted
+over the web interface.)
diff --git a/doc/tips/untrusted_git_push/discussion.mdwn b/doc/tips/untrusted_git_push/discussion.mdwn
new file mode 100644 (file)
index 0000000..d95c01e
--- /dev/null
@@ -0,0 +1,33 @@
+I've just tried this (commit c1fa07a). Recent changes shows:
+
+<div id="change-c1fa07ad4f165b42c962ba2a310681107f38c4f7" class="metadata">
+<span class="desc"><br />Changed pages:</span>
+<span class="pagelinks">
+
+<a href="http://git.ikiwiki.info/?p=ikiwiki;a=blobdiff;h=8bfa3dd7601a09b11ecbd20026849a777dc4b1b9;hp=c6302616f52ec058de5a8f5956fc512149a2f1a3;hb=1ea66c3d3f0a33bc3f04d073457b525a70380c37;f=doc/users/jondowland.mdwn"><img src="/wikiicons/diff.png" alt="diff" /></a><a href="http://ikiwiki.info/ikiwiki.cgi?page=users%2Fjondowland&amp;do=recentchanges_link">users/jondowland</a>
+
+
+</span>
+<span class="desc"><br />Changed by:</span>
+<span class="committer">
+
+<a href="http://ikiwiki.info/ikiwiki.cgi?page=users%2Fjon&amp;do=recentchanges_link">jon</a>
+
+</span>
+<span class="desc"><br />Commit type:</span>
+<span class="committype">git</span>
+<span class="desc"><br />Date:</span>
+<span class="changedate"><span class="relativedate" title="Mon, 10 Nov 2008 18:24:22 -0500">18:24:22 11/10/08</span>
+</div>
+
+Note that the user for the commit is 'jon', and the link points at cgi to
+create users/jon. I was wondering if that is configurable for users pushing
+via git. It would be nice perhaps to specify it in some way, perhaps via a
+git-config setting (user.name?). I'm not too familiar with exactly what the
+changeset contains. -- [[users/Jon]]
+
+> All ikiwiki can do it look at who git has recorded as the author of
+> the change (and it looks at the username part of the email address).
+> You can set `user.email` in `.git/config`. --[[Joey]]
+
+> > Ah, excellent. In which case this *should* DTRT... -- [[users/Jon]]
diff --git a/doc/tips/upgrade_to_3.0.mdwn b/doc/tips/upgrade_to_3.0.mdwn
new file mode 100644 (file)
index 0000000..d22813b
--- /dev/null
@@ -0,0 +1,95 @@
+Version 3.0 of ikiwiki makes some significant changes, which
+you will need to deal with when upgrading from ikiwiki 2.x.
+
+[[!toc ]]
+
+## setup file format change
+
+The layout of the setup file changed in a significant way in version 2.60
+of ikiwiki. If you have not changed yours to the new format, now would be a
+good time to do so. Some new features, like the [[plugins/websetup]]
+interface, need the new format setup file.
+  
+You can convert old setup files into the new format by running
+`ikiwiki-transition setupformat your.setup`
+
+## moving settings from Preferences page
+
+The admin preferences page used to have settings for allowed attachments,
+locked pages, and banned users. These three settings have moved to the
+setup file, and will no longer appear on the admin preferences page once
+your wiki is upgraded to 3.0.
+
+You can move these preferences into the setup file by running
+`ikiwiki-transition moveprefs your.setup; ikiwiki -setup your.setup -refresh -wrappers`
+
+(Make sure you have converted the setup file to the new format first.)
+
+## prefix directives
+
+In 3.0, the syntax ikiwiki uses for [[directives|ikiwiki/directive]] has
+changed, requiring that the directive start with a bang: 
+
+       \[[!directive ...]]
+
+If you would like to keep the old syntax, it is still supported, add the
+following to your setup file:
+       
+       prefix_directives => 0,
+
+To convert to the new syntax, make sure that your setup file does *not*
+contain the above, then run `ikiwiki-transition prefix_directives your.setup`
+
+(And then commit the changes it makes to pages in your srcdir.)
+
+## GlobLists
+
+In 3.0, the old "GlobList" syntax for [[PageSpecs|ikiwiki/PageSpec]] is no
+longer supported. A GlobList contains multiple term, but does not separate
+them with "and" or "or":
+
+       sandbox !*/Discussion
+
+To convert this to a modern PageSpec, simply add "and" or "or" as
+appropriate between terms:
+       
+       sandbox and !*/Discussion
+
+GlobLists have been deprecated for more than two years. If your wiki dates
+to the ikiwiki 1.0 era, you should check it for any that might have lurked
+unnoticed in it since back then. Ikiwiki version 2.72 will print warnings
+about any GlobLists it sees.
+
+## aggregateinternal
+
+If your wiki uses the [[aggregate|plugins/aggregate]] plugin, it will start
+to aggregate feeds to special "internal" pages.
+
+If you don't want this change, you can add the following to your setup
+file:
+
+       aggregateinternal => 0,
+
+Otherwise, follow this procedure to upgrade a wiki using the aggregate plugin:
+
+1. Update all [[PageSpecs|ikiwiki/PageSpec]] that refer to the aggregated
+   pages -- such as those in inlines. Put "internal()" around globs
+   in those PageSpecs. For example, if the PageSpec was `foo/*`, it should
+   be changed to `internal(foo/*)`. This has to be done because internal
+   pages are not matched by regular globs.
+2. Use [[ikiwiki-transition]] to rename all existing aggregated `.html`
+   files in the srcdir. The command to run is
+   `ikiwiki-transition aggregateinternal your.setup`,
+3. Refresh the wiki. (`ikiwiki -setup your.setup -refresh`)
+
+## embed / googlecalendar
+
+The googlecalendar plugin has been deprecated for a long time, and is
+removed in 3.0.
+
+The embed plugin is also now deprecated, though not yet removed.
+
+If you use either plugin to embed content from google, youtube, etc,
+into your wiki, you should instead configure the [[plugins/htmlscrubber]]
+to skip sanitising some pages, via the `htmlscrubber_skip` setting.
+See [[embedding_content]] for examples.
index d696bacdbd265024f5b4a3f4fdd0603ba5b31f6c..cf9327395bcde7ab38fea3d02df3b9aa65610e5d 100644 (file)
@@ -4,3 +4,10 @@ you to use a real text editor like Emacs or Vim to edit the contents of text
 areas.  This allows you to edit ikiwiki pages with a real text editor through
 the ikiwiki web interface, rather than only with direct commit 
 access. --[[JoshTriplett]] 
+
+For Firefox or Iceweasel users, the vimperator extension is also a good
+idea.  You can press Ctrl-I in the insert mode of vimperator and switch to
+an external editor, e.g. Vim. --[[WeakishJiang]]
+
+Finally, with wikis configured to allow, [[untrusted_git_push]], you can
+ditch the browser altogether. --[[Joey]] 
index 453efa8d1d80568f78ec94c82f0031674bde9422..172b763c34ae96ff879742d34965a1b5a090474d 100644 (file)
@@ -1,2 +1,4 @@
-[[ikiwiki.vim]] is a vim syntax highlighting file for ikiwiki. Installation
-instructions are at the top of the file.
+[[ikiwiki.vim]] is a vim syntax highlighting file for ikiwiki
+[[ikiwiki/markdown]] files. 
+
+Installation instructions are at the top of the file.
index b1637e7584845af0a9c448b03db3b90c335d9052..72cb52aab1c74b49f62bebbf697239ec2e575f84 100644 (file)
@@ -1 +1,8 @@
-I'm going to look at merging this with potwiki.vim (a vim-based personal wiki) so that you can follow wiki-links and auto-create pages etc., direct from vim. (I'm writing this incase I don't get around to it) -- [[JonDowland]]
+I'm going to look at merging this with potwiki.vim (a vim-based personal wiki) so that you can follow wiki-links and auto-create pages etc., direct from vim. (I'm writing this incase I don't get around to it) -- [[users/Jon]]
+
+----
+
+Another attempt at the same thing is here:
+<http://plasticboy.com/markdown-vim-mode/>
+
+In my tests, [[ikiwiki.vim]] works better than that one, YMMV. --[[Joey]]
index fd87f49a21678dd7f9c56ecb1ce6221246c3d977..bbcad4239f81ec4543bec7d58156559580309ca8 100644 (file)
@@ -1,6 +1,6 @@
 " Vim syntax file
 " Language:     Ikiwiki (links)
-" Maintainer:   Recai Oktaþ (roktasATdebian.org)
+" Maintainer:   Recai Oktaş (roktasATdebian.org)
 " Last Change:  2007 May 29
 
 " Instructions:
index c908f57c847f27ab9c09c65cf4fbfd86af2af9a1..8ecdf36d0e765c2f996fbd4ce07b1f04533b1bc4 100644 (file)
@@ -44,7 +44,7 @@ regenerate this one against that).
                          %config %links %renderedfiles %pagesources %destsources);
         our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
         our $version="2.1";my $installdir="/usr";
-       @@ -70,6 +70,7 @@ sub defaultconfig () { #{{{
+       @@ -70,6 +70,7 @@ sub defaultconfig () {
                plugin => [qw{mdwn inline htmlscrubber passwordauth openid signinedit
                              lockedit conditional}],
                timeformat => '%c',
@@ -52,27 +52,27 @@ regenerate this one against that).
                locale => undef,
                sslcookie => 0,
                httpauth => 0,
-       @@ -447,6 +448,15 @@ sub displaytime ($) { #{{{
+       @@ -447,6 +448,15 @@ sub displaytime ($) {
                                $config{timeformat}, localtime($time)));
-        } #}}}
+        }
 
-       +sub displaydate ($) { #{{{
+       +sub displaydate ($) {
        +       my $time=shift;
        +
        +       # strftime doesn't know about encodings, so make sure
        +       # its output is properly treated as utf8
        +       return decode_utf8(POSIX::strftime(
        +                       $config{dateformat}, localtime($time)));
-       +} #}}}
+       +}
        +
-        sub beautify_url ($) { #{{{
+        sub beautify_url ($) {
                my $url=shift;
 
        diff --git a/Plugin/inline.pm b/Plugin/inline.pm
        index 8f6ab51..7bd6147 100644
        --- a/Plugin/inline.pm
        +++ b/Plugin/inline.pm
-       @@ -148,6 +148,7 @@ sub preprocess_inline (@) { #{{{
+       @@ -148,6 +148,7 @@ sub preprocess_inline (@) {
                                $template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
                                $template->param(title => pagetitle(basename($page)));
                                $template->param(ctime => displaytime($pagectime{$page}));
diff --git a/doc/todo/Add_camelcase_exclusions.mdwn b/doc/todo/Add_camelcase_exclusions.mdwn
new file mode 100644 (file)
index 0000000..6b86132
--- /dev/null
@@ -0,0 +1,23 @@
+Camelcase currently looks for any and call camelcase words and turns them into wiki links.  This patch adds a config item called <code>camelcase_ignore</code> which is an array of camelcase words to ignore.
+
+<pre>
+--- /usr/share/perl5/IkiWiki/Plugin/camelcase.pm.orig   2008-12-24 11:49:14.000000000 +1300
++++ /usr/share/perl5/IkiWiki/Plugin/camelcase.pm        2008-12-24 12:02:21.000000000 +1300
+@@ -33,7 +33,11 @@
+        my $destpage=$params{destpage};
+        $params{content}=~s{$link_regexp}{
+-               htmllink($page, $destpage, IkiWiki::linkpage($1))
++                if (grep {/$1/} @{ $config{'camelcase_ignore'} }) {
++                  $1
++                } else {
++                 htmllink($page, $destpage, IkiWiki::linkpage($1)) 
++                }
+        }eg;
+        return $params{content};
+</pre>
+
+--[[puck]]
+
+[[done]]
index e864f53513deaf9ced22901dd36f856c20e6a462..7e7947fbce94d1a73d723df26299f335a0ef2b29 100644 (file)
@@ -27,3 +27,5 @@ A demo is at <http://www.attacklab.net/showdown-gui.html>
 >>> be necessary to insert some sort of placeholder, perhaps by outputting
 >>> the text in monospace form w/ a lighter font to denote that it won't
 >>> directly be shown in the page... -- [[harningt]]
+
+>>>>> We have a wmd plugin now. --[[Joey]] 
index 222cd8c462e88d1c3e539b2e9c79813f0ae7d573..6b9fa05351aafeb1174705d7f812494c317dc2fe 100644 (file)
@@ -12,7 +12,7 @@ This patch allows IkiWiki to work with either of the two:
 
     --- IkiWiki/Plugin/mdwn.pm.orig    2008-03-08 11:33:50.000000000 +0100
     +++ IkiWiki/Plugin/mdwn.pm 2008-03-08 13:37:21.000000000 +0100
-    @@ -28,14 +28,20 @@ sub htmlize (@) { #{{{
+    @@ -28,14 +28,20 @@ sub htmlize (@) {
                        $markdown_sub=\&Markdown::Markdown;
                }
                else {
index 8a398f2e005bf5ef65e37a4ceb35a640b7b793c7..19574b1756e63ca0fad1e0c3f669752ee566e82a 100644 (file)
@@ -12,7 +12,7 @@ I was hoping that the [[plugins/rename]] plugin would allow web uses to change t
     index 527ee88..123b772 100644
     --- a/IkiWiki/Plugin/rename.pm
     +++ b/IkiWiki/Plugin/rename.pm
-    @@ -43,7 +43,7 @@ sub check_canrename ($$$$$$$) { #{{{
+    @@ -43,7 +43,7 @@ sub check_canrename ($$$$$$$) {
        
        # Dest checks can be omitted by passing undef.
        if (defined $dest) {
@@ -21,7 +21,7 @@ I was hoping that the [[plugins/rename]] plugin would allow web uses to change t
                        error(gettext("no change to the file name was specified"));
                }
      
-    @@ -54,7 +54,7 @@ sub check_canrename ($$$$$$$) { #{{{
+    @@ -54,7 +54,7 @@ sub check_canrename ($$$$$$$) {
                }
      
                # Must not be a known source file.
@@ -30,7 +30,7 @@ I was hoping that the [[plugins/rename]] plugin would allow web uses to change t
                        error(sprintf(gettext("%s already exists"),
                                htmllink("", "", $dest, noimageinline => 1)));
                }
-    @@ -97,6 +97,24 @@ sub rename_form ($$$) { #{{{
+    @@ -97,6 +97,24 @@ sub rename_form ($$$) {
        $f->field(name => "do", type => "hidden", value => "rename", force => 1);
        $f->field(name => "page", type => "hidden", value => $page, force => 1);
        $f->field(name => "new_name", value => IkiWiki::pagetitle($page), size => 60);
@@ -55,7 +55,7 @@ I was hoping that the [[plugins/rename]] plugin would allow web uses to change t
        $f->field(name => "attachment", type => "hidden");
      
        return $f, ["Rename", "Cancel"];
-    @@ -223,12 +241,19 @@ sub sessioncgi ($$) { #{{{
+    @@ -223,12 +241,19 @@ sub sessioncgi ($$) {
                        my $dest=IkiWiki::possibly_foolish_untaint(IkiWiki::titlepage($q->param("new_name")));
      
                        # The extension of dest is the same as src if it's
diff --git a/doc/todo/Allow_disabling_edit_and_preferences_links.mdwn b/doc/todo/Allow_disabling_edit_and_preferences_links.mdwn
new file mode 100644 (file)
index 0000000..a356c69
--- /dev/null
@@ -0,0 +1,54 @@
+This patch allows disabling the edit and preferences link in the config file.  It is backwards compatible (so peoples edit and preferences links won't suddenly vanish).
+
+To disable edit or prefs respectively, add the following to the config file:
+
+<pre>
+  'edit' => 0,
+  'prefs' => 0, 
+</pre>
+
+Patch:
+<pre>
+--- /usr/share/perl5/IkiWiki/Render.pm.orig     2008-12-23 16:49:00.000000000 +1300
++++ /usr/share/perl5/IkiWiki/Render.pm  2008-12-23 16:55:40.000000000 +1300
+@@ -80,8 +80,10 @@
+        my $actions=0;
+        if (length $config{cgiurl}) {
+-               $template->param(editurl => cgiurl(do => "edit", page => $page));
+-               $template->param(prefsurl => cgiurl(do => "prefs"));
++               $template->param(editurl => cgiurl(do => "edit", page => $page))
++                       if ! defined $config{edit} || (defined $config{edit} && $config{edit} == 1);
++               $template->param(prefsurl => cgiurl(do => "prefs"))
++                       if ! defined $config{prefs} || (defined $config{prefs} && $config{prefs} == 1);
+                $actions++;
+        }
+
+</pre>
+
+> On irc, you said, "That was to allow the hack to of using wikistatedir to
+> allow me to generate two websites, one with inline editting, the other a
+> static page for public consumption."
+> 
+> The edit and preferences links can already be disabled by editing
+> `page.tmpl`. (Look for PREFSURL and EDITURL).
+> 
+> More to the point though, disabling those links does not disable anyone
+> consticting the urls by hand and logging in and editing a page. So you'd
+> really want to disable the editpage plugin in the setup file for the
+> public, static wiki. Sounds like you might also want to turn off cgi
+> entirely for that build. --[[Joey]] 
+
+>> I want to retain the same page.tmpl for both sites (different templates
+>> will just increase the maintenance hell), so disabling the links in the
+>> config for one public site works better in my case.
+>>
+>> I do have the editpage plugin disabled for the public static wiki, but
+>> the link still appears on the site.  I want to keep the cgi on, so that
+>> the site is still searchable. --[[puck]]
+
+>>> For me, disabling the editpage plugin does make the "Edit" link
+>>> disappear (this is with 3.03) but as far as I can tell, "Preferences"
+>>> is not controlled by any plugin.  It would be nice if it were; I am
+>>> trying to achieve a configuration where the only action supported
+>>> via CGI is blog-style comments.  --[Zack](http://zwol.livejournal.com/)
index b49968c18f2e4185af45f95b9a9f802181d2110d..1b99a4e05e1efa916893cb8bb03cd9fefc3aa905 100644 (file)
@@ -14,7 +14,7 @@ edittemplate there. --[[Joey]]
     index 98308de..c381940 100644
     --- a/IkiWiki/Plugin/edittemplate.pm
     +++ b/IkiWiki/Plugin/edittemplate.pm
-    @@ -56,8 +56,14 @@ sub preprocess (@) { #{{{
+    @@ -56,8 +56,14 @@ sub preprocess (@) {
      
        $pagestate{$params{page}}{edittemplate}{$params{match}}=$params{template};
      
@@ -28,10 +28,10 @@ edittemplate there. --[[Joey]]
     +
     +  return sprintf(gettext("edittemplate: %s registered for %s"),
     +          $linkHTML, $params{match});
-     } # }}}
+     }
      
-     sub formbuilder (@) { #{{{
-    @@ -89,6 +95,9 @@ sub formbuilder (@) { #{{{
+     sub formbuilder (@) {
+    @@ -89,6 +95,9 @@ sub formbuilder (@) {
                                        if (pagespec_match($p, $pagespec, location => $registering_page)) {
                                                $form->field(name => "editcontent",
                                                         value => filltemplate($pagestate{$registering_page}{edittemplate}{$pagespec}, $page));
diff --git a/doc/todo/Allow_filenames_that_are_all_type.mdwn b/doc/todo/Allow_filenames_that_are_all_type.mdwn
new file mode 100644 (file)
index 0000000..bebbcaf
--- /dev/null
@@ -0,0 +1,41 @@
+This is a [[patch]] to allow filenames that are just the type.  The best example of this is wanting to
+pass a `Makefile` through one of the [[todo/syntax_highlighting/]] plugins.  With this patch,
+if the plugin can process files of type `.Makefile` then it will also process `Makefile`.
+
+I put this patch on the [[todo/syntax_highlighting/]] page a while ago, but it seemed to get
+lost because it didn't have its own bug to track it.  Now it does :).  -- [[Will]]
+
+> This changes `pagename()`, but what about `pagetype()`?
+> Many things in ikiwiki check if `pagetype($file)` returns
+> true to see if it's a page, etc. --[[Joey]] 
+
+>> I think this patch is complete.  It does not change `pagename()`, it
+>> changes `pagetype()` (the diff is fairly old - line numbers may have
+>> changed).
+>>
+>> Before this patch, `pagetype()` required a `.` in the page name.  With
+>> this patch it doesn't, as long as the extension is being kept.  This allows
+>> the filename to be all extension.  `pagename()` relies on `pagetype()`
+>> to detect the type.  `pagename()` also removes the extension on some
+>> pages, but this patch only affects pages where the extension isn't
+>> removed.
+>>
+>> So, yeah, I think this patch is complete. :)  -- [[Will]]
+
+>>> Thanks, [[applied|done]], but I added a noextension parameter,
+>>> since having keepextension allow files with no extension didn't make
+>>> sense. Also, made it work for pages in subdirs.. --[[Joey]] 
+
+    diff --git a/IkiWiki.pm b/IkiWiki.pm
+    index 8d728c9..1bd46a9 100644
+    --- a/IkiWiki.pm
+    +++ b/IkiWiki.pm
+    @@ -618,6 +618,8 @@ sub pagetype ($) {
+       
+       if ($page =~ /\.([^.]+)$/) {
+               return $1 if exists $hooks{htmlize}{$1};
+    +  } elsif ($hooks{htmlize}{$page}{keepextension}) {
+    +          return $page;
+       }
+       return;
+     }
index 73157a3268a0d0684b4ceea0acd6decd83c3204f..95c38f794a281760dc90fcb87af8d0774fcc20eb 100644 (file)
@@ -8,9 +8,9 @@ This patch adds function bestdir() which returns best directory from the directo
     +++ IkiWiki.pm  (working copy)
     @@ -391,6 +391,35 @@
             return "";
-     } #}}}
+     }
     
-    +sub bestdir ($$) { #{{{
+    +sub bestdir ($$) {
     +    my $page=shift;
     +       my $link=shift;
     +       my $cwd=$page;
@@ -37,9 +37,9 @@ This patch adds function bestdir() which returns best directory from the directo
     +       }
     +
     +       return "";
-    +} #}}}
+    +}
     +
-     sub isinlinableimage ($) { #{{{
+     sub isinlinableimage ($) {
             my $file=shift;
     
 ---- 
index 4a17bbf8bb1f276db6f1db1639968955d2dca5aa..a904f82870c94691ae34711bae52484ded58411c 100644 (file)
@@ -15,7 +15,7 @@ Inline below is a [[patch]] that implements this:
     index bb21ed2..10c985c 100644
     --- a/IkiWiki/Plugin/editpage.pm
     +++ b/IkiWiki/Plugin/editpage.pm
-    @@ -60,7 +60,7 @@ sub cgi_editpage ($$) { #{{{
+    @@ -60,7 +60,7 @@ sub cgi_editpage ($$) {
      
        decode_cgi_utf8($q);
      
@@ -24,7 +24,7 @@ Inline below is a [[patch]] that implements this:
        my @buttons=("Save Page", "Preview", "Cancel");
        eval q{use CGI::FormBuilder};
        error($@) if $@;
-    @@ -117,9 +117,20 @@ sub cgi_editpage ($$) { #{{{
+    @@ -117,9 +117,20 @@ sub cgi_editpage ($$) {
        }
        else {
                $type=$form->param('type');
@@ -45,7 +45,7 @@ Inline below is a [[patch]] that implements this:
                elsif (defined $from && exists $pagesources{$from}) {
                        # favor the type of linking page
                        $type=pagetype($pagesources{$from});
-    @@ -129,7 +140,7 @@ sub cgi_editpage ($$) { #{{{
+    @@ -129,7 +140,7 @@ sub cgi_editpage ($$) {
                if (! $form->submitted) {
                        $form->field(name => "rcsinfo", value => "", force => 1);
                }
@@ -58,7 +58,7 @@ Inline below is a [[patch]] that implements this:
     index 8efef3f..075d7d8 100644
     --- a/IkiWiki/Plugin/inline.pm
     +++ b/IkiWiki/Plugin/inline.pm
-    @@ -271,6 +271,7 @@ sub preprocess_inline (@) { #{{{
+    @@ -271,6 +271,7 @@ sub preprocess_inline (@) {
                        $rootpage=$params{page};
                }
                $formtemplate->param(rootpage => $rootpage);
index 8693da5e3075c88305e3050eff00aaebe6606d20..b2d9d43edfdc12a54a1127002d32641edc984952 100644 (file)
@@ -5,11 +5,12 @@ Features needed:
 
  * Wiki, duh.
  * Source code viewing: This can be handled quite well with a [[shortcut|shortcuts]] to an external source viewer, or by putting
-    the source in the wiki itself (see the [[todo/automatic_use_of_syntax_plugin_on_source_code_files]] wishlist item) and using the
-    [[plugins/contrib/highlightcode]] or [[plugins/contrib/sourcehighlight]] plugins.
+    the source in the wiki itself (see the [[todo/automatic_use_of_syntax_plugin_on_source_code_files]] wishlist item and [[todo/syntax_highlighting]] todo item).
     * This could be improved with [[todo/source_link]].
     * Currently the source highlighting is a little problematic, as there can be two source files with the same wikiname.
        e.g. a `hello-world.c` and `hello-world.h`.  See [[bugs/multiple_pages_with_same_name]]
+       > That bug was fixed before you linked to the page. :-)
+       >> I was the one that fixed it... :) -- [[Will]]
  * Trac 'Timeline' feature: view history of the RCS - the `recentchanges` button.
  * Trac 'Roadmap' feature: Which TODOs/bugs are needed for which milestones.  Use the [[plugins/progress]] directive to show percentage complete for each milestone.
  * Bug tracking: see [[tips/integrated_issue_tracking_with_ikiwiki]] and [[todo/Updated_bug_tracking_example]].
index fbf1802fdde7c81051ef4ca73e432f3cb2dbb3c3..bc1d5bea470320345e1630dae55b4ebac5b3add1 100644 (file)
@@ -1,6 +1,6 @@
 New Version of gallery is available now. Few more features have been added like support for multiple pages, sorting and resizing of images etc.
 
-SVN repository of plugin is located at http://ned.snow-crash.org:8080/svn/ikiwiki-gallery
+Gallery repo is now available at  <http://github.com/joeyh/ikiwiki/tree/gallery>
 
 --[[arpitjain]]
 
@@ -73,3 +73,9 @@ Additional details are available [here](http://myweb.unomaha.edu/~ajain/ikiwikig
 > the gallery and put it in a "gallery" branch of my git repository.
 > 
 > --[[Joey]]
+
+----
+
+See also [[/users/smcv/gallery]] for another implementation of the same sort of
+thing. Unfortunately, none of the implementation ideas
+I have there seem quite right either... --[[smcv]]
index a644e236b8cf1029bb870a0d2d657a12696656aa..c71250b3a01816614b8126458b03d1c8cfa0fa87 100644 (file)
@@ -94,7 +94,7 @@ most possible of these pages.
 >        index a6e34fc..bb9dd8d 100644
 >        --- a/IkiWiki/Plugin/template.pm
 >        +++ b/IkiWiki/Plugin/template.pm
->        @@ -57,6 +57,8 @@ sub preprocess (@) { #{{{
+>        @@ -57,6 +57,8 @@ sub preprocess (@) {
 >                       }
 >               }
 >        
diff --git a/doc/todo/Improve_display_of_OpenIDs.mdwn b/doc/todo/Improve_display_of_OpenIDs.mdwn
new file mode 100644 (file)
index 0000000..e2ba1d9
--- /dev/null
@@ -0,0 +1,5 @@
+Some OpenIDs seen in the IkiWiki git history are displayed poorly in [[RecentChanges]], including mine :-) (`http://smcv.pseudorandom.co.uk/`, shown as `smcv.pseudorandom [co.uk]`)
+
+My `openid` branch on <http://git.pseudorandom.co.uk/> improves on a couple of cases and adds a regression test. --[[smcv]]
+
+[[!tag patch done]]
index 9f52a724a2954cfab44a49478144563020b87639..69169400968b8b6f4f45847c4ac5871f38fe9146 100644 (file)
@@ -19,7 +19,7 @@ Cheers,
        index 59eabb6..82913ba 100644
        --- a/IkiWiki/Plugin/inline.pm
        +++ b/IkiWiki/Plugin/inline.pm
-       @@ -229,6 +229,7 @@ sub preprocess_inline (@) { #{{{
+       @@ -229,6 +229,7 @@ sub preprocess_inline (@) {
                                                $template->param(content => $content);
                                        }
                                        $template->param(pageurl => urlto(bestlink($params{page}, $page), $params{destpage}));
index d94d24ee4d81f5ae0442d3066772a161cff8eca9..3cedd5ae31e30fcb45975b056afcf824811006ad 100644 (file)
@@ -71,10 +71,10 @@ Happy TeXing.
     +
     +my $default_postfix = '\\end{document}';
     +
-     sub import { #{{{
+     sub import {
        hook(type => "getsetup", id => "teximg", call => \&getsetup);
        hook(type => "preprocess", id => "teximg", call => \&preprocess);
-    @@ -21,6 +33,26 @@ sub getsetup () { #{{{
+    @@ -21,6 +33,26 @@ sub getsetup () {
                        safe => 1,
                        rebuild => undef,
                },
@@ -98,10 +98,10 @@ Happy TeXing.
     +                  safe => 0, # Not sure how secure LaTeX is...
     +                  rebuild => 1,
     +          },
-     } #}}}
+     }
      
-     sub preprocess (@) { #{{{
-    @@ -105,25 +137,35 @@ sub gen_image ($$$$) { #{{{
+     sub preprocess (@) {
+    @@ -105,25 +137,35 @@ sub gen_image ($$$$) {
        my $digest = shift;
        my $imagedir = shift;
      
index dda1ff5e9812ef1c9a4c5666fc36fd2257f2f701..f6c0fc0ec6cbe03227985f20e0ac4a6f1bbefc14 100644 (file)
@@ -1,2 +1,19 @@
 Err, is this really fixed in 2.21? I can't find it anywhere in 2.32.3 
 (debian unstable)
+
+-----
+
+I just did a `--dumpsetup` with the current version from the Git repository
+and the default option is
+
+    # use '!'-prefixed preprocessor directives?
+    prefix_directives => 0,
+
+My impression was that this should be enabled by default now.  --[[JasonBlevins]]
+
+> As stated in `debian/NEWS`:
+>> For backward compatibility with existing wikis,
+>> refix_directives currently defaults to false.  In ikiwiki 3.0,
+>> prefix_directives will default to true [...]
+> --[[intrigeri]]
+
index efa07ad7990f6c48877df2e94d940af0419df1d8..f4023d6dd6cd439bbc1c744b6a86a54854d72652 100644 (file)
@@ -6,3 +6,9 @@ Currently, the page title (either the name of the page or the title specified wi
 > way, # is reserved for h1 if you choose to use headers in your page. --[[Joey]]
 
 [[done]]
+
+> For anyone interested, I've written a small plugin called [h1title][] that does the
+> latter, making `#` (only when on the first line) set the page title, removing it from
+> the page body. --[[JasonBlevins]], October 22, 2008
+
+ [h1title]: http://code.jblevins.org/ikiwiki/plugins.git/plain/h1title.pm
diff --git a/doc/todo/RecentChanges_page_links_without_cgi_wrapper.mdwn b/doc/todo/RecentChanges_page_links_without_cgi_wrapper.mdwn
new file mode 100644 (file)
index 0000000..b371090
--- /dev/null
@@ -0,0 +1,26 @@
+Links to the changed page on RecentChanges only show up if the cgi wrapper is
+enabled. It would be nice if links were also generated on wikis that do not use
+the cgi. [[svend]]
+
+> It would be, but doing so would make updating the recentchanges page for
+> each commit a lot slower, or would result in there often being broken
+> links there.
+> 
+> The broken links would happen if a page is removed.
+> 
+> The speed issue is that currently each individual change in the
+> recentchanges page is built just once, when the change is made, and the
+> html for it is reused thereafter. To avoid broken links, it would need to
+> regenerate each change's html on each commit. That's 100x the overhead.
+> (Perhaps it's possible to be smarter about which need generation tho.)
+> 
+> The best way to approach this that I can see ATM is to use the
+> [[plugins/404]] plugin to handle the broken links and then recentchanges
+> could avoid explicitly using the CGI. But this doesn't meet your use case
+> of having no CGI.
+>
+> If you're willing to live with broken links to removed pages, I suppose
+> that could be made an option..
+> --[[Joey]] 
+
+[[!tag wishlist]]
index a2643391927cfe399ad00a119dc5e25250b2f2b4..89167c084ea64e6fbde3167ed3aeca46cace3dd1 100644 (file)
@@ -42,13 +42,13 @@ Longer term plans:
                 my %cache;
                 my %linkcache;
                @@ -32,6 +34,7 @@
-                sub import { #{{{
+                sub import {
                        hook(type => "needsbuild", id => "version", call => \&needsbuild);
                        hook(type => "preprocess", id => "calendar", call => \&preprocess);
                +       hook(type => "preprocess", id => "event", call => \&preprocess_event);
-                } #}}}
+                }
                 
-                sub is_leap_year (@) { #{{{
+                sub is_leap_year (@) {
                @@ -58,6 +61,7 @@
                        my $nmonth   = $params{nmonth};
                        my $pyear    = $params{pyear};
@@ -137,9 +137,9 @@ Longer term plans:
                        # finish off the week
                @@ -304,6 +333,18 @@
                        return $calendar;
-                } #}}}
+                }
                 
-               +sub preprocess_event (@) { #{{{
+               +sub preprocess_event (@) {
                +       my %params=@_;
                +       # if now time is given, use now
                +       $params{begin} = localtime($time)            unless defined $params{begin};
@@ -151,7 +151,7 @@ Longer term plans:
                +       return "<!-- $params{begin} -->";
                +} #}}
                +
-                sub preprocess (@) { #{{{
+                sub preprocess (@) {
                        my %params=@_;
                        $params{pages} = "*"            unless defined $params{pages};
                @@ -311,6 +352,8 @@
index e3f0224c2eb4fc890cf347e2207ef1d06bd437fe..d875900c5b52c3f37070922f6f30b6aff71421e6 100644 (file)
@@ -4,7 +4,7 @@ A quick [[patch]] to silence a [[rcs/monotone]] warning I started seeing:
     index 4b9be31..9d4e280 100644
     --- a/IkiWiki/Plugin/monotone.pm
     +++ b/IkiWiki/Plugin/monotone.pm
-    @@ -55,7 +55,7 @@ sub checkconfig () { #{{{
+    @@ -55,7 +55,7 @@ sub checkconfig () {
                error("Monotone version too old, is $version but required 0.38");
        }
      
index 2837634d99db21bc20bfcababc532a2d221c9b71..8320f72a60812f12a22e8796e6eb6ace85ea56be 100644 (file)
@@ -20,7 +20,7 @@ That doesn't work in ikiwiki 2.1, but I have it
        index 38aa46a..cd42e8d 100644
        --- a/IkiWiki.pm
        +++ b/IkiWiki.pm
-       @@ -1082,10 +1082,15 @@ sub match_link ($$;@) { #{{{
+       @@ -1082,10 +1082,15 @@ sub match_link ($$;@) {
                my $links = $IkiWiki::links{$page} or return undef;
                return IkiWiki::FailReason->new("$page has no links") unless @$links;
                my $bestlink = IkiWiki::bestlink($from, $link);
@@ -38,7 +38,7 @@ That doesn't work in ikiwiki 2.1, but I have it
        +               }
                }
                return IkiWiki::FailReason->new("$page does not link to $link");
-        } #}}}
+        }
        -- 
        1.5.1.1.g6aead
 
diff --git a/doc/todo/Untrusted_push_in_Monotone.mdwn b/doc/todo/Untrusted_push_in_Monotone.mdwn
new file mode 100644 (file)
index 0000000..a8b1cd7
--- /dev/null
@@ -0,0 +1,28 @@
+As noted in [[tips/untrusted_git_push]] an untrusted push capability was added recently, but only implemented in git.
+(See also [[todo/rcs_updates_needed]])
+
+This note describes (but does not implement) an approach for this with the [[rcs/monotone]] rcs backend.
+
+----
+
+Monotone behaves a little differently to git in its networking.  Git allows anyone to try to push, and then
+check whether it is ok before finally accepting it.  Monotone has no way to accept or reject revisions
+in this way.  However, monotone does have the ability to mark revisions, and to ignore unmarked revisions.
+
+This marking capability can be used to achieve a somewhat similar effect to what happens with git.  The
+problem with this is that anyone could put anything into the monotone database, and while this wouldn't
+affect ikiwiki, it seems bad to leave open, untrusted storage on the web.
+
+The Plan
+=====
+
+In the `note_netsync_revision_received` hook in the monotone server, have the server check to make sure
+that either a) the revision is signed by someone trusted or, b) the revision is checked using the same
+hook that git uses in `pre-receive`.  If the revision passes the ikiwiki `pre-receive` check then the
+monotone hook signs the revision.  This gives that revision the 'ikiwiki seal of approval'.
+
+You'll also want to update the monotone trust hooks to only trust revisions signed by trusted people, or
+ikiwiki.
+
+Now anyone can upload a revision, but only those signed by a trusted person, or which pass the ikiwiki
+check and so get signed by the ikiwiki key, will be seen by ikiwiki.
index c0311bc92d9f8a7d3e2643e8fc7352f8a91c7dc3..7b4323de177cde72df7daf79d3f61e2bd6349fe4 100644 (file)
@@ -13,12 +13,12 @@ Second, the untainting of $configstring should allow newlines.
     +++ wiki-meta/perl/IkiWiki.pm Mon Jun 11 10:52:07 2007
     @@ -205,7 +205,7 @@
      
-     sub possibly_foolish_untaint ($) { #{{{
+     sub possibly_foolish_untaint ($) {
       my $tainted=shift;
     - my ($untainted)=$tainted=~/(.*)/;
     + my ($untainted)=$tainted=~/(.*)/s;
       return $untainted;
-     } #}}}
+     }
      
     
     Modified: wiki-meta/perl/IkiWiki/Wrapper.pm
index 684419f9093d977e5bedd700a946f813657ca0d8..e91c5a42f681e9258234de620bd8ee29a430950c 100644 (file)
@@ -19,7 +19,7 @@ diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
 index d2e5832..9e52712 100644
 --- a/IkiWiki/Plugin/inline.pm
 +++ b/IkiWiki/Plugin/inline.pm
-@@ -194,6 +194,9 @@ sub preprocess_inline (@) { #{{{
+@@ -194,6 +194,9 @@ sub preprocess_inline (@) {
         elsif (! exists $params{sort} || $params{sort} eq 'age') {
                 @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
         }
diff --git a/doc/todo/allow_disabling_backlinks.mdwn b/doc/todo/allow_disabling_backlinks.mdwn
new file mode 100644 (file)
index 0000000..5dd4876
--- /dev/null
@@ -0,0 +1,18 @@
+This patch allows disabling the backlinks in the config file by setting nobacklinks to 0.
+
+It is backwards compatible, and by default enables backlinks in the generated pages.
+
+<pre>
+--- IkiWiki/Render.pm.orig2    2009-01-06 14:54:01.000000000 +1300
++++ IkiWiki/Render.pm  2009-01-06 14:55:08.000000000 +1300
+@@ -107,7 +107,8 @@
+               $template->param(have_actions => 1);
+       }
+-      my @backlinks=sort { $a->{page} cmp $b->{page} } backlinks($page);
++      my @backlinks=sort { $a->{page} cmp $b->{page} } backlinks($page)
++              unless defined $config{nobacklinks} && $config{nobacklinks} == 0;
+       my ($backlinks, $more_backlinks);
+       if (@backlinks <= $config{numbacklinks} || ! $config{numbacklinks}) {
+               $backlinks=\@backlinks;
+</pre>
index cb45faee5d4b245712c10a9aeb9914af8a77eb80..b0524be5fcabfba5b66ef671ddebab6eb0645eb4 100644 (file)
@@ -17,3 +17,14 @@ Cheers,
 You might look at the Wikipedia page on "Spam\_in\_blogs" for more ideas.  In particular, would it be possible to force a subset of the pages (by regex, but you'd choose the regex to match those pages which are publicly writable) to use rel="nofollow" in all links.
 
 > I just wanted to leave a link here to the [[todo/require_CAPTCHA_to_edit]] plugin patch.  Unfortunately that plugin currently interacts badly with the openid plugin. -- [[Will]]
+
+
+---
+
+Ikiwiki now has a checkcontent hook that plugins can use to see content
+that is being entered and check it for spam/whatever.
+
+There is a blogspam plugin that uses the blogspam.org service
+to check for common spam signatures. --[[Joey]] 
+
+[[done]]
diff --git a/doc/todo/apache_404_ErrorDocument_handler.mdwn b/doc/todo/apache_404_ErrorDocument_handler.mdwn
new file mode 100644 (file)
index 0000000..4ae1d1a
--- /dev/null
@@ -0,0 +1,25 @@
+Apache's ErrorDocument directive lets you write a CGI script that will be invoked for all 404s.
+IkiWiki could offer one as an optional wrapper; it would do much the same thing that the
+existing recentchanges_link (or [[generic___39__do__61__goto__39___for_CGI]]) does when
+encountering a nonexistent page.
+
+I think it'd probably have to be a separate CGI script because the environment with which
+404 handlers are invoked is somewhat odd, and because it needs to return a 404 status
+(having said that, it might make sense for `recentchanges_link` to return 404 rather than
+200 anyway if the page doesn't exist).
+
+> This turns out to be untrue, as long as the wrapper lets a couple of extra
+> environment variables through. --[[smcv]]
+
+This would give IkiWiki the behaviour of many other wikis, where visiting a page that
+does not yet exist prompts you to create it, without having to invoke the CGI for
+successful requests.
+
+Due to [a well-known MSIE misfeature](http://support.microsoft.com/default.aspx?scid=kb;en-us;Q294807),
+error output needs to be at least 512 bytes long, so some padding might also be required.
+
+Implemented in the 'goto' branch in my git repository. You can see this
+feature in action [on my blog](http://smcv.pseudorandom.co.uk/no/such/page/).
+--[[smcv]]
+
+[[done]]
index d3eb9793b2da31b20123998995343a31d3e46a2a..d26b0dfe924ff24f090705674ace25ec28517f01 100644 (file)
@@ -1,4 +1,4 @@
-[[!tag wishlist]]
+[[!tag wishlist done]]
 
 [[!toc ]]
 
@@ -54,3 +54,57 @@ modify only *one* page may be easier.
 
 Implementation
 ==============
+
+Also see [[joey]]'s idea on [[users/xma/discussion]], to allow (filtered) anonymous push to this wiki's repository.
+
+> Ideally the filtering should apply the same constraints on what's pushed
+> as are applied to web edits. So locked pages can't be changed, etc.
+> 
+> That could be accomplished by making the git pre-receive hook be a
+> ikiwiki wrapper. A new `git_receive_wrapper` config setting could cause
+> the wrapper to be generated, with `$config{receive}` set to true.
+> 
+> When run that way, ikiwiki would call `rcs_receive`. In the case of git,
+> that would look at the received changes as fed into the hook on stdin,
+> and use `parse_diff_tree` to get a list of the files changed. Then it
+> could determine if the changes were allowed.
+> 
+> To do that, it should first look at what unix user received the
+> commit.  That could be mapped directly to an ikiwiki user. This would
+> typically be an unprivelidged user (that was set up just to allow
+> anonymous pushes), but you might also want to set up
+> separate users who have fewer limits on what they can push. And, of
+> course, pushes from the main user, who owns the wiki, would not be
+> checked at all. So, let's say `$config{usermap}` is a hash, something
+> like `{usera => "wikiusera", userb => "wikiuserb"}`, and pushes from
+> users not in the hash are not checked.
+> 
+> Then it seems like it would want to call `check_canedit` to test if an
+> edit to each changed page is allowed. Might also want to call
+> `check_canattach` and `check_canremove` if the attach and remove plugins
+> are enabled. All three expect to be passed a CGI and a CGI::Session
+> object, which is a bit problimatic here. So dummy the objects up? (To call
+> `check_canattach` the changed attachment would need to be extracted to a
+> temp file for it to check..)
+> 
+> If a change is disallowed, it would print out what was disallowed, and
+> exit nonzero. I think that git then discards the pushed objects (or maybe
+> they remain in the database until `git-gc` .. if so, that could be used
+> to DOS by uploading junk, so need to check this point).
+> 
+> Also, I've not verified that the objects have been recieved already when
+> whe pre-receive hook is called. Although the docs seem to say that is the
+> case. --[[Joey]]
+
+>> Update: The git pre-receive hook stuff is written, and seems to work.
+>> I think it makes more sense than using diffs, and so think this todo
+>> could probably be closed.
+>> --[[Joey]]
+
+>>> I agree, closing this. I really prefer this solution to the one I was
+>>> initially proposing.
+>>> Is this pre-receive hook already enabled on ikiwiki.info?
+>>> If not, do you plan to enable it at some point?
+>>> --[[intrigeri]]
+
+>>>> [[news/git_push_to_this_wiki]] gave me the answer. Well done! --[[intrigeri]]
index bfb4a863bf939a905af3345e75d0d7f5c0a7bc1c..ab92635565a9b8c303455f3d624e1f8d5c032523 100644 (file)
@@ -7,3 +7,102 @@ Also see: <http://madduck.net/blog/2008.01.06:new-blog/> and <http://users.itk.p
 [[!tag wishlist]]
 
 I would love to see this as well. -- dato
+
+---
+
+I have create a patch to tag.pm for add the option for auto create tag pages.
+A new setting is used to enable or disable auto-create tag pages, `tag_autocreate`.
+The new tag file is created during the preprocess phase. 
+The new tag file is then complied during the change phase.
+
+_tag.pm from version 3.01_
+
+
+       --- tag.pm      2009-02-06 10:26:03.000000000 -0700
+       +++ tag_new.pm  2009-02-06 12:17:19.000000000 -0700
+       @@ -14,6 +14,7 @@
+                       hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
+                       hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
+                       hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
+       +       hook(type => "change", id => "tag", call => \&change);
+        }
+        
+        sub getopt () {
+       @@ -36,6 +37,36 @@
+                                                       safe => 1,
+                                                       rebuild => 1,
+                                       },
+       +               tag_autocreate => {
+       +                       type => "boolean",
+       +                       example => 0,
+       +                       description => "Auto-create the new tag pages, uses autotagpage.tmpl ",
+       +                       safe => 1,
+       +                       rebulid => 1,
+       +               },
+       +}
+       +
+       +my $autocreated_page = 0;
+       +
+       +sub gen_tag_page($)    {
+       +       my $tag=shift;
+       +
+       +       my $tag_file=$tag.'.'.$config{default_pageext};
+       +       return if (-f $config{srcdir}.$tag_file);
+       +
+       +       my $template=template("autotagpage.tmpl");
+       +       $template->param(tag => $tag);
+       +       writefile($tag_file, $config{srcdir}, $template->output);
+       +       $autocreated_page = 1;
+       +
+       +       if ($config{rcs}) {
+       +               IkiWiki::disable_commit_hook();
+       +               IkiWiki::rcs_add($tag_file);
+       +               IkiWiki::rcs_commit_staged(
+       +                       gettext("Automatic tag page generation"),
+       +                       undef, undef);
+       +               IkiWiki::enable_commit_hook();
+       +       }
+        }
+        
+        sub tagpage ($) {
+       @@ -47,6 +78,10 @@
+                                       $tag=~y#/#/#s; # squash dups
+                       }
+        
+       +       if (defined $config{tag_autocreate} && $config{tag_autocreate} ) {
+       +               gen_tag_page($tag);
+       +       }
+       +
+                       return $tag;
+        }
+        
+       @@ -125,4 +160,18 @@
+                       }
+        }
+        
+       +sub change(@) {
+       +       return unless($autocreated_page);
+       +       $autocreated_page = 0;
+       +
+       +       # This refresh/saveindex is to complie the autocreated tag pages
+       +       IkiWiki::refresh();
+       +       IkiWiki::saveindex();
+       +
+       +       # This refresh/saveindex is to fix the Tags link
+       +       # With out this additional refresh/saveindex the tag link displays ?tag
+       +       IkiWiki::refresh();
+       +       IkiWiki::saveindex();
+       +}
+       +
+
+
+This uses a template called `autotagpage.tmpl`, here is my template file:
+
+    \[[!inline pages="link(<TMPL_VAR TAG>)" archive="yes"]]
+
+
+A quirk I have not figured out is during the `sub change`, see my comments in the code.
+I am not sure if that is the best way to handle it.
+
+[[!tag patch]]
+-- Jeremy Schultz <jeremy.schultz@uleth.ca>
index 2fad9f19aedbc4112bc67bd259ba816811e65a56..8bc75420dff06992cd02304574e5c5747084142f 100644 (file)
@@ -1,13 +1,66 @@
 Here is another [[patch]] for this.  It is more up to date than either of the patches linked on the previous page.  It is most similar to [[plugins/contrib/sourcehighlight]].
 
-Note that if this is being used with `c` or `c++` then you'll probably want to wait until [[bugs/multiple_pages_with_same_name]] is fixed.
+Updated to use fix noted in [[bugs/multiple_pages_with_same_name]].
 
 -- [[Will]]
 
+----
+I was trying to replace sourcehighlight with sourcecode. I had to modify the 
+htmlize call slightly so that it would work in a format directive.
+([modified version](http://pivot.cs.unb.ca/git/?p=ikiplugins.git;a=blob_plain;f=IkiWiki/Plugin/sourcecode.pm;hb=21fc57091edb9))
+
+> I haven't tested them, but those changes look sensible to me. -- [[Will]]
+
+I hit a wall the following example (the last commit in the above repo).
+
+    \[[!meta title="Solutions to assignment 1"]]
+
+    - [[!format cc """
+    test
+    """]]
+
+
+> I haven't actually tested this to see what the problem is.  How does this fail?
+> Does source-highlight barf on the non-c++ content?  Is there a wiki URL that shows the failure?  -- [[Will]]
+>> Here is the content div from the output page
+>> [[DavidBremner]]
+
+     <div id="content">
+     <p><ul>
+     <li><div id="sourcecode"></li>
+     </ul>
+     2beb4fd7289998159f61976143f66bb6</p>
+
+     <p></div></p>
+
+     </div>
+
+>>> That is quite strange.  I tested your version of the plugin.  I had to revert one your changes to get it to
+>>> work: the linenumber argument should not have a space at the end of it.  Once I made that change,
+>>> everything worked as expected.  The output I get for your example is below:
+
+    <div id="content">
+    <ul>
+    <li><div id="sourcecode"></li>
+    </ul>
+    
+    <pre><tt><span class="linenum">00001:</span> <span class="normal">test</span></tt></pre>
+    
+    <p></div></p>
+    
+    </div>
+
+>>> I don't know what is going wrong for you... source-highlight, Markdown or something else.
+>>> I do find it interesting the way the sourcecode `div` and the list get interleaved.  That
+>>> just looks like a Markdown thing though.
+>>> In any case, I've updated the patch below to include most of your changes.  -- [[Will]]
+
 ----
 
     #!/usr/bin/perl
     # markup source files
+    # Originally by Will Uther
+    # With modifications by David Bremner
     package IkiWiki::Plugin::sourcecode;
     
     use warnings;
@@ -17,143 +70,145 @@ Note that if this is being used with `c` or `c++` then you'll probably want to w
     
     my %metaheaders;
     
-    sub import { #{{{
-       hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
-       hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
-       hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
-    } # }}}
-    
-    sub getsetup () { #{{{
-       return 
-               plugin => {
-                       safe => 1,
-                       rebuild => 1, # format plugin
-               },
-               sourcecode_command => {
-                       type => "string",
-                       example => "/usr/bin/source-highlight",
-                       description => "The command to execute to run source-highlight",
-                       safe => 0,
-                       rebuild => 1,
-               },
-               sourcecode_lang => {
-                       type => "string",
-                       example => "c,cpp,h,java",
-                       description => "Comma separated list of suffixes to recognise as source code",
-                       safe => 1,
-                       rebuild => 1,
-               },
-               sourcecode_linenumbers => {
-                       type => "boolean",
-                       example => 1,
-                       description => "Should we add line numbers to the source code",
-                       safe => 1,
-                       rebuild => 1,
-               },
-               sourcecode_css => {
-                       type => "string",
-                       example => "sourcecode_style",
-                       description => "page to use as css file for source",
-                       safe => 1,
-                       rebuild => 1,
-               },
-    } #}}}
-    
-    sub checkconfig () { #{{{
-       if (! $config{sourcecode_lang}) {
-               error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
-       }
-       
-       if (! $config{sourcecode_command}) {
-               $config{sourcecode_command} = "source-highlight";
-       }
-       
-       if (! length `which $config{sourcecode_command} 2>/dev/null`) {
-               error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
-       }
-    
-       if (! $config{sourcecode_css}) {
-               $config{sourcecode_css} = "sourcecode_style";
-       }
-       
-       if (! defined $config{sourcecode_linenumbers}) {
-               $config{sourcecode_linenumbers} = 1;
-       }
-       
-       my %langs = ();
-       
-       open(LANGS, "$config{sourcecode_command} --lang-list|");
-       while (<LANGS>) {
-               if ($_ =~ /(\w+) = .+\.lang/) {
-                       $langs{$1} = 1;
-               }
-       }
-       close(LANGS);
-       
-       foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
-               if ($langs{$lang}) {
-                       hook(type => "htmlize", id => $lang, call => \&htmlize);
-               } else {
-                       error("Your installation of source-highlight cannot handle sourcecode language $lang!");
-               }
-       }
-    } #}}}
-    
-    sub htmlize (@) { #{{{
-       my %params=@_;
-    
-       my $page = $params{page};
-    
-       eval q{use FileHandle};
-       error($@) if $@;
-       eval q{use IPC::Open2};
-       error($@) if $@;
-    
-       local(*SPS_IN, *SPS_OUT);  # Create local handles
-    
-       my @args;
-    
-       if ($config{sourcecode_linenumbers}) {
-               push @args, '--line-number= ';
-       }
-    
-       my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
-                                       '-s', IkiWiki::pagetype($pagesources{$page}),
-                                       '-c', $config{sourcecode_css}, '--no-doc',
-                                       '-f', 'xhtml',
-                                       @args);
-    
-       error("Unable to open $config{sourcecode_command}") unless $pid;
-    
-       print SPS_OUT $params{content};
-       close SPS_OUT;
-    
-       my @html = <SPS_IN>;
-       close SPS_IN;
-       
-       waitpid $pid, 0;
-    
-       my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
-       if (length $stylesheet) {
-               push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
-                       ' rel="stylesheet"'.
-                       ' type="text/css" />';
-       }
-    
-       return '<div id="sourcecode">'."\r\n".join("\r\n",@html)."\r\n</div>\n";
-    } # }}}
-    
-    sub pagetemplate (@) { #{{{
-       my %params=@_;
-    
-       my $page=$params{page};
-       my $template=$params{template};
-    
-       if (exists $metaheaders{$page} && $template->query(name => "meta")) {
-               # avoid duplicate meta lines
-               my %seen;
-               $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
-       }
-    } # }}}
+    sub import {
+        hook(type => "getsetup", id => "sourcecode", call => \&getsetup);
+        hook(type => "checkconfig", id => "sourcecode", call => \&checkconfig);
+        hook(type => "pagetemplate", id => "sourcecode", call => \&pagetemplate);
+    }
+    
+    sub getsetup () {
+        return 
+            plugin => {
+                safe => 1,
+                rebuild => 1, # format plugin
+            },
+            sourcecode_command => {
+                type => "string",
+                example => "/usr/bin/source-highlight",
+                description => "The command to execute to run source-highlight",
+                safe => 0,
+                rebuild => 1,
+            },
+            sourcecode_lang => {
+                type => "string",
+                example => "c,cpp,h,java",
+                description => "Comma separated list of suffixes to recognise as source code",
+                safe => 1,
+                rebuild => 1,
+            },
+            sourcecode_linenumbers => {
+                type => "boolean",
+                example => 1,
+                description => "Should we add line numbers to the source code",
+                safe => 1,
+                rebuild => 1,
+            },
+            sourcecode_css => {
+                type => "string",
+                example => "sourcecode_style",
+                description => "page to use as css file for source",
+                safe => 1,
+                rebuild => 1,
+            },
+    }
+    
+    sub checkconfig () {
+        if (! $config{sourcecode_lang}) {
+            error("The sourcecode plugin requires a list of suffixes in the 'sourcecode_lang' config option");
+        }
+    
+        if (! $config{sourcecode_command}) {
+            $config{sourcecode_command} = "source-highlight";
+        }
+    
+        if (! length `which $config{sourcecode_command} 2>/dev/null`) {
+            error("The sourcecode plugin is unable to find the $config{sourcecode_command} command");
+        }
+    
+        if (! $config{sourcecode_css}) {
+            $config{sourcecode_css} = "sourcecode_style";
+        }
+    
+        if (! defined $config{sourcecode_linenumbers}) {
+            $config{sourcecode_linenumbers} = 1;
+        }
+    
+        my %langs = ();
+    
+        open(LANGS, "$config{sourcecode_command} --lang-list|");
+        while (<LANGS>) {
+            if ($_ =~ /(\w+) = .+\.lang/) {
+                $langs{$1} = 1;
+            }
+        }
+        close(LANGS);
+    
+        foreach my $lang (split(/[, ]+/, $config{sourcecode_lang})) {
+            if ($langs{$lang}) {
+                hook(type => "htmlize", id => $lang, no_override=>1,
+                call => sub { htmlize(lang=>$lang, @_) }, 
+                keepextension => 1);
+            } else {
+                error("Your installation of source-highlight cannot handle sourcecode language $lang!");
+            }
+        }
+    }
+    
+    sub htmlize (@) {
+        my %params=@_;
+    
+        my $page = $params{page};
+    
+        eval q{use FileHandle};
+        error($@) if $@;
+        eval q{use IPC::Open2};
+        error($@) if $@;
+    
+        local(*SPS_IN, *SPS_OUT);  # Create local handles
+    
+        my @args;
+    
+        if ($config{sourcecode_linenumbers}) {
+            push @args, '--line-number';
+        }
+    
+        my $pid = open2(*SPS_IN, *SPS_OUT, $config{sourcecode_command},
+                        '-s', $params{lang},
+                        '-c', $config{sourcecode_css}, '--no-doc',
+                        '-f', 'xhtml',
+                        @args);
+    
+        error("Unable to open $config{sourcecode_command}") unless $pid;
+    
+        print SPS_OUT $params{content};
+        close SPS_OUT;
+    
+        my @html = <SPS_IN>;
+        close SPS_IN;
+    
+        waitpid $pid, 0;
+    
+        my $stylesheet=bestlink($page, $config{sourcecode_css}.".css");
+        if (length $stylesheet) {
+            push @{$metaheaders{$page}}, '<link href="'.urlto($stylesheet, $page).'"'.
+                ' rel="stylesheet"'.
+                ' type="text/css" />';
+        }
+    
+        return '<div id="sourcecode">'."\r\n".join("",@html)."\r\n</div>\r\n";
+    }
+    
+    sub pagetemplate (@) {
+        my %params=@_;
+    
+        my $page=$params{page};
+        my $template=$params{template};
+    
+        if (exists $metaheaders{$page} && $template->query(name => "meta")) {
+            # avoid duplicate meta lines
+            my %seen;
+            $template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
+        }
+    }
     
     1
diff --git a/doc/todo/avatar.mdwn b/doc/todo/avatar.mdwn
new file mode 100644 (file)
index 0000000..b8aa232
--- /dev/null
@@ -0,0 +1,47 @@
+[[!tag wishlist]]
+
+It would be nice if ikiwiki, particularly [[plugins/comments]]
+supported user avatar icons. I was considering adding a directive for this,
+as designed below.
+
+However, there is no *good* service for mapping openids to avatars --
+openavatar has many issues, including not supporting delegated openids, and
+after trying it, I don't trust it to push users toward. 
+Perhaps instead ikiwiki could get the email address from the openid
+provider, though I think the perl openid modules don't support the openid
+2.x feature that allows that.
+
+At the moment, working on this doesn't feel like a good use of my time.
+--[[Joey]]
+
+Hmm.. unless is just always used a single provider (gravatar) and hashed
+the openid. Then wavatars could be used to get a unique avatar per openid
+at least. --[[Joey]] 
+
+----
+
+The directive displays a small avatar image for a user. Pass it the
+email address, openid, or wiki username of the user.
+
+       \[[!avatar user@example.com]]
+       \[[!avatar http://joey.kitenet.net/]]
+       \[[!avatar user]]
+
+The avatars are provided by various sites. For email addresses, it uses a
+[gravatar](http://gravatar.com/). For openid,
+[openavatar](http://www.openvatar.com/) is used. For a wiki username, the
+user's email address is looked up and the gravatar for that user is
+displayed. (Of course, the user has to have filled in their email address
+on their Preferences page for that to work.)
+
+An optional second parameter can be included, containing additional
+options to pass in the 
+[gravatar url](http://en.gravatar.com/site/implement/url).
+For example, this asks for a smaller gravatar, and if a user does
+not have a gravatar, uses a cute auto-generated "wavatar" avatar.
+
+       \[[!gravatar user@example.com "size=40&default=wavatar"]]
+
+The `gravitar_options` setting in the setup file can be used to
+specify additional options to pass. So for example if you want
+to use wavatars everywhere, set it to "default=wavatar".
diff --git a/doc/todo/avoid_thrashing.mdwn b/doc/todo/avoid_thrashing.mdwn
new file mode 100644 (file)
index 0000000..45b11d8
--- /dev/null
@@ -0,0 +1,22 @@
+Problem: Suppose a server has 256 mb ram. Each ikiwiki process needs about
+15 mb, before it's loaded the index. (And maybe 25 after, but only one such
+process runs at any time). That allows for about 16 ikiwiki processes to
+run concurrently on a server, before it starts to swap. Of course, anything
+else that runs on the server and eats memory will affect this.
+
+One could just set `MaxClients 16` in the apache config, but then it's also
+limited to 16 clients serving static pages, which is silly. Also, 16 is
+optimistic -- 8 might be a saner choice. And then, what if something on the
+server decides to eat a lot of memory? Ikiwiki can again overflow memory 
+and thrash.
+
+It occurred to me that the ikiwiki cgi wrapper could instead do locking of
+its own (say of `.ikiwiki/cgilock`). The wrapper only needs a few kb to
+run, and it starts *fast*. So hundreds could be running waiting for a lock
+with no ill effects. Crank `MaxClients` up to 256? No problem..
+
+And there's no real reason to allow more than one ikiwiki cgi to run at a
+time. Since almost all uses of the CGI lock the index, only one can really
+be doing anything at a time. --[[Joey]]
+
+[[done]]
index 60b1e2515c9ee0d57b5d5003c333b345396fb453..bb91ffd02a299f6cb6e44e2ab241854338237515 100644 (file)
@@ -51,13 +51,13 @@ Index: IkiWiki/Plugin/blogpost.pm
 +use POSIX;
 +use IkiWiki 2.00;
 +
-+sub import { #{{{
++sub import {
 +      hook(type => "checkconfig", id => "blogpost", call => \&checkconfig);
 +      hook(type => "authcgi", id => "blogpost", call => \&authcgi);
 +      hook(type => "canedit", id => "blogpost", call => \&canedit);
-+} # }}}
++}
 +
-+sub checkconfig () { #{{{
++sub checkconfig () {
 +      if (! defined $config{blogformat}){
 +              $config{blogformat} = 'posts/%Y/%m/%d/$title';
 +      }
@@ -72,9 +72,9 @@ Index: IkiWiki/Plugin/blogpost.pm
 +      if (! defined $config{blogusers}) {
 +              $config{blogusers} = (); # disallow all posting by default
 +      }
-+} #}}}
++}
 +
-+sub authcgi ($$) { #{{{
++sub authcgi ($$) {
 +      my $cgi=shift;
 +      my $session=shift;
 +
@@ -115,16 +115,16 @@ Index: IkiWiki/Plugin/blogpost.pm
 +              $cgi->param("page", $page);
 +      }
 +
-+} #}}}
++}
 +
-+sub blogpage ($) { #{{{
++sub blogpage ($) {
 +      my $title=shift;
 +      my $page=POSIX::strftime $config{blogformat}, localtime;
 +      $page =~ s/\$title/$title/;
 +      return $page;
-+} #}}}
++}
 +
-+sub canedit ($$$) { #{{{
++sub canedit ($$$) {
 +      my $page=shift;
 +      my $cgi=shift;
 +      my $session=shift;
@@ -136,7 +136,7 @@ Index: IkiWiki/Plugin/blogpost.pm
 +      return "" if ($config{blogusers} eq "*" ||
 +                    grep {$_ eq $user} $config{blogusers});
 +      return ("not allowed to blog, $user");
-+} #}}}
++}
 +
 +1
 Index: IkiWiki.pm
index 179ea2f24db7ced98c4838858af9c14277c8d668..a50c58d26d1deaee5a1a2dbbef66c09ed848371d 100644 (file)
@@ -56,15 +56,15 @@ and rcs_getctime and rcs_notify aren't written at all. --[[bma]]
             return @ret;
     }
     
-    sub rcs_update () { #{{{
+    sub rcs_update () {
             # Not needed.
-    } #}}}
+    }
     
-    sub rcs_prepedit ($) { #{{{
+    sub rcs_prepedit ($) {
             return "";
-    } #}}}
+    }
     
-    sub rcs_commit ($$$;$$) { #{{{
+    sub rcs_commit ($$$;$$) {
             my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
     
             if (defined $user) {
@@ -95,18 +95,18 @@ and rcs_getctime and rcs_notify aren't written at all. --[[bma]]
             system("bzr","whoami",$olduser);
     
             return undef; # success
-    } #}}}
+    }
     
-    sub rcs_add ($) { # {{{
+    sub rcs_add ($) {
             my ($file) = @_;
     
             my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
             if (system(@cmdline) != 0) {
                     warn "'@cmdline' failed: $!";
             }
-    } #}}}
+    }
     
-    sub rcs_recentchanges ($) { #{{{
+    sub rcs_recentchanges ($) {
             my ($num) = @_;
     
             eval q{use CGI 'escapeHTML'};
@@ -153,15 +153,15 @@ and rcs_getctime and rcs_notify aren't written at all. --[[bma]]
             }
     
             return @ret;
-    } #}}}
+    }
     
-    sub rcs_notify () { #{{{
+    sub rcs_notify () {
             # TODO
-    } #}}}
+    }
     
-    sub rcs_getctime ($) { #{{{
+    sub rcs_getctime ($) {
             # TODO
-    } #}}}
+    }
     
     1
 
index c8ffe70055dcb2a2186fcdc10ff64500fceaf245..8bf7042df2eee760a69583d96349569b42f134b4 100644 (file)
@@ -43,11 +43,11 @@ follows) ?
 > the use of it: `eval q{use AuthCAS}; error $@ if $@`
 
     +
-    +sub import { #{{{
+    +sub import {
     +    hook(type => "getopt", id => "cas", call => \&getopt);
     +    hook(type => "auth", id => "cas", call => \&auth);
     +    hook(type => "formbuilder_setup", id => "cas", call => \&formbuilder_setup);
-    +} # }}}
+    +}
 
 > Could you please use tabs for indentation of program flow?
 
@@ -61,15 +61,15 @@ follows) ?
 > Why would you want to make other auth plugins not work? Could a site not
 > legitimatly chose to use this and another auth method?
 
-    +sub getopt () { #{{{
+    +sub getopt () {
     +    eval q{use Getopt::Long};
     +    error($@) if $@;
     +    Getopt::Long::Configure('pass_through');
     +    GetOptions("cas_url=s" => \$config{cas_url});
     +    GetOptions("ca_file=s" => \$config{ca_file});
-    +} #}}}
+    +}
     +
-    +sub auth ($$) { #{{{
+    +sub auth ($$) {
     +    my $q=shift;
     +    my $session=shift;
     +
@@ -98,11 +98,11 @@ follows) ?
     +            error("CAS failure: ".&AuthCAS::get_errors());
     +        }
     +    }
-    +} #}}}
+    +}
     +
     +# I use formbuilder_setup and not formbuilder type in order to bypass the
     +# Logout processing done in IkiWiki::CGI::cgi_prefs()
-    +sub formbuilder_setup (@) { #{{{
+    +sub formbuilder_setup (@) {
     +    my %params=@_;
     +    
     +    my $form=$params{form};
diff --git a/doc/todo/clear_page_to_delete.mdwn b/doc/todo/clear_page_to_delete.mdwn
new file mode 100644 (file)
index 0000000..6bab6ef
--- /dev/null
@@ -0,0 +1,33 @@
+Would it make sense to automatically delete a page if it's edited and
+cleared to be entirely empty (or only have whitespace)? Discuss. --[[Joey]]
+
+ I'd say so; yes. A method of deleting pages via the web would be great; I
+can't think of a use of keeping blank pages around. What about vandalism --
+if someone blanks a page and deletes it and someone else wishes to restore
+it; or is undoing edits via the web a bigger issue? -- [[users/Jon]]
+
+Of course there's already a way to delete pages (remove plugin). So the
+question is really:
+
+* Does it make sense to have a second way to do it, by clearing the page?
+* Should it be enabled even if the full remove plugin isn't?
+
+Re vandalism in general, I am generally happy using git-revert to kill the
+offending change. --[[Joey]]
+
+I don't think we need a second way to delete pages, which would probably be
+used by the only few people who will learn it's possible by random
+documentation reading, find it useful, *and* remember it. -- [[intrigeri]]
+
+On the other hand, clearing the page's whole content essentially means deleting
+the page.  That's what the user intended to do in this case.  The information
+content of an empty vs. a deleted page is essentially the same, I'd say.  But
+having ikiwiki remove those stale pages would save some (minimal, admittedly)
+time needed for manual clean-up.  --[[tschwinge]]
+
+On EmacsWiki, a page is marked for deletion when it contains just the DeletedPage 
+keyword and if there were no page editions since XX days. Here, I use pages that
+can be empty everyday and filled all day long. It does not make sense to me to 
+delete these pages :). --[[xma]]
+
+I was not aware of [[plugins/remove]]. I don't think another method is necessary -- [[users/Jon]]
index 69afe837d1f66ef8b5721c9357fc44487dd316b3..19fba3b3506e82f7e3e5746e68706703cd379fbc 100644 (file)
@@ -132,12 +132,12 @@ Of course, I'm open for discussion or exchange of ideas :) --[[Paweł|ptecza]]
        +use strict;
        +use IkiWiki 2.00;
        +
-       +sub import { #{{{
+       +sub import {
        +       hook(type => "preprocess", id => "color", call => \&preprocess);
        +       hook(type => "format",     id => "color", call => \&format);
-       +} #}}}
+       +}
        +
-       +sub preserve_style ($$$) { #{{{
+       +sub preserve_style ($$$) {
        +       my $foreground = shift;
        +       my $background = shift;
        +       my $text       = shift;
@@ -162,18 +162,18 @@ Of course, I'm open for discussion or exchange of ideas :) --[[Paweł|ptecza]]
        +       
        +       return $preserved;
        +
-       +} #}}}
+       +}
        +
-       +sub replace_preserved_style ($) { #{{{
+       +sub replace_preserved_style ($) {
        +       my $content = shift;
        +
        +       $content =~ s!<span class="color">((color: ([a-z]+|\#[0-9a-f]{3,6})?)?((; )?(background-color: ([a-z]+|\#[0-9a-f]{3,6})?)?)?)</span>!<span class="color" style="$1">!g;
        +       $content =~ s!<span class="colorend">!!g;
        +
        +       return $content;
-       +} #}}}
+       +}
        +
-       +sub preprocess (@) { #{{{
+       +sub preprocess (@) {
        +       my %params = @_;
        +
        +       # Preprocess the text to expand any preprocessor directives
@@ -182,14 +182,14 @@ Of course, I'm open for discussion or exchange of ideas :) --[[Paweł|ptecza]]
        +                               IkiWiki::filter($params{page}, $params{destpage}, $params{text}));
        +
        +       return preserve_style($params{foreground}, $params{background}, $params{text});
-       +} #}}}
+       +}
        +
-       +sub format (@) { #{{{
+       +sub format (@) {
        +       my %params = @_;
        +
        +       $params{content} = replace_preserved_style($params{content});
        +       return $params{content};        
-       +} #}}}
+       +}
        +
        +1
        --- /dev/null   2008-06-21 02:02:15.000000000 +0200
diff --git a/doc/todo/comments.mdwn b/doc/todo/comments.mdwn
new file mode 100644 (file)
index 0000000..7a113be
--- /dev/null
@@ -0,0 +1,170 @@
+# Known issues with the [[plugins/comments]] plugin
+
+## Unimplemented
+
+* Instead of just a link to add a comment, it could have a form to enter
+  the title, similar to the form for adding a new blog post.
+
+  > I'm not sure this is so useful? On Livejournal titles are allowed on
+  > comments, but very rarely used (and indeed usually not very useful);
+  > it's hard enough to get some people to title their blog posts :-)
+  > --[[smcv]]
+
+## Won't fix
+
+* Because IkiWiki generates static HTML, we can't have a form inlined in
+  page.tmpl where the user fills in an entire comment and can submit it in
+  a single button-press, without being vulnerable to cross-site request forgery.
+  So I'll put this in as wontfix. --[[smcv]]
+
+  > Surely there's a way around that?
+  > A web 2.0 way comes to mind: The user clicks on a link
+  > to open the comment post form. While the nasty web 2.0 javascript :)
+  > is manipulating the page to add the form to it, it looks at the cookie
+  > and uses that to insert a sid field.
+  > 
+  > Or, it could have a mandatory preview page and do the CSRF check then.
+  > --[[Joey]]
+
+* It would be useful to have a pagespec that always matches all comments on
+  pages matching a glob. Something like `comment(blog/*)`.
+  Perhaps postcomment could also be folded into this? Then the pagespec
+  would match both existing comments, as well as new comments that are
+  being posted.
+
+  > Please see [[plugins/comments/discussion]]. If I've convinced you that
+  > internal pages are the way forward, then sure, we can do that, because
+  > people who can comment still won't be able to edit others' comments
+  > (one of my goals is that commenters can't put words into each other's
+  > mouths :-) )
+  >
+  > On the other hand, if you still want me to switch this plugin to "real"
+  > pages, or if internal pages might become editable in future, then
+  > configuring lockedit/anonok so a user X can add comments to blog pages
+  > would also let X edit/delete comments on blog pages (including those
+  > written by others) in arbitrary ways, which doesn't seem good. --[[smcv]]
+
+  > I had a look at implementing comment() and fell afoul of
+  > some optimisations that assume only internal() will be used to match
+  > internal pages. So probably this isn't worth doing. --[[Joey]]
+
+## Done
+
+* There is some common code cargo-culted from other plugins (notably inline and editpage) which
+  should probably be shared
+
+  > Actually, there's less of this now than there used to be - a lot of simple
+  > things that were shared have become unshareable as they became more
+  > complex. --[[smcv]]
+
+  > There's still goto. You have a branch for that. --[[Joey]] 
+
+  >> Now merged --[[smcv]]
+
+* The default template should have a (?) icon next to unauthenticated users (with the IP address
+  as title) and an OpenID icon next to OpenIDs
+
+  > Done in my comments git branch, at least as a mockup (using the (?),
+  > {x} and {*} smileys for anonymous, OpenID and login respectively).
+  > --[[smcv]]
+
+  >> I've improved this to use independent icons from the wikiicons
+  >> directory (untested!) --[[smcv]]
+
+  >>> The new code produces links like /wikiisons/openid.png, which
+  >>> fail if ikiwiki is not at the root of the web server. --[[Joey]]
+
+  >>>> Sorry, I should have spotted that (the assumption failed on my demo
+  >>>> site, but the push to that site was when I was on the way out, so I
+  >>>> didn't have time to investigate). As a note for other ikiwiki hackers,
+  >>>> I should have used
+  >>>> `<img src="<TMPL_VAR NAME=BASEURL>wikiicons/openid.png" />`. --[[smcv]]
+
+  >>> I got to wondering if the icons are needed. On my comments branch
+  >>> (not master), I've dropped the icons and info can be seen by hovering
+  >>> over the author's name. Idea being that you probably don't care how
+  >>> they authenticated unless something is weird, and in that case you
+  >>> can hover to check. Does that make sense, should I merge it?
+  >>> --[[Joey]]
+
+  >>>> Yeah, go ahead. I preferred my layout with the author before the
+  >>>> comment - perhaps that's Livejournal's influence :-) - but I can always
+  >>>> edit the templates for my own site. As long as the default is something
+  >>>> reasonable and both layouts are possible, I don't really mind.
+  >>>> Minimizing the number of "resource" files in the basewiki also seems
+  >>>> a good goal. --[[smcv]]
+
+* Previews always say "unknown IP address"
+
+  > Fixed in my comments branch by commits bc66a00b and 95b3bbbf --[[smcv]]
+
+* The Comments link in the "toolbar" is to `index.html#comments`, not the
+  desired `./#comments`
+
+  > Fixed in my comments branch by commit 0844bd0b; commits 5b1cf21a
+  > and c42f174e fix another `beautify_urlpath` bug and add a regression test
+  > --[[smcv]]
+
+
+* Now that inline has some comments-specific functionality anyway, it would
+  be good to output `<link rel="comments">` in Atom and the equivalent in RSS.
+
+  > Fixed in my comments branch by d0d598e4, 3feebe31, 9e5f504e --[[smcv]]
+
+
+* Add `COMMENTOPENID`: the authenticated/verified user name, if and only if it was an OpenID
+
+  > Done in my comments git branch --[[smcv]]
+
+  > Not seeing it there, which branch? --[[Joey]]
+
+  >> Bah, git push --all is not the default... 'comments' branch now (I've also rebased it).
+  >> Sorry, I'm on mobile Internet at the moment... --[[smcv]]
+
+  >>> merged by [[Joey]] in commit 0f03af38 --[[smcv]]
+
+* Should the comments be visually set off more from the page above?
+  Rather than just a horizontal rule, I'm thinking put the comments
+  in a box like is used for inlined pages.
+
+  > I did put them in a box in the CSS... I agree the default template
+  > could do with visual improvement though. --[[smcv]]
+
+  >> I'll consider this solved by [[Joey]]'s changes. --[[smcv]]
+
+* One can use inline to set up a feed of all comments posted to any page.
+  Using template=comment they are displayed right. Only problem
+  is there is no indication in that template of what page each comment in the
+  feed is a comment on. So, if a comment is inlined into a different page,
+  I think it should show a link back to the page commented on.
+  (BTW, the rss feed in this situation seems ok; there the link element
+  points back to the parent page.
+
+  > done --[[Joey]]
+
+* One of Joey's commit messages says "Not ideal, it would be nicer to jump to
+  the actual comment posted, but no anchor is available". In fact there is
+  an anchor - the `\[[_comment]]` preprocessing wraps the comment in a `<div>`
+  with id="comment_123" or something. I'll fix this, unless Joey gets there
+  first. --[[smcv]]
+
+  > done --[[Joey]]
+
+* If a spammer posts a comment, it is either impossible or hard to clean
+  up via the web. Would be nice to have some kind of link on the comment
+  that allows trusted users to remove it (using the remove plugin of
+  course).
+
+  > Won't the remove plugin refuse to remove internal pages? This would be
+  > a good feature to have, though. --[[smcv]]
+
+  > Here, FWIW, is the first ikiwiki comment spam I've seen:
+  > <http://waldeneffect.org/blog/Snake_bite_information/#blog/Snake_bite_information/comment_1>
+  > So that took about 10 days...
+  > --[[Joey]] 
+
+  >> Implemented in my 'comments' branch, please review. It turns out
+  >> [[plugins/remove]] is happy to remove internal pages, so it was quite
+  >> easy to do. --[[smcv]]
+
+  >>> done --[[Joey]] 
index 3ed50503a61bd00c51e23d8e39bc23eff18f6bb4..f8b1dbbaba7bd57857c9767d6acb3e4ad10e6413 100644 (file)
@@ -3,3 +3,8 @@ It would be nice if the sure could set the timezone of the wiki, and have ikiwik
 This is nice for shared hosting, and other situation where the user doesn't have control over the server timezone.
 
 > [[done]] via the ENV setting in the setup file. --[[Joey]]
+
+
+Example (ikiwiki.setup):
+
+    ENV => { TZ => "Europe/Sofia" }
index b8ddfd485fdcbe6a7e05976e3a8a80e7563f6cd6..882a41379dde48ebebc2dbb4f3c4b524521a4ae1 100644 (file)
@@ -219,14 +219,14 @@ This is my ([bma](bma@bmalee.eu)) darcs.pm - it's messy (my Perl isn't up to muc
        
        package IkiWiki;
        
-       sub rcs_update () { #{{{
+       sub rcs_update () {
                # Do nothing - there's nowhere to update *from*.
-       } #}}}
+       }
        
-       sub rcs_prepedit ($) { #{{{
-       } #}}}
+       sub rcs_prepedit ($) {
+       }
        
-       sub rcs_commit ($$$;$$) { #{{{
+       sub rcs_commit ($$$;$$) {
                my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
        
                # $user should probably be a name and an email address, by darcs
@@ -257,16 +257,16 @@ This is my ([bma](bma@bmalee.eu)) darcs.pm - it's messy (my Perl isn't up to muc
        
                return undef; # success
                
-       sub rcs_add ($) { # {{{
+       sub rcs_add ($) {
                my ($file) = @_;
        
                my @cmdline = ("darcs", "add", "--repodir", "$config{srcdir}", "-a", "-q", "$file");
                if (system(@cmdline) != 0) {
                        warn "'@cmdline' failed: $!";
                }
-       } #}}}
+       }
        
-       sub rcs_recentchanges ($) { #{{{
+       sub rcs_recentchanges ($) {
                # TODO: This is horrible code. It doesn't work perfectly, and uses regexes
                # rather than parsing Darcs' XML output.
                my $num=shift;
@@ -314,15 +314,15 @@ This is my ([bma](bma@bmalee.eu)) darcs.pm - it's messy (my Perl isn't up to muc
                                }
                }
                return @ret;
-       } #}}}
+       }
        
-       sub rcs_notify () { #{{{
+       sub rcs_notify () {
                # TODO
-       } #}}}
+       }
        
-       sub rcs_getctime ($) { #{{{
+       sub rcs_getctime ($) {
                error gettext("getctime not implemented");
-       } #}}}
+       }
        
        1
 
@@ -546,4 +546,6 @@ Regarding the repository layout: There are two darcs repositories. One is the `s
 >> `rcs_commit_staged`. For some revision control systems, which
 >> automatically commit modifications, it would be a no-op. --[[Joey]]
 
+>>> Done. --pesco
+
 [[!tag patch]]
index 5a5560d6c454afb13e409a51f615c2fd70fef688..5f33cde4ce1ec824f3f15366635088ccda21a8ca 100644 (file)
@@ -17,11 +17,11 @@ Index: IkiWiki/Plugin/datearchives.pm
 +use strict;
 +use IkiWiki;
 +
-+sub import { #{{{
++sub import {
 +    hook(type => "pagetemplate", id => "datearchives", call => \&pagetemplate, scan => 1);
-+} # }}}
++}
 +
-+sub pagetemplate (@) { #{{{
++sub pagetemplate (@) {
 +    my %args = @_;
 +    my $dt;
 +    eval {
@@ -37,7 +37,7 @@ Index: IkiWiki/Plugin/datearchives.pm
 +        $template->param(ctime => htmllink( $args{page}, $args{destpage}, $link, 0, 0,
 +                                            $template->param('ctime')));
 +       }
-+} # }}}
++}
 +
 +1
 </pre>
index 2f309dea56e665433e55330ffb0f007e216776a2..9d0fc92c9f891699175f3afe0dbbf4f92b9b9ba8 100644 (file)
@@ -126,7 +126,7 @@ Index: IkiWiki/Plugin/search.pm
 +  $PLUCENE_DIR = $config{wikistatedir}.'/plucene';  
 +}
 +
- sub import { #{{{
+ sub import {
 -       hook(type => "getopt", id => "hyperestraier",
 -               call => \&amp;getopt);
 -       hook(type => "checkconfig", id => "hyperestraier",
@@ -142,14 +142,14 @@ Index: IkiWiki/Plugin/search.pm
                 call => \&amp;change);
 -       hook(type => "cgi", id => "hyperestraier",
 -               call => \&amp;cgi);
- } # }}}
+ }
  
--sub getopt () { #{{{
+-sub getopt () {
 -        eval q{use Getopt::Long};
 -       error($@) if $@;
 -        Getopt::Long::Configure('pass_through');
 -        GetOptions("estseek=s" => \$config{estseek});
--} #}}}
+-}
  
 +sub writer {
 +  init();
@@ -165,20 +165,20 @@ Index: IkiWiki/Plugin/search.pm
 +    grep { defined pagetype($_) } @_;
 +}
 +
- sub checkconfig () { #{{{
+ sub checkconfig () {
         foreach my $required (qw(url cgiurl)) {
                 if (! length $config{$required}) {
 @@ -36,112 +58,55 @@
         }
- } #}}}
+ }
  
 -my $form;
--sub pagetemplate (@) { #{{{
+-sub pagetemplate (@) {
 -       my %params=@_;
 -       my $page=$params{page};
 -       my $template=$params{template};
 +#my $form;
-+#sub pagetemplate (@) { #{{{
++#sub pagetemplate (@) {
 +#      my %params=@_;
 +#      my $page=$params{page};
 +#      my $template=$params{template};
@@ -193,7 +193,7 @@ Index: IkiWiki/Plugin/search.pm
 +#
 +#              $template->param(searchform => $form);
 +#      }
-+#} #}}}
++#}
  
 -       # Add search box to page header.
 -       if ($template->query(name => "searchform")) {
@@ -205,9 +205,9 @@ Index: IkiWiki/Plugin/search.pm
 -
 -               $template->param(searchform => $form);
 -       }
--} #}}}
+-}
 -
- sub delete (@) { #{{{
+ sub delete (@) {
 -       debug(gettext("cleaning hyperestraier search index"));
 -       estcmd("purge -cl");
 -       estcfg();
@@ -219,9 +219,9 @@ Index: IkiWiki/Plugin/search.pm
 +    $reader->delete_term( Plucene::Index::Term->new({ field => "id", text => $_ }));
 +  }
 +  $reader->close;
- } #}}}
+ }
  
- sub change (@) { #{{{
+ sub change (@) {
 -       debug(gettext("updating hyperestraier search index"));
 -       estcmd("gather -cm -bc -cl -sd",
 -               map {
@@ -250,9 +250,9 @@ Index: IkiWiki/Plugin/search.pm
 +    $doc->add(Plucene::Document::Field->UnStored('text' => $data));
 +    $writer->add_document($doc);
 +  }
- } #}}}
+ }
 -
--sub cgi ($) { #{{{
+-sub cgi ($) {
 -       my $cgi=shift;
 -
 -       if (defined $cgi->param('phrase') || defined $cgi->param("navi")) {
@@ -260,10 +260,10 @@ Index: IkiWiki/Plugin/search.pm
 -               chdir("$config{wikistatedir}/hyperestraier") || error("chdir: $!");
 -               exec("./".IkiWiki::basename($config{cgiurl})) || error("estseek.cgi failed");
 -       }
--} #}}}
+-}
 -
 -my $configured=0;
--sub estcfg () { #{{{
+-sub estcfg () {
 -       return if $configured;
 -       $configured=1;
 -
@@ -301,9 +301,9 @@ Index: IkiWiki/Plugin/search.pm
 -       unlink($cgi);
 -       my $estseek = defined $config{estseek} ? $config{estseek} : '/usr/lib/estraier/estseek.cgi';
 -       symlink($estseek, $cgi) || error("symlink $estseek $cgi: $!");
--} # }}}
+-}
 -
--sub estcmd ($;@) { #{{{
+-sub estcmd ($;@) {
 -       my @params=split(' ', shift);
 -       push @params, "-cl", "$config{wikistatedir}/hyperestraier";
 -       if (@_) {
@@ -323,7 +323,7 @@ Index: IkiWiki/Plugin/search.pm
 -               open(STDOUT, "/dev/null"); # shut it up (closing won't work)
 -               exec("estcmd", @params) || error("can't run estcmd");
 -       }
--} #}}}
+-}
 -
 -1
 +1;
index 1f6307381ea20a23b5a884abdf45fa0f68d9e430..2baa61b402bd89ff357c97feac0be688491a5aa9 100644 (file)
@@ -40,15 +40,15 @@ defined them:  --[[Joey]]
     index e476521..afe982a 100644
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -493,6 +493,7 @@ sub loadplugins () { #{{{
+    @@ -493,6 +493,7 @@ sub loadplugins () {
        return 1;
-     } #}}}
+     }
      
     +my $loading_plugin;
-     sub loadplugin ($) { #{{{
+     sub loadplugin ($) {
        my $plugin=shift;
      
-    @@ -502,14 +503,18 @@ sub loadplugin ($) { #{{{
+    @@ -502,14 +503,18 @@ sub loadplugin ($) {
                         "$installdir/lib/ikiwiki") {
                if (defined $dir && -x "$dir/plugins/$plugin") {
                        require IkiWiki::Plugin::external;
@@ -67,7 +67,7 @@ defined them:  --[[Joey]]
        if ($@) {
                error("Failed to load plugin $mod: $@");
        }
-    @@ -1429,6 +1434,9 @@ sub hook (@) { # {{{
+    @@ -1429,6 +1434,9 @@ sub hook (@) {
      
        return if $param{no_override} && exists $hooks{$param{type}}{$param{id}};
        
@@ -76,4 +76,4 @@ defined them:  --[[Joey]]
     +
        $hooks{$param{type}}{$param{id}}=\%param;
        return 1;
-     } # }}}
+     }
index c7a3d6ac9a2979143323f9f03a81ba2e2046873e..990b7ddb3774980fbb081bf496c46fd85869e253 100644 (file)
@@ -30,4 +30,4 @@ I don't think that the nesting is very clear, I found it confusing..
 
 Would each page be its own individual blog? Or its own blog post? To me it seems like an entire wiki can be viewed as a blog, with threaded or unthreaded comments underneath.
 
-[[!tag soc]]
+[[!tag soc done]]
index fa0e23254fcf24fab1a625417ffb4fdc4e5ec31e..5cf80b0a8ea397248531978a2f11b844ff3f068d 100644 (file)
@@ -23,3 +23,10 @@ What's your opinion, Joey? I hope it's also useful for another ikiwiki lovers :)
 >>> Seems like a job for good ol' string interpolation.  rootpage="post/$current_year/$current_month/$current_day"
 >>> Ikiwiki could provide some vars, and it would be nice to write plugins to also provide vars.  Sort of like templates.
 >>> Does that feel OK? --[[sabr]]
+
+> I want the exact same thing.  My compromise was to create a `datedblog` module which overrides `inline`'s `sessioncgi` hook
+> with something that sets the new page name to `%Y-%m-%d.$page` and sets up a meta directive at the beginning of
+> the content, with the title you wanted.  Now if you use the `datedblog` module, you get dated blog entries.  But I'd
+> like to have traditional `inline` functionality too.  This would work great if there were a way to change the `do`
+> parameter in the `blogpost` template's form; if I could change it to `datedblog` instead of `blog` then I could hook
+> my datedblog module in nicely, without having to override anything.  What would be the right way to do that? --[[neale]]
index b3c174fba3f449031748983928fe38e94c161a68..e3b295123484183dcdc8be1e5c184ae8b448b816 100644 (file)
@@ -5,7 +5,7 @@
     @@ -26,7 +26,7 @@
      memoize("file_pruned");
      
-     sub defaultconfig () { #{{{
+     sub defaultconfig () {
     -       wiki_file_prune_regexps => [qr/\.\./, qr/^\./, qr/\/\./,
     +       wiki_file_prune_regexps => [qr/\.\./, qr/^\.(?!htaccess)/, qr/\/\.(?!htaccess)/,
                     qr/\.x?html?$/, qr/\.ikiwiki-new$/,
index b0e92e65c475ab688424f94603fb5c151b804575..c7553f7dd2b8f368b5a1842cec10494f816a62a7 100644 (file)
@@ -41,7 +41,7 @@ Another problimatic thing is plugins often define functions named 'preprocess',
       6 IkiWiki::titlepage
 
 These go together; linkpage is needed by all link plugins, and the others are used widely.
-All should be exported.
+All should be exported. (Done)
 
       7 IkiWiki::saveindex
       5 IkiWiki::loadindex
@@ -92,3 +92,5 @@ Probably needs to evolve more and be more widely used before being exported.
 
 * %IkiWiki::pagecase (aggregate)
 * %IkiWiki::backlinks (pagestats)
+
+[[done]] (until 4.0)..
index 8dfe05581fcb3492bcf627100745ff98386a387f..574883d1b0f3f8e81ac8f935133e2c2076403f40 100644 (file)
@@ -141,13 +141,13 @@ Index: IkiWiki/Plugin/rst.pm
  print html[html.find('<body>')+6:html.find('</body>')].strip();
  ";
  
- sub import { #{{{
+ sub import {
        hook(type => "htmlize", id => "rst", call => \&htmlize);
 +      hook(type => "htmlescape", id => "rst", call => \&htmlescape);
 +      hook(type => "htmlescapelink", id => "rst", call => \&htmlescapelink);
- } # }}}
+ }
  
-+sub htmlescapelink ($$;@) { #{{{
++sub htmlescapelink ($$;@) {
 +      my $url = shift;
 +      my $text = shift;
 +      my %params = @_;
@@ -158,15 +158,15 @@ Index: IkiWiki/Plugin/rst.pm
 +      else {
 +              return "`$text <$url>`_";
 +      }
-+} # }}}
++}
 +
-+sub htmlescape ($) { #{{{
++sub htmlescape ($) {
 +      my $html=shift;
 +      $html=~s/^/  /mg;
 +      return ".. raw:: html\n\n".$html;
-+} # }}}
++}
 +
- sub htmlize (@) { #{{{
+ sub htmlize (@) {
        my %params=@_;
        my $content=$params{content};
 Index: doc/plugins/write.mdwn
@@ -272,7 +272,7 @@ Index: IkiWiki.pm
 +        return $hooks{htmlescapelink}{$type}{call}->($bestlink, $linktext);
 +      }
        return "<a href=\"$bestlink\">$linktext</a>";
- } #}}}
+ }
  
 @@ -628,6 +640,14 @@
                                preview => $preprocess_preview,
index f906312fe6ac883bdfba038bed17b49aee428a1e..ddacd91b526d157917bd5cc6a42271bee63d5745 100644 (file)
@@ -14,9 +14,9 @@
      package IkiWiki::Plugin::fortune;
 
      use warnings;
-    @@ -12,7 +18,13 @@ sub import { #{{{
+    @@ -12,7 +18,13 @@ sub import {
 
-     sub preprocess (@) { #{{{
+     sub preprocess (@) {
             $ENV{PATH}="$ENV{PATH}:/usr/games:/usr/local/games";
     -       my $f = `fortune 2>/dev/null`;
     +       my $f;
diff --git a/doc/todo/generic___39__do__61__goto__39___for_CGI.mdwn b/doc/todo/generic___39__do__61__goto__39___for_CGI.mdwn
new file mode 100644 (file)
index 0000000..26c5202
--- /dev/null
@@ -0,0 +1,35 @@
+The [[plugins/recentchanges]] plugin has a `do=recentchanges_link` feature that will
+redirect to a given wiki page, or an error page with a creation link.
+
+In the [[plugins/contrib/comments]] plugin I've found that it would be useful to do
+the same for users. For now I've just cloned the functionality into the comments
+plugin, but perhaps this functionality could be renamed to `do=goto` or
+something, and moved to `IkiWiki/CGI.pm`?
+
+> Now implemented as the 'goto' branch in my git repository, along with
+> [[apache_404_ErrorDocument_handler]]. --[[smcv]]
+
+>> Looks good, the only things I wonder are:
+>> * Should it be a separate plugin? In particular `cgi_page_from_404()` is
+>>   pretty big, and only works if apache is configured so seems somewhat
+>>   pluginaable.
+
+>>> I've split out `goto` and `apache404` plugins in the branch. I think
+>>> you're right that apache404 should be a plugin. If you think goto is small
+>>> and general enough to not be a plugin, just don't merge my most recent
+>>> patch! --[[smcv]]
+
+>> * I wish there were some way to generalize the workaround for the stupid
+>>   MSIE behavior. Actually, I wish we could ignore the MSIE stupidity,
+>>   as I tend to do, but perhaps it's too stupid in this case for that to
+>>   fly..
+>> * Is there any reason to require do=goto before checking for
+>>   `REDIRECT_STATUS`? Seems that if that code were moved
+>>   out of the enclosing if block, the apache 404 handler could
+>>   be set direct to the cgi, which seems simpler to remember.
+>> --[[Joey]] 
+
+>>> No, good point - the `REDIRECT_STATUS` check is sufficiently unambiguous
+>>> already. Fixed. --[[smcv]]
+
+[[done]]
diff --git a/doc/todo/httpauth_feature_parity_with_passwordauth.mdwn b/doc/todo/httpauth_feature_parity_with_passwordauth.mdwn
new file mode 100644 (file)
index 0000000..eb71cf8
--- /dev/null
@@ -0,0 +1,28 @@
+The only way to have a private ikiwiki, with a shared user database
+for static pages and CGI authentication, is to use
+[[plugins/httpauth]]. It would be good for httpauth to be on par with
+[[plugins/passwordauth]], i.e. to allow registering users, resetting
+passwords, and changing passwords; supporting some kind of
+`account_creation_password` configuration option would be nice, too.
+
+I'll probably propose patches implementing this at some point.
+I've not had a single look at the code yet, but it may be nice to factorize
+the relevant passwordauth code, instead of rewriting it completely in httpauth.
+
+-- [[intrigeri]]
+
+Well, on such a private wiki, one can neither register herself nor
+reset his password: the registration page, as any other page, would be
+forbidden to non-authenticated users. Admin users should then be
+enabled to:
+
+- register a new user
+- reset someone else's password
+
+In both cases, a brand new random password is sent by e-mail to the
+new user.
+
+An authenticated user should nevertheless be able to change his
+own password. -- [[intrigeri]]
+
+[[wishlist]]
index f030f9eea1ded22216fca48f3301d09dcb77dd16..f5e6f8cd7a4f8fa9f290f887d59fea625c3601f6 100644 (file)
@@ -91,15 +91,15 @@ page "A/B/index.html" is treated as "A/B".
     +++ ikidev/IkiWiki.pm       2007-02-25 15:05:22.328852000 -0800
     @@ -192,6 +192,12 @@
         return $untainted;
-     } #}}}
+     }
 
-    +sub titlename($;@) { #{{{
+    +sub titlename($;@) {
     +   my $page = shift;
     +   $page =~ s!/index$!!;
     +   return pagetitle(basename($page), @_);
-    +} #}}}
+    +}
     +
-     sub basename ($) { #{{{
+     sub basename ($) {
         my $file=shift;
 
 
@@ -117,7 +117,7 @@ diff -ru ikiwiki-2.4/IkiWiki.pm ikiwiki/IkiWiki.pm
        $page=~s/\Q.$type\E*$// if defined $type;
 +      $page=~s/\/index$// if $page =~ /\/index$/;
        return $page;
- } #}}}
+ }
  
 </pre>
 
index 95511d99885439f4e7f16a106265702df2d273a7..3d7424b3f606a21b3318b8e19dc11544815392b1 100644 (file)
@@ -1,6 +1,8 @@
 Could you please add numerical ordering by title to [[inline|plugins/inline]]
 plugin? Now I can do only alphabetical order by title, but sometime it's not enough.
 
+> Implemented, see [[natural_sorting]] [[!tag done]] --[[Joey]] 
+
 BTW, it seems that ordering by title is rather ordering by filename of page.
 For me "title" means title of page I can set using `title` parameter
 of [[meta|plugins/meta]] plugin :)
@@ -155,11 +157,11 @@ Joey, have you forgotten about that request? ;) --[[Paweł|ptecza]]
                       %config %links %pagestate %renderedfiles
                       %pagesources %destsources);
      our $VERSION = 2.00; # plugin interface version, next is ikiwiki version
-    @@ -835,6 +835,42 @@ sub titlepage ($) { #{{{
+    @@ -835,6 +835,42 @@ sub titlepage ($) {
        return $title;
-     } #}}}
+     }
      
-    +sub titlecmp ($$) { #{{{
+    +sub titlecmp ($$) {
     +  my $titleA=shift;
     +  my $titleB=shift;
     +  
@@ -193,29 +195,29 @@ Joey, have you forgotten about that request? ;) --[[Paweł|ptecza]]
     +  return -1 if (@listB);
     +  
     +  return 0;
-    +} #}}}
+    +}
     +
-     sub linkpage ($) { #{{{
+     sub linkpage ($) {
        my $link=shift;
        my $chars = defined $config{wiki_file_chars} ? $config{wiki_file_chars} : "-[:alnum:]+/.:_";
     diff --git a/IkiWiki/Plugin/brokenlinks.pm b/IkiWiki/Plugin/brokenlinks.pm
     index 37752dd..ccaa399 100644
     --- a/IkiWiki/Plugin/brokenlinks.pm
     +++ b/IkiWiki/Plugin/brokenlinks.pm
-    @@ -59,7 +59,7 @@ sub preprocess (@) { #{{{
+    @@ -59,7 +59,7 @@ sub preprocess (@) {
                        map {
                                "<li>$_</li>"
                        }
     -                  sort @broken)
     +                  sort titlecmp @broken)
                ."</ul>\n";
-     } # }}}
+     }
      
     diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
     index 8efef3f..263e7a6 100644
     --- a/IkiWiki/Plugin/inline.pm
     +++ b/IkiWiki/Plugin/inline.pm
-    @@ -192,7 +192,7 @@ sub preprocess_inline (@) { #{{{
+    @@ -192,7 +192,7 @@ sub preprocess_inline (@) {
        }
      
        if (exists $params{sort} && $params{sort} eq 'title') {
@@ -228,20 +230,20 @@ Joey, have you forgotten about that request? ;) --[[Paweł|ptecza]]
     index b910758..10a1d87 100644
     --- a/IkiWiki/Plugin/orphans.pm
     +++ b/IkiWiki/Plugin/orphans.pm
-    @@ -56,7 +56,7 @@ sub preprocess (@) { #{{{
+    @@ -56,7 +56,7 @@ sub preprocess (@) {
                                htmllink($params{page}, $params{destpage}, $_,
                                         noimageinline => 1).
                                "</li>"
     -                  } sort @orphans).
     +                  } sort titlecmp @orphans).
                "</ul>\n";
-     } # }}}
+     }
      
     diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
     index ceb7c84..00798e1 100644
     --- a/IkiWiki/Render.pm
     +++ b/IkiWiki/Render.pm
-    @@ -89,7 +89,7 @@ sub genpage ($$) { #{{{
+    @@ -89,7 +89,7 @@ sub genpage ($$) {
                $template->param(have_actions => 1);
        }
      
diff --git a/doc/todo/inline_plugin:_ability_to_override_feed_name.mdwn b/doc/todo/inline_plugin:_ability_to_override_feed_name.mdwn
new file mode 100644 (file)
index 0000000..df5bf91
--- /dev/null
@@ -0,0 +1,29 @@
+If RSS and Atom are enabled by default, the [[plugins/contrib/comments]]
+plugin generates a feed, perhaps `/sandbox/index.atom` for comments on the
+sandbox. If a blog is added to the page, the blog will steal the name
+`/sandbox/index.atom` and the comments plugin's feed will change to
+`/sandbox/index.atom2`.
+
+If `\[[!inline]]` gained a parameter `feedname` or something, the comments
+plugin could use `feedname=comments` to produce `/sandbox/comments.atom`
+instead (this would just require minor enhancements to rsspage(),
+atompage() and targetpage()).
+
+As a side benefit, [my blog](http://smcv.pseudorandom.co.uk/) could go back
+to its historical Atom feed URL of `.../feed.atom` (which is currently a
+symlink to `index.atom` :-) )
+
+On sites not using `usedirs` the current feed is `/sandbox.atom`, and we
+could perhaps change it to `/sandbox-comments.atom` or
+`/sandbox/comments.atom` if `feedname=comments` is given.
+
+--[[smcv]]
+
+> This is slightly hard to do, because you have to worry about 
+> conflicting pages setting feedname, which could cause ikiwiki to blow up.
+> 
+> Particularly for the non-usedirs case, where a page `sandbox/comments`
+> would produce the same feed as sandbox with `feedname=comments`.
+> --[[Joey]]
+
+> [[done]] as feedfile option --[[Joey]]
diff --git a/doc/todo/inline_plugin:_hide_feed_buttons_if_empty.mdwn b/doc/todo/inline_plugin:_hide_feed_buttons_if_empty.mdwn
new file mode 100644 (file)
index 0000000..d046c0c
--- /dev/null
@@ -0,0 +1,7 @@
+      < joeyh> 03:49:19> also, I think it may be less visually confusing to 
+               drop the rss/atom buttons for comments when there are none yet
+
+This seems to me like something that applies to the [[plugins/inline]] plugin in general, rather than the [[plugins/contrib/comments]] plugin specifically. --[[smcv]]
+
+>> [[done]] as emptyfeeds option, not on by default for inline, but I think
+>> it should be for comments --[[Joey]]
diff --git a/doc/todo/inline_postform_autotitles.mdwn b/doc/todo/inline_postform_autotitles.mdwn
new file mode 100644 (file)
index 0000000..5005208
--- /dev/null
@@ -0,0 +1,52 @@
+[[!tag wishlist]]
+[[!tag patch]]
+
+for postforms in inlines of pages which follow a certain scheme, it might not
+be required to set the title for each individual post, but to automatically set
+the title and show no input box prompting for it.
+this can either be based on timestamp formatting, or use the already existing
+munging mechanism, which appends numbers to page titles in case that page
+already exists.
+
+two patches ([1], [2]) set inline up for that, adding an additional `autotitle`
+parameter. if that is given, the regular input of the inline postform will be
+replaced with a hidden input of that text. in addition, the empty title is
+permitted (both for autotitle and regular titles, as they go in the same GET
+parameter, `title`). as the empty page title is illegal, munging is used,
+resulting in ascending numeric page titles to be created.
+
+the second patch is actually a one-liner, filtering the title through strftime.
+
+### potential user interaction issues
+
+this has two side effects which have to be considered: first, the empty page
+title is accepted also in normal postforms (previously, this resulted in a "bad
+page name" error); second, entering a percent sign in that field might result
+in unexpexted strftime substitution (strftime might not even substitute for
+common uses of percent as in "reach 10% market share", but might in others as
+in "the 10%-rule").
+
+both can be circumvented by using another GET parameter for autotexts, as
+implemented in [3].
+> this patch still does not work perfectly; especially, it should make a
+> distinction between "autotitle is set but equal ''" (in which case it
+> should create a page named `1.mdwn`, and "autotitle is not set, and title is
+> equal ''" (in which case it should display the old error message) --[[chrysn]]
+
+### potential security issues
+
+* the autotitle's value is directly output through the template (but that's
+  done in other places as well, so i assume it's safe)
+* i don't know if anything bad can happen if unfiltered content is passed to
+  POSIX::strftime.
+
+### further extension
+
+having a pre-filled input field instead of an unchangable hidden input might be
+cool (eg for creating an entry with yesterday's date), but would be a bit of a
+problem with static pages. javascript could help with the date part, but name
+munging would be yet another thing.
+
+[1]: http://github.com/github076986099/ikiwiki/commit/b568eb257a3ef5ff49a84ac00a3a7465b643c1e1
+[2]: http://github.com/github076986099/ikiwiki/commit/34bc82f232be141edf036d35e8ef5aa289415072
+[3]: http://github.com/github076986099/ikiwiki/commit/40dc10a4ec7809e401b4497c2abccfba30f7a2af
index 33098c601e9ee6f13be3a096313a480e17cb1db9..4ac4e2e2546271628ffe8597e67ab1d6554a0e23 100644 (file)
@@ -54,7 +54,7 @@ This may be useful for sites with a few pages in different languages, but no ful
  my %authorurl;
 +my %lang;
  
- sub import { #{{{
+ sub import {
         hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
 @@ -100,6 +101,11 @@
                 $meta{$page}.='<link href="'.encode_entities($value).
@@ -75,7 +75,7 @@ This may be useful for sites with a few pages in different languages, but no ful
 +       $template->param(lang => $lang{$page})
 +               if exists $lang{$page} && $template->query(name => "lang");
  
- } # }}}
+ }
 </pre>
 
 > Please resolve lang somewhere reusable rather than within meta plugin: It is certainly usable outside
index eb53538b45224af4a63009085f6f05a4b649f8c7..604c5e87f8582a7943ab1eb07ef160268da88101 100644 (file)
@@ -31,6 +31,9 @@ Conversely, how about adding a plugin to support exporting to LaTeX?
 a latex plugin. Examples [here](http://ng.l4x.org/latex/). Currently without image support for hevea. And the latex2html
 output has the wrong charset and no command line switch to change that. Dreamland.
 
+As this link is not working, I setted a mirror here: <a href="http://satangoss.sarava.org/ikiwiki/latex.pm">http://satangoss.sarava.org/ikiwiki/latex.pm</a>.
+
+
 ----
 
 Okay, now is the time for a mid term report i think.
diff --git a/doc/todo/location_of_external_plugins.mdwn b/doc/todo/location_of_external_plugins.mdwn
new file mode 100644 (file)
index 0000000..c28003e
--- /dev/null
@@ -0,0 +1,24 @@
+Would it be possible to make the installation location for the external
+plugins (those talked to via xmlrpc) configurable? Currently, they are
+installed into (and later expected to be in) /usr/lib/ikiwiki/plugins. For
+the Fedora package (which I maintain), I move them to
+/usr/libexec/ikiwiki/plugins. While not covered by the FHS, this seems to
+be a more appropriate place, see:
+https://fedoraproject.org/wiki/Packaging/Guidelines#Libexecdir.
+
+> This would need to be a build time configuration setting so the directory
+> is built into ikiwiki for use at runtime. --[[Joey]]
+
+As a side note, the accompanying proxy.py might better be placed into some directory on the python path.
+
+> If someone can show how to do so without needing a Setup.py and all the
+> pain that using one entails.. --[[Joey]]
+
+>> At the very least I don't think proxy.py should be on the `sys.path`
+>> under its current name. If it was renamed to ikiwiki_proxy or some such,
+>> possibly; but I think it's more appropriate to have it in an
+>> ikiwiki-specific directory (a "private module") since it's not useful for
+>> anything outside ikiwiki, and putting it in the same directory as the
+>> external plugins means it's automatically in their `sys.path` without
+>> needing special configuration. --[[smcv]]
+>> (a mostly-inactive member of Debian's Python modules packaging team)
diff --git a/doc/todo/location_of_ikiwiki-w3m.cgi.mdwn b/doc/todo/location_of_ikiwiki-w3m.cgi.mdwn
new file mode 100644 (file)
index 0000000..8ca925b
--- /dev/null
@@ -0,0 +1,3 @@
+The `ikiwiki-w3m.cgi` script is installed (hard-coded) into `/usr/lib/w3m/cgi-bin`. On Fedora however, the w3m package expects it in `/usr/libexec/w3m/cgi-bin`. So, it would be nice if the destination for this script could be configured.
+
+> You can use `W3M_CGI_BIN now`. [[done]] --[[Joey]]
index 081d512005ad86a0861baeb23b5970127a538717..f7744563cef057d980650b60aded384975e310c8 100644 (file)
@@ -14,3 +14,6 @@ I'd like to be able to drop an unmodified RFC2822 email message into ikiwiki, an
 >>> to page foo). I'm not sure if this is possible and worthwhile to fix. 
 >>  It is certainly workable
 >>> to use a \[[!mailbox ]] directive. -- [[DavidBremner]]
+
+> Your gitweb doesn't tell me where I can git pull this from, which I'd
+> like to do ... --[[Joey]]
diff --git a/doc/todo/mdwn_preview.mdwn b/doc/todo/mdwn_preview.mdwn
new file mode 100644 (file)
index 0000000..c20314c
--- /dev/null
@@ -0,0 +1,305 @@
+The [StackOverflow](http://stackoverflow.com/) site uses markdown for markup.
+It has a fancy javascript thing for showing a real-time preview of what the user
+is editing. It would be nice if ikiwiki could support this, too. The thing they
+use on StackOverflow is supposed to be free software, so it should be easy to
+add to ikiwiki.
+
+> See [[wikiwyg]]. Note that I do not have a copy of the code for that, or
+> it'd be in ikiwiki already. --[[Joey]] 
+
+>> I just had a brief look at the [[wikiwyg]] page and the link to the plugin was
+>> broken.  The StackOverflow site uses the [WMD](http://wmd-editor.com/) editor,
+>> which seems to be related to the [ShowDown](http://attacklab.net/showdown/)
+>> javascript port of Markdown.  Interestingly, [WMD source](http://wmd.googlecode.com/)
+>> is now available under an MIT license, though it is supposedly undergoing heavy
+>> refactoring.  It looks like there was previous discussion ( [[todo/Add_showdown_GUI_input__47__edit]] )
+>> about a showdown plugin.  Maybe a WMD plugin would be worthwhile.  I might
+>> look into it if I have time on the weekend. -- [[Will]]
+
+[[!tag wishlist]]
+
+>>> Below is a simple plugin/[[patch]] to make use of the WMD editor.
+
+>>>> Now added to ikiwiki, thanks! --[[Joey]] 
+
+>>> Turns out it isn't hard at all to
+>>> get a basic version going (which doesn't handle directives at all, nor does it swtich itself off when you're
+>>> editing something other than Markdown source).  I've
+>>> removed the done tag so this is visible as a patch. -- [[Will]]
+
+>>>> Hmm, it would be good if it turned off for !mdwn. Although this could
+>>>> be difficult for a new page, since there is a dropdown selector to
+>>>> choose the markup language then. But it should be doable for editing an
+>>>> existing page.
+
+>>>>> I agree.  I'm working on this for for both new pages and existing pages.
+>>>>> It shouldn't be hard once I get WMD going through the javascript API.
+>>>>> At the moment that is inexplicably failing, and I haven't had time to have a good look at why.
+>>>>> I may not get a chance to look at this again for a few weeks.
+
+>>>> Can I get a license statement (ie, GPL-2+) ffrom you for the plugin?
+>>>> --[[Joey]] 
+
+>>>>> Certainly.  You're free to use the code I posted below under the GPL-2+ license.  You'll note
+>>>>> however that I haven't said anything about the WMD code itself.  The WMD web page says:
+
+>>>>>> "I'm refactoring the code, and will be releasing WMD under the MIT license soon. For now you can download the most recent release (wmd-1.0.1.zip) and use it freely."
+
+>>>>> It might be best to contact <support@attacklab.net> to for an explicit license on that if you want to include it.
+>>>>> -- [[Will]]
+
+> So, I wonder if I should add a copy of the WMD source to ikiwiki, or rely
+> on the user or distribution providing it. It does not seem to be packaged
+> for Debian yet. Hmm, I also can't find any copyright or license info in
+> the zip file. --[[Joey]] 
+
+>> This is a good question.  My thought is that it will probably not be packaged any time soon,
+>> so you're better off adding it to IkiWiki.  I'd contact the author of WMD and ask them.  They
+>> may have more insight.  -- [[Will]]
+
+Note that the WMD plugin does **not** handle directives.  For this reason the normal `preview` button
+remains.  Some CSS to clean up the display of the live WMD preview would be good.
+
+> Can you elucidate the CSS comment -- or will it be obvious what you mean
+> when I try it? Is it what's needed for the live preview? --[[Joey]]
+
+>> In the version of the plugin below, a new `div` is added just below the form.  WMD
+>> populates this div with the HTML it generates from the Markdown source.  This is not very
+>> pretty at the moment - it appears in the same place as the preview used to, but with no
+>> header or anything.  Any standard IkiWiki preview will appear below the WMD live preview.
+>> I recommend having a look at <http://wmd-editor.com/examples/splitscreen>
+>> for what a little CSS could achieve.  -- [[Will]]
+
+> Hmm, now that I've tried it, I notice that it does live preview by
+> default, below the edit window. Which is nice, but then if I hit the
+> preview button, I get two previews.. which is confusing. (Also, minor,
+> but: the live preview is missing the "Page Preview:" header.) --[[Joey]] 
+
+> I wonder how annoying it would be to add some kind of simplistic wikilink
+> support to wmd's preview? And/or a wikilink button? While not supporting
+> directies is fine, not supporting wikilinks in a wiki seems a bit
+> lacking. It may also entice novide users to not use wikilinks and instead
+> use the hyperlinks that wmd does support. --[[Joey]] 
+
+> Bug: When I preview, all the text in the edit field seems to be
+> converted from mdwn to html. I think that wmd is converting the mdwn
+> into html when the form is posted, so it would also save like that.
+> I assume that is designed for websites that do not use markdown
+> internally. Doesn't it have a setting to leave it as markdown?
+>> Found setting, fixed. --[[Joey]] 
+
+>>> As I noted above, I've been working on the non-markdown page issue.
+>>> Below is my a new javascript file that I'm using, and below that a patch
+>>> to enable it.  This patch makes the normal usage prettier - you get
+>>> a side panel with the live preview in it.  It also adds a new config
+>>> option, `wmd_use101api`, which turns on code that tries to use the
+>>> wmd api.  At the moment this code doesn't seem to work - moreover the
+>>> code that uses the new API dies early, so any code after that point is
+>>> completely untested.  I will not
+>>> get a chance to look at this again soon though, so I thought I'd post
+>>> my progress so far.  -- [[Will]]
+
+
+Place the following file in `underlays/wmd/wmd-ikiwiki.js`.
+
+----
+
+    // This is some code to interface the WMD interface 1.0.1 with IkiWiki
+    // The WMD interface is planned to change, so this file will likely need
+    // updating in future.
+    
+    if (useWMDinterface) {
+       wmd_options = { autostart: false, output: "Markdown" };
+       var instance = null;
+    
+       hook("onload", initwmd);
+    } else {
+       var typeSelector = document.getElementById("type");
+       
+       var currentType = getType(typeSelector);
+       
+       if (currentType == "mdwn") {
+               wmd_options = { output: "Markdown" };
+               document.getElementById("wmd-preview-container").style.display = 'none';
+       } else {
+               wmd_options = { autostart: false };
+               document.getElementById("wmd-preview-container").style.display = 'block';
+       }
+    }
+    
+    function initwmd() {
+       if (!Attacklab || !Attacklab.wmd) {
+               alert("WMD hasn't finished loading!");
+               return;
+       }
+       
+       var typeSelector = document.getElementById("type");
+       
+       var currentType = getType(typeSelector);
+       
+       if (currentType == "mdwn") {
+               window.setTimeout(enableWMD,10);
+       }
+       
+       typeSelector.onchange=function() {
+               var docType=getType(this);
+               
+               if (docType=="mdwn") {
+                       enableWMD();
+               } else {
+                       disableWMD();
+               }
+       }
+    }
+    
+    function getType(typeSelector)
+    {
+       if (typeSelector.nodeName.toLowerCase() == 'input') {
+               return typeSelector.getAttribute('value');
+       } else if (typeSelector.nodeName.toLowerCase() == 'select') {
+               return typeSelector.value;
+               // return typeSelector.options[typeSelector.selectedIndex].innerText;
+       }
+       return "";
+    }
+    
+    function enableWMD()
+    {
+       var editContent = document.getElementById("editcontent");
+       var previewDiv = document.getElementById("wmd-preview");
+       var previewDivContainer = document.getElementById("wmd-preview-container");
+       
+       previewDivContainer.style.display = 'block';
+       // editContent.style.width = previewDivContainer.style.width;
+       
+       /***** build the preview manager *****/
+       var panes = {input:editContent, preview:previewDiv, output:null};
+       var previewManager = new Attacklab.wmd.previewManager(panes);
+    
+       /***** build the editor and tell it to refresh the preview after commands *****/
+       var editor = new Attacklab.wmd.editor(editContent,previewManager.refresh);
+    
+       // save everything so we can destroy it all later
+       instance = {ta:editContent, div:previewDiv, ed:editor, pm:previewManager};
+    }
+    
+    function disableWMD()
+    {
+       document.getElementById("wmd-preview-container").style.display = 'none';
+    
+       if (instance != null) {
+               instance.pm.destroy();
+               instance.ed.destroy();
+               // inst.ta.style.width='100%'
+       }
+       instance = null;
+    }
+
+
+----
+
+    diff --git a/IkiWiki/Plugin/wmd.pm b/IkiWiki/Plugin/wmd.pm
+    index 9ddd237..743a0b8 100644
+    --- a/IkiWiki/Plugin/wmd.pm
+    +++ b/IkiWiki/Plugin/wmd.pm
+    @@ -17,6 +17,13 @@ sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+    +                  rebuild => 1,
+    +          },
+    +          wmd_use101api => {
+    +                  type => "boolean",
+    +                  description => "Use the advanced, but unstable, WMD api for markdown preview.",
+    +                  safe => 0,
+    +                  rebuild => 0,
+               },
+     }
+     
+    @@ -24,29 +31,25 @@ sub formbuilder_setup (@) {
+       my %params=@_;
+       my $form=$params{form};
+     
+    -  return if ! defined $form->field("do");
+    +  return unless defined $form->field("do");
+       
+       return unless $form->field("do") eq "edit" ||
+    -                  $form->field("do") eq "create" ||
+    -                  $form->field("do") eq "comment";
+    -
+    -  $form->tmpl_param("wmd_preview", "<div class=\"wmd-preview\"></div>\n".
+    -          include_javascript(undef, 1));
+    -}
+    -
+    -sub include_javascript ($;$) {
+    -  my $page=shift;
+    -  my $absolute=shift;
+    -
+    -  my $wmdjs=urlto("wmd/wmd.js", $page, $absolute);
+    -  return <<"EOF"
+    -<script type="text/javascript">
+    -wmd_options = {
+    -  output: "Markdown"
+    -};
+    -</script>
+    -<script src="$wmdjs" type="text/javascript"></script>
+    -EOF
+    +                          $form->field("do") eq "create" ||
+    +                          $form->field("do") eq "comment";
+    +
+    +  my $useAPI = $config{wmd_use101api}?'true':'false';
+    +  my $ikiwikijs = urlto("ikiwiki.js", undef, 1);
+    +  my $wmdIkiwikijs = urlto("wmd-ikiwiki.js", undef, 1);
+    +  my $wmdjs = urlto("wmd.js", undef, 1);
+    +
+    +  my $previewScripts = <<"EOS";
+    +          <script type="text/javascript">useWMDinterface=$useAPI;</script>
+    +          <script src="$ikiwikijs" type="text/javascript"></script>
+    +          <script src="$wmdIkiwikijs" type="text/javascript"></script>
+    +          <script src="$wmdjs" type="text/javascript"></script>
+    +EOS
+    +
+    +  $form->tmpl_param("wmd_preview", $previewScripts);
+     }
+     
+     1
+    diff --git a/doc/style.css b/doc/style.css
+    index a6e6734..36c2b13
+    --- a/doc/style.css
+    +++ b/doc/style.css
+    @@ -76,9 +76,16 @@ div.tags {
+       float: right;
+     }
+     
+    +/*
+     #editcontent {
+       width: 100%;
+     }
+    +*/
+    +
+    +#wmd-preview-container {
+    +  width: 49%;
+    +  float: right;
+    +}
+     
+     img {
+       border-style: none;
+    diff --git a/templates/editpage.tmpl b/templates/editpage.tmpl
+    index b1cf015..1d2f080 100644
+    --- a/templates/editpage.tmpl
+    +++ b/templates/editpage.tmpl
+    @@ -15,6 +15,14 @@ Page type: <TMPL_VAR FIELD-TYPE>
+     <TMPL_VAR FIELD-PAGE>
+     <TMPL_VAR FIELD-TYPE>
+     </TMPL_IF>
+    +<TMPL_IF NAME="WMD_PREVIEW">
+    +<div id="wmd-preview-container">
+    +<div  class="header">
+    +<span>Live preview:</span>
+    +</div>
+    +<div class="wmd-preview" id="wmd-preview"></div>
+    +</div>
+    +</TMPL_IF>
+     <TMPL_VAR FIELD-EDITCONTENT><br />
+     <TMPL_IF NAME="CAN_COMMIT">
+     Optional comment about this change:<br />
index f0dbf9806e5a4370dfc49799214d6c42181e508a..e71c8106adc832fb30203868174cd857a79450e3 100644 (file)
   It seems that with the current mercurial commit code, it will always
   blindly overwrite the current file with the web edited version, losing
   any other changes.
+* `rcs_commit_staged`, `rcs_rename`, `rcs_remove`, and `rcs_diff` are not
+  implemented for mercurial, and so attachments, remove and rename plugins
+  and recentchangesdiff cannot be used with it. (These should be fairly
+  easy to add..)
 
 Posthook: in `$srcdir/.hg/hgrc`, I have the following
 
@@ -29,6 +33,62 @@ This should update the working directory and run ikiwiki every time a change is
 > It can deadlock if the post-commit hook runs with --refresh in the
 > former case. --[[Joey]]
 
+The problem with --post-commit is that if you delete some pages in $SRC, ikiwiki --setup setupfile --post-commit will not delete them in $DEST. --[[users/weakish]]
+
+> You should really be using a setup file that has `mercurial_wrapper`
+> set, and running the wrapper generated by that from your hook.
+> That will work. I think that the `--setup --post-commit` on the command
+> line is currently broken and does the same expensive rebuild process as --setup
+> alone (which doesn't delete files from $DEST either). Will fix that.
+> (fixed)
+> --[[Joey]] 
+
+>> Mercurial doesn't support put hooks in .hg/hooks/* (like git). In Mercurial, the only way to run
+>> your own hooks is specifying them in the hgrc file. (Or write a new extension.)
+>> I guess use a very long command will work.
+>> (e.g. ikiwiki --post-commit --a-lot-of-switches --set var=value $SRC $DEST)
+>> (Fortunately ikiwiki supports --set var=value so without --setup works.)
+>>
+>> Alternative is always editing via cgi or pushing.  Never work on the $SRC/repo directly.
+>> --[[users/weakish]]
+
+>>> I don't see anything preventing you from using a setup file with
+>>> `mercurial_wrapper => ".hg/ikiwiki-hook",` and then modifying the hgrc
+>>> to run that wrapper. --[[Joey]] 
+
+>> Thanks for pointing out this.  I have some stupid misunderstanding on the
+>> usage of mercurial_wrapper before.  The wrapper works nicely! --[[weakish]]
+
+I add the following to .hg/hgrc:(I use changegroup since I don't think we need refresh per changeset, please point out if I am wrong.)
+
+    [hooks]
+    changegroup = hg update >&2 && ikiwiki --setup path.to.setup.file --refresh
+    post-commit = path.to.the.mercurial.wrapper
+
+-----
+
+I have no idea when the deadlock will happen.  --[[users/weakish]]
+
+> For the deadlock to occur, a edit has to be made via the web.
+> 
+> Ikiwiki,
+> running as a CGI, takes a lock on the wiki, and commits the edit,
+> continuing to run in the background, with the lock still held.
+> When the edit is committed, the hg hook runs, running `ikwiki --refresh`.
+> Nearly the first thing that process does it try to lock the wiki..
+> which is already locked. This lock is taken in a blocking manner,
+> thus the deadlock -- the cgi is waiting for the commit to finish before
+> dropping the lock, and the commit is blocked waiting for the lock to be
+> released.
+> 
+> --post-commit avoids this problem by checking if the cgi is running
+> and avoiding doing anything in that case. (While still handing the
+> refresh if the commit was not made by the CGI.)
+> So in that case, the commit finishes w/o ikiwiki doing anything,
+> and the ikiwiki CGI handles the wiki refresh.
+> --[[Joey]]  
+
+
 ***
 
 I have a few notes on mercurial usage after trying it out for a while:
index 81a2c1328d725a0bcdf04aef30c84db560493728..158edea6e5cd6cd334dcb05412e1b04c2c1f5bd5 100644 (file)
@@ -26,7 +26,7 @@ of CVS/SVN-style keywords (like '$Id$', etc.) from the source file in the page t
      my %copyright;
     +my %rcsid;
  
-     sub import { #{{{
+     sub import {
         hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
     @@ -110,6 +111,9 @@
             $meta{$page}.="<link rel=\"copyright\" href=\"#page_copyright\" />\n";
index 0cc7137ba46b31d0978ca96cc0ad68cc997cef68..c5f2ab535c080c7f47a910e1e8b2addc5957b81c 100644 (file)
@@ -82,15 +82,15 @@ Index: IkiWiki/Plugin/missingparents.pm
 +my %ownfiles;
 +my @pagespecs;
 +
-+sub import { #{{{
++sub import {
 +      hook(type => "checkconfig", id => "missingparents", call => \&checkconfig);
 +      hook(type => "needsdelete", id => "missingparents", call => \&needsdelete);
 +      hook(type => "needsbuild", id => "missingparents", call => \&needsbuild);
 +      hook(type => "savestate", id => "missingparents", call => \&savestate);
 +      hook(type => "preprocess", id => "missingparents", call => \&preprocess_missingparents);
-+} # }}}
++}
 +
-+sub checkconfig () { #{{{
++sub checkconfig () {
 +      IkiWiki::preprocess("missingparents", "missingparents",
 +              readfile(srcfile("missingparents.mdwn")));
 +      loadstate();
@@ -99,9 +99,9 @@ Index: IkiWiki/Plugin/missingparents.pm
 +                      unlink $config{srcdir}.'/'.$file;
 +              }
 +      }
-+} #}}}
++}
 +
-+sub preprocess_missingparents (@) { #{{{
++sub preprocess_missingparents (@) {
 +      my %params=@_;
 +
 +      if (! defined $params{pages} || ! defined $params{generate}) {
@@ -115,10 +115,10 @@ Index: IkiWiki/Plugin/missingparents.pm
 +      #translators: is text for pages that match that pagespec.
 +      return sprintf(gettext("missingparents in %s will be %s"), 
 +                     '`'.$params{pages}.'`', '`\\'.$params{generate}.'`');
-+} # }}}
++}
 +
 +my $state_loaded=0;
-+sub loadstate() { #{{{
++sub loadstate() {
 +      my $filename = "$config{wikistatedir}/missingparents";
 +      if (-e $filename) {
 +              open (IN, $filename) ||
@@ -132,9 +132,9 @@ Index: IkiWiki/Plugin/missingparents.pm
 +
 +              $state_loaded=1;
 +      }
-+} #}}}
++}
 +
-+sub savestate() { #{{{
++sub savestate() {
 +      my $filename = "$config{wikistatedir}/missingparents.new";
 +      my $cleanup = sub { unlink ($filename) };
 +      open (OUT, ">$filename") || error("open $filename: $!", $cleanup);
@@ -143,9 +143,9 @@ Index: IkiWiki/Plugin/missingparents.pm
 +      }
 +      rename($filename, "$config{wikistatedir}/missingparents") ||
 +              error("rename $filename: $!", $cleanup);
-+} #}}}
++}
 +
-+sub needsdelete (@) { #{{{
++sub needsdelete (@) {
 +      my $files=shift;
 +      
 +      my @mydel;
@@ -167,9 +167,9 @@ Index: IkiWiki/Plugin/missingparents.pm
 +      foreach my $page (@mydel){
 +              push @{$files}, $page;
 +      }
-+} #}}}
++}
 +
-+sub check_matches($) { #{{{
++sub check_matches($) {
 +      my $page = shift;
 +      return if $IkiWiki::pagesources{$page};
 +
@@ -183,9 +183,9 @@ Index: IkiWiki/Plugin/missingparents.pm
 +              return $output;
 +      }
 +      return "";
-+} #}}}
++}
 +
-+sub needsbuild ($) { #{{{
++sub needsbuild ($) {
 +      my $files=shift;
 +      my @new;
 +
@@ -209,7 +209,7 @@ Index: IkiWiki/Plugin/missingparents.pm
 +              $ownfiles{$file} = 1;
 +              push @{$files}, $file;
 +      }
-+} #}}}
++}
 +
 +1
 Index: IkiWiki.pm
@@ -227,18 +227,18 @@ Index: IkiWiki.pm
  our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE
 @@ -330,6 +336,30 @@
                error("failed renaming $newfile to $destdir/$file: $!", $cleanup);
- } #}}}
+ }
  
-+sub newpage($$) { #{{{
++sub newpage($$) {
 +      my $file=shift;
 +      my $page=shift;
 +
 +      $pagemtime{$page} = $pagectime{$page} = time;
 +      $pagesources{$page} = $file;
 +      $pagecase{lc $page} = $page;
-+} #}}}
++}
 +
-+sub delpage($) { #{{{
++sub delpage($) {
 +      my $page=shift;
 +      $links{$page}=[];
 +      $renderedfiles{$page}=[];
@@ -251,10 +251,10 @@ Index: IkiWiki.pm
 +                      delete $destsources{$_};
 +                      }
 +              }
-+} #}}}
++}
 +
  my %cleared;
- sub will_render ($$;$) { #{{{
+ sub will_render ($$;$) {
        my $page=shift;
 </pre>
 
index 7c0a909eb7f53f6bad48a086f619fe033b1e8e24..a13c8b62ffeb3d2f6b49dcf381e8fec2354fa62b 100644 (file)
@@ -6,11 +6,13 @@ The problem is that I occasionally have xxx.c and xxx.h in the same directory an
 
 My solution is to allow plugins to provide a hook that sets the pagename. --[[/users/bstpierre]]
 
+> You might also find the solution to [[bugs/multiple_pages_with_same_name]] helps you.  That patch is already applied. -- [[Will]]
+
     --- /usr/share/perl5/IkiWiki.pm.ORIG    2008-10-03 14:12:50.000000000 -0400
     +++ /usr/share/perl5/IkiWiki.pm 2008-10-07 11:57:26.000000000 -0400
     @@ -196,11 +196,32 @@
 
-     sub pagename ($) { #{{{
+     sub pagename ($) {
             my $file=shift;
 
             my $type=pagetype($file);
@@ -27,7 +29,7 @@ My solution is to allow plugins to provide a hook that sets the pagename. --[[/u
             $page=~s/\Q.$type\E*$// if defined $type;
             return $page;
     +   }
-     } #}}}
+     }
 
-     sub htmlpage ($) { #{{{
+     sub htmlpage ($) {
 
diff --git a/doc/todo/natural_sorting.mdwn b/doc/todo/natural_sorting.mdwn
new file mode 100644 (file)
index 0000000..5df17e9
--- /dev/null
@@ -0,0 +1,21 @@
+[[!tag wishlist]]
+[[!tag patch]]
+
+the inline plugin's sorting is plain lexical, thich may not be appropriate for
+page titles if they have numeric components. the
+[Sort::Naturally](http://search.cpan.org/dist/Sort-Naturally/) perl module
+provides an algorithm for that.
+
+there is a
+[patch](http://git.ikiwiki.info/?p=ikiwiki;a=commit;h=55b83cb7bd1cd7c60bb45dc22c3745dd80a63fed)
+attached that makes the [[plugins/inline]] plugin use Sort::Naturally if sort
+is set to "title_natural".
+
+the current patch uses `require Sort::Naturally`, so
+[libsort-naturally-perl](http://packages.debian.org/libsort-naturally-perl)
+does not become a dependency; it might be worth suggesting, though.
+
+> See also: [[inline:_numerical_ordering_by_title]] (I probably prefer your
+> approach..) --[[Joey]] 
+
+> [[applied|done]]
diff --git a/doc/todo/need_global_renamepage_hook.mdwn b/doc/todo/need_global_renamepage_hook.mdwn
new file mode 100644 (file)
index 0000000..b123340
--- /dev/null
@@ -0,0 +1,115 @@
+As documented in [[plugins/write]], the current `renamepage` hook is
+heavily oriented towards updating links in pages' content:  it is run
+once per page linking to the renamed page.
+
+That's fine, but it can't be used to trigger more general actions on
+page rename. E.g. it won't be run at all if the page being renamed is
+an orphan one.
+
+This is a real issue for the [[plugins/contrib/po]] development: what
+I'm about to achieve is:
+
+- when a master page is renamed, the plugin takes notice of it (using
+  the `rename` hook), and later renames the translation pages
+  accordingly (in the `change` hook)
+- when a master page is deleted, the plugin deletes its translations
+  (using the `delete` hook)
+
+With the current `renamepage` hook behavior, combining these two goals
+has an annoying drawback: a plugin can't notice an orphan master page
+has been renamed, so instead of renaming (and preserving) its
+translations, it considers the oldpage as deleted, and deletes its
+translations. Game over.
+
+It may seem like a corner case, but I want to be very careful when
+deleting files automatically in `srcdir`, which is not always under
+version control.
+
+As a sad workaround, I can still disable any deletion in `srcdir`
+when it is not under version control. But I think ikiwiki deserves
+a global `renamepage` hook that would be run once per rename
+operation.
+
+My proposal is thus:
+
+- keep the documented `renamepage` hook as it is
+- use something inspired by the trick `preprocess` uses: when `hook`
+  is passed an optional "global" parameter, set to a true value, the
+  declared `renamepage` hook is run once per rename operation, and is
+  passed named parameters: `src`, `srcfile`, `dest` and `destfile`.
+
+I'm of course volunteering to implement this, or anything related that
+would solve my problem. Hmmm? --[[intrigeri]]
+
+> I think it would be better to have a different hook that is called for
+> renames, since the two hook actions are very different (unlike the
+> preprocess hook, which does a very similar thing in scan mode).
+> 
+> Just calling it `rename` seems like a reasonable name, by analogy with
+> the `delete` and `change` hooks.
+> 
+> It might make sense to rename `renamepage` to `renamelink` to make it
+> clearer what it does. (I'm not very worried about this breaking things, at
+> this point.) --[[Joey]]
+
+>> In my `po` branch, I renamed `renamepage` to `renamelink`, and
+>> created a `rename` hook that is passed a reference to `@torename`.
+>> --[[intrigeri]]
+
+>>> As Joey highlights it on [[plugins/contrib/po]], it's too late to
+>>> merge such a change, as the 3.x plugin API is released and should
+>>> not be broken. I will thus keep the existing `renamepage` as it
+>>> is, and call `rename` the global hook I need. --[[intrigeri]]
+
+>>>> Done in my `po` branch. --[[intrigeri]]
+
+I think I see a problem in the rename hook. The hook is called
+before the plugin adds any subpages to the set of pages to rename.
+So, if the user choses to rename subpages, po will not notice
+they are moving, and will not move their po files.
+Perhaps the hooks should be moved to come after subpages are added.
+This would, though, mean that if the hook somehow decides to add
+entirely other pages to the list, their subpages would not be
+automatically added.
+
+I also have some qualms about the design of the hook. In particular,
+passing the mutable array reference probably makes it impossible
+to use from external plugins. Instead it could return any additional
+rename hashes it wants to add. Or, if the ability to modify existing
+hashes is desired, it could return the full set of hashes.
+
+--[[Joey]] 
+
+> I fixed the last part, i.e. a rename hook function now returns the
+> full set of hashes. As I also converted it to take named parameters,
+> such a function still is passed a reference to the original array,
+> though, because one can't build a hash containing an array of hashes
+> as a value, without passing this array as a reference.
+> 
+>> Sure.
+> 
+> I'm not entirely sure about your first concern. Calling the hook
+> before or after the subpages addition both have their own problems.
+> 
+> What about running the hook before *and* after the subpages
+> addition, with an additional `when` named parameter, so that
+> a given hook function can choose to act only before or after, or both?
+> 
+> --[[intrigeri]]
+>> 
+>> Have you thought about making the hook be run once *per* file that is
+>> selected to be renamed? This would even handle the case where two
+>> plugins use the hook; plugin A would see when plugin B adds a new file
+>> to be renamed. And the subpage renaming stuff could probably be moved
+>> into the rename hook too. --[[Joey]] 
+>>>
+>>> I've implemented this nice solution in my po branch, please review.
+>>> I'm slowly coming back to do the last bits needed to get my po and
+>>> meta branch merged.  --[[intrigeri]]
+
+>>>> It looks good. I made some small changes to it in my own po branch.
+>>>> Nothing significant really. If this were not tied up in the po branch,
+>>>> I've have merged it to master already. --[[Joey]] 
+
+>>>> Thanks, this is great :) --[[intrigeri]]
diff --git a/doc/todo/overriding_displayed_modification_time.mdwn b/doc/todo/overriding_displayed_modification_time.mdwn
new file mode 100644 (file)
index 0000000..160d315
--- /dev/null
@@ -0,0 +1,27 @@
+Some aggregators, like Planet, sort by mtime rather than ctime. This
+means that posts with modified content come to the top (which seems odd
+to me, but is presumably what the aggregator's author or operator
+wants),
+
+> Hah! That's so charitable I hope you can deduct it from your taxes. ;-)
+> --[[Joey]] 
+
+but it also means that posts with insignificant edits (like
+adding tags) come to the top too. Atom defines `<updated>` to be the date
+of the last *significant* change, so it's fine that ikiwiki defaults to
+using the mtime, but it would be good to have a way for the author to
+say "that edit was insignificant, don't use that mtime".
+
+> Yes, this is a real limitiation of ikiwiki's atom support. --[[Joey]] 
+
+See smcv's 'updated' branch for a basic implementation, which only affects
+the Atom `<updated>` field or the RSS equivalent.
+
+Other places the updated metadata item could be used (opinions on whether
+each should use it or not, please):
+
+* sorting by mtime in the inline directive
+* displaying "last edited" on ordinary pages
+
+> Tending toward no for both, but willing to be convinced otherwise..
+> [[merged|done]] --[[Joey]]  
index f7b248670d10e83b4bbe99a270e47e15723983e3..4757988e0a27b0b7cdcb8fa23978f151cc1bbad4 100644 (file)
@@ -57,7 +57,7 @@ diff -urNX ignorepats ikiwiki/IkiWiki/Plugin/relative.pm ikidev/IkiWiki/Plugin/r
 +
 +package IkiWiki::PageSpec;
 +
-+sub match_relative($$;@) { #{{{
++sub match_relative($$;@) {
 +      my $parent = shift;
 +      my $spec = shift;
 +      my %params = @_;
@@ -69,21 +69,21 @@ diff -urNX ignorepats ikiwiki/IkiWiki/Plugin/relative.pm ikidev/IkiWiki/Plugin/r
 +              }
 +      }
 +      return IkiWiki::FailReason->new("$parent can't match $spec against anything");
-+} #}}}
++}
 +
-+sub match_has_child($$;@) { #{{{
++sub match_has_child($$;@) {
 +      my $page = shift;
 +      my $childname = shift;
 +      my $spec;
-+      if ($childname) { #{{{
++      if ($childname) {
 +              $spec = "$page/$childname or $page/*/$childname";
-+      } #}}}
-+      else { #{{{
++      }
++      else {
 +              $spec = "$page/*";
-+      } #}}}
++      }
 +
 +      return match_relative($page, $spec, @_);
-+} #}}}
++}
 +
 +1
 </pre>
diff --git a/doc/todo/pingback_support.mdwn b/doc/todo/pingback_support.mdwn
new file mode 100644 (file)
index 0000000..b10366b
--- /dev/null
@@ -0,0 +1,39 @@
+A "pingback" is a system whereby URLs you might reference in a blog post are
+contacted by the blog publishing software at publishing time (i.e., once) so
+that they might update a list of "pingbacks" to the URL. The originating
+URL's blog software might then display a list of pingbacks, or an excerpt of
+the text from your blog, perhaps interleaved with comments, etc.
+
+At a technical level, external URLs are extracted from your blog post by the
+blogging software, fetched, inspected for information to determine whether the
+remote server is configured to support pingbacks (look for link tags, or HTTP
+headers) and the relevant pingback URL sent an XML-RPC packet.
+
+There are other technologies to achieve the same thing: trackbacks predate
+pingbacks but are more vulnerable to spam due to design problems.
+
+The spec for pingbacks is at <http://www.hixie.ch/specs/pingback/pingback>.
+
+I would like to somehow use pingbacks in conjunction with ikiwiki. I suppose
+this could be achieved using a commit hook and some external software in which
+case I will consider this done with an entry in [[tips]]; otherwise a
+[[plugins|plugin]] to implement pingbacks would be great.
+
+-- [[Jon]] (Wed Jan 14 13:48:47 GMT 2009)
+
+> I think it's now possible to implement trackback and pingback receiving
+> support in ikiwiki. One easy way to do it would be to hook it into the
+> existing [[plugins/comments]] plugin -- each pingback/trackback that
+> ikiwiki recieves would result in the creation if a new comment, which
+> would be subject to the usual comment filtering (ie, blogspam) and
+> moderation and would then show up amoung the other, regular comments on
+> the page.
+>
+> (One wrinkle: would need to guard against duplicate pings. Maybe by
+> checking existing comments for any that have the same url?)
+> 
+> As for sending trackbacks and pingbacks, this could fairly easily be
+> implemented using a `editcontent` hook. Since this hook is called
+> whenever a page is posted or edited, and gets the changed content, it can
+> simply scan it for urls (may have to htmlize first?), and send pings to
+> all urls found. --[[Joey]] 
index 132de44807eabc4ca00c6049356d2ef5f5eac72a..b3e3a78892e246c03ff2334ff7b86d76f3bc1012 100644 (file)
@@ -70,10 +70,6 @@ Suggestions of ideas for plugins:
 > web-server-specific code to list all users, and openid can't feasibly do so
 > at all. --[[JoshTriplett]]
 
-* It would be nice to be able to have a button to show "Differences" (or 
-  "Show Diff") when editing a page. Is that an option that can be enabled?
-  Using a plugin?
-
 * For PlaceWiki I want to be able to do some custom plugins, including one
   that links together subpages about the same place created by different
   users. This seems to call for a plugin that applies to every page w/o any
index 7724576f56c5e0ffa90aa17dfd3c75b55edd0eb0..39a35d0c6088f97c19f62dbc0ba07739321985c2 100644 (file)
@@ -1,3 +1,8 @@
 It would rock if I could view diffs from the web without going via feeds. I envision toggle-style buttons on the recentchanges page, or just links to the CGI, which then displays the diff... --[[madduck]]
 
+> The diffs are actually there, enabled by the `recentchangesdiff`
+> plugin, but they are hidden in the XHTML version by the stylesheet.
+> You might try a user stylesheet with `div.diff { display: block }`.
+> --[[JasonBlevins]]
+
 [[!tag wishlist]]
diff --git a/doc/todo/provide_sha1_for_git_diffurl.mdwn b/doc/todo/provide_sha1_for_git_diffurl.mdwn
new file mode 100644 (file)
index 0000000..01aa512
--- /dev/null
@@ -0,0 +1,26 @@
+This [[patch]] allows for `\[[sha1]]` substitution in the `diffurl`
+for git repositories.  This is useful for use with [cgit][] which has
+diffurls of the following form:
+
+    /project.git/diff/\[[file]]?id=\[[sha1_commit]]
+
+ [cgit]: http://hjemli.net/git/cgit/
+
+    diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm
+    index 5bef928..164210d 100644
+    --- a/IkiWiki/Plugin/git.pm
+    +++ b/IkiWiki/Plugin/git.pm
+    @@ -518,6 +518,7 @@ sub rcs_recentchanges ($) {
+     
+                       my $diffurl = defined $config{'diffurl'} ? $config{'diffurl'} : "";
+                       $diffurl =~ s/\[\[file\]\]/$file/go;
+    +                  $diffurl =~ s/\[\[sha1\]\]/$sha1/go;
+                       $diffurl =~ s/\[\[sha1_parent\]\]/$ci->{'parent'}/go;
+                       $diffurl =~ s/\[\[sha1_from\]\]/$detail->{'sha1_from'}/go;
+                       $diffurl =~ s/\[\[sha1_to\]\]/$detail->{'sha1_to'}/go;
+
+> [[done]], but I called it `sha1_commit` since I think that's what it's
+> actually a sha1 of. --[[Joey]]
+
+>> I was at a loss for something more descriptive...I like that much
+>> better :) Thanks! --[[JasonBlevins]]
similarity index 54%
rename from doc/todo/rcs_updates_needed_for_rename_and_remove.mdwn
rename to doc/todo/rcs_updates_needed.mdwn
index 2af659c3b3c8eb24589bbc947bcee6932f7f0770..472a5800fd03770abafe624e0910146489de462b 100644 (file)
@@ -3,3 +3,8 @@ renaming and removing files using the web interface. The mercurial and
 tla [[rcs]] backends need implementions of these functions.
 
 (The maintainers of these backends have been mailed. --[[Joey]])
+
+Also, currently git is the only VCS to have support for
+[[untrusted_push|tips/untrusted_git_push]]. It _may_ be possible to
+implement it for other DVCS, if they offer a hook that can be used to check
+incoming pushes early.
diff --git a/doc/todo/redirect_automatically_after_rename.mdwn b/doc/todo/redirect_automatically_after_rename.mdwn
new file mode 100644 (file)
index 0000000..1cbb824
--- /dev/null
@@ -0,0 +1,10 @@
+In some wikis, (e.g. Mediawiki) after [[renaming|plugins/rename]] 
+a page, the old page still exist but only redirect to the
+new page.  This is convenient since external sites may
+have links pointing to the old url.  
+
+If [[plugins/meta]] plugin is enabled, users can manually edit the
+page, and put in '\[[!meta redir=newpage]]', but this is
+not very convenient.
+
diff --git a/doc/todo/relative_pagespec_deficiency.mdwn b/doc/todo/relative_pagespec_deficiency.mdwn
new file mode 100644 (file)
index 0000000..4500581
--- /dev/null
@@ -0,0 +1,8 @@
+While a relative pagespec like `./posts/*` will work, when used in a page
+such as `bdale/blog`, you cannot do
+`created_after(./posts/foo)` -- only `glob()` supports relative page
+references.
+
+The other pagespec functions should too, where appropriate.
+
+[[done]]
index dfeacbabd741b20f29ef32a069ef993f7e6ac4ba..c4e78ca0bb7147eba8765b5185820f3beb279eda 100644 (file)
@@ -54,3 +54,7 @@ the templates. I'd prefer not having to touch Perl though...
 -----
 
 Yes, Template::Toolkit is very powerful. But I think it's somehow overkill for a wiki. HTML::Template can keep things simple, though.  --[weakish](http://weakish.int.eu.org/blog/)
+
+I'd have to agree that Template::Toolkit is overkill and personally I'm not a fan, but it is very popular (there is even a book) and the new version (3) is alleged to be much more nimble than current version.  --[[ajt]]
+
+HTML::Template's HTML-like markup prevents me from editing templates in KompoZer or other WYSIWYG HTML editors.  The editor tries to render the template markup rather than display it verbatim, and large parts of the template become invisible.  A markup syntax that doesn't confuse editors (such as Template::Toolkit's "[% FOO %]") may promote template customization.  The ability to replace the template engine would be within the spirit of ikiwiki's extensibility. --Rocco
index 110b4167feef99b8d48655ffd42d33f76dacd0eb..83ba07eb0f8bcd8e9c110c8d5b213fdb139c3229 100644 (file)
@@ -91,15 +91,15 @@ ignored.
 
 --- a/IkiWiki/Plugin/openid.pm
 +++ b/IkiWiki/Plugin/openid.pm
-@@ -18,6 +18,7 @@ sub getopt () { #{{{
+@@ -18,6 +18,7 @@ sub getopt () {
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
        GetOptions("openidsignup=s" => \$config{openidsignup});
 +      GetOptions("openidneedscaptcha=s" => \$config{openidneedscaptcha});
- } #}}}
+ }
  
- sub formbuilder_setup (@) { #{{{
-@@ -61,6 +62,7 @@ sub formbuilder_setup (@) { #{{{
+ sub formbuilder_setup (@) {
+@@ -61,6 +62,7 @@ sub formbuilder_setup (@) {
                        # Skip all other required fields in this case.
                        foreach my $field ($form->field) {
                                next if $field eq "openid_url";
@@ -107,7 +107,7 @@ ignored.
                                $form->field(name => $field, required => 0,
                                        validate => '/.*/');
                        }
-@@ -96,6 +98,18 @@ sub validate ($$$;$) { #{{{
+@@ -96,6 +98,18 @@ sub validate ($$$;$) {
                }
        }
  
@@ -152,19 +152,19 @@ use warnings;
 use strict;
 use IkiWiki 2.00;
 
-sub import { #{{{
+sub import {
        hook(type => "formbuilder_setup", id => "recaptcha", call => \&formbuilder_setup);
-} # }}}
+}
 
-sub getopt () { #{{{
+sub getopt () {
        eval q{use Getopt::Long};
        error($@) if $@;
        Getopt::Long::Configure('pass_through');
        GetOptions("reCaptchaPubKey=s" => \$config{reCaptchaPubKey});
        GetOptions("reCaptchaPrivKey=s" => \$config{reCaptchaPrivKey});
-} #}}}
+}
 
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
        my %params=@_;
 
        my $form=$params{form};
@@ -274,7 +274,7 @@ EOTAGS
                                });
                }
        }
-} # }}}
+}
 
 # The following function is borrowed from
 # Captcha::reCAPTCHA by Andy Armstrong and are under the PERL Artistic License
diff --git a/doc/todo/rewrite_ikiwiki_in_haskell.mdwn b/doc/todo/rewrite_ikiwiki_in_haskell.mdwn
new file mode 100644 (file)
index 0000000..204c48c
--- /dev/null
@@ -0,0 +1,68 @@
+[[!tag wishlist blue-sky]]
+
+In the long term, I have been considering rewriting ikiwiki in haskell.
+It's appealing for a lot of reasons, including:
+
+* No need to depend on a C compiler and have wrappers. Instead, ikiwiki
+  binaries could be built on demand to do the things wrappers are used for
+  now (cgi, post-commit, etc).
+* Potentially much faster. One problem with the now very modular ikiwiki is
+  that it has to load up dozens of perl modules each time it runs, which
+  means both opening lots of files and evaluating them. A haskell version
+  could run from one pre-compiled file. Other speed efficienies are also
+  likely with haskell. For example, pandoc is apparently an order of
+  magnitude faster than perl markdown implementations.
+* Many plugins could be written in pure functional code, with no side
+  effects. Not all of them, of course.
+* It should be much easier to get ikiwiki to support parallel compilation
+  on multi-core systems using haskell.
+* A rewrite would be an opportunity to utterly break compatability and
+  redo things based on experience. Since the haskell libraries used for
+  markdown, templates, etc, are unlikely to be very compatable with the perl
+  versions, and since perl plugins obviously wouldn't work, and perl setup
+  files wouldn't be practical to keep, a lot of things would unavoidably
+  change, and at that point changinge everything else I can think of
+  probably wouldn't hurt (much).
+
+  - Re templates, it would be nice to have a template library that
+    doesn't use html-ish templating tags, since those are hard for users to
+    edit in html editors currently.
+  - This would be a chance to make WikiLinks with link texts read
+    "the right way round" (ie, vaguely wiki creole compatably).
+  - The data structures would probably be quite different.
+  - I might want to drop a lot of the command-line flags, either
+    requiring a setup file be used for those things, or leaving the
+    general-purpose `--set var=value` flag.
+  - Sometimes the current behavior of `--setup` seems confusing; it might
+    only cause a setup file to be read, and not force rebuild mode.
+  - Hard to say how the very high level plugin interface design would change,
+    but at the least some of the names of hooks could stand a rename, and
+    their parameter passing cleaned up.
+
+We know that a big, break-the-world rewrite like this can be a very
+bad thing for a project to attempt. It would be possible to support
+external plugins written in haskell today, without any rewrite; and a few
+of the benefits could be obtained by, eg, making the mdwn plugin be a
+haskell program that uses pandoc. I doubt that wouod be a good first step
+to converting ikiwiki to haskell, because such a program would have very
+different data structures and intercommuniucation than a pure haskell
+version.
+
+Some other things to be scared about:
+
+* By picking perl, I made a lot of people annoyed (and probably turned
+  several people away from using ikiwiki). But over time there turned out
+  to be a lot of folks who knew perl already (even if rustily), and made
+  some *very* useful contributions. I doubt there's as large a pool of haskell
+  programmers, and it's probably harder for a python user to learn haskell
+  than perl if they want to contribute to ikiwiki.
+* It might be harder for users of hosting services to install a haskell based
+  ikiwiki than the perl version. Such systems probably don't have ghc and
+  a bunch of haskell libraries. OTOH, it might be possible to build a
+  static binary at home and upload it, thus avoiding a messy installation
+  procedure entirely.
+* I can barely code in haskell yet. I'm probably about 100x faster at
+  programming in perl. I need to get some more practical experience before
+  I´m fast and seasoned enough in haskell to attempt such a project.
+  (And so far, progress at learning has been slow and I have not managed
+  to write anything serious in haskell.) --[[Joey]] 
diff --git a/doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn b/doc/todo/rewrite_ikiwiki_in_haskell/discussion.mdwn
new file mode 100644 (file)
index 0000000..1edebe4
--- /dev/null
@@ -0,0 +1,14 @@
+Ok, I have to admit, I have no idea if this is an April fool's joke or not.  
+Congratulations for demonstrating that April fools jokes can still be subtle
+(whether intentionally or not!) -- [[Jon]]
+
+> Having said all that, have you looked at erlang? Have you heard of couchdb?
+> I'd strongly recommend looking at that. -- [[Jon]]
+
+>> I've glanced at couchdb, but don't see how it would tie in with ikiwiki.
+>> --[[Joey]] 
+
+
+>>> It doesn't really. I recently (re-)read about couchdb and thought that
+>>> what it was trying to do had some comparisons with the thinking going on
+>>> in [[todo/structured_page_data]]. -- [[Jon]]
index 93791c81af3ec69661b4ac16f1b08bdbb75ac317..b051361a8486db732d34e3ec99625a9f566b5619 100644 (file)
@@ -1,6 +1,6 @@
 How about a direct link from the page header to the source of the latest version, to avoid the need to either use edit or navigate to the current version via the history link?
 
- I'd like this too (and might try to implement it). -- [[jondowland]]
+ I'd like this too (and might try to implement it). -- [[users/jon]]
 
 I just implemented this.  There is one [[patch]] to the default page template, and a new plugin.  -- [[Will]]
 
@@ -31,13 +31,13 @@ I just implemented this.  There is one [[patch]] to the default page template, a
     use IkiWiki;
     use open qw{:utf8 :std};
     
-    sub import { #{{{
+    sub import {
        hook(type => "getsetup", id => "getsource", call => \&getsetup);
        hook(type => "pagetemplate", id => "getsource", call => \&pagetemplate);
        hook(type => "sessioncgi", id => "getsource", call => \&cgi_getsource);
-    } # }}}
+    }
     
-    sub getsetup () { #{{{
+    sub getsetup () {
        return
                plugin => {
                        safe => 1,
@@ -50,9 +50,9 @@ I just implemented this.  There is one [[patch]] to the default page template, a
                        safe => 1,
                        rebuild => 0,
                },
-    } #}}}
+    }
     
-    sub pagetemplate (@) { #{{{
+    sub pagetemplate (@) {
        my %params=@_;
     
        my $page=$params{page};
@@ -62,9 +62,9 @@ I just implemented this.  There is one [[patch]] to the default page template, a
                $template->param(getsourceurl => IkiWiki::cgiurl(do => "getsource", page => $page));
                $template->param(have_actions => 1);
        }
-    } # }}}
+    }
     
-    sub cgi_getsource ($$) { #{{{
+    sub cgi_getsource ($$) {
        my $cgi=shift;
        my $session=shift;
     
index 2a196ed23b642beff60314b51164a3ac3a300465..22f67cc0ae39c18c3eeab5f7ec00de6b031edeb4 100644 (file)
@@ -257,21 +257,21 @@ in a large number of other cases.
     use CGI::FormBuilder;
     use IkiWiki 2.00;
     
-    sub import { #{{{
+    sub import {
        hook(type => "getsetup", id => "form", call => \&getsetup);
        hook(type => "htmlize", id => "form", call => \&htmlize);
        hook(type => "sessioncgi", id => "form", call => \&cgi_submit);
-    } # }}}
+    }
     
-    sub getsetup () { #{{{
+    sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-    } #}}}
+    }
     
-    sub makeFormFromYAML ($$$) { #{{{
+    sub makeFormFromYAML ($$$) {
        my $page = shift;
        my $YAMLString = shift;
        my $q = shift;
@@ -350,9 +350,9 @@ in a large number of other cases.
        # IkiWiki::decode_form_utf8($form);
        
        return $form;
-    } #}}}
+    }
     
-    sub htmlize (@) { #{{{
+    sub htmlize (@) {
        my %params=@_;
        my $content = $params{content};
        my $page = $params{page};
@@ -360,9 +360,9 @@ in a large number of other cases.
        my $form = makeFormFromYAML($page, $content, undef);
     
        return $form->render(submit => 'Update Form');
-    } # }}}
+    }
     
-    sub cgi_submit ($$) { #{{{
+    sub cgi_submit ($$) {
        my $q=shift;
        my $session=shift;
        
@@ -425,11 +425,11 @@ in a large number of other cases.
        }
     
        exit;
-    } #}}}
+    }
     
     package IkiWiki::PageSpec;
     
-    sub match_form_eq ($$;@) { #{{{
+    sub match_form_eq ($$;@) {
        my $page=shift;
        my $argSet=shift;
        my @args=split(/,/, $argSet);
@@ -460,7 +460,7 @@ in a large number of other cases.
        } else {
                return IkiWiki::FailReason->new("field value does not match");
        }
-    } #}}}
+    }
     
     1
 
@@ -476,22 +476,22 @@ in a large number of other cases.
     
     my $inTable = 0;
     
-    sub import { #{{{
+    sub import {
        hook(type => "getsetup", id => "data", call => \&getsetup);
        hook(type => "needsbuild", id => "data", call => \&needsbuild);
        hook(type => "preprocess", id => "data", call => \&preprocess, scan => 1);
        hook(type => "preprocess", id => "datatable", call => \&preprocess_table, scan => 1);   # does this need scan?
-    } # }}}
+    }
     
-    sub getsetup () { #{{{
+    sub getsetup () {
        return
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
                },
-    } #}}}
+    }
     
-    sub needsbuild (@) { #{{{
+    sub needsbuild (@) {
        my $needsbuild=shift;
        foreach my $page (keys %pagestate) {
                if (exists $pagestate{$page}{data}) {
@@ -506,7 +506,7 @@ in a large number of other cases.
        }
     }
     
-    sub preprocess (@) { #{{{
+    sub preprocess (@) {
        my @argslist = @_;
        my %params=@argslist;
        
@@ -546,9 +546,9 @@ in a large number of other cases.
        }
        
        return $html;
-    } # }}}
+    }
     
-    sub preprocess_table (@) { #{{{
+    sub preprocess_table (@) {
        my %params=@_;
     
        my @lines;
@@ -568,11 +568,11 @@ in a large number of other cases.
        push @lines, '</table>';
     
        return join("\n", @lines);
-    } #}}}
+    }
     
     package IkiWiki::PageSpec;
     
-    sub match_data_eq ($$;@) { #{{{
+    sub match_data_eq ($$;@) {
        my $page=shift;
        my $argSet=shift;
        my @args=split(/,/, $argSet);
@@ -592,9 +592,9 @@ in a large number of other cases.
        } else {
                return IkiWiki::FailReason->new("value does not match");
        }
-    } #}}}
+    }
     
-    sub match_data_link ($$;@) { #{{{
+    sub match_data_link ($$;@) {
        my $page=shift;
        my $argSet=shift;
        my @params=@_;
@@ -618,6 +618,6 @@ in a large number of other cases.
        }
     
        return IkiWiki::FailReason->new("No data link on page $page with key $key matches glob $value");
-    } #}}}
+    }
     
     1
index b0ebf5b9e6ae5b51c99d2fa004af2aafc5323b36..5a1e1286df4faa271f1d18b8546669fe1050cade 100644 (file)
@@ -12,7 +12,7 @@ And there is a perl module:   Text::WikiCreole
 
 Syntax file for vim: http://www.peter-hoffmann.com/code/vim/  (Since a typical ikiwiki user usually use external editors. :))
 
-> Should be pretty easy to add a plugin to do it using [[cpan
+> Should be pretty easy to add a plugin to do it using [[!cpan
 > Text::WikiCreole]]. --[[Joey]]
 
 [[done]]
index e0495c8c25e16d5d0c81882f9a0eb3831d630ecf..aae0b3008060994160b2b7207eedd46130fdd3a2 100644 (file)
@@ -91,14 +91,14 @@ Each comment is processed to something like this:
     use strict;
     use IkiWiki '1.02';
 
-    sub import { #{{{
+    sub import {
         hook(type => "formbuilder_setup", id => "comments",
             call => \&formbuilder_setup);
         hook(type => "preprocess", id => "blogcomment",
             call => \&preprocess);  
-    } # }}}
+    }
 
-    sub formbuilder_setup (@) { #{{{
+    sub formbuilder_setup (@) {
         my %params=@_;
         my $cgi = $params{cgi};
         my $form = $params{form};   
@@ -138,9 +138,9 @@ Each comment is processed to something like this:
         $content.=qq{[[!blogcomment from="""$name""" timestamp="""$timestamp""" subject="""$subject""" text="""$comment"""]]\n\n};
         $content=~s/\n/\r\n/g;
         $form->field(name => "editcontent", value => $content, force => 1);
-    } # }}}
+    }
 
-    sub preprocess (@) { #{{{
+    sub preprocess (@) {
         my %params=@_;
 
         my ($text, $date, $from, $subject, $r);
@@ -159,7 +159,7 @@ Each comment is processed to something like this:
         $r .= "</dl>\n" . $text . "</div>\n";
 
         return $r;
-    } # }}}
+    }
     
     1;
 
@@ -213,3 +213,8 @@ do you think so far? Known issues include:
   un-wikiish).
 
 --[[smcv]]
+
+I've updated smcvpostcomment and publicised it as [[plugins/contrib/comments]]. --[[smcv]]
+
+> While there is still room for improvement and entirely other approaches,
+> I am calling this done since smcv's comments plugin is ready. --[[Joey]] 
diff --git a/doc/todo/syntax_highlighting.mdwn b/doc/todo/syntax_highlighting.mdwn
new file mode 100644 (file)
index 0000000..b5d083b
--- /dev/null
@@ -0,0 +1,133 @@
+There's been a lot of work on contrib syntax highlighting plugins. One should be
+picked and added to ikiwiki core.
+
+Ideally, it should support both converting whole source files into wiki
+pages, as well as doing syntax highlighting as a preprocessor directive 
+(which is either passed the text, or reads it from a file).
+
+## The big list of possibilities
+
+* [[plugins/contrib/highlightcode]] uses [[!cpan Syntax::Highlight::Engine::Kate]],
+  operates on whole source files only, has a few bugs (see
+  [here](http://u32.net/Highlight_Code_Plugin/), and needs to be updated to
+  support [[bugs/multiple_pages_with_same_name]].
+* [[!cpan IkiWiki-Plugin-syntax]] only operates as a directive.
+  Interestingly, it supports multiple highlighting backends, including Kate
+  and Vim.
+* [[plugins/contrib/syntax]] only operates as a directive
+  ([[not_on_source_code_files|automatic_use_of_syntax_plugin_on_source_code_files]]),
+  and uses [[!cpan Text::VimColor]].
+* [[plugins/contrib/sourcehighlight]] uses src-highlight, and operates on
+  whole source files only. Needs to be updated to
+  support [[bugs/multiple_pages_with_same_name]].
+* [[sourcecode|todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion]]
+  also uses src-highlight, and operates on whole source files.
+  Updated to work with the fix for [[bugs/multiple_pages_with_same_name]].  Untested with files with no extension, e.g. `Makefile`.
+* [[users/jasonblevins]]'s code plugin uses src-highlight, and supports both
+  while file and directive use.
+
+* [hlsimple](http://pivot.cs.unb.ca/git/?p=ikiplugins.git;a=blob_plain;f=IkiWiki/Plugin/hlsimple.pm;hb=HEAD) is a wrapper for the the perl module Syntax::Highlight::Engine::Simple.  This is pure perl, pretty simple, uses css. It ought to be pretty fast (according to the author, and just because it is not external).
+On the other hand, there are not many predefined languages yet.  Defining language syntaxes is about as much 
+work as source-highlight, but in perl.  I plan to package the base module for debian. Perhaps after the author 
+releases the 5 or 6 language definitions he has running on his web site, it might be suitable for inclusion in ikiwiki. [[DavidBremner]]
+
+## General problems
+
+* Using non-perl syntax highlighting backends is slow. I'd prefer either
+  using a perl module, or a multiple-backend solution that can use a perl
+  module as one option. (Or, if there's a great highlighter python module,
+  we could use an external plugin..)
+* Currently no single plugin supports both modes of operation (directive
+  and whole source file to page).
+
+  > This is now fixed by the [[ikiwiki/directive/format]] directive for all
+  > whole-source-file plugins, right?
+
+* Nothing seems to support 
+  [[wiki-formatted_comments|wiki-formatted_comments_with_syntax_plugin]]
+  inside source files. Doing this probably means post-processing the 
+  results of the highlighting engine, to find places where it's highlighted
+  comments, and then running them through the ikiwiki rendering pipeline.
+  This seems fairly doable with [[!cpan Syntax::Highlight::Engine::Kate]],
+  at least.
+* The whole-file plugins tend to have a problem that things that look like
+  wikilinks in the source code get munged into links by ikiwiki, which can
+  have confusing results. Similar problem with preprocessor directives.
+  One approach that's also been requested for eg,
+  [[plugins/contrib/mediawiki]] is to allow controlling which linkification
+  types a page type can have on it.
+
+  > The previous two points seem to be related.  One thought: instead of
+  > getting the source from the `content` parameter, the plugin could
+  > re-load the page source.  That would stop directives/links from
+  > being processed in the source.  As noted above, comments
+  > could then be parsed for directives/links later.
+  >
+  > Would it be worth adding a `nodirectives` option when registering
+  > an htmlize hook that switches off directive and link processing before
+  > generating the html for a page?
+
+* The whole-file plugins all get confused if there is a `foo.c` and a `foo.h`.
+  This is trivially fixable now by passing the keepextension option when
+  registering the htmlize hooks, though.
+* Whole-file plugins register a bunch of htmlize hooks. The wacky thing
+  about it is that, when creating a new page, you can then pick "c" or
+  "h" or "pl" etc from the dropdown that normally has "mdwn" etc in it.
+  Is this a bug, or a feature? (Even if a feature, plugins with many
+  extensions make the dropdown unusable.. One way to deal with that is have
+  a config setting that lists what extensions to offer highlighting for.
+  Most people won't need/want the dozens some engines support.)
+* The per page highlighters can't handle creating wiki pages from 
+  "Makefile", or other files without a significant extension.
+  Not clear how to fix this, as ikiwiki is very oriented toward file
+  extensions. The workaround is to use a directive on a wiki page, pulling
+  in the Makefile.
+
+  > I wonder how hard it would be to make a patch whereby a file with
+  > no `.` in the name, and a name that matches a filetype, and where
+  > that filetype was registered `keepextension`, then the file is just
+  > chosen as the appropriate type.  This would allow `Makefile` to
+  > work.
+
+like this:
+
+    diff --git a/IkiWiki.pm b/IkiWiki.pm
+    index 8d728c9..1bd46a9 100644
+    --- a/IkiWiki.pm
+    +++ b/IkiWiki.pm
+    @@ -618,6 +618,8 @@ sub pagetype ($) {
+       
+       if ($page =~ /\.([^.]+)$/) {
+               return $1 if exists $hooks{htmlize}{$1};
+    +  } elsif ($hooks{htmlize}{$page}{keepextension}) {
+    +          return $page;
+       }
+       return;
+     }
+
+## format directive
+
+Rather than making syntax highlight plugins have to provide a preprocessor
+directive as well as handling whole source files, perhaps a generic format
+directive could be used:
+
+       \[[!format pl """..."""]]
+
+That would run the text through the pl htmlizer, from the syntax hightligh
+plugin. OTOH, if "rst" were given, it would run the text through the rst
+htmlizer. So, more generic, allows mixing different types of markup on one
+page, as well as syntax highlighting. Does require specifying the type of
+format, instead of allowing it to be guessed (which some syntax highlighters
+can do). (This directive is now implemented..)
+
+Hmm, this would also allow comments inside source files to have mdwn
+embedded in them, without making the use of mdwn a special case, or needing
+to postprocess the syntax highlighter output to find comments.
+
+       /* \[[!format mdwn """
+
+       This is a comment in my C file. You can use mdwn in here.
+
+       """]] */
+
+Note that this assumes that directives are expanded in source files.
diff --git a/doc/todo/syntax_highlighting/discussion.mdwn b/doc/todo/syntax_highlighting/discussion.mdwn
new file mode 100644 (file)
index 0000000..7a4095c
--- /dev/null
@@ -0,0 +1,26 @@
+sourcehighlight is annoyingly slow, but it does support wiki directives 
+in comments. See [here](http://www.cs.unb.ca/~bremner/teaching/java_examples/snippet/ListMerge/)
+for an example (tags).
+
+> I think that is just a result of it expanding directives, and wikilinks,
+> everywhere in the file, which is generally a possible problem..
+> --[[Joey]]
+
+* * * * *
+
+I think having the option to choose source code page types from the
+dropdown list is definitely a feature.  This gives users an easy way
+to contribute programs (say `.pl` files) or code snippets (like, for
+example, the Elisp area of the EmacsWiki).  Actually, would there any
+other way to create a `.pl` file without write access to the
+repository?  --[[JasonBlevins]]
+
+> Well, you can upload them as an attachment if the wiki is configured to
+> allow it. Having them in the drop down becomes a problem when there are
+> so many wacky extensions in there that you can't find anything.
+> --[[Joey]]
+
+>> I should just note that the
+>> [[sourcecode|todo/automatic_use_of_syntax_plugin_on_source_code_files/discussion]]
+>> plugin only adds the file extensions listed in the config.  This shouldn't cause
+>> massive drop-down menu pollution.  -- [[Will]]
diff --git a/doc/todo/tag_pagespec_function.mdwn b/doc/todo/tag_pagespec_function.mdwn
new file mode 100644 (file)
index 0000000..681a1f6
--- /dev/null
@@ -0,0 +1,34 @@
+Implementing tags in terms of links is clever, but it would be nice if it was
+opaque in both directions: tagging and matching tags. Writing pagespecs to
+find out which pages are tagged with a given name means that the pagespec is
+tied to whatever the tagbase is.
+
+This patch adds a pagespec function 'tag' which lets you write pagespecs to
+match tagged pages independent of whatever the tagbase is set to.
+
+ -- [[users/Jon]] 2009/02/17
+
+> So, this looks good, appreciate the patch.
+> 
+> The only problem I see is it could be confusing if `tag(foo)` matched
+> a page that just linked to the tag via a wikilink, w/o actually tagging it.
+>
+> One other thing, perhaps it should be called `tagged()`? --[[Joey]] 
+
+[[!tag patch done]]
+
+    --- a/plugins/IkiWiki/Plugin/tag.pm        2009-02-16 11:30:11.000000000 +0000
+    +++ b/plugins/IkiWiki/Plugin/tag.pm        2009-02-17 15:40:03.000000000 +0000
+    @@ -125,4 +125,12 @@
+       }
+     }
+     
+    +package IkiWiki::PageSpec;
+    +
+    +sub match_tag ($$;@) {
+    +  my $page = shift;
+    +  my $glob = shift;
+    +    return match_link($page, IkiWiki::Plugin::tag::tagpage($glob));
+    +}
+    +
+     1
index aaa040ec7130d3cf3024367829d08353975f787f..bfc130d69d79e793b1bdd31c51118f26d9160dc1 100644 (file)
@@ -10,6 +10,6 @@
        +       debug("ctime for '$file': ". localtime($ctime));
         
                return $ctime;
-        } #}}}
+        }
 
 [[!tag patch done]]
index 6ef8453f184645590b0b34b581ce56d037faa3e6..b6b082cfe75b073b861f25159c8e9663ce0aa9a2 100644 (file)
@@ -1,4 +1,7 @@
 * Need to get post commit hook code working.
 * Need some example urls for web based diffs.
+* `rcs_commit_staged`, `rcs_rename`, `rcs_remove`, are not
+  implemented for tla, and so attachments, remove and rename plugins
+  cannot be used with it. (These should be fairly easy to add..)
 
 [[!tag rcs/tla]]
index f7d06a5793b64ed42608c4221a4a58002ef31d47..644cf23aaffbc42ef5d8cd4abada1fbacd712cd3 100644 (file)
@@ -11,12 +11,12 @@ A simple plugin to allow per-page customization of a template by passing paramat
 
     my %tmplvars;
 
-    sub import { #{{{
+    sub import {
            hook(type => "preprocess", id => "tmplvars", call => \&preprocess);
            hook(type => "pagetemplate", id => "tmplvars", call => \&pagetemplate);
-    } # }}}
+    }
 
-    sub preprocess (@) { #{{{
+    sub preprocess (@) {
            my %params=@_;
 
            if ($params{page} eq $params{destpage}) {
@@ -34,9 +34,9 @@ A simple plugin to allow per-page customization of a template by passing paramat
                    }
            }
     
-    } # }}}
+    }
     
-    sub pagetemplate (@) { #{{{
+    sub pagetemplate (@) {
             my %params=@_;
             my $template = $params{template};
 
@@ -47,6 +47,6 @@ A simple plugin to allow per-page customization of a template by passing paramat
             }
 
             return undef;
-    } # }}}
+    }
 
     1
diff --git a/doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn b/doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn
new file mode 100644 (file)
index 0000000..547c7a8
--- /dev/null
@@ -0,0 +1,3 @@
+It would be nice if the [[plugins/toc]] plugin let you specify a header level "ceiling" above which (or above and including which) the headers would not be incorporated into the toc.
+
+Currently, the levels=X parameter lets you tweak how deep it will go for small headers, but I'd like to chop off the h1's (as I use them for my page title) -- [[Jon]]
index 3af0458bd25bb403bd5cdf17b00b7aae5fdf5473..2832e37aad36c85e0c696bce62cb124791ad8aab 100644 (file)
@@ -194,9 +194,9 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
     index 4e4da11..8b3cdfe 100644
     --- a/IkiWiki.pm
     +++ b/IkiWiki.pm
-    @@ -1550,7 +1550,16 @@ sub globlist_to_pagespec ($) { #{{{
+    @@ -1550,7 +1550,16 @@ sub globlist_to_pagespec ($) {
      
-     sub is_globlist ($) { #{{{
+     sub is_globlist ($) {
        my $s=shift;
     -  return ( $s =~ /[^\s]+\s+([^\s]+)/ && $1 ne "and" && $1 ne "or" );
     +  return ! ($s =~ /
@@ -209,19 +209,19 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
     +                  ) |
     +                          (\s and \s) | (\s or \s)        # or we find 'and' or 'or' somewhere
     +                  /xs);
-     } #}}}
+     }
      
-     sub safequote ($) { #{{{
-    @@ -1631,7 +1640,7 @@ sub pagespec_merge ($$) { #{{{
+     sub safequote ($) {
+    @@ -1631,7 +1640,7 @@ sub pagespec_merge ($$) {
        return "($a) or ($b)";
-     } #}}}
+     }
      
-    -sub pagespec_translate ($) { #{{{
-    +sub pagespec_makeperl ($) { #{{{
+    -sub pagespec_translate ($) {
+    +sub pagespec_makeperl ($) {
        my $spec=shift;
      
        # Support for old-style GlobLists.
-    @@ -1650,12 +1659,14 @@ sub pagespec_translate ($) { #{{{
+    @@ -1650,12 +1659,14 @@ sub pagespec_translate ($) {
                |
                        \)              # )
                |
@@ -238,7 +238,7 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
                my $word=$1;
                if (lc $word eq 'and') {
                        $code.=' &&';
-    @@ -1666,16 +1677,23 @@ sub pagespec_translate ($) { #{{{
+    @@ -1666,16 +1677,23 @@ sub pagespec_translate ($) {
                elsif ($word eq "(" || $word eq ")" || $word eq "!") {
                        $code.=' '.$word;
                }
@@ -265,14 +265,14 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
                }
        }
      
-    @@ -1683,8 +1701,18 @@ sub pagespec_translate ($) { #{{{
+    @@ -1683,8 +1701,18 @@ sub pagespec_translate ($) {
                $code=0;
        }
      
     +  return 'sub { my $page=shift; my %params = @_; '.$code.' }';
-    +} #}}}
+    +}
     +
-    +sub pagespec_translate ($) { #{{{
+    +sub pagespec_translate ($) {
     +  my $spec=shift;
     +
     +  my $code = pagespec_makeperl($spec);
@@ -282,19 +282,19 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
        no warnings;
     -  return eval 'sub { my $page=shift; '.$code.' }';
     +  return eval $code;
-     } #}}}
+     }
      
-     sub pagespec_match ($$;@) { #{{{
-    @@ -1699,7 +1727,7 @@ sub pagespec_match ($$;@) { #{{{
+     sub pagespec_match ($$;@) {
+    @@ -1699,7 +1727,7 @@ sub pagespec_match ($$;@) {
      
        my $sub=pagespec_translate($spec);
        return IkiWiki::FailReason->new("syntax error in pagespec \"$spec\"") if $@;
     -  return $sub->($page, @params);
     +  return $sub->($page, @params, specFuncs => {});
-     } #}}}
+     }
      
-     sub pagespec_valid ($) { #{{{
-    @@ -1748,11 +1776,78 @@ sub new { #{{{
+     sub pagespec_valid ($) {
+    @@ -1748,11 +1776,78 @@ sub new {
      
      package IkiWiki::PageSpec;
      
@@ -361,7 +361,7 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
     +  }
     +}
     +
-     sub match_glob ($$;@) { #{{{
+     sub match_glob ($$;@) {
        my $page=shift;
        my $glob=shift;
        my %params=@_;
@@ -373,9 +373,9 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
        my $from=exists $params{location} ? $params{location} : '';
        
        # relative matching
-    @@ -1782,11 +1877,12 @@ sub match_internal ($$;@) { #{{{
+    @@ -1782,11 +1877,12 @@ sub match_internal ($$;@) {
      
-     sub match_link ($$;@) { #{{{
+     sub match_link ($$;@) {
        my $page=shift;
     -  my $link=lc(shift);
     +  my $fulllink=shift;
@@ -388,7 +388,7 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
        # relative matching
        if ($link =~ m!^\.! && defined $from) {
                $from=~s#/?[^/]+$##;
-    @@ -1804,19 +1900,32 @@ sub match_link ($$;@) { #{{{
+    @@ -1804,19 +1900,32 @@ sub match_link ($$;@) {
                }
                else {
                        return IkiWiki::SuccessReason->new("$page links to page $p matching $link")
@@ -397,9 +397,9 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
                }
        }
        return IkiWiki::FailReason->new("$page does not link to $link");
-     } #}}}
+     }
      
-     sub match_backlink ($$;@) { #{{{
+     sub match_backlink ($$;@) {
     -  return match_link($_[1], $_[0], @_);
     +  my $page=shift;
     +  my $backlink=shift;
@@ -410,9 +410,9 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
     +  }
     +
     +  return match_link($backlink, $page, @params);
-     } #}}}
+     }
      
-     sub match_created_before ($$;@) { #{{{
+     sub match_created_before ($$;@) {
        my $page=shift;
        my $testpage=shift;
     +  my @params=@_;
@@ -423,8 +423,8 @@ account all comments above (which doesn't mean it is above reproach :) ).  --[[W
      
        if (exists $IkiWiki::pagectime{$testpage}) {
                if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) {
-    @@ -1834,6 +1943,11 @@ sub match_created_before ($$;@) { #{{{
-     sub match_created_after ($$;@) { #{{{
+    @@ -1834,6 +1943,11 @@ sub match_created_before ($$;@) {
+     sub match_created_after ($$;@) {
        my $page=shift;
        my $testpage=shift;
     +  my @params=@_;
index 87e55685c17ae3005b8a5a0e17212506115490c2..14bb437824f802e3c2832b74f7b72d810d256daf 100644 (file)
@@ -8,7 +8,7 @@ I think this (untested) patch might just do the trick:
 
     --- a/IkiWiki/Plugin/edittemplate.pm
     +++ b/IkiWiki/Plugin/edittemplate.pm
-    @@ -46,8 +46,13 @@ sub preprocess (@) { #{{{
+    @@ -46,8 +46,13 @@ sub preprocess (@) {
 
       $pagestate{$params{page}}{edittemplate}{$params{match}}=$params{template};
 
@@ -21,9 +21,9 @@ I think this (untested) patch might just do the trick:
     +       else {
     +               return '';
     +       }
-    } # }}}
+    }
 
-    sub formbuilder (@) { #{{{
+    sub formbuilder (@) {
 
 --[[madduck]]
 
diff --git a/doc/todo/using_meta_titles_for_parentlinks.html b/doc/todo/using_meta_titles_for_parentlinks.html
deleted file mode 100644 (file)
index 651b7fa..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-It is possible to set a Page-Title in the meta-plugin, but that one isn't
-reused in parentlinks. This [[patch]] may fix it.
-
-<ul>
-<li> I give pagetitle the full path to a page.
-<li> I redefine the 'pagetitle'-sub to deal with it.
-<li> to maintain compatibility for IkiWikis without the meta-plugin, i added a 'basename' to the Original-pagetitle.
-</ul>
-
-<pre>
-diff -c /usr/share/perl5/IkiWiki/Render.pm.distrib /usr/share/perl5/IkiWiki/Render.pm
-*** /usr/share/perl5/IkiWiki/Render.pm.distrib  Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Render.pm  Tue Aug 26 23:29:32 2008
-***************
-*** 102,108 ****
-        $template->param(
-                title => $page eq 'index' 
-                        ? $config{wikiname} 
-!                       : pagetitle(basename($page)),
-                wikiname => $config{wikiname},
-                content => $content,
-                backlinks => $backlinks,
---- 102,108 ----
-        $template->param(
-                title => $page eq 'index' 
-                        ? $config{wikiname} 
-!                       : pagetitle($page),
-                wikiname => $config{wikiname},
-                content => $content,
-                backlinks => $backlinks,
-
-diff -c /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm
-*** /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm.distrib      Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Plugin/parentlinks.pm      Tue Aug 26 23:19:43 2008
-***************
-*** 44,50 ****
-                        "height_$height" => 1,
-                };
-                $path.="/".$dir;
-!               $title=IkiWiki::pagetitle($dir);
-                $i++;
-        }
-        return @ret;
---- 44,50 ----
-                        "height_$height" => 1,
-                };
-                $path.="/".$dir;
-!               $title=IkiWiki::pagetitle($path);
-                $i++;
-        }
-        return @ret;
-
-diff -c /usr/share/perl5/IkiWiki.pm.distrib /usr/share/perl5/IkiWiki.pm
-*** /usr/share/perl5/IkiWiki.pm.distrib Wed Aug  6 07:48:34 2008
---- /usr/share/perl5/IkiWiki.pm Tue Aug 26 23:47:30 2008
-***************
-*** 792,797 ****
---- 792,799 ----
-        my $page=shift;
-        my $unescaped=shift;
-  
-+       $page=basename($page);
-+ 
-        if ($unescaped) {
-                $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
-       }
-
-diff -c /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib /usr/share/perl5/IkiWiki/Plugin/meta.pm
-*** /usr/share/perl5/IkiWiki/Plugin/meta.pm.distrib     Wed Aug  6 07:34:55 2008
---- /usr/share/perl5/IkiWiki/Plugin/meta.pm     Tue Aug 26 23:30:58 2008
-***************
-*** 3,8 ****
---- 3,9 ----
-  package IkiWiki::Plugin::meta;
-  
-  use warnings;
-+ no warnings 'redefine';
-  use strict;
-  use IkiWiki 2.00;
-  
-***************
-*** 289,294 ****
---- 290,319 ----
-        }
-  } #}}}
-  
-+ sub IkiWiki::pagetitle ($;$) { #{{{
-+       my $page=shift;
-+       my $unescaped=shift;
-+ 
-+       if ($page =~ m#/#) {
-+               $page =~ s#^/##;
-+               $page =~ s#/index$##;
-+               if ($pagestate{"$page/index"}{meta}{title}) {
-+                       $page = $pagestate{"$page/index"}{meta}{title};
-+               } else {
-+                       $page = IkiWiki::basename($page);
-+               }
-+       }
-+ 
-+       if ($unescaped) {
-+               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : chr($2)/eg;
-+       }
-+       else {
-+               $page=~s/(__(\d+)__|_)/$1 eq '_' ? ' ' : "&#$2;"/eg;
-+       }
-+ 
-+       return $page;
-+ } #}}}
-+ 
-  package IkiWiki::PageSpec;
-  
-  sub match_title ($$;@) { #{{{
-
-
-</pre>
index 492a32b366a53c194e7effe393f831752ea0445e..b28469993864708a54e16520440a64ba8dfc271b 100644 (file)
@@ -157,9 +157,9 @@ ManojSrivastava
 +=cut
 +
 +
-+sub import { #{{{
++sub import {
 +      hook(type => "pagetemplate", id => "varioki", call => \&pagetemplate);
-+} # }}}
++}
 +
 +
 +=pod
@@ -175,7 +175,7 @@ ManojSrivastava
 +
 +=cut
 +
-+sub pagetemplate (@) { #{{{
++sub pagetemplate (@) {
 +      my %params=@_;
 +      my $page=$params{page};
 +      my $template=$params{template};
@@ -207,7 +207,7 @@ ManojSrivastava
 +             $template->param("$var" =>"$value");
 +           }
 +        }
-+} # }}}
++}
 +
 +1;
 +
index 08ca61b0ccde803b830a3677757e22851eae80fa..a5244c9ef2a532a9c3b1620976c0bbbdeb7eed55 100644 (file)
@@ -1 +1,4 @@
-[[Wishlist]] item: I'd love to see the ability to optionally switch back to wiki syntax within the comments of code pretty-printed with the [[plugins/contrib/syntax]] plugin.  This would allow the use of links and formatting in comments.
+[[Wishlist]] item: I'd love to see the ability to optionally switch back to
+wiki syntax within the comments of code pretty-printed with the
+[[plugins/contrib/syntax]] plugin.  This would allow the use of links and
+formatting in comments.
index e3d1b3927e55358fad1826c0e8f7f7eff987a70e..839986c7b69a96c7980941a74cb128a1c959dd3b 100644 (file)
@@ -57,3 +57,8 @@ The plugin can be downloaded from <http://ikiwiki.xbaud.com/wikiwyg-1.6.tar.gz>
 * Personalized settings
 
 [Wikiwyg]: http://www.wikiwyg.net/
+
+> As noted in [[discussion]], the url above doesn't work, and I stupidly
+> lost my copy of this before merging it. I hope that this plugin will turn
+> back up. In the meantime, there is a wmd plugin that accomplishes the
+> same basic task of WSYWIG markdown editing. --[[Joey]] 
index b6af75ac81dcd104a3d7be95578de49bf9ef0045..0c618de5c1eac91ac31b11407c90cc4585e0cab6 100644 (file)
@@ -6,7 +6,7 @@ ikiwiki - a wiki compiler
 
 ikiwiki [options] source destination
 
-ikiwiki --setup configfile
+ikiwiki --setup setupfile
 
 # DESCRIPTION
 
@@ -30,19 +30,19 @@ These options control the mode that ikiwiki operates in.
 
   Force a rebuild of all pages.
 
-* --setup configfile
+* --setup setupfile
 
   In setup mode, ikiwiki reads the config file, which is really a perl
   program that can call ikiwiki internal functions.
 
   The default action when --setup is specified is to automatically generate
-  wrappers for a wiki based on data in a config file, and rebuild the wiki.
+  wrappers for a wiki based on data in a setup file, and rebuild the wiki.
   If you only want to build any changed pages, you can use --refresh with
   --setup.
 
-* --dumpsetup configfile
+* --dumpsetup setupfile
 
-  Causes ikiwiki to write to the specified config file, dumping out
+  Causes ikiwiki to write to the specified setup file, dumping out
   its current configuration.
 
 * --wrappers
@@ -103,13 +103,14 @@ These options control the mode that ikiwiki operates in.
 # CONFIG OPTIONS
 
 These options configure the wiki. Note that [[plugins]] can add additional
-configuration options of their own.
+configuration options of their own. All of these options and more besides can
+also be configured using a setup file.
 
-* --wikiname
+* --wikiname name
 
   The name of the wiki, default is "wiki".
 
-* --templatedir
+* --templatedir dir
 
   Specify the directory that the page [[templates|wikitemplates]] are stored in.
   Default is `/usr/share/ikiwiki/templates`, or another location as configured at
@@ -121,7 +122,7 @@ configuration options of their own.
   ikiwiki. Old versions of templates do not always work with new ikiwiki
   versions.
 
-* --underlaydir
+* --underlaydir dir
 
   Specify the directory that is used to underlay the source directory.
   Source files will be taken from here unless overridden by a file in the
@@ -292,7 +293,7 @@ configuration options of their own.
 * --prefix-directives, --no-prefix-directives
 
   Toggle new '!'-prefixed syntax for preprocessor directives.  ikiwiki currently
-  defaults to --no-prefix-directives.
+  defaults to --prefix-directives.
 
 * --w3mmode, --no-w3mmode
 
@@ -307,19 +308,37 @@ configuration options of their own.
 
 * --getctime
 
-  Pull last changed time for each new page out of the revision control
+  Pull creation time for each new page out of the revision control
   system. This rarely used option provides a way to get the real creation
   times of items in weblogs, such as when building a wiki from a new
-  Subversion checkout. It is unoptimised and quite slow. It is best used
+  VCS checkout. It is unoptimised and quite slow. It is best used
   with --rebuild, to force ikiwiki to get the ctime for all pages.
 
 * --set var=value
   
   This allows setting an arbitrary configuration variable, the same as if it
-  were set via a configuration file. Since most options can be configured
+  were set via a setup file. Since most options can be configured
   using command-line switches, you will rarely need to use this, but it can be
   useful for the odd option that lacks a command-line switch.
 
+# EXAMPLES
+
+* ikiwiki --setup my.setup
+
+  Completly (re)build the wiki using the specified setup file.
+
+* ikiwiki --setup my.setup --refresh
+
+  Refresh the wiki, using settings from my.setup, and avoid
+  rebuilding any pages that have not changed. This is faster.
+
+* ikiwiki --setup my.setup --refresh --wrappers
+
+  Refresh the wiki, including regnerating all wrapper programs,
+  but do not rebuild all pages. Useful if you have changed something
+  in the setup file that does not need a full wiki rebuild to update
+  all pages, but that you want to immediatly take effect.
+
 # ENVIRONMENT
 
 * CC
index 0d4483fa87f05431d2d7ee38502eae9896d6b3c0..b32927a1c312b13f632506deaf3fbcd09baf5a7f 100644 (file)
@@ -3,5 +3,7 @@ My watchlist:
 [[!inline archive="yes" sort="mtime" atom="yes" pages="
 todo/allow_wiki_syntax_in_commit_messages*
 todo/shortcut_with_different_link_text*
-todo/structured_page_data* "]]
+todo/structured_page_data*
+tips/convert_mediawiki_to_ikiwiki*
+"]]
 
diff --git a/doc/users/StevenBlack.mdwn b/doc/users/StevenBlack.mdwn
new file mode 100644 (file)
index 0000000..ea7a6a9
--- /dev/null
@@ -0,0 +1,5 @@
+It feels like there are a lot of people named Steven Black. While I'm just one of many with my name, sometimes it is actually just me and I've forgotten that I had an account somewhere.
+
+I'm not a doctor, though I would certainly trust any doctor, dentist, or philosopher named Steven Black. (There are several.)
+
+I *am* a huge Ikiwiki fan. I've had my eye on it for many years for personal projects (though I never quite got around to installing it). Recently, however, I managed to convince my coworkers that it would be a good idea for an internal wiki. Boy was I right. The thing is practically designed to be the perfect developer-centered wiki.
diff --git a/doc/users/ajt.mdwn b/doc/users/ajt.mdwn
new file mode 100644 (file)
index 0000000..bc47040
--- /dev/null
@@ -0,0 +1,20 @@
+[[!meta title="Adam Trickett"]]
+
+# Adam Trickett
+
+## "ajt"
+
+I'm a long time hacker of sorts, I like to program in Perl on Debian systems but work pays me to program in ABAP (COBOL) on SAP.
+
+I like wikis and I'm currently in love with ikiwiki, having moved my home intranet from a home made template solution to ikiwiki over a weekend. I'm using ikiwiki more like a web content management system (e.g. RedDot) rather than a traditional wiki.
+
+### My Links
+
+* [iredale dot net](http://www.iredale.net/) my web server and main blog
+* [ajt](http://www.perlmonks.org/index.pl?node_id=113686) my Perkmonks home node
+* [ajt](http://use.perl.org/~ajt) my use Perl home
+* [ATRICKETT](http://search.cpan.org/~atrickett/) my CPAN folder
+* [ajt](http://www.debian-administration.org/users/ajt) my Debian-Administration home (good site btw)
+* [drajt](http://www.linkedin.com/in/drajt) my LinkedIn profile
+* [drajt](http://www.slideshare.net/drajt) my "Slidespace" on SlideShare
+* [AdamTrickett](http://www.hants.lug.org.uk/cgi-bin/wiki.pl?AdamTrickett) my wiki page on my LUG's site
diff --git a/doc/users/alexander.mdwn b/doc/users/alexander.mdwn
new file mode 100644 (file)
index 0000000..b2894a9
--- /dev/null
@@ -0,0 +1 @@
+I use ikiwiki to organize information - projects, reading notes, outlines, todo lists, etc. 
diff --git a/doc/users/cfm.mdwn b/doc/users/cfm.mdwn
new file mode 100644 (file)
index 0000000..4feab96
--- /dev/null
@@ -0,0 +1 @@
+I maintain a [home page](http://www.panix.com/~cfm/ "Cory Myers").
index 6dfa6a23b251f69f66d0a9fe6cc41d2d6e14b6d5..15c065e45f6bbb9239477c3b27273bbc2c81b2d9 100644 (file)
@@ -1,4 +1,5 @@
 I'd love to see any notes you have on using ikiwiki for GTD.  Would you
 consider documenting them?  Perhaps we could turn the result into a
 [[tip|tips]]. -[[JoshTriplett]]
-> Well, certainly. Basically it's just inline + tag feature. I'm going to have more time in May for ikiwiki, I hope. 
\ No newline at end of file
+> Well, certainly. Basically it's just inline + tag feature. I'm going to have more time in May for ikiwiki, I hope. 
+> > Any news about that ?
index f9a216e18e84cf30c65ebff01f9000f0ab228e72..8fa9965a5a65527766b7d454ee6fb23e38c5bbae 100644 (file)
@@ -1,4 +1,4 @@
 intrigeri AT boum.org, already loving ikiwiki.
 
 * [gnupg key](http://gaffer.ptitcanardnoir.org/intrigeri/intrigeri.asc)
-* Git repository ([gitweb](http://repo.or.cz/w/ikiwiki/intrigeri.git)) with various ikiwiki {feature, bugfix}-branches : `git://repo.or.cz/ikiwiki/intrigeri.git`
+* Git repository with various ikiwiki {feature, bugfix}-branches : `git://gaffer.ptitcanardnoir.org/ikiwiki.git`
index 52420f7c9fdf910dd8dc3a6d3e81c667451cbad4..61c381d961e5d6b2763d56e47617393fb8c10ecb 100644 (file)
+[[!meta title="Jason Blevins"]]
+
 I'm currently hosting a private ikiwiki for keeping research notes
-which, with some patches and a (currently unreleased) plugin, will
+which, with some patches and a plugin (below), will
 convert inline LaTeX expressions to MathML.  I'm working towards a
 patchset and instructions for others to do the same.
 
-There is one thing that needs to be decided first: whether or not to
-include [[sanitization|todo/svg]] of MathML in htmlscrubber (and while
-we're at it, why not SVG).
+I've setup a test ikiwiki [here](http://xbeta.org/colab/) where I've
+started keeping a few notes on my progress.  There is an example of
+inline SVG on the homepage (note that the logo scales along with the
+font size).  There are a few example mathematical expressions in the
+[sandbox](http://xbeta.org/colab/sandbox/).  The MathML is generated
+automatically from inline LaTeX expressions using an experimental
+plugin I'm working on.
 
 My (also MathML-enabled) homepage: <http://jblevins.org/> (still using
 Blosxom...maybe one day I'll convert it to ikiwiki...)
+
+Current ikiwki issues of interest:
+
+ * [[bugs/recentchanges_feed_links]]
+ * [[bugs/HTML_inlined_into_Atom_not_necessarily_well-formed]]
+ * [[plugins/toc/discussion]]
+ * [[todo/BibTeX]]
+ * [[todo/svg]]
+ * [[todo/Option_to_make_title_an_h1?]]
+ * [[bugs/SVG_files_not_recognized_as_images]]
+
+## Plugins
+
+These plugins are experimental.  Use them at your own risk.  Read the
+perldoc documentation for more details.  Patches and suggestions are
+welcome.
+
+ * [mdwn_itex][] - Works with the `mdwn` plugin to convert inline LaTeX
+   expressions to MathML using `itex2MML`.
+
+ * [h1title][] - If present, use the leading level 1 Markdown header to
+   set the page title and remove it from the page body.
+
+ * [code][] - Whole file and inline code snippet syntax highlighting
+   via GNU Source-highlight.  The list of supported file extensions is
+   configurable.  There is also some preliminary [documentation][code-doc].
+   See the [FortranWiki](http://fortranwiki.org) for examples.
+
+ * [metamail][] - a plugin for loading metadata from email-style
+   headers at top of a file (e.g., `title: Page Title` or
+   `date: November 2, 2008 11:14 EST`).
+
+ * [pandoc][] - Markdown page processing via Pandoc.  LaTeX and
+   reStructuredText are optional.
+
+ * [path][] - Provides path-specific template conditionals such as
+   `IS_HOMEPAGE` and `IN_DIR_SUBDIR`.
+
+ [mdwn_itex]: http://code.jblevins.org/ikiwiki/plugins.git/plain/mdwn_itex.pm
+ [h1title]: http://code.jblevins.org/ikiwiki/plugins.git/plain/h1title.pm
+ [code]: http://code.jblevins.org/ikiwiki/plugins.git/plain/code.pm
+ [code-doc]: http://code.jblevins.org/ikiwiki/plugins.git/plain/code.text
+ [metamail]: http://code.jblevins.org/ikiwiki/plugins.git/plain/metamail.pm
+ [pandoc]: http://code.jblevins.org/ikiwiki/plugins.git/plain/pandoc.pm
+ [path]: http://code.jblevins.org/ikiwiki/plugins.git/plain/path.pm
+
+
+## MathML and SVG support
+
+So far, I've made some notes on sanitizing MathML and SVG via
+htmlscrubber on the [[todo/svg]] todo item.
+
+I've also worked out some content-negotiation issues.  First of all,
+one needs to modify the default templates to use the
+XHTML+MathML+SVG doctype (see e.g., this [patch][template-patch]).
+For most browsers, the content type of the pages should be
+`application/xhtml+xml`.  The solution is easy if you want to
+just send `application/xhtml+xml` to everybody:
+just change the content type of `.html` files across the board.
+
+However, if you want to support browsers that don't accept
+`application/xhtml+xml` (and those that will but say they
+don't, such as IE with the MathPlayer plugin), then one
+needs a `mod_rewrite` rule like the following:
+
+    RewriteCond %{HTTP_ACCEPT} application\/xhtml\+xml [OR]
+    RewriteCond %{HTTP_USER_AGENT} (W3C.*Validator|MathPlayer)
+    RewriteRule \.html$ - [T=application/xhtml+xml]
+
+This solves the problem of MathML and inline SVG in static pages
+but some additional work is required for dynamically generated
+pages, like page previews, that are generated by `ikiwiki.cgi`.
+We need to allow `ikiwiki.cgi` to set the content type dynamically
+based on the `HTTP_CONTENT_TYPE` environment variable
+(e.g., with the following [patch][cgi-patch]).  Then, the following
+rewrite rules can pass the correct content type to ikiwiki:
+
+    RewriteCond %{HTTP_ACCEPT} application\/xhtml\+xml [OR]
+    RewriteCond %{HTTP_USER_AGENT} (W3C.*Validator|MathPlayer)
+    RewriteRule ikiwiki.cgi$ - [T=application/xhtml+xml]
+
+One final critical issue is that a production-ready setup needs to
+implement some sort of on-the-fly error handling.  If a user submits
+an invalid LaTeX expression or SVG code (not malicious, just invalid)
+and saves the page, then browsers like Firefox will halt processing of
+the page, preventing any further viewing or editing.  A less than
+optimal solution is to force users to preview the page before saving.
+That way if someone introduces invalid XHTML then they can't save the
+page in the first place (unless they post directly to the right URL).
+
+ [template-patch]: http://xbeta.org/gitweb/?p=xbeta/ikiwiki.git;a=blobdiff;f=templates/page.tmpl;h=380ef699fa72223744eb5c1ee655fb79aa6bce5b;hp=9084ba7e11e92a10528b2ab12c9b73cf7b0f40a7;hb=416d5d1b15b94e604442e4e209a30dee4b77b684;hpb=ececf4fb8766a4ff7eff943b3ef600be81a0df49
+ [cgi-patch]: http://xbeta.org/gitweb/?p=xbeta/ikiwiki.git;a=commitdiff;h=fa538c375250ab08f396634135f7d79fce2a9d36
diff --git a/doc/users/jelmer.mdwn b/doc/users/jelmer.mdwn
new file mode 100644 (file)
index 0000000..1f2f71a
--- /dev/null
@@ -0,0 +1 @@
+[Jelmer Vernooij](http://samba.org/~jelmer/)
diff --git a/doc/users/jon.mdwn b/doc/users/jon.mdwn
new file mode 100644 (file)
index 0000000..1cda239
--- /dev/null
@@ -0,0 +1,20 @@
+[[!meta title="Jon Dowland"]]
+I'm looking at ikiwiki both for my personal site but also as a
+team-documentation management system for a small-sized group of UNIX
+sysadmins.
+
+* my edits should appear either as 'Jon' (if I've used
+  [[tips/untrusted_git_push]]) or 'jmtd.net' (or once upon a time
+  'alcopop.org/me/openid/' or 'jondowland').
+* My [homepage](http://jmtd.net/) is powered by ikiwiki
+
+I gave a talk at the [UK UNIX User's Group](http://www.ukuug.org/) annual
+[Linux conference](http://www.ukuug.org/events/linux2008/) about organising
+system administrator documentation. Roughly a third of this talk was
+discussing IkiWiki in some technical detail and suggesting it as a good piece
+of software for this task.
+
+ * slides at <http://www.staff.ncl.ac.uk/jon.dowland/unix/docs/>.
+
+I am also working on some ikiwiki hacks: an alternative approach to
+[[plugins/comments]]; a system for [[forum/managing_todo_lists]].
diff --git a/doc/users/jondowland.mdwn b/doc/users/jondowland.mdwn
deleted file mode 100644 (file)
index c630261..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-A new ikiwiki user, looking at ikiwiki both for his personal site but also as a team-documentation management system for a small-sized group of UNIX sysadmins.
-
-* My [homepage](http://jmtd.net/) is powered by ikiwiki (replacing my [older homepage](http://alcopop.org/), which was a mess of scripts)
-
-I am giving a talk at the [UK UNIX User's Group](http://www.ukuug.org/) annual [Linux conference](http://www.ukuug.org/events/linux2008/) about organising system administrator documentation which will feature IkiWiki.
index f32d23bb70781148f73c1b49472d9524f9c76242..f85c068c301efdb1aa09e637ace765d3a0690922 100644 (file)
@@ -1,10 +1,15 @@
 [[!meta title="Josh Triplett"]]
 
-Josh Triplett; `josh@{freedesktop.org,kernel.org,psas.pdx.edu}`.
+Email: `josh@{joshtriplett.org,freedesktop.org,kernel.org,psas.pdx.edu}`.
+
+[Josh Triplett's homepage](http://joshtriplett.org)
 
 Proud user of ikiwiki.
 
-Currently working on scripts to convert MoinMoin and TWiki wikis to ikiwikis
-backed by a git repository, including full history.
+Currently working on scripts to convert MoinMoin and TWiki wikis to
+ikiwikis backed by a git repository, including full history.
+Available from the following repositories, though not well-documented:
 
-> I've written about how I converted from Mediawiki here: <http://iki.u32.net/Mediawiki_Conversion/>  Are you ever going to release your scripts?  --[[sabr]]
+    git clone git://svcs.cs.pdx.edu/git/wiki2iki/moin2iki
+    git clone git://svcs.cs.pdx.edu/git/wiki2iki/html-wikiconverter
+    git clone git://svcs.cs.pdx.edu/git/wiki2iki/twiki
diff --git a/doc/users/jrblevin.mdwn b/doc/users/jrblevin.mdwn
new file mode 100644 (file)
index 0000000..4eb250b
--- /dev/null
@@ -0,0 +1 @@
+[[!meta redir=users/jasonblevins]]
diff --git a/doc/users/jwalzer.mdwn b/doc/users/jwalzer.mdwn
new file mode 100644 (file)
index 0000000..e66ad1a
--- /dev/null
@@ -0,0 +1,3 @@
+Jan Walzer started to look on ikiwiki just recently.
+
+Read [here](http://wa.lzer.net/wiki/ikiwiki/whyikiwiki/) why he uses ikiwiki.
diff --git a/doc/users/neale.mdwn b/doc/users/neale.mdwn
new file mode 100644 (file)
index 0000000..5245c2c
--- /dev/null
@@ -0,0 +1,10 @@
+I used IkiWiki to supplant some custom journal software.  I like that it uses
+the filesystem, my intent is to make journal entries as future-proof as
+possible.  I'll probably start using it for generation of entire sites, soon.
+
+Things generated by IkiWiki with some fancypants stylesheets:
+
+* [woozle.org](http://woozle.org/)
+* [My page](http://woozle.org/~neale/)
+* [Amy's blog](http://woozle.org/~aim/blog/)
+* [Heidi's blog](http://woozle.org/~heidi/blog/)
diff --git a/doc/users/nolan.mdwn b/doc/users/nolan.mdwn
new file mode 100644 (file)
index 0000000..64b405e
--- /dev/null
@@ -0,0 +1 @@
+Hi, I'm Nolan. I'll add more later.
diff --git a/doc/users/seanh.mdwn b/doc/users/seanh.mdwn
new file mode 100644 (file)
index 0000000..d093c2f
--- /dev/null
@@ -0,0 +1 @@
+seanh is an ikiwiki user.
diff --git a/doc/users/simonraven.mdwn b/doc/users/simonraven.mdwn
new file mode 100644 (file)
index 0000000..0706859
--- /dev/null
@@ -0,0 +1,3 @@
+New ikiwiki site at my personal site under /ikiwiki/ . This might move to /wiki/ or be on wiki.k.o depending on if I can import my MediaWiki stuff to it.
+
+Thought I'd try it out again and it grew on me.
index 33ae450b24de704c8cc6b6ec80856138bc9155c8..59d1affba20f97c4e8e7f7db94588cb9a5533076 100644 (file)
@@ -1 +1,10 @@
-I'm trying to add enough features/fix enough bugs to convert [smcv.pseudorandom.co.uk](http://smcv.pseudorandom.co.uk/) from Django + Python + misc hacks to ikiwiki.
+Website: [pseudorandom.co.uk](http://www.pseudorandom.co.uk/)
+
+Blog: [smcv.pseudorandom.co.uk](http://smcv.pseudorandom.co.uk/)
+
+My repository containing ikiwiki branches:
+
+* gitweb: http://git.pseudorandom.co.uk/smcv/ikiwiki.git
+* anongit: git://git.pseudorandom.co.uk/git/smcv/ikiwiki.git
+
+Currently thinking about a [[users/smcv/gallery]] plugin.
diff --git a/doc/users/smcv/gallery.mdwn b/doc/users/smcv/gallery.mdwn
new file mode 100644 (file)
index 0000000..b6b8de7
--- /dev/null
@@ -0,0 +1,342 @@
+[[!template id=plugin name=smcvgallery author="[[Simon_McVittie|smcv]]"]]
+[[!tag type/chrome]]
+
+This plugin has not yet been written; this page is an experiment in
+design-by-documentation :-)
+
+## Requirements
+
+This plugin formats a collection of images into a photo gallery,
+in the same way as many websites: good examples include the
+PHP application [Gallery](http://gallery.menalto.com/), Flickr,
+and Facebook's Photos "application".
+
+The web UI I'm trying to achieve consists of one
+[HTML page of thumbnails](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/)
+as an entry point to the gallery, where each thumbnail links to
+[a "viewer" HTML page](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/img_0068/)
+with a full size image, next/previous thumbnail links, and
+[[plugins/comments]].
+
+(The Summer of Code [[plugins/contrib/gallery]] plugin does the
+next/previous UI in Javascript using Lightbox, which means that
+individual photos can't be bookmarked in a meaningful way, and
+the best it can do as a fallback for non-Javascript browsers
+is to provide a direct link to the image.)
+
+Other features that would be good to have:
+
+* minimizing the number of separate operations needed to make a gallery -
+  editing one source file per gallery is acceptable, editing one
+  source file per photo is not
+
+* keeping photos outside source code control, for instance in an
+  underlay
+
+* assigning [[tags|ikiwiki/directive/tag]] to photos, providing a
+  superset of Facebook's "show tagged photos of this person" functionality
+
+* constructing galleries entirely via the web by uploading attachments
+
+* inserting grouping (section headings) within a gallery; as in the example
+  linked above, I'd like this to split up the thumbnails but not the
+  next/previous trail
+
+* rendering an `<object>/<embed>` arrangement to display videos, and possibly
+  thumbnailing them in the same way as totem-video-thumbnailer
+  (my camera can record short videos, so some of my web photo galleries
+  contain them)
+
+My plan is to have these directives:
+
+* \[[!gallery]] registers the page it's on as a gallery, and displays all
+  photos that are part of this gallery but not part of a \[[!gallerysection]]
+  (below).
+
+  All images (i.e. `*.png *.jpg *.gif`) that are attachments to the gallery page
+  or its subpages are considered to be part of the gallery.
+
+  Optional arguments:
+
+  * filter="[[ikiwiki/PageSpec]]": only consider images to be part of the
+    gallery if they also match this filter
+
+  * sort="date|filename": order in which to sort the images
+
+* \[[!gallerysection filter="[[ikiwiki/PageSpec]]"]] displays all photos in the
+  gallery that match the filter
+
+So,
+[the gallery I'm using as an example](http://www.pseudorandom.co.uk/2008/2008-03-08-panic-cell-gig/)
+could look something like this:
+
+    \[[!gallery]]
+    <!-- replaced with one uncategorized photo -->
+
+    # Gamarra
+
+    \[[!gallerysection filter="link(sometag)"]]
+    <!-- all the Gamarra photos -->
+
+    # Smokescreen
+
+    \[[!gallerysection filter="link(someothertag)"]]
+    <!-- all the Smokescreen photos -->
+
+    <!-- ... -->
+
+## Implementation ideas
+
+The next/previous part this plugin overlaps with [[todo/wikitrails]].
+
+A \[[!galleryimg]] directive to assign metadata to images might be necessary, so
+the gallery page can contain something like:
+
+    \[[!galleryimg p1010001.jpg title="..." caption="..." tags="foo"]]
+    \[[!galleryimg p1010002.jpg title="..." caption="..." tags="foo bar"]]
+
+However, allowing other pages to push in metadata like that will make
+dependency tracking difficult.
+
+Making the viewer pages could be rather tricky. Here are some options:
+"synthesize source pages for viewers" is the one I'm leaning towards at the
+moment.
+
+### Viewers' source page is the gallery
+
+One possibility is to write out the viewer pages as a side-effect of
+preprocessing the \[[!gallery]] directive. The proof-of-concept implementation
+below does this.  However, this does mean the viewer pages can't have tags or
+metadata of their own and can't be matched by [[pagespecs|ikiwiki/pagespec]] or
+[[wikilinks|ikiwiki/wikilink]].
+
+It might be possible to implement tagging by using \[[!galleryimg]] to assign
+the metadata to the *images* instead of their viewers; however, that would
+require hacking up both `IkiWiki::htmllink` and `IkiWiki::urlto` to redirect
+links to the image (e.g. from the \[[!map]] on a tag page) to become links to
+the viewer page.
+
+Modifications to the comments plugin would also be required, to make it allow
+comments written to `foo/bar/comment_1._comment` even though the page foo/bar
+does not really exist, and display comments on the viewer pages even though
+they're not real pages. (Writing comments to `foo/bar.jpg/*._comment` is not
+an option!)
+
+### Synthesize source pages for viewers
+
+Another is to synthesize source pages for the viewers. This means they can have
+tags and metadata, but trying to arrange for them to be scanned etc. correctly
+without needing another refresh run is somewhat terrifying.
+[[plugins/autoindex]] can safely create source pages because it runs in
+the refresh hook, but I don't really like the idea of a refresh hook that scans
+all source pages to see if they contain \[[!gallery]]...
+
+The photo galleries I have at the moment, like the Panic Cell example above,
+are made by using an external script to parse XML gallery descriptions (lists
+of image filenames, with metadata such as titles), and using this to write
+IkiWiki markup into a directory which is then used as an underlay. This is a
+hack, but it works. The use of XML is left over from a previous attempt at
+solving the same problem using Django.
+
+Perhaps a better approach would be to have a setupfile option that names a
+particular underlay directory (meeting the objective of not having large
+photos under source code control) and generates a source page for each file
+in that directory during the refresh hook. The source pages could be in the
+underlay until they are edited (e.g. tagged), at which point they would be
+copied into the source-code-controlled version in the usual way.
+
+The synthetic source pages can be very simple, using the same trick as my
+[[plugins/comments]] plugin (a dedicated [[directive|ikiwiki/directives]]
+encapsulating everything the plugin needs). If the plugin automatically
+gathers information like file size, pixel size, date etc. from the images, then
+only the human-edited information and a filename reference need to be present
+in the source page; with some clever lookup rules based on the filename of
+the source page, not even the photo's filename is necessarily needed.
+
+    \[[!meta title="..."]]
+    \[[!meta date="..."]]
+    \[[!meta copyright="..."]]
+    \[[!tag ...]]
+
+    \[[!galleryimageviewer p1010001.jpg]]
+
+However, this would mean that editing tags and other metadata would require
+editing pages individually. Rather than trying to "fix" that, perhaps it would
+be better to have a special CGI interface for bulk tagging/metadata editing.
+This could even be combined with a bulk upload form (a reasonable number of
+file upload controls - maybe 20 - with metadata alongside each).
+
+Uploading multiple images is necessarily awkward due to restrictions placed on
+file upload controls by browsers for security reasons - sites like Facebook
+allow whole directories to be uploaded at the same time, but they achieve this
+by using a signed Java applet with privileged access to the user's filesystem.
+
+I've found that it's often useful to be able to force the creation time of
+photos (my camera's battery isn't very reliable, and it frequently decides that
+the date is 0000-00-00 00:00:00), so treating the \[[!meta date]] of the source
+page and the creation date of the photo as synonymous would be useful.
+
+### Images are the viewer's source - special filename extension
+
+Making the image be the source page (and generate HTML itself) would be
+possible, but I wouldn't want to generate a HTML viewer for every `.jpg` on a
+site, so either the images would have to have a special extension (awkward for
+uploads from Windows users) or the plugin would have to be able to change
+whether HTML was generated in some way (not currently possible).
+
+### Images are the viewer's source - alter `ispage()`
+
+It might be possible to hack up `ispage()` so some, but not all, images are
+considered to "be a page":
+
+* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg
+* srcdir/gallery/photo.jpg → destdir/gallery/photo/index.html
+
+Perhaps one way to do this would be for the photos to appear in a particular
+underlay directory, which would also fulfil the objective of having photos not
+be version-controlled:
+
+* srcdir/not-a-photo.jpg → destdir/not-a-photo.jpg
+* underlay/gallery/photo.jpg → destdir/gallery/photo/index.html
+
+## Proof-of-concept implementation of "viewers' source page is the gallery"
+
+    #!/usr/bin/perl
+    package IkiWiki::Plugin::gallery;
+    
+    use warnings;
+    use strict;
+    use IkiWiki 2.00;
+    
+    sub import {
+       hook(type => "getsetup", id => "gallery",  call => \&getsetup);
+       hook(type => "checkconfig", id => "gallery", call => \&checkconfig);
+       hook(type => "preprocess", id => "gallery",
+               call => \&preprocess_gallery, scan => 1);
+       hook(type => "preprocess", id => "gallerysection",
+               call => \&preprocess_gallerysection, scan => 1);
+       hook(type => "preprocess", id => "galleryimg",
+               call => \&preprocess_galleryimg, scan => 1);
+    }
+    
+    sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+               },
+    }
+    
+    sub checkconfig () {
+    }
+    
+    # page that is a gallery => array of images
+    my %galleries;
+    # page that is a gallery => array of filters
+    my %sections;
+    # page that is an image => page name of generated "viewer"
+    my %viewers;
+    
+    sub preprocess_gallery {
+       # \[[!gallery filter="!*/cover.jpg"]]
+       my %params=@_;
+    
+       my $subpage = qr/^\Q$params{page}\E\//;
+    
+       my @images;
+    
+       foreach my $page (keys %pagesources) {
+               # Reject anything not a subpage or attachment of this page
+               next unless $page =~ $subpage;
+    
+               # Reject non-images
+               # FIXME: hard-coded list of extensions
+               next unless $page =~ /\.(jpg|gif|png|mov)$/;
+    
+               # Reject according to the filter, if any
+               next if (exists $params{filter} &&
+                       !pagespec_match($page, $params{filter},
+                               location => $params{page}));
+    
+               # OK, we'll have that one
+               push @images, $page;
+    
+               my $viewername = $page;
+               $viewername =~ s/\.[^.]+$//;
+               $viewers{$page} = $viewername;
+    
+               my $filename = htmlpage($viewername);
+               will_render($params{page}, $filename);
+       }
+    
+       $galleries{$params{page}} = \@images;
+    
+       # If we're just scanning, don't bother producing output
+       return unless defined wantarray;
+    
+       # actually render the viewers
+       foreach my $img (@images) {
+               my $filename = htmlpage($viewers{$img});
+               debug("rendering image viewer $filename for $img");
+               writefile($filename, $config{destdir}, "# placeholder");
+       }
+    
+       # display a list of "loose" images (those that are in no section);
+       # this works because we collected the sections' filters during the
+       # scan stage
+    
+       my @loose = @images;
+    
+       foreach my $filter (@{$sections{$params{page}}}) {
+               my $_;
+               @loose = grep { !pagespec_match($_, $filter,
+                               location => $params{page}) } @loose;
+       }
+    
+       my $_;
+       my $ret = "<ul>\n";
+       foreach my $img (@loose) {
+               $ret .= "<li>";
+               $ret .= "<a href=\"" . urlto($viewers{$img}, $params{page});
+               $ret .= "\">$img</a></li>\n"
+       }
+       return "$ret</ul>\n";
+    }
+    
+    sub preprocess_gallerysection {
+       # \[[!gallerysection filter="friday/*"]]
+       my %params=@_;
+    
+       # remember the filter for this section so the "loose images" section
+       # won't include these images
+       push @{$sections{$params{page}}}, $params{filter};
+    
+       # If we're just scanning, don't bother producing output
+       return unless defined wantarray;
+    
+       # this relies on the fact that we ran preprocess_gallery once
+       # already, during the scan stage
+       my @images = @{$galleries{$params{page}}};
+       @images = grep { pagespec_match($_, $params{filter},
+                       location => $params{page}) } @images;
+    
+       my $_;
+       my $ret = "<ul>\n";
+       foreach my $img (@images) {
+               $ret .= "<li>";
+               $ret .= htmllink($params{page}, $params{destpage},
+                       $viewers{$img});
+               $ret .= "</li>";
+       }
+       return "$ret</ul>\n";
+    }
+    
+    sub preprocess_galleryimg {
+       # \[[!galleryimg p1010001.jpg title="" caption="" tags=""]]
+       my $file = $_[0];
+       my %params=@_;
+    
+       return "";
+    }
+    
+    1
diff --git a/doc/users/svend.mdwn b/doc/users/svend.mdwn
new file mode 100644 (file)
index 0000000..69d8358
--- /dev/null
@@ -0,0 +1,4 @@
+[[!meta title="Svend Sorensen"]]
+
+* [website](http://www.ciffer.net/~svend/)
+* [blog](http://www.ciffer.net/~svend/blog/)
diff --git a/doc/users/weakish.mdwn b/doc/users/weakish.mdwn
new file mode 100644 (file)
index 0000000..ccd5665
--- /dev/null
@@ -0,0 +1 @@
+email: weakish@gmail.com
diff --git a/doc/users/weakishjiang.mdwn b/doc/users/weakishjiang.mdwn
new file mode 100644 (file)
index 0000000..0cafb46
--- /dev/null
@@ -0,0 +1,4 @@
+[My blog](http://millenniumdark.blog.ubuntu.org.cn)
+
+> So, you're learning haskell. You know, I want to add support for haskell
+> external plugins to ikiwiki.. :-) --[[Joey]] 
diff --git a/doc/users/xma.mdwn b/doc/users/xma.mdwn
new file mode 100644 (file)
index 0000000..89f2ff7
--- /dev/null
@@ -0,0 +1,28 @@
+[[!meta title="Xavier Maillard"]]
+# Xavier Maillard
+
+I just started using [[ikiwiki]] for my own webspace at http://maillard.mobi/~xma/wiki
+
+I am learning how to effectively use it.
+
+Anyway, [[ikiwiki]] is really *awesome* !
+
+## More about me
+
+I am CLI user living in the linux console. More precisely, I live in an [[GNU_Emacs]] frame all day long. My main computer is an EeePC 901 running Slackware GNU/Linux 12.1. I do not have X installed (too lazy) but when in X, I am running an instance of [[CLFSWM]].
+
+## Contacting me
+
+Various channels to contact me:
+
+- mail: xma@gnu.org
+- jabber: xma01@jabber.fr
+- mobile: +33 621-964-362 (I only anwser to people I know though)
+
+Voila.
+
+## Plans
+
+I am planning to make a presentation of [[ikiwiki]]to my [local LUG](http://lolica.org) for our next montly meeting. Any help would be greatly appreciated.
+
+We are discussing to replace our old unmaintained (and unmaintainable) [SPIP](http://spip.net) website with a wiki. This is why I would like using ikiwiki ;)
diff --git a/doc/users/xma/discussion.mdwn b/doc/users/xma/discussion.mdwn
new file mode 100644 (file)
index 0000000..34adbf8
--- /dev/null
@@ -0,0 +1,18 @@
+How do you edit this wiki (I mean [ikiwiki]) without the web browser ? Is there a way to git clone/pull/push and thus to use our favorite [text editor](http://www.gnu.org/software/emacs) ? --[[xma]]
+
+> You can clone ikiwiki's [[git]] repo. I have not implemented a way to
+> allow users to push doc wiki only changesets anonymously, but you can
+> mails changesets to me. --[[Joey]]
+> > How can I send you the changesets ? (git command) --[[xma]]
+> > > `git-format-patch` --[[Joey]]
+
+> > > > Glad to hear I can mail changesets to you, since I wrote the [[todo/applydiff_plugin]] wishlist entry. --[[intrigeri]]
+
+> It would be nice to have a git recieve hook that
+> checked that a commit contained only changes to .mdwn or other allowed
+> extensions.. if someone writes up a good one, I'd be willing to deploy it
+> for ikiwiki. --[[Joey]]
+
+> > I'll think about it. It may solve some of my offline-being issues. --[[intrigeri]]
+
+>>>> Now developed! --[[Joey]]
index c8f43d08e25d767be8396a6998545b2757c7d8b6..a3bfe1098340f0374e839b0a8a95ee3e637542bc 100644 (file)
Binary files a/doc/wikiicons/openidlogin-bg.gif and b/doc/wikiicons/openidlogin-bg.gif differ
index babd70211c2d42c784056b29644d28418b2c7f5a..fc589367741078aa1c615da73ac782e23293d82a 100644 (file)
@@ -29,6 +29,12 @@ located in /usr/share/ikiwiki/templates by default.
   form to wiki pages.
 * `searchquery.tmpl` - This is an omega template, used by the
   [[plugins/search]] plugin.
+* `comment.tmpl` - This template is used to display a comment
+  by the [[plugins/comments]] plugin.
+* `editcomment.tmpl` - This template is the comment post form for the
+  [[plugins/comments]] plugin.
+* `commentmoderation.tmpl` - This template is used to produce the comment
+  moderation form.
 
 The [[plugins/pagetemplate]] plugin can allow individual pages to use a
 different template than `page.tmpl`.
index 6d732fd6b1d59818687a930342b9b02a123e99f5..ffb4a7c16f591104d62615c6f89651467d9f4138 100644 (file)
@@ -15,5 +15,7 @@ use IkiWiki::Setup::Standard {
        userdir => "users",
        usedirs => 0,
        prefix_directives => 1,
+       cgiurl => "http://me",
+       url => "http://me",
        add_plugins => [qw{goodstuff version haiku polygen fortune}],
 }
diff --git a/gitremotes b/gitremotes
new file mode 100755 (executable)
index 0000000..7b9484d
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+# Parses list of remotes in doc/git.mdwn, configures git to use them
+# all, and fetches updates from them.
+
+my $error=0;
+
+open (IN, "doc/git.mdwn") || die "doc/git.mdwn: $!";
+while (<IN>) {
+       if (/^\*\s+\[?\[?(\w+)\]?\]?\s+`([^>]+)`/) {
+               # note that the remote name has to be a simple word (\w)
+               # for security/sanity reasons
+               my $remote=$1;
+               my $url=$2;
+
+               # check configured url to deal with it changing
+               my $info=`git remote show -n $remote`;
+               my ($oldurl)=$info=~/URL: (.*)/m;
+               if ($oldurl ne $url) {
+                       system("git remote rm $remote 2>/dev/null");
+                       $error |= system("git", "remote", "add", "-f", $remote, $url);
+               }
+               else {
+                       $error |= system("git", "fetch", $remote);
+               }
+       }
+}
+close IN;
+
+exit $error;
index 78eea8f537b98df43df51c0bcb1441ee18efeabd..1c9f256bd5a7b3b65a2b21073c5a35f93db9ae78 100755 (executable)
@@ -75,7 +75,7 @@ mercurial)
        hg init "$srcdir"
        cd "$srcdir"
        echo .ikiwiki > .hgignore
-       hg add * .hgignore
+       hg add
        hg commit -m "initial import"
        echo "Directory $srcdir is now set up as a mercurial repository"
 ;;
@@ -83,7 +83,7 @@ bzr)
        bzr init "$srcdir"
        cd "$srcdir"
        echo .ikiwiki > .bzrignore
-       bzr add * .bzrignore
+       bzr add
        bzr commit -m "initial import"
        echo "Directory $srcdir is now set up as a bzr repository"
 ;;
index e42a5137c72f4ef403aeda4e117944e575928d6d..599261a093d798f818942e90577ff07a86d09a44 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -i
+#!/usr/bin/perl
 use warnings;
 use strict;
 use IkiWiki;
@@ -42,11 +42,33 @@ sub handle_directive {
 }
 
 sub prefix_directives {
-       $/=undef; # process whole files at once
-       
-       while (<>) {
-               s{$regex}{handle_directive($1, $2, $3, $4)}eg;
-               print;
+       my $setup=shift;
+       if (! defined $setup) {
+               usage();
+       }
+
+       require IkiWiki::Setup;
+       require IkiWiki::Plugin::aggregate;
+
+       %config = IkiWiki::defaultconfig();
+       IkiWiki::Setup::load($setup);
+       IkiWiki::loadplugins();
+       IkiWiki::checkconfig();
+       IkiWiki::loadindex();
+
+       if (! %pagesources) {
+               error "ikiwiki has not built this wiki yet, cannot transition";
+       }
+
+       foreach my $page (values %pagesources) {
+               next unless defined pagetype($page) &&
+                           -f $config{srcdir}."/".$page;
+               my $content=readfile($config{srcdir}."/".$page);
+               my $oldcontent=$content;
+               $content=~s{$regex}{handle_directive($1, $2, $3, $4)}eg;
+               if ($oldcontent ne $content) {
+                       writefile($page, $config{srcdir}, $content);
+               }
        }
 }
 
@@ -109,12 +131,10 @@ sub aggregateinternal {
        require IkiWiki::Plugin::aggregate;
 
        %config = IkiWiki::defaultconfig();
-       IkiWiki::Setup::load();
+       IkiWiki::Setup::load($setup);
        IkiWiki::checkconfig();
 
        IkiWiki::Plugin::aggregate::migrate_to_internal();
-
-       print "... now add aggregateinternal => 1 to your .setup file\n";
 }
 
 sub setupformat {
@@ -161,14 +181,54 @@ sub setupformat {
        IkiWiki::Setup::dump($setup);
 }
 
+sub moveprefs {
+       my $setup=shift;
+       if (! defined $setup) {
+               usage();
+       }
+
+       require IkiWiki::Setup;
+
+       %config = IkiWiki::defaultconfig();
+       IkiWiki::Setup::load($setup);
+       IkiWiki::checkconfig();
+
+       eval q{use IkiWiki::UserInfo};
+       error $@ if $@;
+
+       foreach my $field (qw{allowed_attachments locked_pages}) {
+               my $orig=$config{$field};
+               foreach my $admin (@{$config{adminuser}}) {
+                       my $a=IkiWiki::userinfo_get($admin, $field);
+                       if (defined $a && length $a &&
+                           # might already have been moved
+                           (! defined $orig || $a ne $orig)) {
+                               if (defined $config{$field} &&
+                                   length $config{$field}) {
+                                       $config{$field}=IkiWiki::pagespec_merge($config{$field}, $a);
+                               }
+                               else {
+                                       $config{$field}=$a;
+                               }
+                       }
+               }
+       }
+
+       my %banned=map { $_ => 1 } @{$config{banned_users}}, IkiWiki::get_banned_users();
+       $config{banned_users}=[sort keys %banned];
+
+       IkiWiki::Setup::dump($setup);
+}
+
 sub usage {
        print STDERR "Usage: ikiwiki-transition type ...\n";
        print STDERR "Currently supported transition subcommands:\n";
-       print STDERR "\tprefix_directives file\n";
-       print STDERR "\tindexdb srcdir\n";
-       print STDERR "\thashpassword srcdir\n";
+       print STDERR "\tprefix_directives setupfile ...\n";
        print STDERR "\taggregateinternal setupfile\n";
        print STDERR "\tsetupformat setupfile\n";
+       print STDERR "\tmoveprefs setupfile\n";
+       print STDERR "\thashpassword srcdir\n";
+       print STDERR "\tindexdb srcdir\n";
        exit 1;
 }
 
@@ -190,6 +250,9 @@ elsif ($mode eq 'aggregateinternal') {
 elsif ($mode eq 'setupformat') {
        setupformat(@ARGV);
 }
+elsif ($mode eq 'moveprefs') {
+       moveprefs(@ARGV);
+}
 else {
        usage();
 }
@@ -247,3 +310,15 @@ sub oldloadindex {
        
        return close($in);
 }
+
+# Used to be in IkiWiki/UserInfo, but only used here now.
+sub get_banned_users () {
+       my @ret;
+       my $userinfo=userinfo_retrieve();
+       foreach my $user (keys %{$userinfo}) {
+               push @ret, $user if $userinfo->{$user}->{banned};
+       }
+       return @ret;
+}
+
+1
index 4f24cfc2eb8ae4c53d7c0f471fbf12aea13c0578..c79a2bfef98dd8ee6a3042bfdde919f3304534b0 100755 (executable)
@@ -9,12 +9,12 @@ use strict;
 use lib '.'; # For use in nonstandard directory, munged by Makefile.
 use IkiWiki;
 
-sub usage () { #{{{
+sub usage () {
        die gettext("usage: ikiwiki [options] source dest"), "\n",
            gettext("       ikiwiki --setup configfile"), "\n";
-} #}}}
+}
 
-sub getconfig () { #{{{
+sub getconfig () {
        if (! exists $ENV{WRAPPED_OPTIONS}) {
                %config=defaultconfig();
                eval q{use Getopt::Long};
@@ -40,6 +40,7 @@ sub getconfig () { #{{{
                        "post-commit" => \$config{post_commit},
                        "render=s" => \$config{render},
                        "wrappers!" => \$config{genwrappers},
+                       "wrappergroup=s" => \$config{wrappergroup},
                        "usedirs!" => \$config{usedirs},
                        "prefix-directives!" => \$config{prefix_directives},
                        "getctime" => \$config{getctime},
@@ -98,7 +99,7 @@ sub getconfig () { #{{{
                        "help|h" => sub { $SIG{__WARN__}=sub {}; die },
                ) || usage();
 
-               if (! $config{setup} && ! $config{render}) {
+               if (! $config{setup}) {
                        loadplugins();
                        if (@ARGV == 2) {
                                $config{srcdir} = possibly_foolish_untaint(shift @ARGV);
@@ -118,12 +119,13 @@ sub getconfig () { #{{{
                        error("WRAPPED_OPTIONS: $@");
                }
                delete $ENV{WRAPPED_OPTIONS};
+
                loadplugins();
                checkconfig();
        }
-} #}}}
+}
 
-sub main () { #{{{
+sub main () {
        getconfig();
        
        if ($config{setup}) {
@@ -133,7 +135,8 @@ sub main () { #{{{
 
                if (@{$config{wrappers}} && 
                    ! $config{render} && ! $config{dumpsetup} &&
-                   (! $config{refresh} || $config{genwrappers})) {
+                   ((! $config{refresh} && ! $config{post_commit})
+                    || $config{genwrappers})) {
                        debug(gettext("generating wrappers.."));
                        require IkiWiki::Wrapper;
                        my %origconfig=(%config);
@@ -145,7 +148,8 @@ sub main () { #{{{
                                        if exists $config{setupsyslog};
                                delete @config{qw(setupsyslog setupverbose wrappers genwrappers rebuild)};
                                checkconfig();
-                               if (! $config{cgi} && ! $config{post_commit}) {
+                               if (! $config{cgi} && ! $config{post_commit} &&
+                                   ! $config{test_receive}) {
                                        $config{post_commit}=1;
                                }
                                gen_wrapper();
@@ -154,13 +158,16 @@ sub main () { #{{{
                }
                
                # setup implies a wiki rebuild by default
-               if (! $config{refresh}) {
+               if (! $config{refresh} && ! $config{render} &&
+                   ! $config{post_commit}) {
                        $config{rebuild}=1;
                }
        }
 
        if ($config{dumpsetup}) {
-               $config{srdir}=$config{destdir}="";
+               $config{srcdir}="" if ! defined $config{srcdir};
+               $config{destdir}="" if ! defined $config{destdir};
+               $config{syslog}=1 if $config{setupsyslog};
                require IkiWiki::Setup;
                IkiWiki::Setup::dump($config{dumpsetup});
        }
@@ -183,6 +190,10 @@ sub main () { #{{{
        elsif ($config{post_commit} && ! commit_hook_enabled()) {
                # do nothing
        }
+       elsif ($config{test_receive}) {
+               require IkiWiki::Receive;
+               IkiWiki::Receive::test();
+       }
        else {
                if ($config{rebuild}) {
                        debug(gettext("rebuilding wiki.."));
@@ -198,6 +209,6 @@ sub main () { #{{{
                saveindex();
                debug(gettext("done"));
        }
-} #}}}
+}
 
 main;
index fa93e672d86f24c1e253d20717e4c09b19109be1..be7aba8b929807db3a6b56a6846e7d34b3c79a25 100755 (executable)
@@ -101,16 +101,15 @@ sub import {
        # stage of ikiwiki.
        rpc_call("hook", type => "preprocess", id => "externaldemo", call => "preprocess");
 
-       # Here's an example of how to inject an arbitrary function into
-       # ikiwiki. Ikiwiki will be able to call bob() just like any other
-       # function. Note use of automatic memoization.
-       rpc_call("inject", name => "IkiWiki::bob", call => "bob",
-               memoize => 1);
-
        # Here's an exmaple of how to access values in %IkiWiki::config.
        print STDERR "url is set to: ".
                rpc_call("getvar", "config", "url")."\n";
 
+       # Here's an example of how to inject an arbitrary function into
+       # ikiwiki. Note use of automatic memoization.
+       rpc_call("inject", name => "IkiWiki::bob",
+               call => "formattime", memoize => 1);
+
        print STDERR "externaldemo plugin successfully imported\n";
 }
 
index 5ee5a1b9890d8b2b60ae67686aa1f841a7531d01..4984f32d906eae416001dad7f29baab986c0d8c2 100755 (executable)
--- a/pm_filter
+++ b/pm_filter
@@ -7,14 +7,14 @@ BEGIN {
 }
 
 if (/INSTALLDIR_AUTOREPLACE/) {
-       $_=qq{my \$installdir="$prefix";};
+       $_=qq{our \$installdir="$prefix";};
 }
 elsif (/VERSION_AUTOREPLACE/) {
        $_=qq{our \$version="$ver";};
 }
 elsif (/^use lib/) {
        # The idea here is to figure out if the libdir the Makefile.PL
-       # was configure to use is in perl's normal search path.
+       # was configured to use is in perl's normal search path.
        # If not, hard code it into ikiwiki.
        if ((grep { $_ eq $libdir } @INC) &&
             (! exists $ENV{PERL5LIB} || ! length $ENV{PERL5LIB} ||
index a8f386ccfd24355834312db4e7fa50ec1edef5e8..ce963f99467a1015d34a6ceb6fbafb76e1c9d44b 100644 (file)
--- a/po/bg.po
+++ b/po/bg.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki-bg\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-01-12 01:19+0200\n"
 "Last-Translator: Damyan Ivanov <dam@modsodtsys.com>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
@@ -20,109 +20,115 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Първо трябва да влезете."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 #, fuzzy
 msgid "Preferences"
 msgstr "Предпочитанията са запазени."
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Предпочитанията са запазени."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Достъпът ви е забранен."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Грешка"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, fuzzy, perl-format
 msgid "missing %s parameter"
 msgstr "липсващ параметър „id” на шаблона"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "нов източник"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "съобщения"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "ново"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "премахване на „%s” (на %s дни)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "премахване на „%s”"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "е обработен нормално от %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "проверка на източника „%s”"
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "не е намерен източник на адрес „%s”"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 #, fuzzy
 msgid "feed not found"
 msgstr "шаблонът „%s” не е намерен"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "данните от източника предизвикаха грешка в модула XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "създаване на нова страницa „%s”"
@@ -131,7 +137,7 @@ msgstr "създаване на нова страницa „%s”"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "готово"
 
@@ -154,29 +160,35 @@ msgstr "Грешка при изпращане на поща"
 msgid "Failed to delete file from S3: "
 msgstr "грешка при запис на файла „%s”: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -191,6 +203,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "Няма „счупени” връзки!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "създаване на %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -212,19 +289,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "премахване на старата страница „%s”"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "създаване на %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "промяна на %s"
@@ -249,14 +326,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "грешка при обработване на шаблона"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "грешшка в приставката „fortune”"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "При използване на приеставката „search” е необходимо е да се укаже %s"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
 #, fuzzy
-msgid "failed to find url in html"
-msgstr "приставката „googlecalendar” не намери URL в HTML-кода"
+msgid "missing page"
+msgstr "липсващ параметър „id” на шаблона"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 #, fuzzy
@@ -293,41 +403,45 @@ msgstr "грешка при запис на файла „%s”: %s"
 msgid "failed to determine size of image %s"
 msgstr "грешка при запис на файла „%s”: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Когато се използва „--rss” или „--atom” трябва да се укаже и "
 "местоположението на уикито посредством параметъра „--url”"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "шаблонът „%s” не е намерен"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "липсващ параметър „id” на шаблона"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "непознат вид сортиране „%s”"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Дискусия"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "модулът „RPC::XML::Client” не е намерен; източникът не е проверен"
 
@@ -336,7 +450,7 @@ msgstr "модулът „RPC::XML::Client” не е намерен; източ
 msgid "failed to run dot"
 msgstr "приставката „linkmap”: грешка при изпълнение на „dot”"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr ""
@@ -353,17 +467,17 @@ msgstr ""
 "грешка при зареждането на perl-модула „Markdown.pm” (%s) или „/usr/bin/"
 "markdown” (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 #, fuzzy
 msgid "stylesheet not found"
 msgstr "шаблонът „%s” не е намерен"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "шаблонът „%s” не е намерен"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "шаблонът „%s” не е намерен"
@@ -549,17 +663,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "липсващ параметър „id” на шаблона"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -579,16 +683,16 @@ msgstr ""
 msgid "%s is not a file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -626,20 +730,20 @@ msgstr "обновяване на страницата „%s”"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "обновяване на страниците от уики „%s”: %s от потребител „%s”"
@@ -658,11 +762,12 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 #, fuzzy
 msgid "missing name or url parameter"
 msgstr "препратката няма указани параметрите „name” или „url”"
@@ -670,7 +775,7 @@ msgstr "препратката няма указани параметрите 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, fuzzy, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "препратката „%s” сочи към „%s”"
@@ -721,34 +826,34 @@ msgstr "приставката „linkmap”: грешка при изпълне
 msgid "cannot find file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, fuzzy, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "грешка при запис на файла „%s”: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 #, fuzzy
 msgid "missing id parameter"
 msgstr "липсващ параметър „id” на шаблона"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "шаблонът „%s” не е намерен"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 #, fuzzy
 msgid "failed to process:"
 msgstr "грешка при обработване на шаблона"
@@ -775,10 +880,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -807,6 +908,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "пропускане на невалидното име на файл „%s”"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -871,16 +982,16 @@ msgstr "ikiwiki: неуспех при обновяване на страниц
 msgid "cannot read %s: %s"
 msgstr "грешка при четене на „%s”: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -897,21 +1008,14 @@ msgstr "не може да бъде създадена обвивка, коят
 msgid "wrapper filename not specified"
 msgstr "не е указан файл на обвивката"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "грешка при запис на файла „%s”: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "крешка при компилиране на файла %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "успешно генериране на %s"
@@ -924,43 +1028,43 @@ msgstr "формат: ikiwiki [опции] източник местоназна
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "генериране на обвивки..."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "обновяване на уики..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "осъвременяване на уики..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 "При използване на пареметъра „--cgi” е необходимо да се укаже и "
 "местоположението на уикито чрез параметъра „--url”"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "открита е циклична завидимост при %s на „%s” на дълбочина %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -977,13 +1081,23 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "грешка при запис на файла „%s”: %s"
+
+#, fuzzy
+#~ msgid "failed to find url in html"
+#~ msgstr "приставката „googlecalendar” не намери URL в HTML-кода"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "е обработен нормално от %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "Паролата ви е изпратена по пощата."
 
index 757fae5fb1c60efd8a28b0e4d0d67fc04677815d..c66004dcbe328c66035869bf724caccce7560468 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-05-09 21:21+0200\n"
 "Last-Translator: Miroslav Kure <kurem@debian.cz>\n"
 "Language-Team: Czech <debian-l10n-czech@lists.debian.org>\n"
@@ -19,107 +19,113 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Nejprve se musíte přihlásit."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr "přihlášení selhalo; možná si musíte povolit cookies?"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr "Přihlášení"
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr "Předvolby"
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr "Správce"
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Nastavení uloženo."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Jste vyhoštěni."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Chyba"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "chybí parametr %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "nový zdroj"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "příspěvky"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "nový"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "expiruji %s (stará %s dnů)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "expiruji %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "zpracováno ok %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "kontroluji zdroj %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "nemohu najít zdroj na %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "zdroj nebyl nalezen"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "(neplatné UTF-8 bylo ze zdroje odstraněno)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "zdroj shodil XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "vytvářím novou stránku %s"
@@ -128,7 +134,7 @@ msgstr "vytvářím novou stránku %s"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "hotovo"
 
@@ -151,29 +157,35 @@ msgstr "Nepodařilo se odeslat email."
 msgid "Failed to delete file from S3: "
 msgstr "nelze změnit velikost: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -188,6 +200,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "Žádné porušené odkazy!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "vytvářím %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -209,19 +286,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "odstraňuji starou stránku %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "%s není editovatelná stránka"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "vytvářím %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "upravuji %s"
@@ -246,13 +323,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "nepodařilo se zpracovat:"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "fortune selhal"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
-msgstr "v html se nepodařilo nalézt url"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Při používání vyhledávacího modulu musíte zadat %s"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
+#, fuzzy
+msgid "missing page"
+msgstr "chybí hodnoty"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -288,39 +399,43 @@ msgstr "nelze změnit velikost: %s"
 msgid "failed to determine size of image %s"
 msgstr "nelze změnit velikost: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr "Při používání --rss nebo --atom musíte pomocí --url zadat url k wiki"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "zdroj nebyl nalezen"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "chybí parametr %s"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "neznámý typ řazení %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Přidat nový příspěvek nazvaný:"
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "neexistující šablona %s"
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Diskuse"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "RPC::XML::Client nebyl nalezen, nepinkám"
 
@@ -328,7 +443,7 @@ msgstr "RPC::XML::Client nebyl nalezen, nepinkám"
 msgid "failed to run dot"
 msgstr "nepodařilo se spustit dot"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr "Stránka %s je zamknutá uživatelem %s a nelze ji měnit"
@@ -343,16 +458,16 @@ msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
 msgstr ""
 "selhalo nahrání perlového modulu Markdown.pm (%s) nebo /usr/bin/markdown (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "styl nebyl nalezen"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "zdroj nebyl nalezen"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "zdroj nebyl nalezen"
@@ -538,17 +653,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "chybí hodnoty"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -567,16 +672,16 @@ msgstr "Stránka %s je zamknutá uživatelem %s a nelze ji měnit"
 msgid "%s is not a file"
 msgstr "%s není editovatelná stránka"
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -614,20 +719,20 @@ msgstr "zpracovávám %s"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "aktualizace %s (%s) uživatelem %s"
@@ -646,18 +751,19 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "chybí parametr jméno nebo url"
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "zkratka %s odkazuje na <i>%s</i>"
@@ -702,33 +808,33 @@ msgstr "nepodařilo se spustit php"
 msgid "cannot find file"
 msgstr "nemohu najít soubor"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "neznámý formát dat"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "prázdná data"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Stáhnout zdrojová data"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "zpracovávání selhalo na řádku %d: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "chybí parametr id"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "šablona %s nebyla nalezena"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "nepodařilo se zpracovat:"
 
@@ -755,10 +861,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -788,6 +890,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "přeskakuji chybné jméno souboru %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -852,16 +964,16 @@ msgstr "ikiwiki: nelze zpracovat %s"
 msgid "cannot read %s: %s"
 msgstr "nemohu číst %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -878,21 +990,14 @@ msgstr "nemohu vytvořit obal, který využívá soubor setup"
 msgid "wrapper filename not specified"
 msgstr "jméno souboru s obalem nebylo zadáno"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "nelze zapsat %s: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "nelze zkompilovat %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "%s byl úspěšně vytvořen"
@@ -905,41 +1010,41 @@ msgstr "použití: ikiwiki [volby] zdroj cíl"
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "generuji obaly..."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "znovu vytvářím wiki..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "obnovuji wiki..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr "Při použití --cgi musíte pomocí --url zadat url k wiki"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "Byla rozpoznána smyčka direktivy %s na %s v hloubce %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -956,13 +1061,22 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "nelze zapsat %s: %s"
+
+#~ msgid "failed to find url in html"
+#~ msgstr "v html se nepodařilo nalézt url"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "zpracováno ok %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "Vaše heslo vám bylo zasláno."
 
index 9378a4fb9c62ad4935998e6f3eb0e698dde819ac..5f582312d8c3645851153d5d1b5c777138acaccb 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -7,14 +7,14 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
-"PO-Revision-Date: 2008-08-11 01:04+0200\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
+"PO-Revision-Date: 2008-10-22 19:13+0100\n"
 "Last-Translator: Jonas Smedegaard <dr@jones.dk>\n"
 "Language-Team: None\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms:  nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: Danish\n"
 "X-Poedit-Country: DENMARK\n"
 "X-Poedit-SourceCharset: utf-8\n"
@@ -23,107 +23,113 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Du skal først logge på."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr "Pålogning mislykkedes, måske skal du tillade infokager (cookies)?"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr "Din kørsel (login session) er udløbet"
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr "Pålogning"
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr "Indstillinger"
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr "Admin"
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Indstillinger gemt"
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Du er banlyst."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Fejl"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr "Indsamling udløst via web."
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr "Intet at gøre lige nu, alle fødninger er tidssvarende!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "mangler parametren %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "ny fødning"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "indlæg"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "nyt"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "udløber %s (%s dage gammel)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "udløber %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "korrekt dannet ved %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "undersøger fødning %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "kunne ikke finde fødning ved %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "fødning ikke fundet"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "(defekt UTF-8 fjernet fra fødning)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr "(fødningselementer omgået (escaped))"
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "fødning fik XML::Feed til at bryde sammen!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "opretter ny side %s"
@@ -132,7 +138,7 @@ msgstr "opretter ny side %s"
 msgid "deleting bucket.."
 msgstr "sletter bundt.."
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "færdig"
 
@@ -153,29 +159,35 @@ msgstr "Arkivering af fil i S3 mislykkedes: "
 msgid "Failed to delete file from S3: "
 msgstr "Sletning af fil fra S3 mislykkedes: "
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr "der er allerede en side ved navn %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr "forhindret af allowed_attachments"
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr "dårligt vedhæftningsfilnavn"
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr "vedhæftningsoplægning"
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr "automatisk indeks-dannelse"
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -190,6 +202,72 @@ msgstr "%s fra %s"
 msgid "There are no broken links!"
 msgstr "Ingen henvisninger der ikker fungerer!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, fuzzy, perl-format
+msgid "unsupported page format %s"
+msgstr "revisionskontrolsystem %s ikke understøttet"
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+#, fuzzy
+msgid "bad page name"
+msgstr "dårligt vedhæftningsfilnavn"
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "opretter %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr "du er ikke logget på som en administrator"
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -207,23 +285,23 @@ msgid "no text was copied in this page with id %s"
 msgstr "ingen tekst blev kopieret i denne side med id %s"
 
 #: ../IkiWiki/Plugin/editpage.pm:40
-#, fuzzy, perl-format
+#, perl-format
 msgid "removing old preview %s"
-msgstr "fjerner gammel side %s"
+msgstr "fjerner gammelt smugkig %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "%s er ikke en redigérbar side"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "opretter %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "redigerer %s"
@@ -245,13 +323,47 @@ msgstr "redigeringsskabelon %s registreret for %s"
 msgid "failed to process"
 msgstr "dannelsen mislykkedes"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "spådom (fortune) fejlede"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
-msgstr "lokalisering af url i html mislykkedes"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, fuzzy, perl-format
+msgid "you are not allowed to change %s"
+msgstr "du er ikke logget på som en administrator"
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+#, fuzzy
+msgid "you are not allowed to change file modes"
+msgstr "du er ikke logget på som en administrator"
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Skal angive %s når google søgeudvidelsen bruges"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr "Tolkning af URL mislykkedes, kan ikke afgøre domænenavn"
+
+#: ../IkiWiki/Plugin/goto.pm:49
+msgid "missing page"
+msgstr "manglende side"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr "Siden %s eksisterer ikke."
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -286,38 +398,41 @@ msgstr "Ændring af størrelse mislykkedes: %s"
 msgid "failed to determine size of image %s"
 msgstr "Vurdering af størrelse på billede mislykkedes: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr "Skal angive url til wiki med --url når --rss eller --atom anvendes"
 
-#: ../IkiWiki/Plugin/inline.pm:139
-#, fuzzy
+#: ../IkiWiki/Plugin/inline.pm:138
 msgid "page editing not allowed"
-msgstr "ring af henvisninger er ikke tilladt"
+msgstr "sideredigering er ikke tilladt"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 msgid "missing pages parameter"
 msgstr "mangler pages-parametren"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "ukendt sorteringsform %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Tilføj nyt indlæg med følgende titel:"
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "ikke-eksisterende skabelon: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Diskussion"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "RPC::XML::Client ikke fundet, pinger ikke"
 
@@ -325,10 +440,10 @@ msgstr "RPC::XML::Client ikke fundet, pinger ikke"
 msgid "failed to run dot"
 msgstr "dot-kørsel mislykkedes"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
-#, fuzzy, perl-format
+#: ../IkiWiki/Plugin/lockedit.pm:47
+#, perl-format
 msgid "%s is locked and cannot be edited"
-msgstr "%s er låst af %s og kan ikke redigeres"
+msgstr "%s er låst og kan ikke redigeres"
 
 #: ../IkiWiki/Plugin/mdwn.pm:44
 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed"
@@ -342,15 +457,15 @@ msgstr ""
 "Indlæsning af perl-modulet Markdown.pm (%s) eller /usr/bin/markdown (%s) "
 "mislykkedes"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "stilsnit (stylesheet) ikke fundet"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 msgid "redir page not found"
 msgstr "henvisningsside ikke fundet"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 msgid "redir cycle is not allowed"
 msgstr "ring af henvisninger er ikke tilladt"
 
@@ -526,24 +641,15 @@ msgid "at noon on %A"
 msgstr "midt på dagen %A"
 
 #: ../IkiWiki/Plugin/progress.pm:34
-#, fuzzy, perl-format
+#, perl-format
 msgid "illegal percent value %s"
-msgstr "ugyldigt navn"
+msgstr "ugyldigt procentværdi %s"
 
 #: ../IkiWiki/Plugin/progress.pm:59
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
-msgstr ""
+msgstr "Kræver enten parametre `percent` eller `totalpages og `donepages`"
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-msgid "missing page"
-msgstr "manglende side"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr "Siden %s eksisterer ikke."
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr "(Diff trunkeret)"
 
@@ -562,16 +668,16 @@ msgstr "%s er ikke i srcdir, så kan ikke blive slettet"
 msgid "%s is not a file"
 msgstr "%s er ikke en fil"
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr "bekræft at %s bliver fjernet"
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr "Vælg vedhæftning der skal slettes."
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr "fjernet"
 
@@ -606,22 +712,22 @@ msgstr "omdøb %s"
 
 #: ../IkiWiki/Plugin/rename.pm:138
 msgid "Also rename SubPages and attachments"
-msgstr ""
+msgstr "Omdøb også UnderSider og vedhæftninger"
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr "Kun en vedhæftning kan blive omdøbt ad gangen."
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr "Vælg vedhæftningen som skal omdøbes."
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr "omdøb %s til %s"
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, perl-format
 msgid "update for rename of %s to %s"
 msgstr "opdatering til omdøbning af %s til %s"
@@ -640,18 +746,19 @@ msgstr "behøver Digest::SHA1 til indeks %s"
 msgid "search"
 msgstr "søg"
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, fuzzy, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr "genvejsudvidelsen vil ikke fungere uden en shortcuts.mdwn"
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "manglende navn eller url parameter"
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "genvej %s viser til <i>%s</i>"
@@ -696,33 +803,33 @@ msgstr "php-kørsel mislykkedes"
 msgid "cannot find file"
 msgstr "kan ikke finde fil"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "ukendt dataformat"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "blanke data"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Direkte datanedlastning"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "afkodningsfejl på linje %d: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "manglende id-parameter"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "skabelon %s ikke fundet"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "dannelsen mislykkedes:"
 
@@ -740,52 +847,63 @@ msgstr "billedopbygning fra kode mislykkedes"
 
 #: ../IkiWiki/Plugin/websetup.pm:89
 msgid "plugin"
-msgstr ""
+msgstr "udvidelse"
 
 #: ../IkiWiki/Plugin/websetup.pm:108
-#, fuzzy, perl-format
+#, perl-format
 msgid "enable %s?"
-msgstr "omdøb %s"
-
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
+msgstr "aktivér %s?"
 
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
-msgstr ""
+msgstr "opsætningsfilen for denne wiki er ukendt"
 
 #: ../IkiWiki/Plugin/websetup.pm:256
-#, fuzzy
 msgid "main"
-msgstr "Admin"
+msgstr "primær"
 
 #: ../IkiWiki/Plugin/websetup.pm:257
 msgid "plugins"
-msgstr ""
+msgstr "udvidelser"
 
 #: ../IkiWiki/Plugin/websetup.pm:395
 msgid ""
 "The configuration changes shown below require a wiki rebuild to take effect."
 msgstr ""
+"Opsætningsændringerne vist nedenfor kræver wiki-genopbygning for at træde i "
+"kraft."
 
 #: ../IkiWiki/Plugin/websetup.pm:399
 msgid ""
 "For the configuration changes shown below to fully take effect, you may need "
 "to rebuild the wiki."
 msgstr ""
+"For at opsætningsændringerne vist nedenfor træder fuldt ud i kraft, skal du "
+"muligvis genopbygge wikien."
 
 #: ../IkiWiki/Plugin/websetup.pm:433
 #, perl-format
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
+msgstr "<p class=\"error\">Fejl: %s sluttede med fejl (%s)"
+
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "udelader forkert filnavn %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
 "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to "
 "allow this"
 msgstr ""
+"symbolsk lænke fundet i srcdir-sti (%s) -- sæt allow_symlinks_before_srcdir "
+"for at tillade dette"
 
 #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302
 #, perl-format
@@ -795,7 +913,7 @@ msgstr "udelader forkert filnavn %s"
 #: ../IkiWiki/Render.pm:284
 #, perl-format
 msgid "%s has multiple possible source pages"
-msgstr ""
+msgstr "%s har flere mulige kildesider"
 
 #: ../IkiWiki/Render.pm:360
 #, perl-format
@@ -844,18 +962,18 @@ msgstr "ikiwiki: kan ikke danne %s"
 msgid "cannot read %s: %s"
 msgstr "kan ikke læse %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
-msgstr ""
+msgstr "du skal angive et wikinavn (som indeholder alfanumeriske tegn)"
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
-msgstr ""
+msgstr "revisionskontrolsystem %s ikke understøttet"
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
-msgstr ""
+msgstr "opsætning af depotet med ikiwiki-makerepo mislykkedes"
 
 #: ../IkiWiki/Wrapper.pm:16
 #, perl-format
@@ -870,21 +988,14 @@ msgstr "kan ikke oprette en wrapper som bruger en opsætningsfil"
 msgid "wrapper filename not specified"
 msgstr "wrapper-navn ikke angivet"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "skrivning ad %s mislykkedes: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "kompilering af %s mislykkedes"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "Korrekt bygget %s"
@@ -895,62 +1006,73 @@ msgstr "brug: ikiwiki [valg] kilde mål"
 
 #: ../ikiwiki.in:14
 msgid "       ikiwiki --setup configfile"
-msgstr ""
+msgstr "       ikiwiki --setup opsætningsfil"
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr "brug: --set var=værdi"
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "bygger wrappers.."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "genopbygger wiki..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "genopfrisker wiki..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr "Skal angive url til wiki med --url når der bruges --cgi"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
-msgstr ""
+msgstr "kan ikke bruge flere samtidige RCS-udvidelser"
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
+"indlæsning af ekstern udvidelse krævet af udvidelsen %s mislykkedes: %s"
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "forudberegningssløkke fundet på %s ved dybde %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr "ja"
 
 #: ../auto.setup:16
 msgid "What will the wiki be named?"
-msgstr ""
+msgstr "Hvad skal wikien hedde?"
 
 #: ../auto.setup:16
 msgid "wiki"
-msgstr ""
+msgstr "wiki"
 
 #: ../auto.setup:18
 msgid "What revision control system to use?"
-msgstr ""
+msgstr "Hvilket revisionskontrolsystem skal bruges?"
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
-msgstr ""
+#, fuzzy
+msgid "What wiki user (or openid) will be admin?"
+msgstr "Hvilken wiki bruger (eller openid) skal være administrator?"
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
-msgstr ""
+msgstr "Hvad er domænenavnet på webserveren?"
+
+#~ msgid "failed to write %s: %s"
+#~ msgstr "skrivning ad %s mislykkedes: %s"
+
+#~ msgid "failed to find url in html"
+#~ msgstr "lokalisering af url i html mislykkedes"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "korrekt dannet ved %s"
index d33a6aca72c4bf4cbffac51bfaf82d041f71d7e5..7482659246a2477a0d46b7db39b1348bfd12037a 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1,13 +1,13 @@
 # German translation of the ikiwiki language file resulting in de.po
-# Copyright © 2008 Kai Wasserbäch <debian@carbon-project.org>
+# Copyright © 2008-2009 Kai Wasserbäch <debian@carbon-project.org>
 # This file is distributed under the same license as the ikiwiki package.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: ikiwiki 2.40\n"
+"Project-Id-Version: ikiwiki 3.06\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
-"PO-Revision-Date: 2008-03-03 21:22+0100\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
+"PO-Revision-Date: 2009-03-02 15:39+0100\n"
 "Last-Translator: Kai Wasserbäch <debian@carbon-project.org>\n"
 "Language-Team: German <debian-l10n-german@lists.debian.org>\n"
 "MIME-Version: 1.0\n"
@@ -18,162 +18,176 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Sie müssen sich zuerst anmelden."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+"mögliche Fehlkonfiguration: »sslcookie« ist gesetzt, aber Sie versuchen sich "
+"mittels HTTP und nicht HTTPS anzumelden"
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 "Anmeldung fehlgeschlagen, möglicherweise müssen Sie zuvor Cookies aktivieren?"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
-msgstr ""
+msgstr "Ihre Anmeldung für die aktuelle Sitzung ist abgelaufen."
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr "Anmelden"
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr "Einstellungen"
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr "Administrator"
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Einstellungen gespeichert."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Sie sind ausgeschlossen worden."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Fehler"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
-msgstr ""
+msgstr "Feed-Erstellung wurde über das Web ausgelöst."
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
-msgstr ""
+msgstr "Derzeit nichts zu tun, alle Feeds sind auf dem neusten Stand!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "Parameter %s fehlt"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "neuer Feed"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "Beiträge"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "neu"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "%s läuft aus (%s Tage alt)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "%s läuft aus"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "normal verarbeitet um %s"
+msgid "last checked %s"
+msgstr "zuletzt überprüft am %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "überprüfe Feed %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "konnte Feed unter %s nicht finden"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "Feed nicht gefunden"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
-msgstr "(ungültiges UTF-8 wurde aus dem Feed entfernt)"
+msgstr "(ungültiges UTF-8-Zeichen wurde aus dem Feed entfernt)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
-msgstr "(Feedentitäten maskiert)"
+msgstr "(Feed-Entitäten maskiert)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "Feed führte zum Absturz von XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "erstelle neue Seite %s"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:31
 msgid "deleting bucket.."
-msgstr ""
+msgstr "Lösche Bucket..."
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "fertig"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:97
 #, perl-format
 msgid "Must specify %s"
-msgstr ""
+msgstr "%s muss angegeben werden"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:136
 msgid "Failed to create bucket in S3: "
-msgstr ""
+msgstr "Konnte keinen Bucket in S3 erstellen: "
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:221
-#, fuzzy
 msgid "Failed to save file to S3: "
-msgstr "Es konnte keine E-Mail versandt werden"
+msgstr "Konnte Datei nicht bei S3 speichern: "
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:243
-#, fuzzy
 msgid "Failed to delete file from S3: "
-msgstr "konnte kein Bild aus dem Code erzeugen"
+msgstr "Konnte Datei nicht bei S3 löschen: "
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
-msgstr ""
+msgstr "eine Seite mit dem Namen %s existiert bereits"
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
-msgstr ""
+msgstr "durch allowed_attachements verboten"
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
-msgstr ""
+msgstr "fehlerhafter Dateiname für Anhang"
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
-msgstr ""
+msgstr "Anhang hochladen"
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
+msgstr "automatische Index-Erstellung"
+
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
 msgstr ""
+"Entschuldigung, aber <a href=\"http://blogspam.net/\">blogspam</a> stuft das "
+"als Spam ein: "
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -188,6 +202,74 @@ msgstr "%s von %s"
 msgid "There are no broken links!"
 msgstr "Es gibt keine ungültigen Links!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr "nicht unterstütztes Seitenformat %s"
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr "Kommentare dürfen nicht leer sein."
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr "Anonymer Benutzer"
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr "fehlerhafter Seitenname"
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, perl-format
+msgid "commenting on %s"
+msgstr "kommentiere %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+"Die Seite »%s« existiert nicht, deshalb können Sie sie nicht kommentieren."
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+"Es können keine weiteren Kommentare für die Seite »%s« abgegeben werden."
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr "Kommentar wurde gespeichert und erwartet Freischaltung."
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+"Ihr Kommentar wird freigegeben, nachdem ein Moderator ihn überprüft hat."
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr "Kommentar hinzugefügt."
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr "Kommentar hinzugefügt: %s"
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr "Sie sind nicht als Administrator angemeldet"
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr "Kommentarmoderation"
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr "Kommentarmoderation"
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr "Kommentare"
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -197,31 +279,31 @@ msgstr "der Parameter %s wird benötigt"
 
 #: ../IkiWiki/Plugin/cutpaste.pm:66
 msgid "no text was copied in this page"
-msgstr ""
+msgstr "es wurde kein Text in diese Seite kopiert"
 
 #: ../IkiWiki/Plugin/cutpaste.pm:69
 #, perl-format
 msgid "no text was copied in this page with id %s"
-msgstr ""
+msgstr "es wurde kein Text in die Seite mit der ID %s kopiert"
 
 #: ../IkiWiki/Plugin/editpage.pm:40
-#, fuzzy, perl-format
+#, perl-format
 msgid "removing old preview %s"
-msgstr "entferne alte Seite %s"
+msgstr "entferne alte Vorschau %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
-msgstr "%s ist keine bearbeitbare Seite"
+msgstr "Die Seite %s kann nicht bearbeitet werden"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "erstelle %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "bearbeite %s"
@@ -237,37 +319,71 @@ msgstr "Übereinstimmung nicht angegeben"
 #: ../IkiWiki/Plugin/edittemplate.pm:62
 #, perl-format
 msgid "edittemplate %s registered for %s"
-msgstr "»edittemplate« %s registriert für %s"
+msgstr "»edittemplate« %s für %s registriert."
 
 #: ../IkiWiki/Plugin/edittemplate.pm:133
 msgid "failed to process"
-msgstr "Bearbeitung fehlgeschlagen"
+msgstr "Verarbeitung fehlgeschlagen"
+
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr "Format und Text müssen spezifiziert werden"
 
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "»fortune« fehlgeschlagen"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
-msgstr "URL in HTML nicht gefunden"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr "es ist Ihnen nicht erlaubt, %s zu ändern"
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr "Sie können Dateien mit den Zugriffsrechten %s nicht verändern"
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr "Es ist Ihnen nicht erlaubt, Dateizugriffsrechte zu ändern"
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr ""
+"%s muss angegeben werden, wenn die Google-Sucherweiterung verwandt wird"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+"Verarbeiten der URL fehlgeschlagen, konnte Domainnamen nicht feststellen"
+
+#: ../IkiWiki/Plugin/goto.pm:49
+msgid "missing page"
+msgstr "fehlende Seite"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr "Die Seite %s existiert nicht."
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
-msgstr "konnte graphviz nicht ausführen"
+msgstr "graphviz konnte nicht ausgeführt werden"
 
 #: ../IkiWiki/Plugin/graphviz.pm:94
 msgid "prog not a valid graphviz program"
 msgstr "prog ist kein gültiges graphviz-Programm"
 
 #: ../IkiWiki/Plugin/img.pm:62
-#, fuzzy
 msgid "Image::Magick is not installed"
-msgstr "polygen ist nicht installiert"
+msgstr "Image::Magick ist nicht installiert"
 
 #: ../IkiWiki/Plugin/img.pm:69
 #, perl-format
 msgid "bad size \"%s\""
-msgstr "falsche Größe \"%s\""
+msgstr "falsche Größe »%s«"
 
 #: ../IkiWiki/Plugin/img.pm:80 ../IkiWiki/Plugin/img.pm:84
 #: ../IkiWiki/Plugin/img.pm:101
@@ -285,73 +401,76 @@ msgstr "Größenänderung fehlgeschlagen: %s"
 msgid "failed to determine size of image %s"
 msgstr "Größe des Bildes %s konnte nicht festgestellt werden."
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Die URL zum Wiki muss mit --url angegeben werden, wenn --rss oder --atom "
 "genutzt wird"
 
-#: ../IkiWiki/Plugin/inline.pm:139
-#, fuzzy
+#: ../IkiWiki/Plugin/inline.pm:138
 msgid "page editing not allowed"
-msgstr "Zyklische Umleitungen sind nicht erlaubt"
+msgstr "Seitenbearbeitungen sind nicht erlaubt"
 
-#: ../IkiWiki/Plugin/inline.pm:156
-#, fuzzy
+#: ../IkiWiki/Plugin/inline.pm:155
 msgid "missing pages parameter"
-msgstr "Parameter %s fehlt"
+msgstr "Fehlender Seitenparameter"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "Unbekannter Sortierungstyp %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Füge einen neuen Beitrag hinzu. Titel:"
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "nicht-vorhandene Vorlage %s"
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Diskussion"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
-msgstr "RPC::XML::Client nicht gefunden, pinge nicht"
+msgstr "RPC::XML::Client nicht gefunden, führe Ping nicht aus"
 
 #: ../IkiWiki/Plugin/linkmap.pm:106
 msgid "failed to run dot"
 msgstr "dot konnte nicht ausgeführt werden"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
-#, fuzzy, perl-format
+#: ../IkiWiki/Plugin/lockedit.pm:47
+#, perl-format
 msgid "%s is locked and cannot be edited"
-msgstr "%s wurde von %s gesperrt und kann nicht bearbeitet werden"
+msgstr "%s wurde gesperrt und kann nicht bearbeitet werden"
 
 #: ../IkiWiki/Plugin/mdwn.pm:44
 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed"
 msgstr ""
+"»multimarkdown« ist aktiviert, aber Text::MultiMarkdown ist nicht installiert"
 
 #: ../IkiWiki/Plugin/mdwn.pm:67
 #, perl-format
 msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
 msgstr ""
-"Laden des des Perl-Moduls »Markdown.pm« (%s) oder von »/usr/bin/markdown« (%s) "
+"Laden des Perl-Moduls »Markdown.pm« (%s) oder »/usr/bin/markdown« (%s) "
 "fehlgeschlagen"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "Stylesheet nicht gefunden"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 msgid "redir page not found"
 msgstr "Umleitungsseite nicht gefunden"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 msgid "redir cycle is not allowed"
 msgstr "Zyklische Umleitungen sind nicht erlaubt"
 
@@ -398,6 +517,8 @@ msgstr "Konto konnte nicht erstellt werden."
 #: ../IkiWiki/Plugin/passwordauth.pm:257
 msgid "No email address, so cannot email password reset instructions."
 msgstr ""
+"Keine E-Mail-Adresse angegeben; deshalb können keine Anweisungen zum "
+"Zurücksetzen des Passworts via E-Mail versandt werden."
 
 #: ../IkiWiki/Plugin/passwordauth.pm:291
 msgid "Failed to send mail"
@@ -405,38 +526,37 @@ msgstr "Es konnte keine E-Mail versandt werden"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:293
 msgid "You have been mailed password reset instructions."
-msgstr ""
+msgstr "Ihnen wurden Anweisungen zum Zurücksetzen des Passworts zugesandt."
 
 #: ../IkiWiki/Plugin/passwordauth.pm:328
 msgid "incorrect password reset url"
-msgstr ""
+msgstr "Fehlerhafte URL zum Zurücksetzen des Passworts"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:331
 msgid "password reset denied"
-msgstr ""
+msgstr "Zurücksetzen des Passworts abgelehnt"
 
 #: ../IkiWiki/Plugin/pingee.pm:30
 msgid "Ping received."
-msgstr ""
+msgstr "Ping empfangen."
 
 #: ../IkiWiki/Plugin/pinger.pm:53
 msgid "requires 'from' and 'to' parameters"
-msgstr ""
+msgstr "erfordert die Parameter »from« und »to«"
 
 #: ../IkiWiki/Plugin/pinger.pm:58
-#, fuzzy, perl-format
+#, perl-format
 msgid "Will ping %s"
-msgstr "bearbeite %s"
+msgstr "Werde Ping an %s senden"
 
 #: ../IkiWiki/Plugin/pinger.pm:61
 #, perl-format
 msgid "Ignoring ping directive for wiki %s (this wiki is %s)"
-msgstr ""
+msgstr "Ignoriere Ping-Direktiven für Wiki %s (dies ist Wiki %s)"
 
 #: ../IkiWiki/Plugin/pinger.pm:77
-#, fuzzy
 msgid "LWP not found, not pinging"
-msgstr "RPC::XML::Client nicht gefunden, pinge nicht"
+msgstr "LWP nicht gefunden, führe Ping nicht aus"
 
 #: ../IkiWiki/Plugin/poll.pm:69
 msgid "vote"
@@ -451,9 +571,8 @@ msgid "polygen not installed"
 msgstr "polygen ist nicht installiert"
 
 #: ../IkiWiki/Plugin/polygen.pm:60
-#, fuzzy
 msgid "command failed"
-msgstr "»fortune« fehlgeschlagen"
+msgstr "Befehl fehlgeschlagen"
 
 #: ../IkiWiki/Plugin/postsparkline.pm:41
 msgid "missing formula"
@@ -469,11 +588,11 @@ msgstr "unbekannte Formel"
 #. translators: %A- is the name of the previous day.
 #: ../IkiWiki/Plugin/prettydate.pm:15
 msgid "late %A- night"
-msgstr "spät am %A- in der Nacht"
+msgstr "%A- spät in der Nacht"
 
 #: ../IkiWiki/Plugin/prettydate.pm:17
 msgid "in the wee hours of %A- night"
-msgstr "in den frühen Morgenstunden %A-"
+msgstr "%A- in den frühen Morgenstunden"
 
 #: ../IkiWiki/Plugin/prettydate.pm:20
 msgid "terribly early %A morning"
@@ -525,109 +644,103 @@ msgstr "um Mitternacht"
 
 #: ../IkiWiki/Plugin/prettydate.pm:108
 msgid "at noon on %A"
-msgstr "am Nachmittag des %A"
+msgstr "%A am Nachmittag"
 
 #: ../IkiWiki/Plugin/progress.pm:34
 #, perl-format
 msgid "illegal percent value %s"
-msgstr ""
+msgstr "Unzulässiger Prozentwert (%s)"
 
 #: ../IkiWiki/Plugin/progress.pm:59
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
+"Es werden entweder »percent«- oder »totalpages«- und »donepages«-Parameter "
+"benötigt"
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-msgid "missing page"
-msgstr "fehlende Seite"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr "Die Seite %s exisitiert nicht."
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
-msgstr ""
+msgstr "(Diff verkürzt)"
 
 #: ../IkiWiki/Plugin/remove.pm:31 ../IkiWiki/Plugin/rename.pm:36
-#, fuzzy, perl-format
+#, perl-format
 msgid "%s does not exist"
-msgstr "Die Seite %s exisitiert nicht."
+msgstr "%s existiert nicht"
 
 #: ../IkiWiki/Plugin/remove.pm:38
-#, fuzzy, perl-format
+#, perl-format
 msgid "%s is not in the srcdir, so it cannot be deleted"
-msgstr "%s wurde von %s gesperrt und kann nicht bearbeitet werden"
+msgstr ""
+"%s ist nicht im Quellverzeichnis und kann deshalb nicht gelöscht werden"
 
 #: ../IkiWiki/Plugin/remove.pm:41 ../IkiWiki/Plugin/rename.pm:45
-#, fuzzy, perl-format
+#, perl-format
 msgid "%s is not a file"
-msgstr "%s ist keine bearbeitbare Seite"
+msgstr "%s ist keine Datei"
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
-msgstr ""
+msgstr "Bestätigen Sie die Entfernung von %s"
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
-msgstr ""
+msgstr "Bitte wählen Sie die zu entfernenden Anhänge aus."
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
-msgstr ""
+msgstr "entfernt"
 
 #: ../IkiWiki/Plugin/rename.pm:42
 #, perl-format
 msgid "%s is not in the srcdir, so it cannot be renamed"
 msgstr ""
+"%s ist nicht im Quellverzeichnis und kann deshalb nicht umbenannt werden"
 
 #: ../IkiWiki/Plugin/rename.pm:62
-#, fuzzy
 msgid "no change to the file name was specified"
-msgstr "Dateiname des Wrappers nicht angegeben"
+msgstr "Es wurde keine Änderung des Dateinames angegeben"
 
 #: ../IkiWiki/Plugin/rename.pm:68
 #, perl-format
 msgid "illegal name"
-msgstr ""
+msgstr "unzulässiger Name"
 
 #: ../IkiWiki/Plugin/rename.pm:73
 #, perl-format
 msgid "%s already exists"
-msgstr ""
+msgstr "%s existiert bereits"
 
 #: ../IkiWiki/Plugin/rename.pm:79
 #, perl-format
 msgid "%s already exists on disk"
-msgstr ""
+msgstr "%s existiert bereits auf der Festplatte"
 
 #: ../IkiWiki/Plugin/rename.pm:101
-#, fuzzy, perl-format
+#, perl-format
 msgid "rename %s"
-msgstr "erzeuge %s"
+msgstr "benenne %s um"
 
 #: ../IkiWiki/Plugin/rename.pm:138
 msgid "Also rename SubPages and attachments"
-msgstr ""
+msgstr "Auch Unterseiten und Anhänge umbenennen"
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
-msgstr ""
+msgstr "Es kann immer nur ein Anhang gleichzeitig umbenannt werden."
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
-msgstr ""
+msgstr "Bitte wählen Sie den umzubenennenden Anhang aus."
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
-msgstr ""
+msgstr "Benenne %s in %s um"
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, perl-format
 msgid "update for rename of %s to %s"
-msgstr ""
+msgstr "Aktualisierung für Umbenennung von %s in %s"
 
 #: ../IkiWiki/Plugin/search.pm:36
 #, perl-format
@@ -637,35 +750,36 @@ msgstr "%s muss angegeben werden, wenn die Sucherweiterung verwandt wird"
 #: ../IkiWiki/Plugin/search.pm:182
 #, perl-format
 msgid "need Digest::SHA1 to index %s"
-msgstr ""
+msgstr "Benötige Digest::SHA1, um %s zu indexieren"
 
 #: ../IkiWiki/Plugin/search.pm:217
 msgid "search"
-msgstr ""
+msgstr "suchen"
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
-msgstr "das »shortcut«-Plugin funktioniert nicht ohne eine »shortcuts.mdwn«"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
+msgstr "die »shortcut«-Erweiterung funktioniert nicht ohne %s"
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "fehlender Name oder URL-Parameter"
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
-msgstr "Shortcut %s zeigt auf <i>%s</i>"
+msgstr "Tastenkürzel %s verweist auf <i>%s</i>"
 
 #: ../IkiWiki/Plugin/smiley.pm:43
 msgid "failed to parse any smileys"
-msgstr "Smileys konnten nicht geparst werden"
+msgstr "Smileys konnten nicht verarbeitet werden"
 
 #: ../IkiWiki/Plugin/sparkline.pm:72
 msgid "parse error"
-msgstr "Parse-Fehler"
+msgstr "Verarbeitungsfehler"
 
 #: ../IkiWiki/Plugin/sparkline.pm:78
 msgid "bad featurepoint diameter"
@@ -693,39 +807,39 @@ msgstr "fehlerhafte Breitenangabe"
 
 #: ../IkiWiki/Plugin/sparkline.pm:153
 msgid "failed to run php"
-msgstr "konnte PHP nicht ausführen"
+msgstr "PHP konnte nicht ausgeführt werden"
 
 #: ../IkiWiki/Plugin/table.pm:31
 msgid "cannot find file"
-msgstr "konnte Datei nicht finden"
+msgstr "Datei konnte nicht gefunden werden"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "unbekanntes Datenformat"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "keine Daten"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Direkter Daten-Download"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
-msgstr "Parse-Fehler in Zeile %d: %s"
+msgstr "Verarbeitungsfehler in Zeile %d: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "fehlender »id«-Parameter"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "Vorlage %s nicht gefunden"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "Verarbeitung fehlgeschlagen von:"
 
@@ -743,45 +857,55 @@ msgstr "konnte kein Bild aus dem Code erzeugen"
 
 #: ../IkiWiki/Plugin/websetup.pm:89
 msgid "plugin"
-msgstr ""
+msgstr "Erweiterung"
 
 #: ../IkiWiki/Plugin/websetup.pm:108
 #, perl-format
 msgid "enable %s?"
-msgstr ""
-
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
+msgstr "%s aktivieren?"
 
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
-msgstr ""
+msgstr "Die Einrichtungsdatei für dieses Wiki ist unbekannt"
 
 #: ../IkiWiki/Plugin/websetup.pm:256
-#, fuzzy
 msgid "main"
-msgstr "Administrator"
+msgstr "Hauptseite"
 
 #: ../IkiWiki/Plugin/websetup.pm:257
 msgid "plugins"
-msgstr ""
+msgstr "Erweiterungen"
 
 #: ../IkiWiki/Plugin/websetup.pm:395
 msgid ""
 "The configuration changes shown below require a wiki rebuild to take effect."
 msgstr ""
+"Die unten aufgeführten Konfigurationsänderungen erfordern eine erneute "
+"Erzeugung des Wikis, um aktiviert zu werden."
 
 #: ../IkiWiki/Plugin/websetup.pm:399
 msgid ""
 "For the configuration changes shown below to fully take effect, you may need "
 "to rebuild the wiki."
 msgstr ""
+"Damit die unten aufgeführten Konfigurationsänderungen aktiviert werden, kann "
+"es erforderlich sein, das Wiki neu zu erzeugen."
 
 #: ../IkiWiki/Plugin/websetup.pm:433
 #, perl-format
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
+"<p class=\"error\">Fehler: %s beendete sich mit einem Wert ungleich Null (%s)"
+
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr "Kann ID des nicht vertrauenswürdigen Bearbeiters %s nicht feststellen"
+
+#: ../IkiWiki/Receive.pm:85
+#, perl-format
+msgid "bad file name %s"
+msgstr "fehlerhafter Dateiname %s"
 
 #: ../IkiWiki/Render.pm:253
 #, perl-format
@@ -789,6 +913,8 @@ msgid ""
 "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to "
 "allow this"
 msgstr ""
+"Symbolischer Verweis im Quellverzeichnis (%s) gefunden -- setzen Sie "
+"allow_symlinks_before_srcdir, um dies zu erlauben"
 
 #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302
 #, perl-format
@@ -798,7 +924,7 @@ msgstr "überspringe fehlerhaften Dateinamen %s"
 #: ../IkiWiki/Render.pm:284
 #, perl-format
 msgid "%s has multiple possible source pages"
-msgstr ""
+msgstr "%s hat mehrere mögliche Quellseiten"
 
 #: ../IkiWiki/Render.pm:360
 #, perl-format
@@ -818,12 +944,12 @@ msgstr "erzeuge %s"
 #: ../IkiWiki/Render.pm:426
 #, perl-format
 msgid "rendering %s, which links to %s"
-msgstr "erzeuge %s, was auf %s verweist"
+msgstr "erzeuge %s, die auf %s verlinkt"
 
 #: ../IkiWiki/Render.pm:447
 #, perl-format
 msgid "rendering %s, which depends on %s"
-msgstr "erzeuge %s, das von %s abhängt"
+msgstr "erzeuge %s, die von %s abhängt"
 
 #: ../IkiWiki/Render.pm:486
 #, perl-format
@@ -847,18 +973,19 @@ msgstr "ikiwiki: kann %s nicht erzeugen"
 msgid "cannot read %s: %s"
 msgstr "kann %s nicht lesen: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
+"Sie müssen einen Wiki-Namen eingeben (der alphanumerische Zeichen enthält)"
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
-msgstr ""
+msgstr "Nicht unterstütztes Versionskontrollsystem %s"
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
-msgstr ""
+msgstr "Erstellen des Depots mit ikiwiki-makerepo ist fehlgeschlagen"
 
 #: ../IkiWiki/Wrapper.pm:16
 #, perl-format
@@ -873,104 +1000,85 @@ msgstr "Kann keinen Wrapper erzeugen, der eine Einrichtungsdatei verwendet"
 msgid "wrapper filename not specified"
 msgstr "Dateiname des Wrappers nicht angegeben"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "schreiben von %s fehlgeschlagen: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
-msgstr "erzeugen von %s fehlgeschlagen"
+msgstr "Erzeugen von %s fehlgeschlagen"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "%s wurde erfolgreich erstellt"
 
 #: ../ikiwiki.in:13
 msgid "usage: ikiwiki [options] source dest"
-msgstr "Benutzung: ikiwiki [Optionen] Quelle Ziel"
+msgstr "Aufruf: ikiwiki [Optionen] Quelle Ziel"
 
 #: ../ikiwiki.in:14
 msgid "       ikiwiki --setup configfile"
-msgstr ""
+msgstr "       ikiwiki --setup Konfigurationsdatei "
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
-msgstr "Benutzung: --set Variable=Wert"
+msgstr "Aufruf: --set Variable=Wert"
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
-msgstr "erzeuge Wrapper.."
+msgstr "erzeuge Wrapper..."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
-msgstr "erzeuge Wiki neu.."
+msgstr "erzeuge Wiki neu..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
-msgstr "aktualisiere Wiki.."
+msgstr "aktualisiere Wiki..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 "Es muss eine URL zum Wiki mit --url angegeben werden, wenn --cgi verwandt "
 "wird"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
+"Es können nicht mehrere Versionskontrollsystem-Erweiterungen verwandt werden"
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
-msgstr ""
+msgstr "Laden der für %s benötigten externen Erweiterung fehlgeschlagen: %s"
 
-#: ../IkiWiki.pm:1136
-#, fuzzy, perl-format
+#: ../IkiWiki.pm:1194
+#, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
-msgstr "Präprozessorschleife %s auf Seite %s in Tiefe %i erkannt"
+msgstr "Präprozessorschleife auf %s in Tiefe %i erkannt"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
-msgstr ""
+msgstr "ja"
 
 #: ../auto.setup:16
 msgid "What will the wiki be named?"
-msgstr ""
+msgstr "Wie soll das Wiki heißen?"
 
 #: ../auto.setup:16
 msgid "wiki"
-msgstr ""
+msgstr "Wiki"
 
 #: ../auto.setup:18
 msgid "What revision control system to use?"
-msgstr ""
+msgstr "Welches Versionskontrollsystem soll verwandt werden?"
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
+"Welcher Wiki-Benutzer (oder welche OpenID) soll der Administrator des Wikis "
+"sein?"
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
-msgstr ""
-
-#~ msgid "Your password has been emailed to you."
-#~ msgstr "Ihr Passwort wurde Ihnen via E-Mail zugesandt."
-
-#~ msgid "polygen failed"
-#~ msgstr "polygen fehlgeschlagen"
-
-#~ msgid "cleaning hyperestraier search index"
-#~ msgstr "bereinige hyperestraier-Suchindex"
-
-#~ msgid "updating hyperestraier search index"
-#~ msgstr "aktualisiere hyperestraier-Suchindex"
-
-#~ msgid "(not toggleable in preview mode)"
-#~ msgstr "(nicht aus-/einklappbar im Vorschaumodus)"
+msgstr "Wie lautet der Domainname des Webservers?"
index ff02ea86a31b8f123469e056e1d6164a660c8fd1..f7887ad7ceac8a07271b33a669200871eceb708c 100644 (file)
--- a/po/es.po
+++ b/po/es.po
+# translation of es.po to spanish
+# translation of es.po to
 # ikiwiki spanish translation
-# Copyright (C) 2007 The Free Software Foundation, Inc
+# Copyright (C) 2007, 2009 The Free Software Foundation, Inc
 # This file is distributed under the same license as the ikiwiki package.
 #
-# Víctor Moral <victor@taquiones.net>, 2007.
+# Víctor Moral <victor@taquiones.net>, 2007, 2009.
+# Victor Moral <victor@taquiones.net>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: es\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-10-08 17:34-0400\n"
-"PO-Revision-Date: 2008-10-07 12:44+0200\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
+"PO-Revision-Date: 2009-03-03 10:48+0100\n"
 "Last-Translator: Víctor Moral <victor@taquiones.net>\n"
-"Language-Team: Spanish <es@li.org>\n"
+"Language-Team: spanish <es@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
 
 #: ../IkiWiki/CGI.pm:113
 msgid "You need to log in first."
 msgstr "Antes es necesario identificarse."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+"probablemente algo está mal configurado: la característica 'sslcookie' está "
+"activa, pero está intentando registrarse en el sistema vía el protocolo "
+"'http' y no 'https'"
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 "registro fallido, ¿ tal vez necesita activar las cookies en el navegador ?"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr "Su registro en el sistema ha expirado."
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr "Identificación"
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr "Preferencias"
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr "Administración"
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Las preferencias se han guardado."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Ha sido expulsado."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Error"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr "Contenido añadido activado vía web."
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 "¡ No hay nada que hacer, todas las fuentes de noticias están actualizadas !"
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "falta el parámetro %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "nueva entrada"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "entradas"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "nuevo"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "%s caducada (%s días de antigüedad)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "%s caducada"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "proceso completado con éxito a %s"
+msgid "last checked %s"
+msgstr "última comprobación el %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "comprobando fuente de datos %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "no puedo encontrar la fuente de datos en %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "fuente de datos no encontrada"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "(una secuencia UTF-8 inválida ha sido eliminada de la fuente de datos)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr "(los caracteres especiales de la fuente de datos están exceptuados)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "¡ la fuente de datos ha provocado un error fatal en XML::Feed !"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "creando nueva página %s"
@@ -130,7 +143,7 @@ msgstr "creando nueva página %s"
 msgid "deleting bucket.."
 msgstr "borrando el directorio.."
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "completado"
 
@@ -151,20 +164,20 @@ msgstr "No puedo guardar el archivo en S3: "
 msgid "Failed to delete file from S3: "
 msgstr "No puedo borrar archivo en S3: "
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr "ya existe una página de nombre %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr "prohibido por la claúsula allowed_attachments"
 
-#: ../IkiWiki/Plugin/attachment.pm:189
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr "nombre de archivo adjunto erróneo"
 
-#: ../IkiWiki/Plugin/attachment.pm:231
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr "enviado el adjunto"
 
@@ -172,8 +185,16 @@ msgstr "enviado el adjunto"
 msgid "automatic index generation"
 msgstr "creación de índice automática"
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+"Lo siento, pero el analizador <a href=\"http://blospam.net\">blogspam</a> "
+"dice que el texto puede ser spam."
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -188,6 +209,71 @@ msgstr "%s desde la página %s"
 msgid "There are no broken links!"
 msgstr "¡ No hay enlaces rotos !"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr "formato de página %s no soportado"
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr "Un comentario debe tener algún contenido"
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr "Anónimo"
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr "nombre de página erróneo"
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, perl-format
+msgid "commenting on %s"
+msgstr "creando comentarios en la página %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr "la página '%s' no existe, así que no se puede comentar sobre ella"
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr "los comentarios para la página '%s' están cerrados"
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr "comentario guardado a la espera de aprobación"
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr "Su comentario será publicado después de que el moderador lo revise"
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr "Añadir un comentario"
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr "Comentario añadido: %s"
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr "No está registrado como un administrador"
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr "Aprobación de comentarios"
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr "aprobación de comentarios"
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr "Comentarios"
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -209,19 +295,19 @@ msgstr "no se ha copiado ningún texto con el identificador %s en esta pagina"
 msgid "removing old preview %s"
 msgstr "eliminando la antigua previsualización %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "la página %s no es modificable"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "creando página %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "modificando página %s"
@@ -243,14 +329,49 @@ msgstr "plantilla de edición %s registrada para %s"
 msgid "failed to process"
 msgstr "fallo en el proceso"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr "se deben especificar tanto el formato como el texto"
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "el programa fortune ha fallado"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr "No puede cambiar %s"
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr "no puede actuar sobre un archivo con permisos %s"
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr "No puede cambiar los permisos de acceso de un archivo"
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr ""
+"Es obligatorio indicar %s cuando se utiliza el complemento de búsqueda de "
+"google"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
 msgstr ""
-"El complemento googlecalendar no ha encontrado un URL en el código html "
+"Error en el análisis del URL, no puedo determinar el nombre del dominio"
+
+#: ../IkiWiki/Plugin/goto.pm:49
+msgid "missing page"
+msgstr "página no encontrada"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr "No existe la página %s."
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -278,46 +399,50 @@ msgstr "no puedo leer de %s: %s "
 #: ../IkiWiki/Plugin/img.pm:87
 #, perl-format
 msgid "failed to resize: %s"
-msgstr "redimensionado fallido: %s"
+msgstr "dimensionamiento fallido: %s"
 
 #: ../IkiWiki/Plugin/img.pm:118
 #, perl-format
 msgid "failed to determine size of image %s"
 msgstr "no he podido determinar el tamaño de la imagen %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Es obligatorio indicar un url al wiki cuando se usan los parámetros --rss ó "
 "--atom"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 msgid "page editing not allowed"
 msgstr "no está permitida la modificación de páginas"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 msgid "missing pages parameter"
 msgstr "falta el parámetro pages"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "no conozco este tipo de ordenación %s"
 
-#: ../IkiWiki/Plugin/inline.pm:285
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Añadir una entrada nueva titulada:"
 
-#: ../IkiWiki/Plugin/inline.pm:301
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "la plantilla %s no existe "
 
-#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Comentarios"
 
-#: ../IkiWiki/Plugin/inline.pm:571
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna"
 
@@ -325,7 +450,7 @@ msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna
 msgid "failed to run dot"
 msgstr "no he podido ejecutar el programa dot"
 
-#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr "La página %s está bloqueada y no puede modificarse"
@@ -342,15 +467,15 @@ msgstr ""
 "no he podido cargar el módulo Perl Markdown.pm (%s) ó no he podido ejecutar "
 "el programa /usr/bin/markdown (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "hoja de estilo no encontrada "
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 msgid "redir page not found"
 msgstr "falta la página a donde redirigir"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 msgid "redir cycle is not allowed"
 msgstr "ciclo de redirección no permitido"
 
@@ -407,7 +532,7 @@ msgstr "No he podido enviar el mensaje de correo electrónico"
 #: ../IkiWiki/Plugin/passwordauth.pm:293
 msgid "You have been mailed password reset instructions."
 msgstr ""
-"Las instrucciones para reinicar la contraseña se le han enviado por correo "
+"Las instrucciones para reiniciar la contraseña se le han enviado por correo "
 "electrónico"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:328
@@ -537,16 +662,7 @@ msgstr "%s es un valor erróneo para un porcentaje"
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr "son necesarios los parámetros 'donepages' y 'percent' ó 'totalpages'"
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-msgid "missing page"
-msgstr "página no encontrada"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr "No existe la página %s."
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr "(Lista de diferencias truncada)"
 
@@ -624,7 +740,7 @@ msgstr "Por favor, seleccione el adjunto al que cambiar el nombre."
 msgid "rename %s to %s"
 msgstr "%s cambia de nombre a %s"
 
-#: ../IkiWiki/Plugin/rename.pm:490
+#: ../IkiWiki/Plugin/rename.pm:493
 #, perl-format
 msgid "update for rename of %s to %s"
 msgstr "actualizado el cambio de nombre de %s a %s"
@@ -643,18 +759,19 @@ msgstr "se necesita la instalación de Digest::SHA1 para indexar %s"
 msgid "search"
 msgstr "buscar"
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
-msgstr "el complemento shortcut no funciona sin una página shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
+msgstr "el complemento shortcut no funcionará si no existe la página %s"
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "shortcut necesita el parámetro 'name' ó el parámetro 'url'"
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "El atajo %s apunta a <i>%s</i>"
@@ -699,33 +816,33 @@ msgstr "error fatal invocando el programa php"
 msgid "cannot find file"
 msgstr "no puedo encontrar el archivo"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "formato de datos desconocido"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "sin datos"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Enlace directo para descarga"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "error de análisis en la línea %d: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "falta el parámetro \"id\""
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "no he encontrado la plantilla %s"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "se ha producido un error fatal mientras procesaba la plantilla:"
 
@@ -750,10 +867,6 @@ msgstr "complemento"
 msgid "enable %s?"
 msgstr "¿ activar %s ?"
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr "No está registrado como un administrador"
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr "El archivo de configuración para este wiki es desconocido"
@@ -786,6 +899,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr "<p class=\"error\">Error: %s finaliza con código distinto de cero (%s)"
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr "no puedo determinar el identificador de un usuario no fiable como %s"
+
+#: ../IkiWiki/Receive.pm:85
+#, perl-format
+msgid "bad file name %s"
+msgstr "el nombre de archivo %s es erróneo"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -845,7 +968,7 @@ msgstr "eliminando la página %s puesto que ya no se deriva de %s"
 #: ../IkiWiki/Render.pm:522
 #, perl-format
 msgid "ikiwiki: cannot render %s"
-msgstr "ikwiki: no puedo convertir la página %s"
+msgstr "ikiwiki: no puedo convertir la página %s"
 
 #. translators: The first parameter is a filename, and the second
 #. translators: is a (probably not translated) error message.
@@ -854,16 +977,16 @@ msgstr "ikwiki: no puedo convertir la página %s"
 msgid "cannot read %s: %s"
 msgstr "no puedo leer el archivo %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr "debe escribir un nombre wiki (que contiene caracteres alfanuméricos)"
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr "el sistema de control de versiones %s no está soportado"
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr "no he podido crear un repositorio con el programa ikiwiki-makerepo"
 
@@ -881,21 +1004,14 @@ msgstr ""
 msgid "wrapper filename not specified"
 msgstr "el programa envoltorio no ha sido especificado"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "no puedo escribir en %s: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "ha fallado la compilación del programa %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "creado con éxito el programa envoltorio %s"
@@ -908,45 +1024,45 @@ msgstr "uso: ikiwiki [opciones] origen destino"
 msgid "       ikiwiki --setup configfile"
 msgstr "       ikiwiki --setup archivo_de_configuración"
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr "uso: --set variable=valor"
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "generando programas auxiliares.."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "reconstruyendo el wiki.."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "actualizando el wiki.."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 "Es obligatorio especificar un url al wiki con el parámetro --url si se "
 "utiliza el parámetro --cgi"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr "no puedo emplear varios complementos rcs"
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr "no he podido cargar el complemento externo %s necesario para %s"
 
-#: ../IkiWiki.pm:1149
+#: ../IkiWiki.pm:1194
 #, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr ""
 "se ha detectado en la página %s un bucle de preprocesado en la iteración "
 "número %i"
 
-#: ../IkiWiki.pm:1658
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr "si"
 
@@ -963,58 +1079,11 @@ msgid "What revision control system to use?"
 msgstr "¿ Qué sistema de control de versiones empleará ?"
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
-"¿ Qué usuario del wiki (ó identificador openid) será el administrador del "
-"wiki ? "
+"¿ Qué usuario del wiki (ó qué identificador openid) será el empleado como "
+"administrador ? "
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr "¿ Cuál es el dominio para el servidor web ?"
-
-#~ msgid "Your password has been emailed to you."
-#~ msgstr "Se le ha enviado su contraseña por correo electrónico."
-
-#~ msgid "polygen failed"
-#~ msgstr "El programa polygen ha fallado"
-
-#~ msgid "cleaning hyperestraier search index"
-#~ msgstr "limpiando el índice de búsquedas de hyperestraier"
-
-#~ msgid "updating hyperestraier search index"
-#~ msgstr "actualizando el índice de búsquedas de hyperstraier"
-
-#~ msgid "(not toggleable in preview mode)"
-#~ msgstr "(no se puede cambiar en el modo de previsualización)"
-
-#~ msgid ""
-#~ "REV is not set, not running from mtn post-commit hook, cannot send "
-#~ "notifications"
-#~ msgstr ""
-#~ "La variable de entorno REV no está definida, por lo que no puede "
-#~ "funcionar svn post-commit desde monotone; no puedo enviar ninguna "
-#~ "notificación"
-
-#~ msgid "REV is not a valid revision identifier, cannot send notifications"
-#~ msgstr ""
-#~ "REV no es un identificador de revisión válido, por lo que no puedo enviar "
-#~ "ninguna notificación"
-
-#~ msgid ""
-#~ "REV is not set, not running from svn post-commit hook, cannot send "
-#~ "notifications"
-#~ msgstr ""
-#~ "La variable de entorno REV no está definida, por lo que no puede "
-#~ "funcionar svn post-commit; no puedo enviar ninguna notificación"
-
-#~ msgid "link is no longer supported"
-#~ msgstr "el metadato link ya no puede usarse"
-
-#~ msgid "%s not found"
-#~ msgstr "no he encontrado la plantilla %s "
-
-#~ msgid "What's this?"
-#~ msgstr "¿ Qué es esto ?"
-
-#~ msgid "(use FirstnameLastName)"
-#~ msgstr "(utilice la forma NombreApellidos)"
index 0c8406381d547e26eeeb3649ce2740e96f85ad50..78b3bbe0f6bd3979c8f0f596fc91923ba57246f8 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
 # Cyril Brulebois <cyril.brulebois@enst-bretagne.fr>, 2007.
 msgid ""
 msgstr ""
-"Project-Id-Version: \n"
+"Project-Id-Version: ikiwiki 3.04\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-10-05 19:11-0400\n"
-"PO-Revision-Date: 2008-09-23 10:00+0100\n"
-"Last-Translator: Julien Patriarca <patriarcaj@gmail.com>\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
+"PO-Revision-Date: 2009-03-15 16:10+0100\n"
+"Last-Translator: Philippe Batailler <philippe.batailler@free.fr>\n"
 "Language-Team: French <debian-l10n-french@lists.debian.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
 
 #: ../IkiWiki/CGI.pm:113
 msgid "You need to log in first."
 msgstr "Vous devez d'abord vous identifier."
 
-#: ../IkiWiki/CGI.pm:145
-msgid "login failed, perhaps you need to turn on cookies?"
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
 msgstr ""
-"Échec de l'identification, vous devriez peut-être autoriser les cookies."
+"Erreur de configuration probable : sslcookie est positionné mais vous tentez "
+"de vous connecter avec http et non https"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:149
+msgid "login failed, perhaps you need to turn on cookies?"
+msgstr "Échec de l'identification, vous devez autoriser les cookies."
+
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr "Session d'authentification expirée."
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr "S’identifier"
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr "Préférences"
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr "Administrateur"
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Les préférences ont été enregistrées."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Vous avez été banni."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Erreur"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
-msgstr "Agrégation déclenchée via Internet"
+msgstr "Agrégation déclenchée par le web"
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
-msgstr "Rien à faire pour le moment, tous les flux sont à jour!"
+msgstr "Rien à faire pour le moment, tous les flux sont à jour !"
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "Paramètre %s manquant"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "Nouveau flux"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "Articles"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "Nouveau"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "Fin de validité de %s (date de %s jours)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "Fin de validité de %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "A été correctement traité à %s"
+msgid "last checked %s"
+msgstr "dernière vérification : %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "Vérification du flux %s..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "Impossible de trouver de flux à %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "Flux introuvable "
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "(chaîne UTF-8 non valable supprimée du flux)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr "(échappement des entités de flux)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "Plantage du flux XML::Feed !"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "Création de la nouvelle page %s"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:31
 msgid "deleting bucket.."
-msgstr "vidage du panier..."
+msgstr "Suppression du compartiment S3 (« bucket »)..."
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "Terminé"
 
@@ -143,39 +149,47 @@ msgstr "Vous devez spécifier %s"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:136
 msgid "Failed to create bucket in S3: "
-msgstr "Echec lors de la création du panier en S3:"
+msgstr "Impossible de créer un compartiment S3 :"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:221
 msgid "Failed to save file to S3: "
-msgstr "Echec lors de la création du fichier en S3:"
+msgstr "Impossible de sauvegarder le fichier dans le compartiment S3 :"
 
 #: ../IkiWiki/Plugin/amazon_s3.pm:243
 msgid "Failed to delete file from S3: "
-msgstr "Echec lors de la suppression du fichier de S3:"
+msgstr "Échec lors de la suppression du fichier sur S3 :"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
-msgstr "il existe déjà une page nommée %s"
+msgstr "Il existe déjà une page nommée %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
-msgstr "action interdite par pièces jointes autorisées"
+msgstr "Action interdite par allowed_attachments"
 
-#: ../IkiWiki/Plugin/attachment.pm:189
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
-msgstr "Mauvais nom de la pièce jointe"
+msgstr "Nom de la pièce jointe incorrect"
 
-#: ../IkiWiki/Plugin/attachment.pm:231
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
-msgstr "envoi de la pièce jointe"
+msgstr "Envoi de la pièce jointe"
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
-msgstr "génération de l'index automatique"
+msgstr "Génération de l'index automatique"
+
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+"Désolé, mais ceci ressemble à un spam à destination de <a href=\"http://"
+"blogspam.net/\">blogspam</a>: "
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -188,18 +202,83 @@ msgstr "%s sur %s"
 
 #: ../IkiWiki/Plugin/brokenlinks.pm:56
 msgid "There are no broken links!"
-msgstr "Il n'existe pas de lien cassé !"
+msgstr "Aucun lien cassé !"
+
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr "Format de page non reconnu %s"
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr "Un commentaire doit avoir un contenu."
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr "Anonyme"
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr "Nom de page incorrect"
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, perl-format
+msgid "commenting on %s"
+msgstr "Faire un commentaire sur %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr "La page '%s' n'existe pas, commentaire impossible."
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr "Le commentaire pour la page '%s' est terminé."
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr "Le commentaire a été enregistré en attente de modération"
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr "Votre commentaire sera publié après que le modérateur l'ait vérifié"
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr "Commentaire ajouté"
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr "Commentaire ajouté : %s"
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr "Vous n'êtes pas authentifié comme administrateur"
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr "Modération du commentaire"
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr "modération du commentaire"
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr "Commentaires"
 
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
 #, perl-format
 msgid "%s parameter is required"
-msgstr "le paramètre %s est obligatoire"
+msgstr "Le paramètre %s est obligatoire"
 
 #: ../IkiWiki/Plugin/cutpaste.pm:66
 msgid "no text was copied in this page"
-msgstr "aucun texte n'a été copié dans cette page"
+msgstr "Aucun texte n'a été copié dans cette page"
 
 #: ../IkiWiki/Plugin/cutpaste.pm:69
 #, perl-format
@@ -207,23 +286,23 @@ msgid "no text was copied in this page with id %s"
 msgstr "Aucun texte n'a été copié dans cette page avec l'identifiant %s"
 
 #: ../IkiWiki/Plugin/editpage.pm:40
-#, fuzzy, perl-format
+#, perl-format
 msgid "removing old preview %s"
-msgstr "Suppression de l'ancienne page %s"
+msgstr "Suppression de l'ancienne prévisualisation %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "%s n'est pas une page éditable"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "Création de %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "Édition de %s"
@@ -245,13 +324,46 @@ msgstr "edittemplate %s enregistré pour %s"
 msgid "failed to process"
 msgstr "Échec du traitement"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr "le format et le texte doivent être indiqués"
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "Échec du lancement de « fortune »"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
-msgstr "Échec dans la recherche d'une URL dans le Code HTML"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr "Vous n'êtes pas autorisé à modifier %s"
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr "Vous ne pouvez utiliser le mode %s pour les fichiers"
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr "Vous n'êtes pas autorisé à modifier le mode des fichiers"
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Vous devez indiquer %s lors de l'utilisation du greffon « google »."
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr "Impossible d'analyser l'url, pas de nom de domaine"
+
+#: ../IkiWiki/Plugin/goto.pm:49
+msgid "missing page"
+msgstr "Page manquante"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr "La page %s n'existe pas."
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -286,40 +398,43 @@ msgstr "Échec du redimensionnement : %s"
 msgid "failed to determine size of image %s"
 msgstr "Échec de la détermination de la taille de l'image : %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Vous devez indiquer l'URL du wiki par --url lors de l'utilisation de --rss "
 "ou --atom"
 
-#: ../IkiWiki/Plugin/inline.pm:139
-#, fuzzy
+#: ../IkiWiki/Plugin/inline.pm:138
 msgid "page editing not allowed"
-msgstr "Redirection cyclique non autorisée"
+msgstr "Modification de page interdite"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 msgid "missing pages parameter"
-msgstr "paramètres de la page manquants"
+msgstr "Paramètre « pages » manquant"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "Type de tri %s inconnu"
 
-#: ../IkiWiki/Plugin/inline.pm:285
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Ajouter un nouvel article dont le titre est :"
 
-#: ../IkiWiki/Plugin/inline.pm:301
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
-msgstr "Le modèle (« template ») %s n'existe pas"
+msgstr "Le modèle de page %s n'existe pas"
 
-#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Discussion"
 
-#: ../IkiWiki/Plugin/inline.pm:571
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "RPC::XML::Client introuvable, pas de réponse au ping"
 
@@ -327,10 +442,10 @@ msgstr "RPC::XML::Client introuvable, pas de réponse au ping"
 msgid "failed to run dot"
 msgstr "Échec du lancement de dot"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, perl-format
 msgid "%s is locked and cannot be edited"
-msgstr "%s est verouillé et ne peut être édité"
+msgstr "%s est verrouillé et ne peut être modifié"
 
 #: ../IkiWiki/Plugin/mdwn.pm:44
 msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed"
@@ -343,15 +458,15 @@ msgstr ""
 "Échec du chargement du module Perl Markdown.pm (%s) ou de /usr/bin/markdown "
 "(%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "Feuille de style introuvable "
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 msgid "redir page not found"
-msgstr "Page de redirection introuvable "
+msgstr "Page de redirection introuvable"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 msgid "redir cycle is not allowed"
 msgstr "Redirection cyclique non autorisée"
 
@@ -385,7 +500,7 @@ msgstr "Toutes les pages sont liées à d'autres pages."
 
 #: ../IkiWiki/Plugin/pagetemplate.pm:30
 msgid "bad or missing template"
-msgstr "Modèle incorrect ou manquant"
+msgstr "Modèle de page incorrect ou manquant"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:247
 msgid "Account creation successful. Now you can Login."
@@ -398,26 +513,26 @@ msgstr "Erreur lors de la création du compte."
 #: ../IkiWiki/Plugin/passwordauth.pm:257
 msgid "No email address, so cannot email password reset instructions."
 msgstr ""
-"Pas d'adresse email spécifiée. Impossible d'envoyer les instructions de "
-"remise à zéro du mot de passe"
+"Pas d'adresse spécifiée. Impossible d'envoyer les instructions pour "
+"réinitialiser le mot de passe."
 
 #: ../IkiWiki/Plugin/passwordauth.pm:291
 msgid "Failed to send mail"
-msgstr "Échec de l'envoi du courriel"
+msgstr "Impossible d'envoyer un courriel"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:293
 msgid "You have been mailed password reset instructions."
 msgstr ""
-"Vous avez reçu un message contenant les instructions de remise à zéro du mot "
-"de passe"
+"Vous avez reçu un message contenant les instructions pour réinitialiser le "
+"mot de passe"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:328
 msgid "incorrect password reset url"
-msgstr "Adresse de remise à zéro du mot de passe incorrecte"
+msgstr "Adresse pour la réinitialisation du mot de passe incorrecte"
 
 #: ../IkiWiki/Plugin/passwordauth.pm:331
 msgid "password reset denied"
-msgstr "remise à zéro du mot de passe refusée"
+msgstr "réinitialisation du mot de passe refusée"
 
 #: ../IkiWiki/Plugin/pingee.pm:30
 msgid "Ping received."
@@ -435,7 +550,7 @@ msgstr "va envoyer un ping à %s"
 #: ../IkiWiki/Plugin/pinger.pm:61
 #, perl-format
 msgid "Ignoring ping directive for wiki %s (this wiki is %s)"
-msgstr "les instructions du wiki %s sont ignorées (ce wiki est %s)"
+msgstr "Les instructions du wiki %s sont ignorées (ce wiki est %s)"
 
 #: ../IkiWiki/Plugin/pinger.pm:77
 msgid "LWP not found, not pinging"
@@ -455,7 +570,7 @@ msgstr "polygen n'est pas installé"
 
 #: ../IkiWiki/Plugin/polygen.pm:60
 msgid "command failed"
-msgstr "Echec lors du lancement de la commande"
+msgstr "Échec de la commande"
 
 #: ../IkiWiki/Plugin/postsparkline.pm:41
 msgid "missing formula"
@@ -503,15 +618,15 @@ msgstr "%A après-midi"
 
 #: ../IkiWiki/Plugin/prettydate.pm:32
 msgid "late %A afternoon"
-msgstr "tard l'après-midi de %A"
+msgstr "tard dans l'après-midi de %A"
 
 #: ../IkiWiki/Plugin/prettydate.pm:33
 msgid "%A evening"
-msgstr "%A soir"
+msgstr "%A en soirée"
 
 #: ../IkiWiki/Plugin/prettydate.pm:35
 msgid "late %A evening"
-msgstr "tard %A soir"
+msgstr "tard %A en soirée"
 
 #: ../IkiWiki/Plugin/prettydate.pm:37
 msgid "%A night"
@@ -530,24 +645,16 @@ msgid "at noon on %A"
 msgstr "%A, à midi"
 
 #: ../IkiWiki/Plugin/progress.pm:34
-#, fuzzy, perl-format
+#, perl-format
 msgid "illegal percent value %s"
-msgstr "appellation non autorisé"
+msgstr "pourcentage %s illégal"
 
 #: ../IkiWiki/Plugin/progress.pm:59
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
+"L'un des paramètres « percent », « totalpages » ou « donepages » est nécessaire."
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-msgid "missing page"
-msgstr "Page manquante"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr "La page %s n'existe pas."
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr "(fichier de différences tronqué)"
 
@@ -566,16 +673,16 @@ msgstr "%s n'est pas dans srcdir et ne peut donc pas être supprimé"
 msgid "%s is not a file"
 msgstr "%s n'est pas un fichier"
 
-#: ../IkiWiki/Plugin/remove.pm:113
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr "Suppression de %s confirmée"
 
-#: ../IkiWiki/Plugin/remove.pm:150
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr "Veuillez choisir la pièce jointe à supprimer"
 
-#: ../IkiWiki/Plugin/remove.pm:190
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr "supprimé"
 
@@ -591,7 +698,7 @@ msgstr "Aucun changement dans le nom du fichier n'a été spécifié"
 #: ../IkiWiki/Plugin/rename.pm:68
 #, perl-format
 msgid "illegal name"
-msgstr "appellation non autorisé"
+msgstr "Appellation non autorisée"
 
 #: ../IkiWiki/Plugin/rename.pm:73
 #, perl-format
@@ -606,15 +713,15 @@ msgstr "%s existe déjà sur le disque"
 #: ../IkiWiki/Plugin/rename.pm:101
 #, perl-format
 msgid "rename %s"
-msgstr "%s  renommé"
+msgstr "%s renommé"
 
 #: ../IkiWiki/Plugin/rename.pm:138
 msgid "Also rename SubPages and attachments"
-msgstr ""
+msgstr "« SubPages » et attachements renommés."
 
 #: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
-msgstr "Seule une pièce jointe peut être renommée à la fois"
+msgstr "Une seule pièce jointe peut être renommée à la fois"
 
 #: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
@@ -623,17 +730,17 @@ msgstr "Veuillez sélectionner la pièce jointe à renommer"
 #: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
-msgstr "renomme %s en %s"
+msgstr "Renomme %s en %s"
 
-#: ../IkiWiki/Plugin/rename.pm:490
+#: ../IkiWiki/Plugin/rename.pm:493
 #, perl-format
 msgid "update for rename of %s to %s"
-msgstr "du nouveau nom de %s en %s"
+msgstr "mise à jour, suite au changement de %s en %s"
 
 #: ../IkiWiki/Plugin/search.pm:36
 #, perl-format
 msgid "Must specify %s when using the search plugin"
-msgstr "Vous devez indiquer %s lors de l'utilisation du greffon de recherche"
+msgstr "Vous devez indiquer %s lors de l'utilisation du greffon « search »."
 
 #: ../IkiWiki/Plugin/search.pm:182
 #, perl-format
@@ -644,19 +751,19 @@ msgstr "Digest::SHA1 est nécessaire pour indexer %s"
 msgid "search"
 msgstr "recherche"
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
-msgstr ""
-"Le greffon de raccourci (« shortcut ») ne fonctionnera pas sans shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
+msgstr "Le greffon « shortcut » ne fonctionnera pas sans %s"
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "Il manque le paramètre nom ou URL."
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "Le raccourci %s pointe vers <i>%s</i>"
@@ -687,7 +794,7 @@ msgstr "Hauteur incorrecte"
 
 #: ../IkiWiki/Plugin/sparkline.pm:111
 msgid "missing width parameter"
-msgstr "Le paramètre de largeur manque dans le modèle (« template »)"
+msgstr "Le paramètre largeur manque"
 
 #: ../IkiWiki/Plugin/sparkline.pm:115
 msgid "bad width value"
@@ -701,33 +808,33 @@ msgstr "Échec du lancement de php"
 msgid "cannot find file"
 msgstr "Fichier introuvable"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "Format de données inconnu"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
-msgstr "Données vides"
+msgstr "Pas de données"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Téléchargement direct des données"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "Erreur d'analyse à la ligne %d : %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "Paramètre d'identification manquant"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
-msgstr "Modèle (« template ») %s introuvable "
+msgstr "Modèle de page %s introuvable"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "Échec du traitement :"
 
@@ -745,34 +852,30 @@ msgstr "Échec de la création de l'image à partir du code"
 
 #: ../IkiWiki/Plugin/websetup.pm:89
 msgid "plugin"
-msgstr "module complémentaire"
+msgstr "greffon"
 
 #: ../IkiWiki/Plugin/websetup.pm:108
 #, perl-format
 msgid "enable %s?"
-msgstr "activer %s?"
-
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr "vous n'êtes pas authentifié comme administrateur"
+msgstr "activer %s ?"
 
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
-msgstr "le fichier de configuration de ce wiki n'est pas connu"
+msgstr "Le fichier de configuration de ce wiki n'est pas connu"
 
 #: ../IkiWiki/Plugin/websetup.pm:256
 msgid "main"
-msgstr "principal"
+msgstr "Partie principale"
 
 #: ../IkiWiki/Plugin/websetup.pm:257
 msgid "plugins"
-msgstr "modules complémentaires"
+msgstr "Greffons"
 
 #: ../IkiWiki/Plugin/websetup.pm:395
 msgid ""
 "The configuration changes shown below require a wiki rebuild to take effect."
 msgstr ""
-"les changements de configuration ci dessous nécessitent une recompilation du "
+"Les changements de configuration ci-dessous nécessitent une recompilation du "
 "wiki pour prendre effet"
 
 #: ../IkiWiki/Plugin/websetup.pm:399
@@ -780,13 +883,25 @@ msgid ""
 "For the configuration changes shown below to fully take effect, you may need "
 "to rebuild the wiki."
 msgstr ""
-"Pour que les changements de configuration ci dessous prennent effet vous "
+"Pour que les changements de configuration ci-dessous prennent effet vous "
 "devez recompiler le wiki"
 
 #: ../IkiWiki/Plugin/websetup.pm:433
 #, perl-format
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
-msgstr "<p class=\"erreur\">Erreur: %s a quitté nonzero (%s)"
+msgstr ""
+"<p class=\"erreur\">Erreur : %s s'est terminé, valeur de sortie nonzero (%s)"
+
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+"Impossible de déterminer l'identifiant de %s, (enregistrement non fiable)"
+
+#: ../IkiWiki/Receive.pm:85
+#, perl-format
+msgid "bad file name %s"
+msgstr "Nom de fichier incorrect %s"
 
 #: ../IkiWiki/Render.pm:253
 #, perl-format
@@ -794,6 +909,8 @@ msgid ""
 "symlink found in srcdir path (%s) -- set allow_symlinks_before_srcdir to "
 "allow this"
 msgstr ""
+"Lien symbolique trouvé dans l'adresse de srcdir (%s) -- pour l'autoriser, "
+"activez le paramètre « allow_symlinks_before_srcdir »."
 
 #: ../IkiWiki/Render.pm:277 ../IkiWiki/Render.pm:302
 #, perl-format
@@ -803,7 +920,7 @@ msgstr "Omission du fichier au nom incorrect %s"
 #: ../IkiWiki/Render.pm:284
 #, perl-format
 msgid "%s has multiple possible source pages"
-msgstr ""
+msgstr "%s peut être associé à plusieurs pages source."
 
 #: ../IkiWiki/Render.pm:360
 #, perl-format
@@ -813,37 +930,37 @@ msgstr "Suppression de l'ancienne page %s"
 #: ../IkiWiki/Render.pm:400
 #, perl-format
 msgid "scanning %s"
-msgstr "Parcours de %s"
+msgstr "Examen de %s"
 
 #: ../IkiWiki/Render.pm:405
 #, perl-format
 msgid "rendering %s"
-msgstr "Affichage de %s"
+msgstr "Reconstruction de %s"
 
 #: ../IkiWiki/Render.pm:426
 #, perl-format
 msgid "rendering %s, which links to %s"
-msgstr "Affichage de %s, qui est lié à %s"
+msgstr "Reconstruction de %s, qui est lié à %s"
 
 #: ../IkiWiki/Render.pm:447
 #, perl-format
 msgid "rendering %s, which depends on %s"
-msgstr "Affichage de %s, qui dépend de %s"
+msgstr "Reconstruction de %s, qui dépend de %s"
 
 #: ../IkiWiki/Render.pm:486
 #, perl-format
 msgid "rendering %s, to update its backlinks"
-msgstr "Affichage de %s, afin de mettre à jour ses rétroliens"
+msgstr "Reconstruction de %s, afin de mettre à jour ses rétroliens"
 
 #: ../IkiWiki/Render.pm:498
 #, perl-format
 msgid "removing %s, no longer rendered by %s"
-msgstr "Suppression de %s, qui n'est plus affiché par %s"
+msgstr "Suppression de %s, qui n'est plus rendu par %s"
 
 #: ../IkiWiki/Render.pm:522
 #, perl-format
 msgid "ikiwiki: cannot render %s"
-msgstr "ikiwiki : impossible d'afficher %s"
+msgstr "ikiwiki : impossible de reconstruire %s"
 
 #. translators: The first parameter is a filename, and the second
 #. translators: is a (probably not translated) error message.
@@ -852,20 +969,20 @@ msgstr "ikiwiki : impossible d'afficher %s"
 msgid "cannot read %s: %s"
 msgstr "Lecture impossible de %s : %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 "Vous devez spécifier un nom de wiki (contenant des caractères "
 "alphanumériques)"
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
-msgstr "Système de contôles des version non supporté"
+msgstr "Système de contrôle de version non reconnu : %s"
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
-msgstr "Echec lors de la création du dépôt avec ikiwiki-makerepo"
+msgstr "Échec lors de la création du dépôt avec ikiwiki-makerepo"
 
 #: ../IkiWiki/Wrapper.pm:16
 #, perl-format
@@ -879,23 +996,16 @@ msgstr ""
 
 #: ../IkiWiki/Wrapper.pm:24
 msgid "wrapper filename not specified"
-msgstr "Le nom de fichier de l'enrobage n'a pas été indiqué"
-
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "Échec de l'écriture de %s : %s"
+msgstr "Le nom du fichier CGI n'a pas été indiqué"
 
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "Échec de la compilation de %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "%s a été créé avec succès"
@@ -906,53 +1016,50 @@ msgstr "Syntaxe : ikiwiki [options] source destination"
 
 #: ../ikiwiki.in:14
 msgid "       ikiwiki --setup configfile"
-msgstr ""
+msgstr "       ikiwiki --setup fichier de configuration"
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr "Syntaxe : -- set var=valeur"
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "Création des fichiers CGI..."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "Reconstruction du wiki..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "Rafraîchissement du wiki..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
-"Vous devez indiquer une URL vers le wiki par --url lors de l'utilisation de "
-"--cgi"
+"Vous devez indiquer l'URL du wiki par --url lors de l'utilisation de --cgi"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
-msgstr ""
-"impossible d'utiliser plusieurs modules complémentaires dans le système de "
-"contrôle des versions"
+msgstr "Impossible d'utiliser plusieurs systèmes de contrôle des versions"
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
-msgstr ""
+msgstr "Impossible de charger le greffon externe nécessaire au greffon %s : %s"
 
-#: ../IkiWiki.pm:1149
+#: ../IkiWiki.pm:1194
 #, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
-msgstr "une boucle de pré traitement a été detectée sur %s à hauteur de %i"
+msgstr "Une boucle de pré traitement a été détectée sur %s à hauteur de %i"
 
-#: ../IkiWiki.pm:1658
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr "oui"
 
 #: ../auto.setup:16
 msgid "What will the wiki be named?"
-msgstr "Nom du wiki"
+msgstr "Nom du wiki :"
 
 #: ../auto.setup:16
 msgid "wiki"
@@ -960,27 +1067,12 @@ msgstr "wiki"
 
 #: ../auto.setup:18
 msgid "What revision control system to use?"
-msgstr "Système de contrôle de version utilisé?"
+msgstr "Système de contrôle de version utilisé :"
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
-msgstr "Identifiant de l'administrateur?"
+msgid "What wiki user (or openid) will be admin?"
+msgstr "Identifiant de l'administrateur (utilisateur du wiki ou openid) :"
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
-msgstr "Nom de domaine du serveur HTTP?"
-
-#~ msgid "Your password has been emailed to you."
-#~ msgstr "Votre mot de passe vous a été envoyé par courriel."
-
-#~ msgid "polygen failed"
-#~ msgstr "Échec du lancement de polygen"
-
-#~ msgid "cleaning hyperestraier search index"
-#~ msgstr "Nettoyage de l'index de recherche de hyperestraier"
-
-#~ msgid "updating hyperestraier search index"
-#~ msgstr "Mise à jour de l'index de recherche de hyperestraier"
-
-#~ msgid "(not toggleable in preview mode)"
-#~ msgstr "(non permutable en mode prévisualisation)"
+msgstr "Nom de domaine du serveur HTTP :"
index afde93b9ebd66b6bf6e99004dcb9cce1af0890e8..dd9c7c5a145e1acc06f67654f8f21b226a144d0d 100644 (file)
--- a/po/gu.po
+++ b/po/gu.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki-gu\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-01-11 16:05+0530\n"
 "Last-Translator: Kartik Mistry <kartik.mistry@gmail.com>\n"
 "Language-Team: Gujarati <team@utkarsh.org>\n"
@@ -19,108 +19,114 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "તમારે પ્રથમ લોગ ઇન થવું પડશે."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr "પ્રવેશ નિષ્ફળ, કદાચ તમારી કુકીઓ સક્રિય બનાવવી પડશે?"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 #, fuzzy
 msgid "Preferences"
 msgstr "પ્રાથમિકતાઓ સંગ્રહાઇ."
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "પ્રાથમિકતાઓ સંગ્રહાઇ."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "તમારા પર પ્રતિબંધ છે."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "ક્ષતિ"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr "ખોવાયેલ %s વિકલ્પ"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "નવું ફીડ"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "પોસ્ટ"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "નવું"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "જુનું કરે છે %s (%s દિવસો જુનું)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "જુનું કરે છે %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "આના પર બરાબર છે %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "ફીડ %s ચકાસે છે ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "%s પર ફીડ મળી શક્યું નહી"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr "ફીડ મળ્યું નહી"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, fuzzy, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "ફીડમાંથી અયોગ્ય રીતે UTF-8 નીકાળેલ છે"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "ફીડ ભાંગી ગયું XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "નવું પાનું %s બનાવે છે"
@@ -129,7 +135,7 @@ msgstr "નવું પાનું %s બનાવે છે"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "સંપૂર્ણ"
 
@@ -152,29 +158,35 @@ msgstr "મેઇલ મોકલવામાં નિષ્ફળ"
 msgid "Failed to delete file from S3: "
 msgstr "માપ બદલવામાં નિષ્ફળ: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -189,6 +201,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "અહીં કોઇ તૂટેલ કડી નથી!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "%s બનાવે છે"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -210,19 +287,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "જુનાં પાનાં દૂર કરે છે %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "%s એ સુધારી શકાય તેવું પાનું નથી"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "%s બનાવે છે"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "%s સુધારે છે"
@@ -247,13 +324,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "ક્રિયા કરવામાં નિષ્ફળ:"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "ભવિષ્ય નિષ્ફળ"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
-msgstr "htmlમાં યુઆરએલ શોધવામાં નિષ્ફળ"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "જ્યારે શોધ પ્લગઇન ઉપયોગ કરતા હોવ ત્યારે %s સ્પષ્ટ કરવું જ પડશે"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
+#, fuzzy
+msgid "missing page"
+msgstr "ખોવાયેલ કિંમતો"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 msgid "failed to run graphviz"
@@ -289,39 +400,43 @@ msgstr "માપ બદલવામાં નિષ્ફળ: %s"
 msgid "failed to determine size of image %s"
 msgstr "માપ બદલવામાં નિષ્ફળ: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr "--rss અથવા --atom ઉપયોગ કરતી વખતે વીકીમાં --url ઉપયોગ કરવું જ પડશે"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "ફીડ મળ્યું નહી"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "ખોવાયેલ %s વિકલ્પ"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "અજાણ્યો ગોઠવણી પ્રકાર %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "આ શિર્ષકથી નવું પોસ્ટ ઉમેરો:"
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "અસ્તિત્વમાં ન હોય તેવું ટેમ્પલેટ %s"
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "ચર્ચા"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "RPC::XML::Client મળ્યું નહી, પિંગ કરવામાં આવતું નથી"
 
@@ -329,7 +444,7 @@ msgstr "RPC::XML::Client મળ્યું નહી, પિંગ કરવા
 msgid "failed to run dot"
 msgstr "ડોટ ચલાવવામાં નિષ્ફળ"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr "%s એ %s દ્વારા તાળું મરાયેલ છે અને તેમાં સુધારો કરી શકાશે નહી"
@@ -343,16 +458,16 @@ msgstr ""
 msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
 msgstr "Markdown.pm પર્લ મોડ્યુલ (%s) અથવા /usr/bin/markdown (%s) લાવવામાં નિષ્ફળ"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr "સ્ટાઇલશીટ મળ્યું નહી"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "ફીડ મળ્યું નહી"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "ફીડ મળ્યું નહી"
@@ -539,17 +654,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "ખોવાયેલ કિંમતો"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -568,16 +673,16 @@ msgstr "%s એ %s દ્વારા તાળું મરાયેલ છે 
 msgid "%s is not a file"
 msgstr "%s એ સુધારી શકાય તેવું પાનું નથી"
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -615,20 +720,20 @@ msgstr "રેન્ડર કરે છે %s"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "%s નો સુધારો %s નાં %s વડે"
@@ -647,18 +752,19 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr "ખોવાયેલ નામ અથવા યુઆરએલ વિકલ્પ"
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "ટુંકોરસ્તો %s એ <i>%s</i> નો નિર્દેશ કરે છે"
@@ -703,33 +809,33 @@ msgstr "php ચલાવવામાં નિષ્ફળ"
 msgid "cannot find file"
 msgstr "ફાઇલ મળી શકી નહી"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "અજાણ્યો માહિતી પ્રકાર"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "ખાલી માહિતી"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "સીધી માહિતી ડાઉનલોડ"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "ઉકેલવાનું લીટી %d પર નિષ્ફળ: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr "ખોવાયેલ આઇડી વિકલ્પ"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "ટેમ્પલેટ %s મળ્યું નહી"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr "ક્રિયા કરવામાં નિષ્ફળ:"
 
@@ -756,10 +862,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -788,6 +890,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "ખરાબ ફાઇલ નામ છોડી દે છે %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -852,16 +964,16 @@ msgstr "ikiwiki: %s રેન્ડર કરી શકાતું નથી"
 msgid "cannot read %s: %s"
 msgstr "વાંચી શકાતી નથી %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -878,21 +990,14 @@ msgstr "ગોઠવણ ફાઇલનો ઉપયોગ કરે છે ત
 msgid "wrapper filename not specified"
 msgstr "આવરણ ફાઇલનામ સ્પષ્ટ કરેલ નથી"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "%s લખવામાં નિષ્ફળ: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "%s કમ્પાઇલ કરવામાં નિષ્ફળ"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "સફળતાપૂર્વક પેદા કરેલ છે %s"
@@ -905,41 +1010,41 @@ msgstr "ઉપયોગ: ikiwiki [વિકલ્પો] source dest"
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "આવરણ બનાવે છે.."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "વીકી ફરીથી બનાવે છે.."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "વીકીને તાજી કરે છે.."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr "જ્યારે --cgi ઉપયોગ કરતાં હોય ત્યારે વીકીનું યુઆરએલ સ્પષ્ટ કરવું જ પડશે"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "%s પર શોધાયેલ લુપ  %s પર ચલાવે છે %i ઉંડાણ પર"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -956,13 +1061,22 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "%s લખવામાં નિષ્ફળ: %s"
+
+#~ msgid "failed to find url in html"
+#~ msgstr "htmlમાં યુઆરએલ શોધવામાં નિષ્ફળ"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "આના પર બરાબર છે %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "તમારો પાસવર્ડ તમને ઇમેઇલ કરવામાં આવ્યો છે."
 
index f07f2bf6236fbd263d24d937d9de7a5e11d30189..b8592bd48f770cbe9900bbae090ed295bb26a27c 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-10-08 17:34-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -20,107 +20,113 @@ msgstr ""
 msgid "You need to log in first."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 msgid "Preferences"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1166
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, perl-format
 msgid "missing %s parameter"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
+msgid "last checked %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 msgid "feed not found"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr ""
@@ -129,7 +135,7 @@ msgstr ""
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr ""
 
@@ -150,20 +156,20 @@ msgstr ""
 msgid "Failed to delete file from S3: "
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:189
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:231
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
@@ -171,8 +177,14 @@ msgstr ""
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:326 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -187,6 +199,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr ""
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, perl-format
+msgid "commenting on %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -208,19 +285,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr ""
@@ -242,12 +319,45 @@ msgstr ""
 msgid "failed to process"
 msgstr ""
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr ""
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
-msgid "failed to find url in html"
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
+msgid "missing page"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
 msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
@@ -283,37 +393,41 @@ msgstr ""
 msgid "failed to determine size of image %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 msgid "page editing not allowed"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 msgid "missing pages parameter"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:285
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:301
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:334 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:571
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr ""
 
@@ -321,7 +435,7 @@ msgstr ""
 msgid "failed to run dot"
 msgstr ""
 
-#: ../IkiWiki/Plugin/lockedit.pm:49 ../IkiWiki/Plugin/lockedit.pm:66
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr ""
@@ -335,15 +449,15 @@ msgstr ""
 msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 msgid "stylesheet not found"
 msgstr ""
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 msgid "redir page not found"
 msgstr ""
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 msgid "redir cycle is not allowed"
 msgstr ""
 
@@ -526,16 +640,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-msgid "missing page"
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -613,7 +718,7 @@ msgstr ""
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:490
+#: ../IkiWiki/Plugin/rename.pm:493
 #, perl-format
 msgid "update for rename of %s to %s"
 msgstr ""
@@ -632,18 +737,19 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 msgid "missing name or url parameter"
 msgstr ""
 
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr ""
@@ -688,33 +794,33 @@ msgstr ""
 msgid "cannot find file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, perl-format
 msgid "parse fail at line %d: %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 msgid "missing id parameter"
 msgstr ""
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr ""
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 msgid "failed to process:"
 msgstr ""
 
@@ -739,10 +845,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -771,6 +873,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, perl-format
+msgid "bad file name %s"
+msgstr ""
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -835,16 +947,16 @@ msgstr ""
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -861,21 +973,14 @@ msgstr ""
 msgid "wrapper filename not specified"
 msgstr ""
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr ""
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr ""
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr ""
@@ -888,41 +993,41 @@ msgstr ""
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr ""
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr ""
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr ""
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1149
+#: ../IkiWiki.pm:1194
 #, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr ""
 
-#: ../IkiWiki.pm:1658
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -939,7 +1044,7 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
index 3cf7377a19939abf2eeae944e0630a350ffdd4f4..305d8bfc630b75ebc4b01977d35269a861b342bb 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki 1.51\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-04-27 22:05+0200\n"
 "Last-Translator: Pawel Tecza <ptecza@net.icm.edu.pl>\n"
 "Language-Team: Debian L10n Polish <debian-l10n-polish@lists.debian.org>\n"
@@ -20,111 +20,117 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Proszę najpierw zalogować się."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 "Nieudane logowanie. Proszę sprawdzić czy w przeglądarce włączone są "
 "ciasteczka (ang. cookies)"
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 #, fuzzy
 msgid "Preferences"
 msgstr "Preferencje zapisane."
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Preferencje zapisane."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Twój dostęp został zabroniony przez administratora."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Błąd"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, fuzzy, perl-format
 msgid "missing %s parameter"
 msgstr "brakujący parametr %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "nowy kanał RSS"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "wpisy"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "nowy wpis"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "wygasający wpis %s (ma już %s dni)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "wygasający wpis %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "kanał RSS przetworzony w dniu %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "sprawdzanie kanału RSS %s..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "nie znaleziono kanału RSS pod adresem %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 #, fuzzy
 msgid "feed not found"
 msgstr "nieznaleziony kanał RSS"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, fuzzy, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr "Nieprawidłowe kodowanie UTF-8 usunięte z kanału RSS"
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "awaria kanału RSS w module XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "tworzenie nowej strony %s"
@@ -133,7 +139,7 @@ msgstr "tworzenie nowej strony %s"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "gotowe"
 
@@ -156,29 +162,35 @@ msgstr "Awaria w trakcie wysyłania wiadomości"
 msgid "Failed to delete file from S3: "
 msgstr "awaria w trakcie zmiany rozmiaru: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -193,6 +205,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "Wszystkie odnośniki są aktualne!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "tworzenie %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -214,19 +291,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "usuwanie starej strony %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr "Strona %s nie może być edytowana"
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "tworzenie %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "edycja %s"
@@ -251,14 +328,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "awaria w trakcie przetwarzania:"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "awaria fortunki"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Wtyczka do wyszukiwarka wymaga podania %s"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
 #, fuzzy
-msgid "failed to find url in html"
-msgstr "awaria w trakcie wyszukiwania adresu URL na stronie HTML"
+msgid "missing page"
+msgstr "brakujące wartości"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 #, fuzzy
@@ -295,41 +405,45 @@ msgstr "awaria w trakcie zmiany rozmiaru: %s"
 msgid "failed to determine size of image %s"
 msgstr "awaria w trakcie zmiany rozmiaru: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Użycie parametru --rss lub --atom wymaga podania adresu URL do wiki za "
 "pomocą parametru --url"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "nieznaleziony kanał RSS"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "brakujący parametr %s"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "nieznany sposób sortowania %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr "Tytuł nowego wpisu"
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr "brakujący szablon %s"
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Dyskusja"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "Nieznaleziony moduł RPC::XML::Client, brak możliwości pingowania"
 
@@ -338,7 +452,7 @@ msgstr "Nieznaleziony moduł RPC::XML::Client, brak możliwości pingowania"
 msgid "failed to run dot"
 msgstr "awaria w trakcie uruchamiania dot"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr ""
@@ -356,17 +470,17 @@ msgstr ""
 "Awaria w trakcie ładowania perlowego modułu Markdown.pm (%s) lub "
 "uruchamiania programu /usr/bin/markdown (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 #, fuzzy
 msgid "stylesheet not found"
 msgstr "nieznaleziony szablon ze stylami CSS"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "nieznaleziony kanał RSS"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "nieznaleziony kanał RSS"
@@ -553,17 +667,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "brakujące wartości"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -584,16 +688,16 @@ msgstr ""
 msgid "%s is not a file"
 msgstr "Strona %s nie może być edytowana"
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -631,20 +735,20 @@ msgstr "renderowanie %s"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "aktualizacja stron wiki %s: %s przez użytkownika %s"
@@ -663,11 +767,12 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 #, fuzzy
 msgid "missing name or url parameter"
 msgstr "brakujący parametr name lub url"
@@ -675,7 +780,7 @@ msgstr "brakujący parametr name lub url"
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, fuzzy, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "skrót %s wskazuje na adres <i>%s</i>"
@@ -726,34 +831,34 @@ msgstr "awaria w trakcie uruchamiania php"
 msgid "cannot find file"
 msgstr "nie można znaleźć pliku"
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr "nieznany format danych"
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr "brak danych"
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr "Bezpośrednie pobieranie danych"
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, fuzzy, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "awaria w trakcie przetwarzania linii %d: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 #, fuzzy
 msgid "missing id parameter"
 msgstr "brakujący parametr id"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "nieznaleziony szablon %s"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 #, fuzzy
 msgid "failed to process:"
 msgstr "awaria w trakcie przetwarzania:"
@@ -781,10 +886,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -813,6 +914,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "pomijanie nieprawidłowej nazwy pliku %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -877,16 +988,16 @@ msgstr "ikiwiki: awaria w trakcie tworzenia %s"
 msgid "cannot read %s: %s"
 msgstr "awaria w trakcie odczytu %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -903,21 +1014,14 @@ msgstr "awaria w trakcie tworzenia osłony używającej pliku konfiguracyjnego"
 msgid "wrapper filename not specified"
 msgstr "nieokreślona nazwa pliku osłony"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "awaria w trakcie zapisu %s: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "awaria w trakcie kompilowania %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "pomyślnie utworzono %s"
@@ -930,43 +1034,43 @@ msgstr "użycie: ikiwiki [parametry] źródło cel"
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "tworzenie osłon..."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "przebudowywanie wiki..."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "odświeżanie wiki..."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr ""
 "Użycie parametru --cgi wymaga podania adresu URL do wiki za pomocą parametru "
 "--url"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "polecenie preprocesora %s wykryte w %s na głębokości %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -983,13 +1087,23 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "awaria w trakcie zapisu %s: %s"
+
+#, fuzzy
+#~ msgid "failed to find url in html"
+#~ msgstr "awaria w trakcie wyszukiwania adresu URL na stronie HTML"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "kanał RSS przetworzony w dniu %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "Wiadomość z hasłem została wysłana."
 
index cf5341af03a93daf9cf588f51e5eb1e585f56b4a..eeeac88f8c1d5aad7dcf0a56f658a1d32045844f 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-01-10 23:47+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -19,109 +19,115 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Du måste logga in först."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 #, fuzzy
 msgid "Preferences"
 msgstr "Inställningar sparades."
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Inställningar sparades."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Du är bannlyst."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Fel"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, fuzzy, perl-format
 msgid "missing %s parameter"
 msgstr "mall saknar id-parameter"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "ny kanal"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "inlägg"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "ny"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "låter %s gå ut (%s dagar gammal)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "låter %s gå ut"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "behandlad ok på %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "kontrollerar kanalen %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "kunde inte hitta kanalen på %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 #, fuzzy
 msgid "feed not found"
 msgstr "mallen %s hittades inte"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "kanalen kraschade XML::Feed!"
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "skapar nya sidan %s"
@@ -130,7 +136,7 @@ msgstr "skapar nya sidan %s"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "klar"
 
@@ -153,29 +159,35 @@ msgstr "Misslyckades med att skicka e-post"
 msgid "Failed to delete file from S3: "
 msgstr "misslyckades med att skriva %s: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -190,6 +202,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "Det finns inga trasiga länkar!"
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "skapar %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -211,19 +288,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "tar bort gammal sida %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "skapar %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "redigerar %s"
@@ -248,14 +325,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "misslyckades med att behandla mall:"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "fortune misslyckades"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Måste ange %s när sökinsticket används"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
 #, fuzzy
-msgid "failed to find url in html"
-msgstr "googlecalendar misslyckades med att hitta url i html"
+msgid "missing page"
+msgstr "mall saknar id-parameter"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 #, fuzzy
@@ -292,39 +402,43 @@ msgstr "misslyckades med att skriva %s: %s"
 msgid "failed to determine size of image %s"
 msgstr "misslyckades med att skriva %s: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr "Måste ange url till wiki med --url när --rss eller --atom används"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "mallen %s hittades inte"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "mall saknar id-parameter"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "okänd sorteringstyp %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Diskussion"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "RPC::XML::Client hittades inte, pingar inte"
 
@@ -333,7 +447,7 @@ msgstr "RPC::XML::Client hittades inte, pingar inte"
 msgid "failed to run dot"
 msgstr "linkmap misslyckades att köra dot"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr "%s är låst av %s och kan inte redigeras"
@@ -349,17 +463,17 @@ msgstr ""
 "misslyckades med att läsa in Perl-modulen Markdown.pm (%s) eller /usr/bin/"
 "markdown (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 #, fuzzy
 msgid "stylesheet not found"
 msgstr "mallen %s hittades inte"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "mallen %s hittades inte"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "mallen %s hittades inte"
@@ -545,17 +659,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "mall saknar id-parameter"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -574,16 +678,16 @@ msgstr "%s är låst av %s och kan inte redigeras"
 msgid "%s is not a file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -621,20 +725,20 @@ msgstr "ritar upp %s"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "uppdatering av %s, %s av %s"
@@ -653,11 +757,12 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 #, fuzzy
 msgid "missing name or url parameter"
 msgstr "genväg saknar parameter för namn eller url"
@@ -665,7 +770,7 @@ msgstr "genväg saknar parameter för namn eller url"
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, fuzzy, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "genvägen %s pekar på %s"
@@ -716,34 +821,34 @@ msgstr "linkmap misslyckades att köra dot"
 msgid "cannot find file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, fuzzy, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "misslyckades med att skriva %s: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 #, fuzzy
 msgid "missing id parameter"
 msgstr "mall saknar id-parameter"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "mallen %s hittades inte"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 #, fuzzy
 msgid "failed to process:"
 msgstr "misslyckades med att behandla mall:"
@@ -770,10 +875,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -802,6 +903,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "hoppar över felaktigt filnamn %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -866,16 +977,16 @@ msgstr "ikiwiki: kan inte rita upp %s"
 msgid "cannot read %s: %s"
 msgstr "kan inte läsa %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -892,21 +1003,14 @@ msgstr "kan inte skapa en wrapper som använder en konfigurationsfil"
 msgid "wrapper filename not specified"
 msgstr "filnamn för wrapper har inte angivits"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "misslyckades med att skriva %s: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "misslyckades med att kompilera %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "generering av %s lyckades"
@@ -919,41 +1023,41 @@ msgstr "användning: ikiwiki [flaggor] källa mål"
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "genererar wrappers.."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "bygger om wiki.."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "uppdaterar wiki.."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr "Måste ange url till wiki med --url när --cgi används"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "%s förbehandlingsslinga detekterades på %s, djup %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -970,13 +1074,23 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "misslyckades med att skriva %s: %s"
+
+#, fuzzy
+#~ msgid "failed to find url in html"
+#~ msgstr "googlecalendar misslyckades med att hitta url i html"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "behandlad ok på %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "Ditt lösenord har skickats till dig via e-post."
 
index c988f38d970555f9b553f8079030e6f0c6b73211..719e998892f5889599ed5f8b813534051ca507f2 100644 (file)
--- a/po/vi.po
+++ b/po/vi.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: ikiwiki\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-29 17:12-0400\n"
+"POT-Creation-Date: 2009-04-04 14:59-0400\n"
 "PO-Revision-Date: 2007-01-13 15:31+1030\n"
 "Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
 "Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
@@ -20,109 +20,115 @@ msgstr ""
 msgid "You need to log in first."
 msgstr "Trước tiên bạn cần phải đăng nhập."
 
-#: ../IkiWiki/CGI.pm:145
+#: ../IkiWiki/CGI.pm:146
+msgid ""
+"probable misconfiguration: sslcookie is set, but you are attepting to login "
+"via http, not https"
+msgstr ""
+
+#: ../IkiWiki/CGI.pm:149
 msgid "login failed, perhaps you need to turn on cookies?"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:163 ../IkiWiki/Plugin/editpage.pm:350
+#: ../IkiWiki/CGI.pm:168 ../IkiWiki/CGI.pm:299
 msgid "Your login session has expired."
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:184
+#: ../IkiWiki/CGI.pm:189
 msgid "Login"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:185
+#: ../IkiWiki/CGI.pm:190
 #, fuzzy
 msgid "Preferences"
 msgstr "Tùy thích đã được lưu."
 
-#: ../IkiWiki/CGI.pm:186
+#: ../IkiWiki/CGI.pm:191
 msgid "Admin"
 msgstr ""
 
-#: ../IkiWiki/CGI.pm:253
+#: ../IkiWiki/CGI.pm:231
 msgid "Preferences saved."
 msgstr "Tùy thích đã được lưu."
 
-#: ../IkiWiki/CGI.pm:271
+#: ../IkiWiki/CGI.pm:262
 msgid "You are banned."
 msgstr "Bạn bị cấm ra."
 
-#: ../IkiWiki/CGI.pm:385 ../IkiWiki/CGI.pm:386 ../IkiWiki.pm:1153
+#: ../IkiWiki/CGI.pm:390 ../IkiWiki/CGI.pm:391 ../IkiWiki.pm:1211
 msgid "Error"
 msgstr "Lỗi"
 
-#: ../IkiWiki/Plugin/aggregate.pm:80
+#: ../IkiWiki/Plugin/aggregate.pm:84
 msgid "Aggregation triggered via web."
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:89
+#: ../IkiWiki/Plugin/aggregate.pm:93
 msgid "Nothing to do right now, all feeds are up-to-date!"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:216
+#: ../IkiWiki/Plugin/aggregate.pm:220
 #, fuzzy, perl-format
 msgid "missing %s parameter"
 msgstr "mẫu thiếu tham số id"
 
-#: ../IkiWiki/Plugin/aggregate.pm:250
+#: ../IkiWiki/Plugin/aggregate.pm:255
 msgid "new feed"
 msgstr "nguồn tin mới"
 
-#: ../IkiWiki/Plugin/aggregate.pm:264
+#: ../IkiWiki/Plugin/aggregate.pm:269
 msgid "posts"
 msgstr "bài"
 
-#: ../IkiWiki/Plugin/aggregate.pm:266
+#: ../IkiWiki/Plugin/aggregate.pm:271
 msgid "new"
 msgstr "mới"
 
-#: ../IkiWiki/Plugin/aggregate.pm:429
+#: ../IkiWiki/Plugin/aggregate.pm:435
 #, perl-format
 msgid "expiring %s (%s days old)"
 msgstr "đang mãn hạn %s (cũ %s ngày)"
 
-#: ../IkiWiki/Plugin/aggregate.pm:436
+#: ../IkiWiki/Plugin/aggregate.pm:442
 #, perl-format
 msgid "expiring %s"
 msgstr "đang mãn hạn %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:463
+#: ../IkiWiki/Plugin/aggregate.pm:469
 #, perl-format
-msgid "processed ok at %s"
-msgstr "đã xử lý được ở %s"
+msgid "last checked %s"
+msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:467
+#: ../IkiWiki/Plugin/aggregate.pm:473
 #, perl-format
 msgid "checking feed %s ..."
 msgstr "đang kiểm tra nguồn tin %s ..."
 
-#: ../IkiWiki/Plugin/aggregate.pm:472
+#: ../IkiWiki/Plugin/aggregate.pm:478
 #, perl-format
 msgid "could not find feed at %s"
 msgstr "không tìm thấy nguồn tin ở %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:487
+#: ../IkiWiki/Plugin/aggregate.pm:497
 #, fuzzy
 msgid "feed not found"
 msgstr "không tìm thấy mẫu %s"
 
-#: ../IkiWiki/Plugin/aggregate.pm:498
+#: ../IkiWiki/Plugin/aggregate.pm:508
 #, perl-format
 msgid "(invalid UTF-8 stripped from feed)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:504
+#: ../IkiWiki/Plugin/aggregate.pm:516
 #, perl-format
 msgid "(feed entities escaped)"
 msgstr ""
 
-#: ../IkiWiki/Plugin/aggregate.pm:510
+#: ../IkiWiki/Plugin/aggregate.pm:524
 msgid "feed crashed XML::Feed!"
 msgstr "nguồn tin đã gây ra XML::Feed sụp đổ."
 
-#: ../IkiWiki/Plugin/aggregate.pm:590
+#: ../IkiWiki/Plugin/aggregate.pm:610
 #, perl-format
 msgid "creating new page %s"
 msgstr "đang tạo trang mới %s"
@@ -131,7 +137,7 @@ msgstr "đang tạo trang mới %s"
 msgid "deleting bucket.."
 msgstr ""
 
-#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:199
+#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:210
 msgid "done"
 msgstr "xong"
 
@@ -154,29 +160,35 @@ msgstr "Lỗi gửi thư"
 msgid "Failed to delete file from S3: "
 msgstr "lỗi ghi %s: %s"
 
-#: ../IkiWiki/Plugin/attachment.pm:48
+#: ../IkiWiki/Plugin/attachment.pm:49
 #, perl-format
 msgid "there is already a page named %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:81
+#: ../IkiWiki/Plugin/attachment.pm:65
 msgid "prohibited by allowed_attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:188
+#: ../IkiWiki/Plugin/attachment.pm:140
 msgid "bad attachment filename"
 msgstr ""
 
-#: ../IkiWiki/Plugin/attachment.pm:230
+#: ../IkiWiki/Plugin/attachment.pm:182
 msgid "attachment upload"
 msgstr ""
 
-#: ../IkiWiki/Plugin/autoindex.pm:103
+#: ../IkiWiki/Plugin/autoindex.pm:105
 msgid "automatic index generation"
 msgstr ""
 
-#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:261
-#: ../IkiWiki/Plugin/inline.pm:323 ../IkiWiki/Plugin/opendiscussion.pm:26
+#: ../IkiWiki/Plugin/blogspam.pm:105
+msgid ""
+"Sorry, but that looks like spam to <a href=\"http://blogspam.net/"
+"\">blogspam</a>: "
+msgstr ""
+
+#: ../IkiWiki/Plugin/brokenlinks.pm:33 ../IkiWiki/Plugin/editpage.pm:233
+#: ../IkiWiki/Plugin/inline.pm:361 ../IkiWiki/Plugin/opendiscussion.pm:26
 #: ../IkiWiki/Plugin/orphans.pm:37 ../IkiWiki/Render.pm:79
 #: ../IkiWiki/Render.pm:149
 msgid "discussion"
@@ -191,6 +203,71 @@ msgstr ""
 msgid "There are no broken links!"
 msgstr "Không có liên kết bị ngắt nào."
 
+#: ../IkiWiki/Plugin/comments.pm:122 ../IkiWiki/Plugin/format.pm:23
+#, perl-format
+msgid "unsupported page format %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:127
+msgid "comment must have content"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:183
+msgid "Anonymous"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:326 ../IkiWiki/Plugin/editpage.pm:97
+msgid "bad page name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:331
+#, fuzzy, perl-format
+msgid "commenting on %s"
+msgstr "đang tạo %s"
+
+#: ../IkiWiki/Plugin/comments.pm:349
+#, perl-format
+msgid "page '%s' doesn't exist, so you can't comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:356
+#, perl-format
+msgid "comments on page '%s' are closed"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:450
+msgid "comment stored for moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:452
+msgid "Your comment will be posted after moderator review"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:465
+msgid "Added a comment"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:469
+#, perl-format
+msgid "Added a comment: %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:511 ../IkiWiki/Plugin/websetup.pm:236
+msgid "you are not logged in as an admin"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:562
+msgid "Comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:601
+msgid "comment moderation"
+msgstr ""
+
+#: ../IkiWiki/Plugin/comments.pm:752
+msgid "Comments"
+msgstr ""
+
 #: ../IkiWiki/Plugin/conditional.pm:27 ../IkiWiki/Plugin/cutpaste.pm:30
 #: ../IkiWiki/Plugin/cutpaste.pm:45 ../IkiWiki/Plugin/cutpaste.pm:61
 #: ../IkiWiki/Plugin/testpagespec.pm:26
@@ -212,19 +289,19 @@ msgstr ""
 msgid "removing old preview %s"
 msgstr "đang gỡ bỏ trang cũ %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:141
+#: ../IkiWiki/Plugin/editpage.pm:113
 #, perl-format
 msgid "%s is not an editable page"
 msgstr ""
 
-#: ../IkiWiki/Plugin/editpage.pm:317
+#: ../IkiWiki/Plugin/editpage.pm:289
 #, perl-format
 msgid "creating %s"
 msgstr "đang tạo %s"
 
-#: ../IkiWiki/Plugin/editpage.pm:335 ../IkiWiki/Plugin/editpage.pm:363
-#: ../IkiWiki/Plugin/editpage.pm:373 ../IkiWiki/Plugin/editpage.pm:408
-#: ../IkiWiki/Plugin/editpage.pm:453
+#: ../IkiWiki/Plugin/editpage.pm:307 ../IkiWiki/Plugin/editpage.pm:326
+#: ../IkiWiki/Plugin/editpage.pm:336 ../IkiWiki/Plugin/editpage.pm:380
+#: ../IkiWiki/Plugin/editpage.pm:419
 #, perl-format
 msgid "editing %s"
 msgstr "đang sửa %s"
@@ -249,14 +326,47 @@ msgstr ""
 msgid "failed to process"
 msgstr "mẫu không xử lý được:"
 
+#: ../IkiWiki/Plugin/format.pm:20
+msgid "must specify format and text"
+msgstr ""
+
 #: ../IkiWiki/Plugin/fortune.pm:27
 msgid "fortune failed"
 msgstr "fortune bị lỗi"
 
-#: ../IkiWiki/Plugin/googlecalendar.pm:32
+#: ../IkiWiki/Plugin/git.pm:626 ../IkiWiki/Plugin/git.pm:644
+#: ../IkiWiki/Receive.pm:129
+#, perl-format
+msgid "you are not allowed to change %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:666
+#, perl-format
+msgid "you cannot act on a file with mode %s"
+msgstr ""
+
+#: ../IkiWiki/Plugin/git.pm:670
+msgid "you are not allowed to change file modes"
+msgstr ""
+
+#: ../IkiWiki/Plugin/google.pm:27
+#, fuzzy, perl-format
+msgid "Must specify %s when using the google search plugin"
+msgstr "Cần phải xác định %s khi dùng bổ sung tìm kiếm"
+
+#: ../IkiWiki/Plugin/google.pm:31
+msgid "Failed to parse url, cannot determine domain name"
+msgstr ""
+
+#: ../IkiWiki/Plugin/goto.pm:49
 #, fuzzy
-msgid "failed to find url in html"
-msgstr "googlecalendar không tìm thấy địa chỉ URL trong mã HTML"
+msgid "missing page"
+msgstr "mẫu thiếu tham số id"
+
+#: ../IkiWiki/Plugin/goto.pm:51
+#, perl-format
+msgid "The page %s does not exist."
+msgstr ""
 
 #: ../IkiWiki/Plugin/graphviz.pm:67
 #, fuzzy
@@ -293,41 +403,45 @@ msgstr "lỗi ghi %s: %s"
 msgid "failed to determine size of image %s"
 msgstr "lỗi ghi %s: %s"
 
-#: ../IkiWiki/Plugin/inline.pm:93
+#: ../IkiWiki/Plugin/inline.pm:92
 msgid "Must specify url to wiki with --url when using --rss or --atom"
 msgstr ""
 "Cần phải xác định địa chỉ URL tới wiki với « --url » khi dùng « --rss » hay « --"
 "atom »"
 
-#: ../IkiWiki/Plugin/inline.pm:139
+#: ../IkiWiki/Plugin/inline.pm:138
 #, fuzzy
 msgid "page editing not allowed"
 msgstr "không tìm thấy mẫu %s"
 
-#: ../IkiWiki/Plugin/inline.pm:156
+#: ../IkiWiki/Plugin/inline.pm:155
 #, fuzzy
 msgid "missing pages parameter"
 msgstr "mẫu thiếu tham số id"
 
-#: ../IkiWiki/Plugin/inline.pm:204
+#: ../IkiWiki/Plugin/inline.pm:200
+msgid "Sort::Naturally needed for title_natural sort"
+msgstr ""
+
+#: ../IkiWiki/Plugin/inline.pm:211
 #, perl-format
 msgid "unknown sort type %s"
 msgstr "kiểu sắp xếp không rõ %s"
 
-#: ../IkiWiki/Plugin/inline.pm:282
+#: ../IkiWiki/Plugin/inline.pm:314
 msgid "Add a new post titled:"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:298
+#: ../IkiWiki/Plugin/inline.pm:334
 #, perl-format
 msgid "nonexistant template %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/inline.pm:331 ../IkiWiki/Render.pm:83
+#: ../IkiWiki/Plugin/inline.pm:369 ../IkiWiki/Render.pm:83
 msgid "Discussion"
 msgstr "Thảo luận"
 
-#: ../IkiWiki/Plugin/inline.pm:568
+#: ../IkiWiki/Plugin/inline.pm:600
 msgid "RPC::XML::Client not found, not pinging"
 msgstr "Không tìm thấy RPC::XML::Client nên không gửi gói tin ping"
 
@@ -336,7 +450,7 @@ msgstr "Không tìm thấy RPC::XML::Client nên không gửi gói tin ping"
 msgid "failed to run dot"
 msgstr "linkmap không chạy dot được"
 
-#: ../IkiWiki/Plugin/lockedit.pm:46 ../IkiWiki/Plugin/lockedit.pm:60
+#: ../IkiWiki/Plugin/lockedit.pm:47
 #, fuzzy, perl-format
 msgid "%s is locked and cannot be edited"
 msgstr "%s bị %s khoá nên không thể sửa được"
@@ -350,17 +464,17 @@ msgstr ""
 msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
 msgstr "lỗi nạp mô-đun perl Markdown.pm (%s) hay « /usr/bin/markdown » (%s)"
 
-#: ../IkiWiki/Plugin/meta.pm:150
+#: ../IkiWiki/Plugin/meta.pm:158
 #, fuzzy
 msgid "stylesheet not found"
 msgstr "không tìm thấy mẫu %s"
 
-#: ../IkiWiki/Plugin/meta.pm:184
+#: ../IkiWiki/Plugin/meta.pm:192
 #, fuzzy
 msgid "redir page not found"
 msgstr "không tìm thấy mẫu %s"
 
-#: ../IkiWiki/Plugin/meta.pm:197
+#: ../IkiWiki/Plugin/meta.pm:205
 #, fuzzy
 msgid "redir cycle is not allowed"
 msgstr "không tìm thấy mẫu %s"
@@ -546,17 +660,7 @@ msgstr ""
 msgid "need either `percent` or `totalpages` and `donepages` parameters"
 msgstr ""
 
-#: ../IkiWiki/Plugin/recentchanges.pm:100
-#, fuzzy
-msgid "missing page"
-msgstr "mẫu thiếu tham số id"
-
-#: ../IkiWiki/Plugin/recentchanges.pm:102
-#, perl-format
-msgid "The page %s does not exist."
-msgstr ""
-
-#: ../IkiWiki/Plugin/recentchangesdiff.pm:36
+#: ../IkiWiki/Plugin/recentchangesdiff.pm:37
 msgid "(Diff truncated)"
 msgstr ""
 
@@ -575,16 +679,16 @@ msgstr "%s bị %s khoá nên không thể sửa được"
 msgid "%s is not a file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:112
+#: ../IkiWiki/Plugin/remove.pm:115
 #, perl-format
 msgid "confirm removal of %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:148
+#: ../IkiWiki/Plugin/remove.pm:152
 msgid "Please select the attachments to remove."
 msgstr ""
 
-#: ../IkiWiki/Plugin/remove.pm:188
+#: ../IkiWiki/Plugin/remove.pm:192
 msgid "removed"
 msgstr ""
 
@@ -622,20 +726,20 @@ msgstr "đang vẽ %s"
 msgid "Also rename SubPages and attachments"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:223
+#: ../IkiWiki/Plugin/rename.pm:224
 msgid "Only one attachment can be renamed at a time."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:226
+#: ../IkiWiki/Plugin/rename.pm:227
 msgid "Please select the attachment to rename."
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:332
+#: ../IkiWiki/Plugin/rename.pm:338
 #, perl-format
 msgid "rename %s to %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/rename.pm:484
+#: ../IkiWiki/Plugin/rename.pm:493
 #, fuzzy, perl-format
 msgid "update for rename of %s to %s"
 msgstr "cập nhật %2$s của %1$s bởi %3$s"
@@ -654,11 +758,12 @@ msgstr ""
 msgid "search"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:27
-msgid "shortcut plugin will not work without a shortcuts.mdwn"
+#: ../IkiWiki/Plugin/shortcut.pm:31
+#, perl-format
+msgid "shortcut plugin will not work without %s"
 msgstr ""
 
-#: ../IkiWiki/Plugin/shortcut.pm:36
+#: ../IkiWiki/Plugin/shortcut.pm:44
 #, fuzzy
 msgid "missing name or url parameter"
 msgstr "lối tắt thiếu tên hay tham số url"
@@ -666,7 +771,7 @@ msgstr "lối tắt thiếu tên hay tham số url"
 #. translators: This is used to display what shortcuts are defined.
 #. translators: First parameter is the name of the shortcut, the second
 #. translators: is an URL.
-#: ../IkiWiki/Plugin/shortcut.pm:45
+#: ../IkiWiki/Plugin/shortcut.pm:54
 #, fuzzy, perl-format
 msgid "shortcut %s points to <i>%s</i>"
 msgstr "lối tắt %s chỉ tới %s"
@@ -717,34 +822,34 @@ msgstr "linkmap không chạy dot được"
 msgid "cannot find file"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:73
+#: ../IkiWiki/Plugin/table.pm:87
 msgid "unknown data format"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:81
+#: ../IkiWiki/Plugin/table.pm:95
 msgid "empty data"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:100
+#: ../IkiWiki/Plugin/table.pm:114
 msgid "Direct data download"
 msgstr ""
 
-#: ../IkiWiki/Plugin/table.pm:134
+#: ../IkiWiki/Plugin/table.pm:148
 #, fuzzy, perl-format
 msgid "parse fail at line %d: %s"
 msgstr "lỗi ghi %s: %s"
 
-#: ../IkiWiki/Plugin/template.pm:28
+#: ../IkiWiki/Plugin/template.pm:29
 #, fuzzy
 msgid "missing id parameter"
 msgstr "mẫu thiếu tham số id"
 
-#: ../IkiWiki/Plugin/template.pm:35
+#: ../IkiWiki/Plugin/template.pm:36
 #, perl-format
 msgid "template %s not found"
 msgstr "không tìm thấy mẫu %s"
 
-#: ../IkiWiki/Plugin/template.pm:54
+#: ../IkiWiki/Plugin/template.pm:55
 #, fuzzy
 msgid "failed to process:"
 msgstr "mẫu không xử lý được:"
@@ -771,10 +876,6 @@ msgstr ""
 msgid "enable %s?"
 msgstr ""
 
-#: ../IkiWiki/Plugin/websetup.pm:236
-msgid "you are not logged in as an admin"
-msgstr ""
-
 #: ../IkiWiki/Plugin/websetup.pm:240
 msgid "setup file for this wiki is not known"
 msgstr ""
@@ -803,6 +904,16 @@ msgstr ""
 msgid "<p class=\"error\">Error: %s exited nonzero (%s)"
 msgstr ""
 
+#: ../IkiWiki/Receive.pm:35
+#, perl-format
+msgid "cannot determine id of untrusted committer %s"
+msgstr ""
+
+#: ../IkiWiki/Receive.pm:85
+#, fuzzy, perl-format
+msgid "bad file name %s"
+msgstr "đang bỏ qua tên tập tin sai %s"
+
 #: ../IkiWiki/Render.pm:253
 #, perl-format
 msgid ""
@@ -867,16 +978,16 @@ msgstr "ikiwiki: không thể vẽ %s"
 msgid "cannot read %s: %s"
 msgstr "không thể đọc %s: %s"
 
-#: ../IkiWiki/Setup/Automator.pm:33
+#: ../IkiWiki/Setup/Automator.pm:34
 msgid "you must enter a wikiname (that contains alphanumerics)"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:67
+#: ../IkiWiki/Setup/Automator.pm:68
 #, perl-format
 msgid "unsupported revision control system %s"
 msgstr ""
 
-#: ../IkiWiki/Setup/Automator.pm:83
+#: ../IkiWiki/Setup/Automator.pm:94
 msgid "failed to set up the repository with ikiwiki-makerepo"
 msgstr ""
 
@@ -893,21 +1004,14 @@ msgstr "không thể tạo bộ bao bọc sử dụng tập tin thiết lập"
 msgid "wrapper filename not specified"
 msgstr "chưa xác định tên tập tin bộ bao bọc"
 
-#. translators: The first parameter is a filename, and the second is
-#. translators: a (probably not translated) error message.
-#: ../IkiWiki/Wrapper.pm:48
-#, perl-format
-msgid "failed to write %s: %s"
-msgstr "lỗi ghi %s: %s"
-
 #. translators: The parameter is a C filename.
-#: ../IkiWiki/Wrapper.pm:99
+#: ../IkiWiki/Wrapper.pm:152
 #, perl-format
 msgid "failed to compile %s"
 msgstr "lỗi biên dịch %s"
 
 #. translators: The parameter is a filename.
-#: ../IkiWiki/Wrapper.pm:119
+#: ../IkiWiki/Wrapper.pm:172
 #, perl-format
 msgid "successfully generated %s"
 msgstr "%s đã được tạo ra"
@@ -920,41 +1024,41 @@ msgstr "cách sử dụng: ikiwiki [tùy chọn] nguồn đích"
 msgid "       ikiwiki --setup configfile"
 msgstr ""
 
-#: ../ikiwiki.in:90
+#: ../ikiwiki.in:91
 msgid "usage: --set var=value"
 msgstr ""
 
-#: ../ikiwiki.in:137
+#: ../ikiwiki.in:140
 msgid "generating wrappers.."
 msgstr "đang tạo ra các bộ bao bọc.."
 
-#: ../ikiwiki.in:188
+#: ../ikiwiki.in:199
 msgid "rebuilding wiki.."
 msgstr "đang xây dựng lại wiki.."
 
-#: ../ikiwiki.in:191
+#: ../ikiwiki.in:202
 msgid "refreshing wiki.."
 msgstr "đang làm tươi wiki.."
 
-#: ../IkiWiki.pm:458
+#: ../IkiWiki.pm:480
 msgid "Must specify url to wiki with --url when using --cgi"
 msgstr "Cần phải xác định địa chỉ URL tới wiki với « --url » khi dùng « --cgi »"
 
-#: ../IkiWiki.pm:504
+#: ../IkiWiki.pm:526
 msgid "cannot use multiple rcs plugins"
 msgstr ""
 
-#: ../IkiWiki.pm:533
+#: ../IkiWiki.pm:555
 #, perl-format
 msgid "failed to load external plugin needed for %s plugin: %s"
 msgstr ""
 
-#: ../IkiWiki.pm:1136
+#: ../IkiWiki.pm:1194
 #, fuzzy, perl-format
 msgid "preprocessing loop detected on %s at depth %i"
 msgstr "vòng lặp tiền xử lý %s được phát hiện trên %s ở độ sâu %i"
 
-#: ../IkiWiki.pm:1645
+#: ../IkiWiki.pm:1732
 msgid "yes"
 msgstr ""
 
@@ -971,13 +1075,23 @@ msgid "What revision control system to use?"
 msgstr ""
 
 #: ../auto.setup:20
-msgid "What wiki user (or openid) will be wiki admin?"
+msgid "What wiki user (or openid) will be admin?"
 msgstr ""
 
 #: ../auto.setup:23
 msgid "What is the domain name of the web server?"
 msgstr ""
 
+#~ msgid "failed to write %s: %s"
+#~ msgstr "lỗi ghi %s: %s"
+
+#, fuzzy
+#~ msgid "failed to find url in html"
+#~ msgstr "googlecalendar không tìm thấy địa chỉ URL trong mã HTML"
+
+#~ msgid "processed ok at %s"
+#~ msgstr "đã xử lý được ở %s"
+
 #~ msgid "Your password has been emailed to you."
 #~ msgstr "Mật khẩu đã được gửi đính kèm thư cho bạn."
 
diff --git a/t/404.t b/t/404.t
new file mode 100755 (executable)
index 0000000..0bb3c60
--- /dev/null
+++ b/t/404.t
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 17;
+
+BEGIN { use_ok("IkiWiki::Plugin::404"); }
+
+sub cgi_page_from_404 {
+       return IkiWiki::Plugin::404::cgi_page_from_404(shift, shift, shift);
+}
+
+$IkiWiki::config{htmlext} = 'html';
+
+is(cgi_page_from_404('/', 'http://example.com', 1), 'index');
+is(cgi_page_from_404('/index.html', 'http://example.com', 0), 'index');
+is(cgi_page_from_404('/', 'http://example.com/', 1), 'index');
+is(cgi_page_from_404('/index.html', 'http://example.com/', 0), 'index');
+
+is(cgi_page_from_404('/~user/foo/bar', 'http://example.com/~user', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar/index.html', 'http://example.com/~user', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar/', 'http://example.com/~user', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar.html', 'http://example.com/~user', 0),
+   'foo/bar');
+
+is(cgi_page_from_404('/~user/foo/bar', 'http://example.com/~user/', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar/index.html', 'http://example.com/~user/', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar/', 'http://example.com/~user/', 1),
+   'foo/bar');
+is(cgi_page_from_404('/~user/foo/bar.html', 'http://example.com/~user/', 0),
+   'foo/bar');
+
+is(cgi_page_from_404('/~user/foo', 'https://example.com/~user', 1),
+   'foo');
+is(cgi_page_from_404('/~user/foo/index.html', 'https://example.com/~user', 1),
+   'foo');
+is(cgi_page_from_404('/~user/foo/', 'https://example.com/~user', 1),
+   'foo');
+is(cgi_page_from_404('/~user/foo.html', 'https://example.com/~user', 0),
+   'foo');
index 0a6b2c39ef3538de2bf3189683fde1f191553c31..41768f7820a093676460395bf7831e0e78050560 100644 (file)
@@ -1 +1 @@
-[[brokenlinks ]]
+[[!brokenlinks ]]
diff --git a/t/beautify_urlpath.t b/t/beautify_urlpath.t
new file mode 100755 (executable)
index 0000000..94b923d
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 8;
+
+BEGIN { use_ok("IkiWiki"); }
+
+$IkiWiki::config{usedirs} = 1;
+$IkiWiki::config{htmlext} = "HTML";
+is(IkiWiki::beautify_urlpath("foo/bar"), "./foo/bar");
+is(IkiWiki::beautify_urlpath("../badger"), "../badger");
+is(IkiWiki::beautify_urlpath("./bleh"), "./bleh");
+is(IkiWiki::beautify_urlpath("foo/index.HTML"), "./foo/");
+is(IkiWiki::beautify_urlpath("index.HTML"), "./");
+is(IkiWiki::beautify_urlpath("../index.HTML"), "../");
+$IkiWiki::config{usedirs} = 0;
+is(IkiWiki::beautify_urlpath("foo/index.HTML"), "./foo/index.HTML");
diff --git a/t/git.t b/t/git.t
index b3aa6a80b7d3556d16cfd03e28ce1461b092ee77..f1c24b3598e1709d9d58a9f962df4fef1f12a3f1 100755 (executable)
--- a/t/git.t
+++ b/t/git.t
@@ -3,19 +3,17 @@ use warnings;
 use strict;
 
 my $dir;
-my $gitrepo;
 BEGIN {
        $dir="/tmp/ikiwiki-test-git.$$";
-       $gitrepo="$dir/repo";
        my $git=`which git`;
        chomp $git;
-       if (! -x $git || ! mkdir($dir) || ! mkdir($gitrepo)) {
+       if (! -x $git || ! mkdir($dir)) {
                eval q{
-                       use Test::More skip_all => "git not available or could not make test dirs"
+                       use Test::More skip_all => "git not available or could not make test dir"
                }
        }
 }
-use Test::More tests => 16;
+use Test::More tests => 18;
 
 BEGIN { use_ok("IkiWiki"); }
 
@@ -25,17 +23,16 @@ $config{srcdir} = "$dir/src";
 IkiWiki::loadplugins();
 IkiWiki::checkconfig();
 
-system "cd $gitrepo && git init >/dev/null 2>&1";
-system "cd $gitrepo && echo dummy > dummy; git add . >/dev/null 2>&1";
-system "cd $gitrepo && git commit -m Initial >/dev/null 2>&1";
-system "git clone -l -s $gitrepo $config{srcdir} >/dev/null 2>&1";
+ok (mkdir($config{srcdir}));
+is (system("./ikiwiki-makerepo git $config{srcdir} $dir/repo"), 0);
 
 my @changes;
 @changes = IkiWiki::rcs_recentchanges(3);
 
 is($#changes, 0); # counts for dummy commit during repo creation
-is($changes[0]{message}[0]{"line"}, "Initial");
-is($changes[0]{pages}[0]{"page"}, "dummy");
+# ikiwiki-makerepo's first commit is setting up the .gitignore
+is($changes[0]{message}[0]{"line"}, "initial commit");
+is($changes[0]{pages}[0]{"page"}, ".gitignore");
 
 # Web commit
 my $test1 = readfile("t/test1.mdwn");
diff --git a/t/htmlbalance.t b/t/htmlbalance.t
new file mode 100755 (executable)
index 0000000..e5a5db0
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+BEGIN {
+       eval q{
+               use HTML::TreeBuilder;
+       };
+       if ($@) {
+               eval q{use Test::More skip_all => "HTML::TreeBuilder not available"};
+       }
+       else {
+               eval q{use Test::More tests => 7};
+       }
+       use_ok("IkiWiki::Plugin::htmlbalance");
+}
+
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "<br></br>"), "<br />");
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "<div><p b=\"c\">hello world</div>"), "<div><p b=\"c\">hello world</p></div>");
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "<a></a></a>"), "<a></a>");
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "<b>foo <a</b>"), "<b>foo </b>");
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "<b> foo <a</a></b>"), "<b> foo </b>");
+is(IkiWiki::Plugin::htmlbalance::sanitize(content => "a>"), "a&gt;");
diff --git a/t/openiduser.t b/t/openiduser.t
new file mode 100755 (executable)
index 0000000..52d8794
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+BEGIN {
+       eval q{
+               use Net::OpenID::VerifiedIdentity;
+       };
+       if ($@) {
+               eval q{use Test::More skip_all => "Net::OpenID::VerifiedIdentity not available"};
+       }
+       else {
+               eval q{use Test::More tests => 9};
+       }
+       use_ok("IkiWiki::Plugin::openid");
+}
+
+# Some typical examples:
+
+# This test, when run by Test::Harness using perl -w, exposes a warning in
+# Net::OpenID::VerifiedIdentity. Normally that warning is not displayed, as
+# that module does not use warnings. To avoid cluttering the test output,
+# disable the -w switch temporarily.
+$^W=0;
+is(IkiWiki::openiduser('http://josephturian.blogspot.com'), 'josephturian [blogspot.com]');
+$^W=1;
+
+is(IkiWiki::openiduser('http://yam655.livejournal.com/'), 'yam655 [livejournal.com]');
+is(IkiWiki::openiduser('http://id.mayfirst.org/jamie/'), 'jamie [id.mayfirst.org]');
+
+# and some less typical ones taken from the ikiwiki commit history
+
+is(IkiWiki::openiduser('http://thm.id.fedoraproject.org/'), 'thm [id.fedoraproject.org]');
+is(IkiWiki::openiduser('http://dtrt.org/'), 'dtrt.org');
+is(IkiWiki::openiduser('http://alcopop.org/me/openid/'), 'openid [alcopop.org/me]');
+is(IkiWiki::openiduser('http://id.launchpad.net/882/bielawski1'), 'bielawski1 [id.launchpad.net/882]');
+is(IkiWiki::openiduser('http://technorati.com/people/technorati/drajt'), 'drajt [technorati.com/people/technorati]');
index c7f1ce1801d92ee470f901e7f9f1eca35a6fa6fb..540d10f4c0bcc4a4a020674a0574e89ce42b3214 100755 (executable)
@@ -1,14 +1,35 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 5;
+use Test::More tests => 19;
 
 BEGIN { use_ok("IkiWiki"); }
 
-# Used internally.
-$IkiWiki::hooks{htmlize}{mdwn}{call}=sub {};
-
+# define mdwn as an extension
+$IkiWiki::hooks{htmlize}{mdwn}={};
+is(pagetype("foo.mdwn"), "mdwn");
 is(pagename("foo.mdwn"), "foo");
+is(pagetype("foo/bar.mdwn"), "mdwn");
 is(pagename("foo/bar.mdwn"), "foo/bar");
+
+# bare files get the full filename as page name, undef type
+is(pagetype("foo.png"), undef);
 is(pagename("foo.png"), "foo.png");
+is(pagetype("foo/bar.png"), undef);
+is(pagename("foo/bar.png"), "foo/bar.png");
+is(pagetype("foo"), undef);
 is(pagename("foo"), "foo");
+
+# keepextension preserves the extension in the page name
+$IkiWiki::hooks{htmlize}{txt}={keepextension => 1};
+is(pagename("foo.txt"), "foo.txt");
+is(pagetype("foo.txt"), "txt");
+is(pagename("foo/bar.txt"), "foo/bar.txt");
+is(pagetype("foo/bar.txt"), "txt");
+
+# noextension makes extensionless files be treated as first-class pages
+$IkiWiki::hooks{htmlize}{Makefile}={noextension =>1};
+is(pagetype("Makefile"), "Makefile");
+is(pagename("Makefile"), "Makefile");
+is(pagetype("foo/Makefile"), "Makefile");
+is(pagename("foo/Makefile"), "foo/Makefile");
index c61d1612285944c96f05c99ef02dded5ac1edb0a..69cf361de4ed6aa4fa3cb591aa5c3481cab46a49 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 56;
+use Test::More tests => 51;
 
 BEGIN { use_ok("IkiWiki"); }
 
@@ -40,6 +40,7 @@ $links{"bugs/bar"}=[qw{done}];
 $links{"done"}=[];
 $links{"examples/softwaresite/bugs/fails_to_frobnicate"}=[qw{done}];
 $links{"examples/softwaresite/bugs/done"}=[];
+$links{"ook"}=[qw{/blog/tags/foo}];
 
 ok(pagespec_match("foo", "link(bar)"), "link");
 ok(pagespec_match("foo", "link(ba?)"), "glob link");
@@ -55,6 +56,8 @@ ok(pagespec_match("bar", "backlink(foo)"), "backlink");
 ok(! pagespec_match("quux", "backlink(foo)"), "failed backlink");
 ok(! pagespec_match("bar", ""), "empty pagespec should match nothing");
 ok(! pagespec_match("bar", "           "), "blank pagespec should match nothing");
+ok(pagespec_match("ook", "link(blog/tags/foo)"), "link internal absolute success");
+ok(pagespec_match("ook", "link(/blog/tags/foo)"), "link explicit absolute success");
 
 $IkiWiki::pagectime{foo}=1154532692; # Wed Aug  2 11:26 EDT 2006
 $IkiWiki::pagectime{bar}=1154532695; # after
@@ -74,12 +77,3 @@ ok(! pagespec_match("foo", "no_such_function(foo)"), "foo");
 my $ret=pagespec_match("foo", "(invalid");
 ok(! $ret, "syntax error");
 ok($ret =~ /syntax error/, "error message");
-
-# old style globlists
-ok(pagespec_match("foo", "foo bar"), "simple list");
-ok(pagespec_match("bar", "foo bar"), "simple list 2");
-ok(pagespec_match("foo", "f?? !foz"));
-ok(! pagespec_match("foo", "f?? !foo"));
-ok(! pagespec_match("foo", "* !foo"));
-ok(! pagespec_match("foo", "foo !foo"));
-ok(! pagespec_match("foo.png", "* !*.*"));
index cbb06219c15184d82caf320b5842f16de74daf6a..9e38d576164c184ada3bd48646126fe818259250 100755 (executable)
@@ -28,17 +28,17 @@ ok(same("!foo", "!bar", "foo"), "double inversion failed match");
 ok(same("!foo", "!bar", "bar"), "double inversion failed match 2");
 ok(same("*", "!bar", "foo"), "glob+inversion match");
 ok(same("*", "!bar", "bar"), "matching glob and matching inversion");
-ok(same("* !foo", "!bar", "bar"), "matching glob and matching inversion");
-ok(same("* !foo", "!bar", "foo"), "matching glob with matching inversion and non-matching inversion");
-ok(same("* !foo", "!foo", "foo"), "matching glob with matching inversion and matching inversion");
+ok(same("* and !foo", "!bar", "bar"), "matching glob and matching inversion");
+ok(same("* and !foo", "!bar", "foo"), "matching glob with matching inversion and non-matching inversion");
+ok(same("* and !foo", "!foo", "foo"), "matching glob with matching inversion and matching inversion");
 ok(same("b??", "!b??", "bar"), "matching glob and matching inverted glob");
 ok(same("f?? !f??", "!bar", "bar"), "matching glob and matching inverted glob");
 ok(same("b??", "!b?z", "bar"), "matching glob and non-matching inverted glob");
 ok(same("f?? !f?z", "!bar", "bar"), "matching glob and non-matching inverted glob");
 ok(same("!foo bar baz", "!bar", "bar"), "matching list and matching inversion");
 ok(pagespec_match("foo/Discussion",
-       IkiWiki::pagespec_merge("* !*/Discussion", "*/Discussion")), "should match");
-ok(same("* !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1");
-ok(same("*/Discussion", "* !*/Discussion", "foo/Discussion"), "Discussion merge 2");
+       IkiWiki::pagespec_merge("* and !*/Discussion", "*/Discussion")), "should match");
+ok(same("* and !*/Discussion", "*/Discussion", "foo/Discussion"), "Discussion merge 1");
+ok(same("*/Discussion", "* and !*/Discussion", "foo/Discussion"), "Discussion merge 2");
 ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/Discussion"), "bidirectional merge 1");
 ok(same("*/Discussion !*/bar", "*/bar !*/Discussion", "foo/bar"), "bidirectional merge 2");
diff --git a/t/pagetype.mdwn b/t/pagetype.mdwn
deleted file mode 100755 (executable)
index 76cacd8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/perl
-use warnings;
-use strict;
-use Test::More tests => 5;
-
-BEGIN { use_ok("IkiWiki"); }
-
-# Used internally.
-$IkiWiki::hooks{htmlize}{mdwn}=1;
-
-is(pagetype("foo.mdwn"), "mdwn");
-is(pagetype("foo/bar.mdwn"), "mdwn");
-is(pagename("foo.png"), undef);
-is(pagename("foo"), undef);
index 010c85de176b49373a879e2227edd4d1653f5fe1..72ba7846aa3620f124b8205e21c5f65fcf1cecae 100644 (file)
@@ -1 +1 @@
-[[inline pages="post" rss=yes]]
+[[!inline pages="post" rss=yes]]
diff --git a/t/yesno.t b/t/yesno.t
new file mode 100755 (executable)
index 0000000..60a8c07
--- /dev/null
+++ b/t/yesno.t
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More tests => 10;
+
+BEGIN { use_ok("IkiWiki"); }
+
+# note: yesno always accepts English even if localized.
+# So no need to bother setting locale to C.
+
+ok(IkiWiki::yesno("yes") == 1);
+ok(IkiWiki::yesno("Yes") == 1);
+ok(IkiWiki::yesno("YES") == 1);
+
+ok(IkiWiki::yesno("no") == 0);
+ok(IkiWiki::yesno("No") == 0);
+ok(IkiWiki::yesno("NO") == 0);
+
+ok(IkiWiki::yesno("1") == 1);
+ok(IkiWiki::yesno("0") == 0);
+ok(IkiWiki::yesno("mooooooooooo") == 0);
index 1ff7f4f4eff5a2a4e4e1ce3d989faaad8401d1b6..768695a2ca0d434e376cdf1b1de7325376b5aa49 100644 (file)
          <TMPL_VAR CONTENT ESCAPE=HTML>
         </content>
        </TMPL_IF>
+       <TMPL_IF NAME="COMMENTSURL">
+       <link rel="comments" href="<TMPL_VAR NAME="COMMENTSURL">" type="text/html" />
+       </TMPL_IF>
+       <TMPL_IF NAME="ATOMCOMMENTSURL">
+       <link rel="comments" href="<TMPL_VAR NAME="ATOMCOMMENTSURL">" type="application/atom+xml" />
+       </TMPL_IF>
 </entry>
index 4a99cf5ff47a457774e686d1cbd0c320c142d363..0e61a80f4efc2d1fc173d031b827006bfce69cef 100644 (file)
@@ -3,7 +3,10 @@
 [[!meta authorurl="""<TMPL_VAR AUTHORURL>"""]]
 </TMPL_IF>
 [[!meta title="""change to<TMPL_LOOP NAME="PAGES"> <TMPL_VAR PAGE></TMPL_LOOP> on <TMPL_VAR WIKINAME>"""]]
-<div class="metadata">
+<TMPL_IF PERMALINK>
+[[!meta permalink="<TMPL_VAR PERMALINK>"]]
+</TMPL_IF>
+<div id="change-<TMPL_VAR REV>" class="metadata">
 <span class="desc"><br />Changed pages:</span>
 <span class="pagelinks">
 <TMPL_LOOP NAME="PAGES">
@@ -16,7 +19,7 @@
 <span class="desc"><br />Changed by:</span>
 <span class="committer">
 <TMPL_IF NAME="AUTHORURL">
-<a href="<TMPL_VAR AUTHORURL>"><TMPL_VAR USER></a>
+<a href="<TMPL_VAR AUTHORURL>" rel="nofollow"><TMPL_VAR USER></a>
 <TMPL_ELSE>
 <TMPL_VAR USER>
 </TMPL_IF>
 <span class="desc"><br />Commit type:</span>
 <span class="committype"><TMPL_VAR COMMITTYPE></span>
 <span class="desc"><br />Date:</span>
-<span class="changedate"><TMPL_VAR COMMITDATE></span>
+<span class="changedate"><TMPL_VAR COMMITDATE>
 </div>
 <div class=changelog>
 <TMPL_LOOP NAME="MESSAGE">
 <TMPL_IF NAME="LINE">
-<TMPL_VAR NAME="LINE" ESCAPE="HTML"><br />
+<TMPL_VAR NAME="LINE"><br />
 </TMPL_IF>
 </TMPL_LOOP>
 </div>
 <TMPL_IF NAME="DIFF">
 <div class=diff>
 <pre>
-<TMPL_VAR NAME="DIFF" ESCAPE="HTML">
+<TMPL_VAR NAME="DIFF">
 </pre>
 </div>
 </TMPL_IF>
diff --git a/templates/comment.tmpl b/templates/comment.tmpl
new file mode 100644 (file)
index 0000000..fb76ea0
--- /dev/null
@@ -0,0 +1,59 @@
+<div class="comment" id="<TMPL_VAR NAME=COMMENTID>">
+
+<div class="comment-subject">
+<TMPL_IF PERMALINK>
+<a href="<TMPL_VAR PERMALINK>"><TMPL_VAR TITLE></a>
+<TMPL_ELSE>
+<TMPL_VAR TITLE>
+</TMPL_IF>
+</div>
+
+<div class="inlinecontent">
+<TMPL_VAR CONTENT>
+</div>
+
+<div class="comment-header">
+Comment by
+
+<TMPL_IF NAME="COMMENTUSER">
+<TMPL_IF NAME="COMMENTOPENID">
+<span class="author" title="OpenID">
+<a href="<TMPL_VAR NAME=COMMENTOPENID>"><TMPL_VAR NAME=COMMENTAUTHOR></a>
+</span>
+<TMPL_ELSE>
+<span class="author" title="Signed in">
+<TMPL_IF NAME="COMMENTAUTHORURL">
+<a href="<TMPL_VAR NAME=COMMENTAUTHORURL>"><TMPL_VAR NAME=COMMENTAUTHOR></a>
+<TMPL_ELSE>
+<TMPL_VAR NAME=COMMENTAUTHOR>
+</TMPL_IF>
+</span>
+</TMPL_IF>
+<TMPL_ELSE><!-- !COMMENTUSER -->
+<TMPL_IF NAME=COMMENTIP>
+<span class="author" title="Unauthenticated, from <TMPL_VAR NAME=COMMENTIP>">
+<TMPL_ELSE><!-- !COMMENTIP -->
+<span class="author" title="Unauthenticated, from unknown IP address">
+</TMPL_IF>
+<TMPL_IF NAME="AUTHORURL">
+<a href="<TMPL_VAR NAME=AUTHORURL>"><TMPL_VAR NAME=AUTHOR></a>
+<TMPL_ELSE>
+<TMPL_VAR NAME=AUTHOR>
+</TMPL_IF>
+</span>
+</TMPL_IF><!-- !COMMENTUSER -->
+
+&mdash; <TMPL_VAR CTIME>
+</div>
+
+<TMPL_IF NAME="HAVE_ACTIONS">
+<div class="actions">
+<ul>
+<TMPL_IF NAME="REMOVEURL">
+<li><a href="<TMPL_VAR REMOVEURL>" rel="nofollow">Remove comment</a></li>
+</TMPL_IF>
+</ul>
+</div><!--.actions-->
+</TMPL_IF>
+
+</div><!--.comment-->
diff --git a/templates/commentmoderation.tmpl b/templates/commentmoderation.tmpl
new file mode 100644 (file)
index 0000000..e91d314
--- /dev/null
@@ -0,0 +1,29 @@
+<TMPL_IF NAME="COMMENTS">
+<br />
+<form action="<TMPL_VAR CGIURL>" method="post">
+<input type="hidden" name="do" value="commentmoderation" />
+<input type="hidden" name="sid" value="<TMPL_VAR SID>" />
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+<br />  
+<TMPL_LOOP NAME="COMMENTS">
+<div>
+<div>
+<TMPL_VAR VIEW>
+</div>
+<input type="radio" value="Defer" name="<TMPL_VAR ID>" checked />Defer
+<input type="radio" value="Accept" name="<TMPL_VAR ID>" />Accept
+<input type="radio" value="Reject" name="<TMPL_VAR ID>" />Reject
+</div>
+<br />
+</TMPL_LOOP>
+<input type="submit" value="Submit" />
+<input type="checkbox" name="rejectalldefer" value="1" />Reject
+all comments marked <em>Defer</em>
+</form>
+<TMPL_ELSE>
+<p>
+No comments need moderation at this time.
+</p>
+</TMPL_IF>
diff --git a/templates/editcomment.tmpl b/templates/editcomment.tmpl
new file mode 100644 (file)
index 0000000..7590cdf
--- /dev/null
@@ -0,0 +1,30 @@
+<div class="editcomment">
+<TMPL_VAR MESSAGE>
+<TMPL_VAR FORM-START>
+<TMPL_VAR FIELD-DO>
+<TMPL_VAR FIELD-SID>
+<TMPL_VAR FIELD-PAGE>
+<TMPL_UNLESS NAME=USERNAME>
+<TMPL_IF NAME=ALLOWAUTHOR>
+Name: <TMPL_VAR NAME=FIELD-AUTHOR> (optional)<br />
+Website: <TMPL_VAR NAME=FIELD-URL> (optional)<br />
+</TMPL_IF>
+</TMPL_UNLESS>
+Subject: <TMPL_VAR FIELD-SUBJECT><br />
+<TMPL_VAR FIELD-EDITCONTENT><br />
+<TMPL_VAR FORM-SUBMIT> <TMPL_VAR FIELD-TYPE> <TMPL_VAR HELPONFORMATTINGLINK><br />
+IkiWiki directives ([[!directive]]) are <TMPL_UNLESS NAME="ALLOWDIRECTIVES">not </TMPL_UNLESS>allowed in comments on this wiki.<br />
+<TMPL_VAR NAME="FORM-END">
+<TMPL_VAR WMD_PREVIEW>
+
+<TMPL_IF NAME="PAGE_PREVIEW">
+<hr />
+<div class="header">
+<span>Comment preview:</span>
+</div><!-- .header -->
+<div id="preview">
+<TMPL_VAR PAGE_PREVIEW>
+</div><!-- #preview -->
+</TMPL_IF>
+
+</div><!-- .editcomment -->
index 4b54db2d15b9344ef14eb1fde87948d676b97ab4..b1cf015a2b2aa67adbc3b568d68102632a0a832f 100644 (file)
@@ -37,6 +37,7 @@ Optional comment about this change:<br />
 </div>
 </TMPL_IF>
 <TMPL_VAR FORM-END>
+<TMPL_VAR WMD_PREVIEW>
 
 <TMPL_IF NAME="PAGE_PREVIEW">
 <hr />
index 523cff0019bf31ce958373ef3b8c3c1d1f940258..e2d4a1f43df8212051e0fa5bd67866f417a88d95 100644 (file)
@@ -1,6 +1,6 @@
 <form method="get" action="http://www.google.com/search" id="searchform">
  <div>
-  <input name="sitesearch" value="<TMPL_VAR SITEFQDN>" type="hidden">
-  <input name="q" value="" id="searchbox" size="16" maxlength="255" type="text">
+  <input name="sitesearch" value="<TMPL_VAR SITEFQDN>" type="hidden" />
+  <input name="q" value="" id="searchbox" size="16" maxlength="255" type="text" />
  </div>
 </form>
index ffcb897a8d250b88fd1a3e22d1ab765329da39f6..3c0b933159b168fe94119a51258b0d0f49baec06 100644 (file)
@@ -5,9 +5,9 @@
 <TMPL_IF NAME="AUTHOR">
 <span class="author">
 <TMPL_IF NAME="AUTHORURL">
-<a href="<TMPL_VAR NAME=AUTHORURL>"><TMPL_VAR NAME=AUTHOR></a>
+<a href="<TMPL_VAR AUTHORURL>"><TMPL_VAR AUTHOR></a>
 <TMPL_ELSE>
-<TMPL_VAR NAME=AUTHOR>
+<TMPL_VAR AUTHOR>
 </TMPL_IF>
 </span>
 </TMPL_IF>
@@ -35,7 +35,7 @@ Posted <TMPL_VAR CTIME>
 <span class="tags">
 Tags:
 <TMPL_LOOP NAME="TAGS">
-<TMPL_VAR NAME=LINK>
+<TMPL_VAR LINK>
 </TMPL_LOOP>
 </span>
 </TMPL_IF>
@@ -58,9 +58,13 @@ License: <TMPL_VAR LICENSE>
 <TMPL_IF NAME="EDITURL">
 <li><a href="<TMPL_VAR EDITURL>" rel="nofollow">Edit</a></li>
 </TMPL_IF>
+<TMPL_IF NAME="COMMENTSLINK">
+<li><TMPL_VAR COMMENTSLINK></li>
+<TMPL_ELSE>
 <TMPL_IF NAME="DISCUSSIONLINK">
 <li><TMPL_VAR DISCUSSIONLINK></li>
 </TMPL_IF>
+</TMPL_IF>
 </ul>
 </div><!--.actions-->
 </TMPL_IF>
index 7f65217d124b0423d523814d2964d18e0d24952f..0de56edebc61dda8ee05eb190b6c8dbee1069b5d 100644 (file)
 </head>
 <body>
 
+<div class="pageheader">
 <div class="header">
 <span>
 <TMPL_VAR INDEXLINK>/ <TMPL_VAR TITLE>
 </span>
 </div>
+</div> <!-- .pageheader -->
 
 <div id="content">
 <TMPL_VAR PAGEBODY>
index f2f9c34cc1cfdbaff1dc32ed0f2e717e81ea99e1..29ba688c749de8b2823d67a465bab96be798d8a5 100644 (file)
@@ -13,6 +13,7 @@
 <link rel="alternate" type="application/x-wiki" title="Edit this page" href="<TMPL_VAR EDITURL>" />
 </TMPL_IF>
 <TMPL_IF NAME="FEEDLINKS"><TMPL_VAR FEEDLINKS></TMPL_IF>
+<TMPL_IF NAME="RELVCS"><TMPL_VAR RELVCS></TMPL_IF>
 <TMPL_IF NAME="META"><TMPL_VAR META></TMPL_IF>
 </head>
 <body>
@@ -22,7 +23,7 @@
 <span>
 <span class="parentlinks">
 <TMPL_LOOP NAME="PARENTLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>/ 
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>/ 
 </TMPL_LOOP>
 </span>
 <span class="title">
 <TMPL_IF NAME="PREFSURL">
 <li><a href="<TMPL_VAR PREFSURL>">Preferences</a></li>
 </TMPL_IF>
+<TMPL_IF NAME="COMMENTSLINK">
+<li><TMPL_VAR COMMENTSLINK><br /></li>
+<TMPL_ELSE>
 <TMPL_IF NAME="DISCUSSIONLINK">
 <li><TMPL_VAR DISCUSSIONLINK><br /></li>
 </TMPL_IF>
+</TMPL_IF>
 </ul>
 </div>
 </TMPL_IF>
 <TMPL_VAR CONTENT>
 </div>
 
+<TMPL_IF COMMENTS>
+<div id="comments">
+<TMPL_VAR COMMENTS>
+<TMPL_IF ADDCOMMENTURL>
+<div class="addcomment">
+<a href="<TMPL_VAR ADDCOMMENTURL>">Add a comment</a>
+</div>
+<TMPL_ELSE>
+<div class="addcomment">Comments on this page are closed.</div>
+</TMPL_IF>
+</div>
+</TMPL_IF>
+
 <div id="footer" class="pagefooter">
 <div id="pageinfo">
 
@@ -74,7 +92,7 @@
 <div class="tags">
 Tags:
 <TMPL_LOOP NAME="TAGS">
-<TMPL_VAR NAME=LINK>
+<TMPL_VAR LINK>
 </TMPL_LOOP>
 </div>
 </TMPL_IF>
@@ -83,13 +101,13 @@ Tags:
 <div id="backlinks">
 Links:
 <TMPL_LOOP NAME="BACKLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
 </TMPL_LOOP>
 <TMPL_IF NAME="MORE_BACKLINKS">
 <span class="popup">...
 <span class="balloon">
 <TMPL_LOOP NAME="MORE_BACKLINKS">
-<a href="<TMPL_VAR NAME=URL>"><TMPL_VAR NAME=PAGE></a>
+<a href="<TMPL_VAR URL>"><TMPL_VAR PAGE></a>
 </TMPL_LOOP>
 </span>
 </span>
@@ -112,13 +130,13 @@ License: <TMPL_VAR LICENSE>
 </TMPL_IF>
 
 <div class="pagedate">
-Last edited <TMPL_VAR NAME=MTIME>
-<!-- Created <TMPL_VAR NAME=CTIME> -->
+Last edited <TMPL_VAR MTIME>
+<!-- Created <TMPL_VAR CTIME> -->
 </div>
 
 </div><!-- #pageinfo -->
 <TMPL_IF EXTRAFOOTER><TMPL_VAR EXTRAFOOTER></TMPL_IF>
-<!-- from <TMPL_VAR NAME=WIKINAME> -->
+<!-- from <TMPL_VAR WIKINAME> -->
 </div><!-- .pagefooter #footer -->
 
 </body>
index 42936a668f591bf7cf1a9a23fae4e076e3e48988..a61b92b6127505e3f61b068d046e3f706a956d9a 100644 (file)
@@ -23,4 +23,7 @@
        <TMPL_ELSE>
        <description><TMPL_VAR CONTENT ESCAPE=HTML></description>
        </TMPL_IF>
+       <TMPL_IF NAME="COMMENTSURL">
+       <comments><TMPL_VAR NAME="COMMENTSURL"></comments>
+       </TMPL_IF>
 </item>
diff --git a/underlays/basewiki/directive.mdwn b/underlays/basewiki/directive.mdwn
deleted file mode 120000 (symlink)
index e8ce42c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../doc/ikiwiki/directive.mdwn
\ No newline at end of file
diff --git a/underlays/javascript/ikiwiki.js b/underlays/javascript/ikiwiki.js
new file mode 100644 (file)
index 0000000..1252f24
--- /dev/null
@@ -0,0 +1,52 @@
+// ikiwiki's javascript utility function library
+
+var hooks;
+
+// Run onload as soon as the DOM is ready, if possible.
+// gecko, opera 9
+if (document.addEventListener) {
+       document.addEventListener("DOMContentLoaded", run_hooks_onload, false);
+}
+// other browsers
+window.onload = run_hooks_onload;
+
+function run_hooks_onload() {
+       // avoid firing twice
+       if (arguments.callee.done)
+               return;
+       arguments.callee.done = true;
+
+       run_hooks("onload");
+}
+
+function run_hooks(name) {
+       if (typeof(hooks) != "undefined") {
+               for (var i = 0; i < hooks.length; i++) {
+                       if (hooks[i].name == name) {
+                               hooks[i].call();
+                       }
+               }
+       }
+}
+
+function hook(name, call) {
+       if (typeof(hooks) == "undefined")
+               hooks = new Array;
+       hooks.push({name: name, call: call});
+}
+
+function getElementsByClass(cls, node, tag) {
+        if (document.getElementsByClass)
+                return document.getElementsByClass(cls, node, tag);
+        if (! node) node = document;
+        if (! tag) tag = '*';
+        var ret = new Array();
+        var pattern = new RegExp("(^|\\s)"+cls+"(\\s|$)");
+        var els = node.getElementsByTagName(tag);
+        for (i = 0; i < els.length; i++) {
+                if ( pattern.test(els[i].className) ) {
+                        ret.push(els[i]);
+                }
+        }
+        return ret;
+}
diff --git a/underlays/javascript/relativedate.js b/underlays/javascript/relativedate.js
new file mode 100644 (file)
index 0000000..8e05d40
--- /dev/null
@@ -0,0 +1,70 @@
+// Causes html elements in the 'relativedate' class to be displayed
+// as relative dates. The date is parsed from the title attribute, or from
+// the element content.
+
+var dateElements;
+
+hook("onload", getDates);
+
+function getDates() {
+       dateElements = getElementsByClass('relativedate');
+       for (var i = 0; i < dateElements.length; i++) {
+               var elt = dateElements[i];
+               var title = elt.attributes.title;
+               var d = new Date(title ? title.value : elt.innerHTML);
+               if (! isNaN(d)) {
+                       dateElements[i].date=d;
+                       elt.title=elt.innerHTML;
+               }
+       }
+
+       showDates();
+}
+
+function showDates() {
+       for (var i = 0; i < dateElements.length; i++) {
+               var elt = dateElements[i];
+               var d = elt.date;
+               if (! isNaN(d)) {
+                       elt.innerHTML=relativeDate(d);
+               }
+       }
+       setTimeout(showDates,30000); // keep updating every 30s
+}
+
+var timeUnits = new Array;
+timeUnits['minute'] = 60;
+timeUnits['hour'] = timeUnits['minute'] * 60;
+timeUnits['day'] = timeUnits['hour'] * 24;
+timeUnits['month'] = timeUnits['day'] * 30;
+timeUnits['year'] = timeUnits['day'] * 364;
+var timeUnitOrder = ['year', 'month', 'day', 'hour', 'minute'];
+
+function relativeDate(date) {
+       var now = new Date();
+       var offset = date.getTime() - now.getTime();
+       var seconds = Math.round(Math.abs(offset) / 1000);
+
+       var ret = "";
+       var shown = 0;
+       for (i = 0; i < timeUnitOrder.length; i++) {
+               var unit = timeUnitOrder[i];
+               if (seconds >= timeUnits[unit]) {
+                       var num = Math.floor(seconds / timeUnits[unit]);
+                       seconds -= num * timeUnits[unit];
+                       if (ret)
+                               ret += "and ";
+                       ret += num + " " + unit + (num > 1 ? "s" : "") + " ";
+
+                       if (++shown == 2)
+                               break;
+               }
+               else if (shown)
+                       break;
+       }
+
+       if (! ret)
+               ret = "less than a minute "
+
+       return ret + (offset < 0 ? "ago" : "from now");
+}
diff --git a/underlays/javascript/toggle.js b/underlays/javascript/toggle.js
new file mode 100644 (file)
index 0000000..d190b73
--- /dev/null
@@ -0,0 +1,29 @@
+// Uses CSS to hide toggleables, to avoid any flashing on page load. The
+// CSS is only emitted after it tests that it's going to be able
+// to show the toggleables.
+if (document.getElementById && document.getElementsByTagName && document.createTextNode) {
+       document.write('<style type="text/css">div.toggleable { display: none; }</style>');
+       hook("onload", inittoggle);
+}
+
+function inittoggle() {
+       var as = getElementsByClass('toggle');
+       for (var i = 0; i < as.length; i++) {
+               var id = as[i].href.match(/#(\w.+)/)[1];
+               if (document.getElementById(id).className == "toggleable")
+                       document.getElementById(id).style.display="none";
+               as[i].onclick = function() {
+                       toggle(this);
+                       return false;
+               }
+       }
+}
+
+function toggle(s) {
+       var id = s.href.match(/#(\w.+)/)[1];
+       style = document.getElementById(id).style;
+       if (style.display == "none")
+               style.display = "block";
+       else
+               style.display = "none";
+}