Merge branch 'master' into sipb
authorQuentin Smith <quentin@mit.edu>
Sat, 13 Mar 2010 22:53:12 +0000 (17:53 -0500)
committerQuentin Smith <quentin@mit.edu>
Sat, 13 Mar 2010 22:53:12 +0000 (17:53 -0500)
Conflicts:
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
templates/misc.tmpl
templates/page.tmpl

528 files changed:
IkiWiki.pm
IkiWiki/CGI.pm
IkiWiki/Plugin/404.pm
IkiWiki/Plugin/amazon_s3.pm
IkiWiki/Plugin/anonok.pm
IkiWiki/Plugin/attachment.pm
IkiWiki/Plugin/blogspam.pm
IkiWiki/Plugin/brokenlinks.pm
IkiWiki/Plugin/bzr.pm
IkiWiki/Plugin/calendar.pm
IkiWiki/Plugin/color.pm
IkiWiki/Plugin/comments.pm
IkiWiki/Plugin/conditional.pm
IkiWiki/Plugin/creole.pm
IkiWiki/Plugin/cutpaste.pm
IkiWiki/Plugin/cvs.pm
IkiWiki/Plugin/darcs.pm
IkiWiki/Plugin/date.pm [new file with mode: 0644]
IkiWiki/Plugin/editdiff.pm
IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/edittemplate.pm
IkiWiki/Plugin/external.pm
IkiWiki/Plugin/format.pm
IkiWiki/Plugin/fortune.pm
IkiWiki/Plugin/getsource.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/google.pm
IkiWiki/Plugin/goto.pm
IkiWiki/Plugin/graphviz.pm
IkiWiki/Plugin/haiku.pm
IkiWiki/Plugin/highlight.pm
IkiWiki/Plugin/hnb.pm
IkiWiki/Plugin/html.pm
IkiWiki/Plugin/htmlscrubber.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/localstyle.pm [new file with mode: 0644]
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/moderatedcomments.pm [new file with mode: 0644]
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/parentlinks.pm
IkiWiki/Plugin/passwordauth.pm
IkiWiki/Plugin/po.pm
IkiWiki/Plugin/poll.pm
IkiWiki/Plugin/polygen.pm
IkiWiki/Plugin/postsparkline.pm
IkiWiki/Plugin/progress.pm
IkiWiki/Plugin/rawhtml.pm
IkiWiki/Plugin/recentchanges.pm
IkiWiki/Plugin/relativedate.pm
IkiWiki/Plugin/remove.pm
IkiWiki/Plugin/rename.pm
IkiWiki/Plugin/repolist.pm
IkiWiki/Plugin/search.pm
IkiWiki/Plugin/shortcut.pm
IkiWiki/Plugin/signinedit.pm
IkiWiki/Plugin/sparkline.pm
IkiWiki/Plugin/svn.pm
IkiWiki/Plugin/table.pm
IkiWiki/Plugin/template.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
IkiWiki/Plugin/version.pm
IkiWiki/Plugin/websetup.pm
IkiWiki/Plugin/wikitext.pm
IkiWiki/Plugin/wmd.pm
IkiWiki/Render.pm
IkiWiki/Setup.pm
IkiWiki/Setup/Automator.pm
IkiWiki/Setup/Standard.pm
IkiWiki/Wrapper.pm
Makefile.PL
auto-blog.setup
auto.setup
debian/NEWS
debian/changelog
debian/control
debian/copyright
debian/examples [deleted file]
debian/postinst
doc/bugs/404_plugin_and_lighttpd.mdwn [new file with mode: 0644]
doc/bugs/Another_UTF-8_problem.mdwn
doc/bugs/Building_a_sidebar_does_not_regenerate_the_subpages.mdwn
doc/bugs/Exception:_Unknown_function___96__this__39___.mdwn [new file with mode: 0644]
doc/bugs/External_links_with_Creole.mdwn [new file with mode: 0644]
doc/bugs/Inline_doesn__39__t_wikilink_to_pages.mdwn
doc/bugs/Search_summary_includes_text_from_navigational_elements.mdwn [new file with mode: 0644]
doc/bugs/align_doesn__39__t_always_work_with_img_plugin_.mdwn [new file with mode: 0644]
doc/bugs/anonok_vs._httpauth.mdwn [new file with mode: 0644]
doc/bugs/bestlink_change_update_issue.mdwn
doc/bugs/bestlink_returns_deleted_pages.mdwn [new file with mode: 0644]
doc/bugs/broken_parentlinks.mdwn
doc/bugs/brokenlinks_accumulates_duplicate_items.mdwn [new file with mode: 0644]
doc/bugs/cgi_does_not_use_templatedir_overlay.mdwn
doc/bugs/debbug_shortcut_should_expand_differently.mdwn
doc/bugs/disable_sub-discussion_pages.mdwn
doc/bugs/discussion_of_what__63__.mdwn
doc/bugs/firefox_doesn__39__t_want_to_load_updated_pages_at_ikiwiki.info.mdwn
doc/bugs/git_utf8.mdwn
doc/bugs/img_vs_align.mdwn [new file with mode: 0644]
doc/bugs/inline_breaks_PERMALINK_variable.mdwn [new file with mode: 0644]
doc/bugs/inline_plugin_sets_editurl_even_when_editpage_is_disabled.html [new file with mode: 0644]
doc/bugs/inline_raw_broken_on_unknown_pagetype.mdwn [new file with mode: 0644]
doc/bugs/inline_skip_causes_empty_inline.mdwn [new file with mode: 0644]
doc/bugs/librpc-xml-perl_0.69_breaks_XML-RPC_plugins.mdwn [new file with mode: 0644]
doc/bugs/map_sorts_by_pagename_and_not_title_when_show__61__title_is_used.mdwn [new file with mode: 0644]
doc/bugs/minor:_tiny_rendering_error.mdwn [new file with mode: 0644]
doc/bugs/pages_missing_top-level_directory.mdwn [new file with mode: 0644]
doc/bugs/rebuild_after_changing_the_underlaydir_config_option.mdwn [new file with mode: 0644]
doc/bugs/removing_pages_with_utf8_characters.mdwn [new file with mode: 0644]
doc/bugs/rst_plugin_has_python_hardcode_in_shebang_line.mdwn [new file with mode: 0644]
doc/bugs/rst_tweak.mdwn
doc/bugs/templateForRecentChangesMissingCloseSpan.mdwn [new file with mode: 0644]
doc/bugs/the_login_page_is_unclear_when_multiple_methods_exist.mdwn [new file with mode: 0644]
doc/bugs/toggle_expects_body_element_without_attributes.mdwn [new file with mode: 0644]
doc/bugs/transitive_dependencies.mdwn [new file with mode: 0644]
doc/bugs/unicode_encoded_urls_and_recentchanges.mdwn
doc/bugs/utf-8_bug_in_websetup.pm.mdwn [new file with mode: 0644]
doc/competition.mdwn [new file with mode: 0644]
doc/css.mdwn
doc/css/discussion.mdwn [new file with mode: 0644]
doc/css_market.mdwn
doc/download.mdwn
doc/examples/blog.mdwn
doc/examples/blog/comments.mdwn [new file with mode: 0644]
doc/examples/blog/index.mdwn
doc/examples/blog/tags.mdwn
doc/examples/softwaresite.mdwn
doc/forum.mdwn
doc/forum/Cannot_write_to_commitlock.mdwn [new file with mode: 0644]
doc/forum/Error:_bad_page_name.mdwn [new file with mode: 0644]
doc/forum/How_does_ikiwiki_remember_times__63__.mdwn
doc/forum/Ikiwiki_CGI_not_working_on_my_server__44___and_it__39__s_a_binary_file__63__.mdwn [new file with mode: 0644]
doc/forum/News_site_where_articles_are_submitted_and_then_reviewed_before_posting.mdwn [new file with mode: 0644]
doc/forum/Regex_for_Valid_Characters_in_Filenames.mdwn [new file with mode: 0644]
doc/forum/Render_more_than_one_dest_page_from_same_source_page.mdwn [new file with mode: 0644]
doc/forum/Should_not_create_an_existing_page.mdwn [new file with mode: 0644]
doc/forum/Spaces_in_wikilinks.mdwn [new file with mode: 0644]
doc/forum/Upgrade_steps_from_RecentChanges_CGI_to_static_page.mdwn [new file with mode: 0644]
doc/forum/Various_ways_to_use_Subversion_with_ikiwiki.mdwn [new file with mode: 0644]
doc/forum/Warnings:___39__utf8___34____92__xAB__34___does_not_map_to_Unicode_at___47__usr__47__share__47__perl5__47__IkiWiki.pm_line_774__44_____60____36__in__62___chunk_1.__39__.mdwn [new file with mode: 0644]
doc/forum/an_alternative_approach_to_structured_data.mdwn [new file with mode: 0644]
doc/forum/cleaning_up_discussion_pages_and_the_like.mdwn [new file with mode: 0644]
doc/forum/editing_the_style_sheet.mdwn [new file with mode: 0644]
doc/forum/ever-growing_list_of_pages.mdwn [new file with mode: 0644]
doc/forum/google_openid_broken__63__.mdwn
doc/forum/how_do_I_translate_a_TWiki_site.mdwn [new file with mode: 0644]
doc/forum/ikiwiki_and_big_files.mdwn [new file with mode: 0644]
doc/forum/installation_and_setup_questions.mdwn [new file with mode: 0644]
doc/forum/installation_as_non-root_user.mdwn [new file with mode: 0644]
doc/forum/installation_of_selected_docs.mdwn [new file with mode: 0644]
doc/forum/link_to_an_image_inside_the_wiki_without_inlining_it.mdwn [new file with mode: 0644]
doc/forum/missing_pages_redirected_to_search-SOLVED.mdwn [new file with mode: 0644]
doc/forum/navigation_of_wiki_pages_on_local_filesystem_with_vim.mdwn [new file with mode: 0644]
doc/forum/speeding_up_ikiwiki.mdwn
doc/forum/transition_from_handwritten_html_to_ikiwiki.mdwn [new file with mode: 0644]
doc/forum/understanding_filter_hooks.mdwn
doc/forum/upgrade_steps.mdwn [new file with mode: 0644]
doc/forum/web_service_API__44___fastcgi_support.mdwn [new file with mode: 0644]
doc/forum/where_are_the_tags.mdwn [new file with mode: 0644]
doc/forum/wishlist-discussion:_Editformular_showing_existing_tags.mdwn [new file with mode: 0644]
doc/git.mdwn
doc/ikiwiki-calendar.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/brokenlinks/discussion.mdwn
doc/ikiwiki/directive/calendar.mdwn
doc/ikiwiki/directive/comment.mdwn
doc/ikiwiki/directive/date.mdwn [new file with mode: 0644]
doc/ikiwiki/directive/format.mdwn
doc/ikiwiki/directive/img.mdwn
doc/ikiwiki/directive/inline.mdwn
doc/ikiwiki/directive/inline/discussion.mdwn
doc/ikiwiki/directive/linkmap.mdwn
doc/ikiwiki/directive/map.mdwn
doc/ikiwiki/directive/map/discussion.mdwn
doc/ikiwiki/directive/meta.mdwn
doc/ikiwiki/directive/pagestats.mdwn
doc/ikiwiki/directive/pagestats/discussion.mdwn
doc/ikiwiki/directive/pagetemplate.mdwn
doc/ikiwiki/directive/postsparkline.mdwn
doc/ikiwiki/directive/sparkline.mdwn
doc/ikiwiki/directive/toc.mdwn
doc/ikiwiki/openid.mdwn
doc/ikiwiki/pagespec.mdwn
doc/ikiwiki/pagespec/po.mdwn
doc/ikiwiki/pagespec/sorting.mdwn [new file with mode: 0644]
doc/ikiwiki/wikilink/discussion.mdwn
doc/ikiwikiusers.mdwn
doc/ikiwikiusers/discussion.mdwn
doc/index.mdwn
doc/index/discussion.mdwn
doc/news/code_swarm/discussion.mdwn [new file with mode: 0644]
doc/news/discussion.mdwn
doc/news/openid.mdwn
doc/news/server_move_2009.mdwn [new file with mode: 0644]
doc/news/version_3.141.mdwn [deleted file]
doc/news/version_3.141/discussion.mdwn [deleted file]
doc/news/version_3.1415.mdwn [deleted file]
doc/news/version_3.14159.mdwn [deleted file]
doc/news/version_3.141592.mdwn [deleted file]
doc/news/version_3.1415926.mdwn [deleted file]
doc/news/version_3.20100102.3.mdwn [new file with mode: 0644]
doc/news/version_3.20100122.mdwn [new file with mode: 0644]
doc/news/version_3.20100212.mdwn [new file with mode: 0644]
doc/news/version_3.20100302.mdwn [new file with mode: 0644]
doc/news/version_3.20100312.mdwn [new file with mode: 0644]
doc/plugins.mdwn
doc/plugins/404.mdwn
doc/plugins/404/discussion.mdwn [new file with mode: 0644]
doc/plugins/aggregate.mdwn
doc/plugins/autoindex.mdwn
doc/plugins/autoindex/discussion.mdwn
doc/plugins/calendar.mdwn
doc/plugins/color.mdwn
doc/plugins/comments.mdwn
doc/plugins/conditional.mdwn
doc/plugins/conditional/discussion.mdwn
doc/plugins/contrib.mdwn
doc/plugins/contrib/album/discussion.mdwn [new file with mode: 0644]
doc/plugins/contrib/field.mdwn [new file with mode: 0644]
doc/plugins/contrib/ftemplate.mdwn [new file with mode: 0644]
doc/plugins/contrib/getfield.mdwn [new file with mode: 0644]
doc/plugins/contrib/getfield/discussion.mdwn [new file with mode: 0644]
doc/plugins/contrib/groupfile.mdwn [new file with mode: 0644]
doc/plugins/contrib/mediawiki.mdwn
doc/plugins/contrib/pod.mdwn [new file with mode: 0644]
doc/plugins/contrib/postal.mdwn
doc/plugins/contrib/report.mdwn [new file with mode: 0644]
doc/plugins/contrib/unixauth.mdwn
doc/plugins/contrib/xslt.mdwn [new file with mode: 0644]
doc/plugins/contrib/xslt/discussion.mdwn [new file with mode: 0644]
doc/plugins/contrib/ymlfront.mdwn [new file with mode: 0644]
doc/plugins/creole/discussion.mdwn
doc/plugins/cutpaste.mdwn
doc/plugins/date.mdwn [new file with mode: 0644]
doc/plugins/ddate.mdwn
doc/plugins/editpage.mdwn
doc/plugins/filecheck.mdwn
doc/plugins/format.mdwn
doc/plugins/fortune.mdwn
doc/plugins/getsource.mdwn
doc/plugins/getsource/discussion.mdwn [new file with mode: 0644]
doc/plugins/google.mdwn
doc/plugins/google/discussion.mdwn
doc/plugins/goto.mdwn
doc/plugins/graphviz.mdwn
doc/plugins/haiku.mdwn
doc/plugins/httpauth.mdwn
doc/plugins/img.mdwn
doc/plugins/inline.mdwn
doc/plugins/linkmap.mdwn
doc/plugins/listdirectives.mdwn
doc/plugins/localstyle.mdwn [new file with mode: 0644]
doc/plugins/lockedit.mdwn
doc/plugins/lockedit/discussion.mdwn [new file with mode: 0644]
doc/plugins/map.mdwn
doc/plugins/mirrorlist.mdwn
doc/plugins/moderatedcomments.mdwn [new file with mode: 0644]
doc/plugins/more.mdwn
doc/plugins/opendiscussion.mdwn
doc/plugins/openid/discussion.mdwn
doc/plugins/orphans.mdwn
doc/plugins/pagecount.mdwn
doc/plugins/pagestats.mdwn
doc/plugins/pagetemplate.mdwn
doc/plugins/parentlinks.mdwn
doc/plugins/po.mdwn
doc/plugins/poll.mdwn
doc/plugins/polygen.mdwn
doc/plugins/postsparkline.mdwn
doc/plugins/prettydate.mdwn
doc/plugins/progress.mdwn
doc/plugins/recentchanges.mdwn
doc/plugins/recentchangesdiff.mdwn
doc/plugins/relativedate.mdwn
doc/plugins/rename.mdwn
doc/plugins/repolist.mdwn
doc/plugins/rst/discussion.mdwn
doc/plugins/rsync.mdwn
doc/plugins/rsync/discussion.mdwn
doc/plugins/shortcut.mdwn
doc/plugins/shortcut/discussion.mdwn
doc/plugins/sidebar.mdwn
doc/plugins/sidebar/discussion.mdwn [new file with mode: 0644]
doc/plugins/sparkline.mdwn
doc/plugins/table.mdwn
doc/plugins/tag/discussion.mdwn
doc/plugins/template.mdwn
doc/plugins/testpagespec.mdwn
doc/plugins/teximg.mdwn
doc/plugins/toc.mdwn
doc/plugins/toggle.mdwn
doc/plugins/type/chrome.mdwn
doc/plugins/type/useful.mdwn [deleted file]
doc/plugins/type/widget.mdwn [new file with mode: 0644]
doc/plugins/typography.mdwn
doc/plugins/underlay.mdwn
doc/plugins/version.mdwn
doc/plugins/wmd.mdwn
doc/plugins/write.mdwn
doc/quotes.mdwn [new file with mode: 0644]
doc/quotes/pizza.mdwn [new file with mode: 0644]
doc/quotes/pizza/discussion.mdwn [new file with mode: 0644]
doc/quotes/sold.mdwn [new file with mode: 0644]
doc/sandbox.mdwn
doc/sandbox/Post.mdwn [new file with mode: 0644]
doc/sandbox/danc.mdwn [new file with mode: 0644]
doc/sandbox/plop.mdwn [new file with mode: 0644]
doc/security.mdwn
doc/setup.mdwn
doc/setup/byhand.mdwn
doc/setup/discussion.mdwn
doc/shortcuts.mdwn
doc/style.css
doc/tipjar.mdwn
doc/tips/add_chatterbox_to_blog.mdwn
doc/tips/convert_mediawiki_to_ikiwiki.mdwn
doc/tips/convert_mediawiki_to_ikiwiki/discussion.mdwn
doc/tips/dot_cgi/discussion.mdwn
doc/tips/follow_wikilinks_from_inside_vim.mdwn [new file with mode: 0644]
doc/tips/github.mdwn
doc/tips/laptop_wiki_with_git.mdwn
doc/tips/optimising_ikiwiki.mdwn [new file with mode: 0644]
doc/tips/parentlinks_style.mdwn
doc/tips/spam_and_softwaresites.mdwn [new file with mode: 0644]
doc/tips/vim_syntax_highlighting.mdwn
doc/todo/ACL.mdwn
doc/todo/Add_label_to_search_form_input_field.mdwn
doc/todo/CSS_classes_for_links.mdwn
doc/todo/Fix_selflink_in_po_plugin.mdwn [new file with mode: 0644]
doc/todo/Mailing_list.mdwn
doc/todo/OpenSearch.mdwn
doc/todo/Resolve_native_reStructuredText_links_to_ikiwiki_pages.mdwn [new file with mode: 0644]
doc/todo/Set_templates_for_whole_sections_of_the_site.mdwn [new file with mode: 0644]
doc/todo/Support_XML-RPC-based_blogging.mdwn
doc/todo/abbreviation.mdwn
doc/todo/adjust_commit_message_for_rename__44___remove.mdwn [new file with mode: 0644]
doc/todo/allow_site-wide_meta_definitions.mdwn
doc/todo/auto-create_tag_pages_according_to_a_template.mdwn
doc/todo/auto_getctime_on_fresh_build.mdwn [new file with mode: 0644]
doc/todo/avoid_attachement_ui_if_upload_not_allowed.mdwn [new file with mode: 0644]
doc/todo/beef_up_sidebar_to_allow_for_multiple_sidebars.mdwn
doc/todo/cache_backlinks.mdwn [new file with mode: 0644]
doc/todo/cas_authentication.mdwn
doc/todo/cdate_and_mdate_available_for_templates.mdwn [new file with mode: 0644]
doc/todo/conflict_free_comment_merges.mdwn [new file with mode: 0644]
doc/todo/dependency_types.mdwn [new file with mode: 0644]
doc/todo/description_meta_param_passed_to_templates.mdwn [new file with mode: 0644]
doc/todo/double-click_protection_for_form_buttons.mdwn [new file with mode: 0644]
doc/todo/edit_form:_no_fixed_size_for_textarea.mdwn
doc/todo/enable-htaccess-files.mdwn
doc/todo/enable_arbitrary_markup_for_directives.mdwn [new file with mode: 0644]
doc/todo/finer_control_over___60__object___47____62__s.mdwn [new file with mode: 0644]
doc/todo/http_bl_support.mdwn [new file with mode: 0644]
doc/todo/mark_edit_as_trivial__44___identify__47__filter_on_trivial_changes.mdwn [new file with mode: 0644]
doc/todo/mercurial.mdwn
doc/todo/openid_user_filtering.mdwn
doc/todo/pagespec_to_disable_ikiwiki_directives.mdwn [new file with mode: 0644]
doc/todo/preview_changes_before_git_commit.mdwn [new file with mode: 0644]
doc/todo/salmon_protocol_for_comment_sharing.mdwn [new file with mode: 0644]
doc/todo/sort_parameter_for_map_plugin_and_directive.mdwn [new file with mode: 0644]
doc/todo/structured_page_data.mdwn
doc/todo/support_link__40__.__41___in_pagespec.mdwn [new file with mode: 0644]
doc/todo/svg.mdwn
doc/todo/tagging_with_a_publication_date.mdwn
doc/todo/toc_plugin:_set_a_header_ceiling___40__opposite_of_levels__61____41__.mdwn
doc/todo/tracking_bugs_with_dependencies.mdwn
doc/todo/wrapperuser.mdwn [new file with mode: 0644]
doc/translation.mdwn
doc/usage.mdwn
doc/users/David_Riebenbauer.mdwn [new file with mode: 0644]
doc/users/Edward_Betts.mdwn
doc/users/KathrynAndersen.mdwn [new file with mode: 0644]
doc/users/Mick_Pollard.mdwn [new file with mode: 0644]
doc/users/NicolasLimare.mdwn
doc/users/Oblomov.mdwn [new file with mode: 0644]
doc/users/Will.mdwn
doc/users/ericdrechsel.mdwn [new file with mode: 0644]
doc/users/harishcm.mdwn
doc/users/ivan_shmakov.mdwn [new file with mode: 0644]
doc/users/jeanprivat.mdwn [new file with mode: 0644]
doc/users/jerojasro.mdwn [new file with mode: 0644]
doc/users/jmtd.mdwn [new file with mode: 0644]
doc/users/jogo.mdwn
doc/users/jon.mdwn
doc/users/joshtriplett.mdwn
doc/users/joshtriplett/discussion.mdwn [new file with mode: 0644]
doc/users/nil.mdwn [new file with mode: 0644]
doc/users/rubykat.mdwn [new file with mode: 0644]
doc/users/tschwinge.mdwn
doc/users/ulrik.mdwn [new file with mode: 0644]
doc/users/weakish.mdwn
doc/users/xma.mdwn [deleted file]
doc/w3mmode.mdwn
docwiki.setup
gitremotes
ikiwiki-calendar [new file with mode: 0755]
ikiwiki-transition
ikiwiki.in
ikiwiki.spec [new file with mode: 0644]
mdwn2man
plugins/externaldemo
plugins/pythondemo
plugins/rst
po/bg.po
po/cs.po
po/da.po
po/de.po
po/es.po
po/fr.po
po/gu.po
po/ikiwiki.pot
po/it.po
po/pl.po
po/sv.po
po/tr.po [new file with mode: 0644]
po/underlay.setup
po/underlays/basewiki/ikiwiki.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/directive.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/formatting.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/markdown.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/openid.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/pagespec.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/pagespec/attachment.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/pagespec/po.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/searching.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/subpage.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/subpage/linkingrules.es.po [new file with mode: 0644]
po/underlays/basewiki/ikiwiki/wikilink.es.po [new file with mode: 0644]
po/underlays/basewiki/index.es.po [new file with mode: 0644]
po/underlays/basewiki/recentchanges.es.po [new file with mode: 0644]
po/underlays/basewiki/sandbox.es.po [new file with mode: 0644]
po/underlays/basewiki/shortcuts.es.po [new file with mode: 0644]
po/underlays/basewiki/templates.es.po [new file with mode: 0644]
po/underlays/basewiki/templates.fr.po
po/underlays/basewiki/templates/note.es.po [new file with mode: 0644]
po/underlays/basewiki/templates/popup.es.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/aggregate.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/brokenlinks.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/calendar.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/color.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/comment.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/copy.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/cut.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/cutpaste.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/edittemplate.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/format.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/fortune.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/graph.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/haiku.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/if.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/img.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/inline.da.po
po/underlays/directives/ikiwiki/directive/inline.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/linkmap.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/listdirectives.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/map.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/meta.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/more.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/orphans.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/pagecount.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/pagestats.da.po
po/underlays/directives/ikiwiki/directive/pagestats.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/pagetemplate.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/paste.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/ping.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/poll.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/polygen.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/postsparkline.da.po
po/underlays/directives/ikiwiki/directive/postsparkline.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/progress.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/shortcut.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/sparkline.da.po
po/underlays/directives/ikiwiki/directive/sparkline.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/table.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/tag.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/taglink.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/template.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/testpagespec.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/teximg.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/toc.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/toggle.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/toggleable.fr.po [new file with mode: 0644]
po/underlays/directives/ikiwiki/directive/version.fr.po [new file with mode: 0644]
po/underlays/smiley/smileys.fr.po [new file with mode: 0644]
po/vi.po
t/add_depends.t [new file with mode: 0755]
t/basewiki_brokenlinks.t
t/bestlink.t
t/cvs.t
t/file_pruned.t
t/pagespec_match.t
t/pagespec_match_list.t [new file with mode: 0755]
t/pagespec_match_result.t [new file with mode: 0755]
t/preprocess.t
t/yesno.t
templates/atomitem.tmpl
templates/atompage.tmpl
templates/calendarmonth.tmpl [new file with mode: 0644]
templates/calendaryear.tmpl [new file with mode: 0644]
templates/change.tmpl
templates/editcomment.tmpl
templates/googleform.tmpl
templates/rssitem.tmpl
underlays/basewiki/ikiwiki/pagespec/sorting.mdwn [new file with mode: 0644]
underlays/javascript/ikiwiki.js

index 85d8eea68419cb350e530c322958796186e05b1f..00eadfd9818e6e41adc36457b6bb45361355817b 100644 (file)
@@ -17,22 +17,27 @@ use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase
            %forcerebuild %loaded_plugins};
 
 use Exporter q{import};
-our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
-                 pagespec_match_list bestlink htmllink readfile writefile
-                pagetype srcfile pagename displaytime will_render gettext urlto
-                targetpage add_underlay pagetitle titlepage linkpage
-                newpagefile inject add_link
+our @EXPORT = qw(hook debug error template htmlpage deptype
+                 add_depends pagespec_match pagespec_match_list bestlink
+                htmllink readfile writefile pagetype srcfile pagename
+                displaytime will_render gettext ngettext urlto targetpage
+                add_underlay pagetitle titlepage linkpage newpagefile
+                inject add_link
                  %config %links %pagestate %wikistate %renderedfiles
                  %pagesources %destsources);
 our $VERSION = 3.00; # plugin interface version, next is ikiwiki version
 our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE
 our $installdir='/usr'; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE
 
+# Page dependency types.
+our $DEPEND_CONTENT=1;
+our $DEPEND_PRESENCE=2;
+our $DEPEND_LINKS=4;
+
 # Optimisation.
 use Memoize;
 memoize("abs2rel");
 memoize("pagespec_translate");
-memoize("file_pruned");
 memoize("template_file");
 
 sub getsetup () {
@@ -404,6 +409,13 @@ sub getsetup () {
                safe => 0,
                rebuild => 0,
        },
+       clean => {
+               type => "internal",
+               default => 0,
+               description => "running in clean mode",
+               safe => 0,
+               rebuild => 0,
+       },
        refresh => {
                type => "internal",
                default => 0,
@@ -544,12 +556,12 @@ sub loadplugins () {
        }
        
        if ($config{rcs}) {
-               if (exists $IkiWiki::hooks{rcs}) {
+               if (exists $hooks{rcs}) {
                        error(gettext("cannot use multiple rcs plugins"));
                }
                loadplugin($config{rcs});
        }
-       if (! exists $IkiWiki::hooks{rcs}) {
+       if (! exists $hooks{rcs}) {
                loadplugin("norcs");
        }
 
@@ -876,7 +888,7 @@ sub bestlink ($$) {
                $l.="/" if length $l;
                $l.=$link;
 
-               if (exists $links{$l}) {
+               if (exists $pagesources{$l}) {
                        return $l;
                }
                elsif (exists $pagecase{lc $l}) {
@@ -886,7 +898,7 @@ sub bestlink ($$) {
 
        if (length $config{userdir}) {
                my $l = "$config{userdir}/".lc($link);
-               if (exists $links{$l}) {
+               if (exists $pagesources{$l}) {
                        return $l;
                }
                elsif (exists $pagecase{lc $l}) {
@@ -936,7 +948,12 @@ sub linkpage ($) {
 sub cgiurl (@) {
        my %params=@_;
 
-       return $config{cgiurl}."?".
+       my $cgiurl=$config{cgiurl};
+       if (exists $params{cgiurl}) {
+               $cgiurl=$params{cgiurl};
+               delete $params{cgiurl};
+       }
+       return $cgiurl."?".
                join("&amp;", map $_."=".uri_escape_utf8($params{$_}), keys %params);
 }
 
@@ -1076,16 +1093,20 @@ sub htmllink ($$$;@) {
        }
 
        my @attrs;
-       if (defined $opts{rel}) {
-               push @attrs, ' rel="'.$opts{rel}.'"';
-       }
-       if (defined $opts{class}) {
-               push @attrs, ' class="'.$opts{class}.'"';
+       foreach my $attr (qw{rel class title}) {
+               if (defined $opts{$attr}) {
+                       push @attrs, " $attr=\"$opts{$attr}\"";
+               }
        }
 
        return "<a href=\"$bestlink\"@attrs>$linktext</a>";
 }
 
+sub userpage ($) {
+       my $user=shift;
+       return length $config{userdir} ? "$config{userdir}/$user" : $user;
+}
+
 sub openiduser ($) {
        my $user=shift;
 
@@ -1094,11 +1115,10 @@ sub openiduser ($) {
                my $display;
 
                if (Net::OpenID::VerifiedIdentity->can("DisplayOfURL")) {
-                       # this works in at least 2.x
                        $display = Net::OpenID::VerifiedIdentity::DisplayOfURL($user);
                }
                else {
-                       # this only works in 1.x
+                       # backcompat with old version
                        my $oid=Net::OpenID::VerifiedIdentity->new(identity => $user);
                        $display=$oid->display;
                }
@@ -1121,23 +1141,6 @@ sub openiduser ($) {
        return;
 }
 
-sub userlink ($) {
-       my $user=shift;
-
-       my $oiduser=eval { openiduser($user) };
-       if (defined $oiduser) {
-               return "<a href=\"$user\">$oiduser</a>";
-       }
-       else {
-               eval q{use CGI 'escapeHTML'};
-               error($@) if $@;
-
-               return htmllink("", "", escapeHTML(
-                       length $config{userdir} ? $config{userdir}."/".$user : $user
-               ), noimageinline => 1);
-       }
-}
-
 sub htmlize ($$$$) {
        my $page=shift;
        my $destpage=shift;
@@ -1224,7 +1227,7 @@ sub preprocess ($$$;$$) {
                                (?:
                                        """(.*?)"""     # 2: triple-quoted value
                                |
-                                       "([^"]+)"       # 3: single-quoted value
+                                       "([^"]*?)"      # 3: single-quoted value
                                |
                                        (\S+)           # 4: unquoted value
                                )
@@ -1310,7 +1313,7 @@ sub preprocess ($$$;$$) {
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
-                                               "[^"]+"         # single-quoted value
+                                               "[^"]*?"        # single-quoted value
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
@@ -1333,7 +1336,7 @@ sub preprocess ($$$;$$) {
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
-                                               "[^"]+"         # single-quoted value
+                                               "[^"]*?"        # single-quoted value
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
@@ -1403,7 +1406,7 @@ sub check_content (@) {
                my %old=map { $_ => 1 }
                        split("\n", readfile(srcfile($pagesources{$params{page}})));
                foreach my $line (split("\n", $params{content})) {
-                       push @diff, $line if ! exists $old{$_};
+                       push @diff, $line if ! exists $old{$line};
                }
                $params{diff}=join("\n", @diff);
        }
@@ -1524,18 +1527,28 @@ sub loadindex () {
                                $links{$page}=$d->{links};
                                $oldlinks{$page}=[@{$d->{links}}];
                        }
-                       if (exists $d->{depends_simple}) {
+                       if (ref $d->{depends_simple} eq 'ARRAY') {
+                               # old format
                                $depends_simple{$page}={
                                        map { $_ => 1 } @{$d->{depends_simple}}
                                };
                        }
+                       elsif (exists $d->{depends_simple}) {
+                               $depends_simple{$page}=$d->{depends_simple};
+                       }
                        if (exists $d->{dependslist}) {
+                               # old format
                                $depends{$page}={
-                                       map { $_ => 1 } @{$d->{dependslist}}
+                                       map { $_ => $DEPEND_CONTENT }
+                                               @{$d->{dependslist}}
                                };
                        }
+                       elsif (exists $d->{depends} && ! ref $d->{depends}) {
+                               # old format
+                               $depends{$page}={$d->{depends} => $DEPEND_CONTENT };
+                       }
                        elsif (exists $d->{depends}) {
-                               $depends{$page}={$d->{depends} => 1};
+                               $depends{$page}=$d->{depends};
                        }
                        if (exists $d->{state}) {
                                $pagestate{$page}=$d->{state};
@@ -1581,11 +1594,11 @@ sub saveindex () {
                };
 
                if (exists $depends{$page}) {
-                       $index{page}{$src}{dependslist} = [ keys %{$depends{$page}} ];
+                       $index{page}{$src}{depends} = $depends{$page};
                }
 
                if (exists $depends_simple{$page}) {
-                       $index{page}{$src}{depends_simple} = [ keys %{$depends_simple{$page}} ];
+                       $index{page}{$src}{depends_simple} = $depends_simple{$page};
                }
 
                if (exists $pagestate{$page}) {
@@ -1753,57 +1766,99 @@ sub rcs_receive () {
        $hooks{rcs}{rcs_receive}{call}->();
 }
 
-sub add_depends ($$) {
+sub add_depends ($$;$) {
        my $page=shift;
        my $pagespec=shift;
+       my $deptype=shift || $DEPEND_CONTENT;
 
+       # Is the pagespec a simple page name?
        if ($pagespec =~ /$config{wiki_file_regexp}/ &&
-               $pagespec !~ /[\s*?()!]/) {
-               # a simple dependency, which can be matched by string eq
-               $depends_simple{$page}{lc $pagespec} = 1;
+           $pagespec !~ /[\s*?()!]/) {
+               $depends_simple{$page}{lc $pagespec} |= $deptype;
                return 1;
        }
 
-       return unless pagespec_valid($pagespec);
+       # Add explicit dependencies for influences.
+       my $sub=pagespec_translate($pagespec);
+       return if $@;
+       foreach my $p (keys %pagesources) {
+               my $r=$sub->($p, location => $page);
+               my $i=$r->influences;
+               foreach my $k (keys %$i) {
+                       $depends_simple{$page}{lc $k} |= $i->{$k};
+               }
+               last if $r->influences_static;
+       }
 
-       $depends{$page}{$pagespec} = 1;
+       $depends{$page}{$pagespec} |= $deptype;
        return 1;
 }
 
-sub file_pruned ($$) {
-       require File::Spec;
-       my $file=File::Spec->canonpath(shift);
-       my $base=File::Spec->canonpath(shift);
-       $file =~ s#^\Q$base\E/+##;
+sub deptype (@) {
+       my $deptype=0;
+       foreach my $type (@_) {
+               if ($type eq 'presence') {
+                       $deptype |= $DEPEND_PRESENCE;
+               }
+               elsif ($type eq 'links') { 
+                       $deptype |= $DEPEND_LINKS;
+               }
+               elsif ($type eq 'content') {
+                       $deptype |= $DEPEND_CONTENT;
+               }
+       }
+       return $deptype;
+}
+
+sub file_pruned ($;$) {
+       my $file=shift;
+       if (@_) {
+               require File::Spec;
+               $file=File::Spec->canonpath($file);
+               my $base=File::Spec->canonpath(shift);
+               return if $file eq $base;
+               $file =~ s#^\Q$base\E/+##;
+       }
 
        my $regexp='('.join('|', @{$config{wiki_file_prune_regexps}}).')';
-       return $file =~ m/$regexp/ && $file ne $base;
+       return $file =~ m/$regexp/;
 }
 
 sub define_gettext () {
        # If translation is needed, redefine the gettext function to do it.
        # Otherwise, it becomes a quick no-op.
-       no warnings 'redefine';
+       my $gettext_obj;
+       my $getobj;
        if ((exists $ENV{LANG} && length $ENV{LANG}) ||
            (exists $ENV{LC_ALL} && length $ENV{LC_ALL}) ||
            (exists $ENV{LC_MESSAGES} && length $ENV{LC_MESSAGES})) {
-               *gettext=sub {
-                       my $gettext_obj=eval q{
+               $getobj=sub {
+                       $gettext_obj=eval q{
                                use Locale::gettext q{textdomain};
                                Locale::gettext->domain('ikiwiki')
                        };
-
-                       if ($gettext_obj) {
-                               $gettext_obj->get(shift);
-                       }
-                       else {
-                               return shift;
-                       }
                };
        }
-       else {
-               *gettext=sub { return shift };
-       }
+
+       no warnings 'redefine';
+       *gettext=sub {
+               $getobj->() if $getobj;
+               if ($gettext_obj) {
+                       $gettext_obj->get(shift);
+               }
+               else {
+                       return shift;
+               }
+       };
+       *ngettext=sub {
+               $getobj->() if $getobj;
+               if ($gettext_obj) {
+                       $gettext_obj->nget(@_);
+               }
+               else {
+                       return ($_[2] == 1 ? $_[0] : $_[1])
+               }
+       };
 }
 
 sub gettext {
@@ -1811,6 +1866,11 @@ sub gettext {
        gettext(@_);
 }
 
+sub ngettext {
+       define_gettext();
+       ngettext(@_);
+}
+
 sub yesno ($) {
        my $val=shift;
 
@@ -1870,13 +1930,13 @@ sub pagespec_translate ($) {
                        [^\s()]+        # any other text
                )
                \s*             # ignore whitespace
-       }igx) {
+       }gx) {
                my $word=$1;
                if (lc $word eq 'and') {
-                       $code.=' &&';
+                       $code.=' &';
                }
                elsif (lc $word eq 'or') {
-                       $code.=' ||';
+                       $code.=' |';
                }
                elsif ($word eq "(" || $word eq ")" || $word eq "!") {
                        $code.=' '.$word;
@@ -1922,27 +1982,87 @@ sub pagespec_match ($$;@) {
 }
 
 sub pagespec_match_list ($$;@) {
-       my $pages=shift;
-       my $spec=shift;
-       my @params=@_;
+       my $page=shift;
+       my $pagespec=shift;
+       my %params=@_;
 
-       my $sub=pagespec_translate($spec);
-       error "syntax error in pagespec \"$spec\""
-               if $@ || ! defined $sub;
-       
-       my @ret;
-       my $r;
-       foreach my $page (@$pages) {
-               $r=$sub->($page, @params);
-               push @ret, $page if $r;
+       # Backwards compatability with old calling convention.
+       if (ref $page) {
+               print STDERR "warning: a plugin (".caller().") is using pagespec_match_list in an obsolete way, and needs to be updated\n";
+               $params{list}=$page;
+               $page=$params{location}; # ugh!
        }
 
-       if (! @ret && defined $r && $r->isa("IkiWiki::ErrorReason")) {
-               error(sprintf(gettext("cannot match pages: %s"), $r));
+       my $sub=pagespec_translate($pagespec);
+       error "syntax error in pagespec \"$pagespec\""
+               if $@ || ! defined $sub;
+
+       my @candidates;
+       if (exists $params{list}) {
+               @candidates=exists $params{filter}
+                       ? grep { ! $params{filter}->($_) } @{$params{list}}
+                       : @{$params{list}};
        }
        else {
-               return @ret;
+               @candidates=exists $params{filter}
+                       ? grep { ! $params{filter}->($_) } keys %pagesources
+                       : keys %pagesources;
+       }
+
+       if (defined $params{sort}) {
+               my $f;
+               if ($params{sort} eq 'title') {
+                       $f=sub { pagetitle(basename($a)) cmp pagetitle(basename($b)) };
+               }
+               elsif ($params{sort} eq 'title_natural') {
+                       eval q{use Sort::Naturally};
+                       if ($@) {
+                               error(gettext("Sort::Naturally needed for title_natural sort"));
+                       }
+                       $f=sub { Sort::Naturally::ncmp(pagetitle(basename($a)), pagetitle(basename($b))) };
+                }
+               elsif ($params{sort} eq 'mtime') {
+                       $f=sub { $pagemtime{$b} <=> $pagemtime{$a} };
+               }
+               elsif ($params{sort} eq 'age') {
+                       $f=sub { $pagectime{$b} <=> $pagectime{$a} };
+               }
+               else {
+                       error sprintf(gettext("unknown sort type %s"), $params{sort});
+               }
+               @candidates = sort { &$f } @candidates;
+       }
+
+       @candidates=reverse(@candidates) if $params{reverse};
+       
+       $depends{$page}{$pagespec} |= ($params{deptype} || $DEPEND_CONTENT);
+       
+       # clear params, remainder is passed to pagespec
+       my $num=$params{num};
+       delete @params{qw{num deptype reverse sort filter list}};
+       
+       my @matches;
+       my $firstfail;
+       my $count=0;
+       my $accum=IkiWiki::SuccessReason->new();
+       foreach my $p (@candidates) {
+               my $r=$sub->($p, %params, location => $page);
+               error(sprintf(gettext("cannot match pages: %s"), $r))
+                       if $r->isa("IkiWiki::ErrorReason");
+               $accum |= $r;
+               if ($r) {
+                       push @matches, $p;
+                       last if defined $num && ++$count == $num;
+               }
+       }
+
+       # Add simple dependencies for accumulated influences.
+       my $i=$accum->influences;
+       foreach my $k (keys %$i) {
+               $depends_simple{$page}{lc $k} |= $i->{$k};
        }
+
+       return @matches;
 }
 
 sub pagespec_valid ($) {
@@ -1962,36 +2082,65 @@ sub glob2re ($) {
 package IkiWiki::FailReason;
 
 use overload (
-       '""'    => sub { ${$_[0]} },
+       '""'    => sub { $_[0][0] },
        '0+'    => sub { 0 },
        '!'     => sub { bless $_[0], 'IkiWiki::SuccessReason'},
+       '&'     => sub { $_[0]->merge_influences($_[1], 1); $_[0] },
+       '|'     => sub { $_[1]->merge_influences($_[0]); $_[1] },
        fallback => 1,
 );
 
-sub new {
-       my $class = shift;
-       my $value = shift;
-       return bless \$value, $class;
-}
-
-package IkiWiki::ErrorReason;
-
-our @ISA = 'IkiWiki::FailReason';
+our @ISA = 'IkiWiki::SuccessReason';
 
 package IkiWiki::SuccessReason;
 
 use overload (
-       '""'    => sub { ${$_[0]} },
+       '""'    => sub { $_[0][0] },
        '0+'    => sub { 1 },
        '!'     => sub { bless $_[0], 'IkiWiki::FailReason'},
+       '&'     => sub { $_[1]->merge_influences($_[0], 1); $_[1] },
+       '|'     => sub { $_[0]->merge_influences($_[1]); $_[0] },
        fallback => 1,
 );
 
 sub new {
        my $class = shift;
        my $value = shift;
-       return bless \$value, $class;
-};
+       return bless [$value, {@_}], $class;
+}
+
+sub influences {
+       my $this=shift;
+       $this->[1]={@_} if @_;
+       my %i=%{$this->[1]};
+       delete $i{""};
+       return \%i;
+}
+
+sub influences_static {
+       return ! $_[0][1]->{""};
+}
+
+sub merge_influences {
+       my $this=shift;
+       my $other=shift;
+       my $anded=shift;
+
+       if (! $anded || (($this || %{$this->[1]}) &&
+                       ($other || %{$other->[1]}))) {
+               foreach my $influence (keys %{$other->[1]}) {
+                       $this->[1]{$influence} |= $other->[1]{$influence};
+               }
+       }
+       else {
+               # influence blocker
+               $this->[1]={};
+       }
+}
+
+package IkiWiki::ErrorReason;
+
+our @ISA = 'IkiWiki::FailReason';
 
 package IkiWiki::PageSpec;
 
@@ -2042,27 +2191,30 @@ sub match_link ($$;@) {
        my $from=exists $params{location} ? $params{location} : '';
 
        my $links = $IkiWiki::links{$page};
-       return IkiWiki::FailReason->new("$page has no links") unless $links && @{$links};
+       return IkiWiki::FailReason->new("$page has no links", "" => 1)
+               unless $links && @{$links};
        my $bestlink = IkiWiki::bestlink($from, $link);
        foreach my $p (@{$links}) {
                if (length $bestlink) {
-                       return IkiWiki::SuccessReason->new("$page links to $link")
+                       return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if $bestlink eq IkiWiki::bestlink($page, $p);
                }
                else {
-                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link")
+                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
                                if match_glob($p, $link, %params);
-                       $p=~s/^\///;
+                       my ($p_rel)=$p=~/^\/?(.*)/;
                        $link=~s/^\///;
-                       return IkiWiki::SuccessReason->new("$page links to page $p matching $link")
-                               if match_glob($p, $link, %params);
+                       return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1)
+                               if match_glob($p_rel, $link, %params);
                }
        }
-       return IkiWiki::FailReason->new("$page does not link to $link");
+       return IkiWiki::FailReason->new("$page does not link to $link", "" => 1);
 }
 
 sub match_backlink ($$;@) {
-       return match_link($_[1], $_[0], @_);
+       my $ret=match_link($_[1], $_[0], @_);
+       $ret->influences($_[1] => $IkiWiki::DEPEND_LINKS);
+       return $ret;
 }
 
 sub match_created_before ($$;@) {
@@ -2074,14 +2226,14 @@ sub match_created_before ($$;@) {
 
        if (exists $IkiWiki::pagectime{$testpage}) {
                if ($IkiWiki::pagectime{$page} < $IkiWiki::pagectime{$testpage}) {
-                       return IkiWiki::SuccessReason->new("$page created before $testpage");
+                       return IkiWiki::SuccessReason->new("$page created before $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
                }
                else {
-                       return IkiWiki::FailReason->new("$page not created before $testpage");
+                       return IkiWiki::FailReason->new("$page not created before $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
                }
        }
        else {
-               return IkiWiki::ErrorReason->new("$testpage does not exist");
+               return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage => $IkiWiki::DEPEND_PRESENCE);
        }
 }
 
@@ -2094,14 +2246,14 @@ sub match_created_after ($$;@) {
 
        if (exists $IkiWiki::pagectime{$testpage}) {
                if ($IkiWiki::pagectime{$page} > $IkiWiki::pagectime{$testpage}) {
-                       return IkiWiki::SuccessReason->new("$page created after $testpage");
+                       return IkiWiki::SuccessReason->new("$page created after $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
                }
                else {
-                       return IkiWiki::FailReason->new("$page not created after $testpage");
+                       return IkiWiki::FailReason->new("$page not created after $testpage", $testpage => $IkiWiki::DEPEND_PRESENCE);
                }
        }
        else {
-               return IkiWiki::ErrorReason->new("$testpage does not exist");
+               return IkiWiki::ErrorReason->new("$testpage does not exist", $testpage => $IkiWiki::DEPEND_PRESENCE);
        }
 }
 
@@ -2137,11 +2289,13 @@ sub match_user ($$;@) {
        my $user=shift;
        my %params=@_;
        
+       my $regexp=IkiWiki::glob2re($user);
+       
        if (! exists $params{user}) {
                return IkiWiki::ErrorReason->new("no user specified");
        }
 
-       if (defined $params{user} && lc $params{user} eq lc $user) {
+       if (defined $params{user} && $params{user}=~/^$regexp$/i) {
                return IkiWiki::SuccessReason->new("user is $user");
        }
        elsif (! defined $params{user}) {
index 64a481ce01f49ce2a5427695f4448da24340a232..d7c85ecb88c93b286cabe23ddb218c4f3fb48b68 100644 (file)
@@ -15,7 +15,8 @@ sub printheader ($) {
        if ($config{sslcookie}) {
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1, -secure => 1));
-       } else {
+       }
+       else {
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1));
        }
@@ -40,7 +41,8 @@ sub showform ($$$$;@) {
 
 sub redirect ($$) {
        my $q=shift;
-       my $url=shift;
+       eval q{use URI};
+       my $url=URI->new(shift);
        if (! $config{w3mmode}) {
                print $q->redirect($url);
        }
@@ -51,7 +53,7 @@ sub redirect ($$) {
 }
 
 sub decode_cgi_utf8 ($) {
-       # decode_form_utf8 method is needed for 5.10
+       # decode_form_utf8 method is needed for 5.01
        if ($] < 5.01) {
                my $cgi = shift;
                foreach my $f ($cgi->param) {
@@ -64,8 +66,9 @@ sub decode_form_utf8 ($) {
        if ($] >= 5.01) {
                my $form = shift;
                foreach my $f ($form->field) {
+                       my @value=map { decode_utf8($_) } $form->field($f);
                        $form->field(name  => $f,
-                                    value => decode_utf8($form->field($f)),
+                                    value => \@value,
                                     force => 1,
                        );
                }
@@ -244,11 +247,15 @@ sub cgi_prefs ($$) {
        showform($form, $buttons, $session, $q);
 }
 
-sub cgi_custom_failure ($$) {
-       my $header=shift;
+sub cgi_custom_failure ($$$) {
+       my $q=shift;
+       my $httpstatus=shift;
        my $message=shift;
 
-       print $header;
+       print $q->header(
+               -status => $httpstatus,
+               -charset => 'utf-8',
+       );
        print $message;
 
        # Internet Explod^Hrer won't show custom 404 responses
@@ -283,7 +290,7 @@ sub check_banned ($$) {
                $session->delete();
                cgi_savesession($session);
                cgi_custom_failure(
-                       $q->header(-status => "403 Forbidden"),
+                       $q, "403 Forbidden",
                        gettext("You are banned."));
        }
 }
index bae9e15d1a67ea8705626d69dc69cdc486e68306..8adfd5dd99668c526168b09ba4f0fc334873d578 100644 (file)
@@ -21,6 +21,7 @@ sub getsetup () {
                        # server admin action too
                        safe => 0,
                        rebuild => 0,
+                       section => "web",
                }
 }
 
@@ -69,7 +70,8 @@ sub cgi ($) {
 
        if (exists $ENV{REDIRECT_STATUS} && 
            $ENV{REDIRECT_STATUS} eq '404') {
-               my $page = cgi_page_from_404($ENV{REDIRECT_URL},
+               my $page = cgi_page_from_404(
+                       Encode::decode_utf8($ENV{REDIRECT_URL}),
                        $config{url}, $config{usedirs});
                IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
        }
index 3571c4189e43fe5b70e1032832a6978cded1af6b..cfd8cd3477f81dd0758564994f35979419e330a0 100644 (file)
@@ -132,6 +132,10 @@ sub getbucket {
                });
        }
 
+       if (! $bucket) {
+               # Try to use existing bucket.
+               $bucket=$s3->bucket($config{amazon_s3_bucket});
+       }
        if (! $bucket) {
                error(gettext("Failed to create S3 bucket: ").
                        $s3->err.": ".$s3->errstr."\n");
@@ -178,7 +182,7 @@ sub writefile ($$$;$$) {
 
        # First, write the file to disk.
        my $ret=$IkiWiki::Plugin::amazon_s3::subs{'IkiWiki::writefile'}->($file, $destdir, $content, $binary, $writer);
-               
+
        my @keys=IkiWiki::Plugin::amazon_s3::file2keys("$destdir/$file");
 
        # Store the data in S3.
index 243b9892056028ea3cd289257c70274a54a410f6..0e74cbfadfbe71986ae2755b98d979cd3d00cb9b 100644 (file)
@@ -15,6 +15,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
                anonok_pagespec => {
                        type => "pagespec",
index 087c315a9af355569921c9150c05c0ba89ec8df1..ad1dd9bcaabdd24dbe111093b57face731ab3bbf 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "web",
                },
                allowed_attachments => {
                        type => "pagespec",
@@ -112,7 +113,7 @@ sub formbuilder (@) {
 
        return if ! defined $form->field("do") || ($form->field("do") ne "edit" && $form->field("do") ne "create") ;
 
-       my $filename=$q->param('attachment');
+       my $filename=Encode::decode_utf8($q->param('attachment'));
        if (defined $filename && length $filename &&
             ($form->submitted eq "Upload Attachment" || $form->submitted eq "Save Page")) {
                my $session=$params{session};
@@ -189,9 +190,10 @@ sub formbuilder (@) {
                IkiWiki::saveindex();
        }
        elsif ($form->submitted eq "Insert Links") {
-               my $page=quotemeta($q->param("page"));
+               my $page=quotemeta(Encode::decode_utf8($q->param("page")));
                my $add="";
                foreach my $f ($q->param("attachment_select")) {
+                       $f=Encode::decode_utf8($f);
                        $f=~s/^$page\///;
                        $add.="[[$f]]\n";
                }
@@ -230,6 +232,7 @@ 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},
                        };
                }
        }
index 626c8ec42acc8f69297d416ef358e66702a153b3..c4e5cf390cb397a994414bf718c135b4bf498c22 100644 (file)
@@ -18,6 +18,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
                blogspam_pagespec => {
                        type => 'pagespec',
index eb698b0bef9f7b2c9df90b342dcfac56c79a1795..8ee734bf947b6137a2925bac3eeb69ebc965a9bd 100644 (file)
@@ -23,19 +23,15 @@ sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
-       # Needs to update whenever a page is added or removed, so
-       # register a dependency.
-       add_depends($params{page}, $params{pages});
-       
        my @broken;
        foreach my $link (keys %IkiWiki::brokenlinks) {
                next if $link =~ /.*\/\Q$config{discussionpage}\E/i && $config{discussion};
 
-               my @pages;
-               foreach my $page (@{$IkiWiki::brokenlinks{$link}}) {
-                       push @pages, $page
-                               if pagespec_match($page, $params{pages}, location => $params{page});
-               }
+               my @pages=pagespec_match_list($params{page}, $params{pages},
+                       list => $IkiWiki::brokenlinks{$link},
+                       # needs to update when links on a page change
+                       deptype => deptype("links")
+               );
                next unless @pages;
 
                my $page=$IkiWiki::brokenlinks{$link}->[0];
index 8830073672663b77d2e21fb837a15a913b7b6c0d..1ffdc23535d81578b9fab129953659028a6ec96e 100644 (file)
@@ -36,6 +36,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                bzr_wrapper => {
                        type => "string",
index 5d16dff75ba7a98a68c3fc8c94d9d9378cb11732..aaee2c61000d743bebbe62023092278e4b6608a2 100644 (file)
@@ -24,8 +24,6 @@ use IkiWiki 3.00;
 use Time::Local;
 use POSIX;
 
-my %cache;
-my %linkcache;
 my $time=time;
 my @now=localtime($time);
 
@@ -40,6 +38,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
                archivebase => {
                        type => "string",
@@ -67,23 +66,50 @@ sub month_days {
 sub format_month (@) {
        my %params=@_;
 
-       my $pagespec = $params{pages};
-       my $year     = $params{year};
-       my $month    = $params{month};
-       my $pmonth   = $params{pmonth};
-       my $nmonth   = $params{nmonth};
-       my $pyear    = $params{pyear};
-       my $nyear    = $params{nyear};
+       my %linkcache;
+       foreach my $p (pagespec_match_list($params{page}, 
+                               "creation_year($params{year}) and creation_month($params{month}) and ($params{pages})",
+                               # add presence dependencies to update
+                               # month calendar when pages are added/removed
+                               deptype => deptype("presence"))) {
+               my $mtime = $IkiWiki::pagectime{$p};
+               my @date  = localtime($mtime);
+               my $mday  = $date[3];
+               my $month = $date[4] + 1;
+               my $year  = $date[5] + 1900;
+               my $mtag  = sprintf("%02d", $month);
+
+               # Only one posting per day is being linked to.
+               $linkcache{"$year/$mtag/$mday"} = $p;
+       }
+               
+       my $pmonth = $params{month} - 1;
+       my $nmonth = $params{month} + 1;
+       my $pyear  = $params{year};
+       my $nyear  = $params{year};
+
+       # Adjust for January and December
+       if ($params{month} == 1) {
+               $pmonth = 12;
+               $pyear--;
+       }
+       if ($params{month} == 12) {
+               $nmonth = 1;
+               $nyear++;
+       }
+
+       # Add padding.
+       $pmonth=sprintf("%02d", $pmonth);
+       $nmonth=sprintf("%02d", $nmonth);
 
-       my @list;
        my $calendar="\n";
 
        # When did this month start?
-       my @monthstart = localtime(timelocal(0,0,0,1,$month-1,$year-1900));
+       my @monthstart = localtime(timelocal(0,0,0,1,$params{month}-1,$params{year}-1900));
 
        my $future_dom = 0;
        my $today      = 0;
-       if ($year == $now[5]+1900 && $month == $now[4]+1) {
+       if ($params{year} == $now[5]+1900 && $params{month} == $now[4]+1) {
                $future_dom = $now[3]+1;
                $today      = $now[3];
        }
@@ -99,24 +125,33 @@ sub format_month (@) {
   
        # Calculate URL's for monthly archives.
        my ($url, $purl, $nurl)=("$monthname",'','');
-       if (exists $cache{$pagespec}{"$year/$month"}) {
+       if (exists $pagesources{"$archivebase/$params{year}/$params{month}"}) {
                $url = htmllink($params{page}, $params{destpage}, 
-                       "$archivebase/$year/".sprintf("%02d", $month),
-                       linktext => " $monthname ");
+                       "$archivebase/$params{year}/".$params{month},
+                       noimageinline => 1,
+                       linktext => $monthname,
+                       title => $monthname);
        }
-       add_depends($params{page}, "$archivebase/$year/".sprintf("%02d", $month));
-       if (exists $cache{$pagespec}{"$pyear/$pmonth"}) {
+       add_depends($params{page}, "$archivebase/$params{year}/$params{month}",
+               deptype("presence"));
+       if (exists $pagesources{"$archivebase/$pyear/$pmonth"}) {
                $purl = htmllink($params{page}, $params{destpage}, 
-                       "$archivebase/$pyear/" . sprintf("%02d", $pmonth),
-                       linktext => " $pmonthname ");
+                       "$archivebase/$pyear/$pmonth",
+                       noimageinline => 1,
+                       linktext => "\&larr;",
+                       title => $pmonthname);
        }
-       add_depends($params{page}, "$archivebase/$pyear/".sprintf("%02d", $pmonth));
-       if (exists $cache{$pagespec}{"$nyear/$nmonth"}) {
+       add_depends($params{page}, "$archivebase/$pyear/$pmonth",
+               deptype("presence"));
+       if (exists $pagesources{"$archivebase/$nyear/$nmonth"}) {
                $nurl = htmllink($params{page}, $params{destpage}, 
-                       "$archivebase/$nyear/" . sprintf("%02d", $nmonth),
-                       linktext => " $nmonthname ");
+                       "$archivebase/$nyear/$nmonth",
+                       noimageinline => 1,
+                       linktext => "\&rarr;",
+                       title => $nmonthname);
        }
-       add_depends($params{page}, "$archivebase/$nyear/".sprintf("%02d", $nmonth));
+       add_depends($params{page}, "$archivebase/$nyear/$nmonth",
+               deptype("presence"));
 
        # Start producing the month calendar
        $calendar=<<EOF;
@@ -137,12 +172,12 @@ EOF
        my %downame;
        my %dowabbr;
        for my $dow ($week_start_day..$week_start_day+6) {
-               my @day=localtime(timelocal(0,0,0,$start_day++,$month-1,$year-1900));
+               my @day=localtime(timelocal(0,0,0,$start_day++,$params{month}-1,$params{year}-1900));
                my $downame = POSIX::strftime("%A", @day);
                my $dowabbr = POSIX::strftime("%a", @day);
                $downame{$dow % 7}=$downame;
                $dowabbr{$dow % 7}=$dowabbr;
-               $calendar.= qq{\t\t<th class="month-calendar-day-head $downame">$dowabbr</th>\n};
+               $calendar.= qq{\t\t<th class="month-calendar-day-head $downame" title="$downame">$dowabbr</th>\n};
        }
 
        $calendar.=<<EOF;
@@ -158,9 +193,9 @@ EOF
 
        # At this point, either the first is a week_start_day, in which case
        # nothing has been printed, or else we are in the middle of a row.
-       for (my $day = 1; $day <= month_days(year => $year, month => $month);
+       for (my $day = 1; $day <= month_days(year => $params{year}, month => $params{month});
             $day++, $wday++, $wday %= 7) {
-               # At tihs point, on a week_start_day, we close out a row,
+               # At this point, on a week_start_day, we close out a row,
                # and start a new one -- unless it is week_start_day on the
                # first, where we do not close a row -- since none was started.
                if ($wday == $week_start_day) {
@@ -169,8 +204,8 @@ EOF
                }
                
                my $tag;
-               my $mtag = sprintf("%02d", $month);
-               if (defined $cache{$pagespec}{"$year/$mtag/$day"}) {
+               my $key="$params{year}/$params{month}/$day";
+               if (defined $linkcache{$key}) {
                        if ($day == $today) {
                                $tag='month-calendar-day-this-day';
                        }
@@ -179,9 +214,10 @@ EOF
                        }
                        $calendar.=qq{\t\t<td class="$tag $downame{$wday}">};
                        $calendar.=htmllink($params{page}, $params{destpage}, 
-                                           pagename($linkcache{"$year/$mtag/$day"}),
-                                           "linktext" => "$day");
-                       push @list, pagename($linkcache{"$year/$mtag/$day"});
+                               $linkcache{$key},
+                               noimageinline => 1,
+                               linktext => $day,
+                               title => pagetitle(IkiWiki::basename($linkcache{$key})));
                        $calendar.=qq{</td>\n};
                }
                else {
@@ -207,58 +243,65 @@ EOF
 </table>
 EOF
 
-       # Add dependencies to update the calendar whenever pages
-       # matching the pagespec are added or removed.
-       add_depends($params{page}, $params{pages});
-       # Explicitly add all currently linked pages as dependencies, so
-       # that if they are removed, the calendar will be sure to be updated.
-       foreach my $p (@list) {
-               add_depends($params{page}, $p);
-       }
-
        return $calendar;
 }
 
 sub format_year (@) {
        my %params=@_;
-
-       my $pagespec = $params{pages};
-       my $year     = $params{year};
-       my $month    = $params{month};
-       my $pmonth   = $params{pmonth};
-       my $nmonth   = $params{nmonth};
-       my $pyear    = $params{pyear};
-       my $nyear    = $params{nyear};
-
+       
+       my @post_months;
+       foreach my $p (pagespec_match_list($params{page}, 
+                               "creation_year($params{year}) and ($params{pages})",
+                               # add presence dependencies to update
+                               # year calendar's links to months when
+                               # pages are added/removed
+                               deptype => deptype("presence"))) {
+               my $mtime = $IkiWiki::pagectime{$p};
+               my @date  = localtime($mtime);
+               my $month = $date[4] + 1;
+
+               $post_months[$month]++;
+       }
+               
        my $calendar="\n";
+       
+       my $pyear = $params{year}  - 1;
+       my $nyear = $params{year}  + 1;
 
+       my $thisyear = $now[5]+1900;
        my $future_month = 0;
-       $future_month = $now[4]+1 if ($year == $now[5]+1900);
+       $future_month = $now[4]+1 if $params{year} == $thisyear;
 
        my $archivebase = 'archives';
        $archivebase = $config{archivebase} if defined $config{archivebase};
        $archivebase = $params{archivebase} if defined $params{archivebase};
 
        # calculate URL's for previous and next years
-       my ($url, $purl, $nurl)=("$year",'','');
-       if (exists $cache{$pagespec}{"$year"}) {
+       my ($url, $purl, $nurl)=("$params{year}",'','');
+       if (exists $pagesources{"$archivebase/$params{year}"}) {
                $url = htmllink($params{page}, $params{destpage}, 
-                       "$archivebase/$year",
-                       linktext => "$year");
+                       "$archivebase/$params{year}",
+                       noimageinline => 1,
+                       linktext => $params{year},
+                       title => $params{year});
        }
-       add_depends($params{page}, "$archivebase/$year");
-       if (exists $cache{$pagespec}{"$pyear"}) {
+       add_depends($params{page}, "$archivebase/$params{year}", deptype("presence"));
+       if (exists $pagesources{"$archivebase/$pyear"}) {
                $purl = htmllink($params{page}, $params{destpage}, 
                        "$archivebase/$pyear",
-                       linktext => "\&larr;");
+                       noimageinline => 1,
+                       linktext => "\&larr;",
+                       title => $pyear);
        }
-       add_depends($params{page}, "$archivebase/$pyear");
-       if (exists $cache{$pagespec}{"$nyear"}) {
+       add_depends($params{page}, "$archivebase/$pyear", deptype("presence"));
+       if (exists $pagesources{"$archivebase/$nyear"}) {
                $nurl = htmllink($params{page}, $params{destpage}, 
                        "$archivebase/$nyear",
-                       linktext => "\&rarr;");
+                       noimageinline => 1,
+                       linktext => "\&rarr;",
+                       title => $nyear);
        }
-       add_depends($params{page}, "$archivebase/$nyear");
+       add_depends($params{page}, "$archivebase/$nyear", deptype("presence"));
 
        # Start producing the year calendar
        $calendar=<<EOF;
@@ -273,36 +316,34 @@ sub format_year (@) {
        </tr>
 EOF
 
-       for ($month = 1; $month <= 12; $month++) {
-               my @day=localtime(timelocal(0,0,0,15,$month-1,$year-1900));
+       for (my $month = 1; $month <= 12; $month++) {
+               my @day=localtime(timelocal(0,0,0,15,$month-1,$params{year}-1900));
                my $murl;
                my $monthname = POSIX::strftime("%B", @day);
                my $monthabbr = POSIX::strftime("%b", @day);
                $calendar.=qq{\t<tr>\n}  if ($month % $params{months_per_row} == 1);
                my $tag;
                my $mtag=sprintf("%02d", $month);
-               if ($month == $params{month}) {
-                       if ($cache{$pagespec}{"$year/$mtag"}) {
-                               $tag = 'this_month_link';
-                       }
-                       else {
-                               $tag = 'this_month_nolink';
-                       }
+               if ($month == $params{month} && $thisyear == $params{year}) {
+                       $tag = 'year-calendar-this-month';
                }
-               elsif ($cache{$pagespec}{"$year/$mtag"}) {
-                       $tag = 'month_link';
+               elsif ($pagesources{"$archivebase/$params{year}/$mtag"}) {
+                       $tag = 'year-calendar-month-link';
                } 
                elsif ($future_month && $month >= $future_month) {
-                       $tag = 'month_future';
+                       $tag = 'year-calendar-month-future';
                } 
                else {
-                       $tag = 'month_nolink';
+                       $tag = 'year-calendar-month-nolink';
                }
 
-               if ($cache{$pagespec}{"$year/$mtag"}) {
+               if ($pagesources{"$archivebase/$params{year}/$mtag"} &&
+                   $post_months[$mtag]) {
                        $murl = htmllink($params{page}, $params{destpage}, 
-                               "$archivebase/$year/$mtag",
-                               linktext => "$monthabbr");
+                               "$archivebase/$params{year}/$mtag",
+                               noimageinline => 1,
+                               linktext => $monthabbr,
+                               title => $monthname);
                        $calendar.=qq{\t<td class="$tag">};
                        $calendar.=$murl;
                        $calendar.=qq{\t</td>\n};
@@ -310,7 +351,8 @@ EOF
                else {
                        $calendar.=qq{\t<td class="$tag">$monthabbr</td>\n};
                }
-               add_depends($params{page}, "$archivebase/$year/$mtag");
+               add_depends($params{page}, "$archivebase/$params{year}/$mtag",
+                       deptype("presence"));
 
                $calendar.=qq{\t</tr>\n} if ($month % $params{months_per_row} == 0);
        }
@@ -324,74 +366,63 @@ EOF
 
 sub preprocess (@) {
        my %params=@_;
+
+       my $thisyear=1900 + $now[5];
+       my $thismonth=1 + $now[4];
+
        $params{pages} = "*"            unless defined $params{pages};
        $params{type}  = "month"        unless defined $params{type};
-       $params{month} = sprintf("%02d", $params{month}) if defined  $params{month};
        $params{week_start_day} = 0     unless defined $params{week_start_day};
        $params{months_per_row} = 3     unless defined $params{months_per_row};
-
-       if (! defined $params{year} || ! defined $params{month}) {
-               # Record that the calendar next changes at midnight.
+       $params{year}  = $thisyear      unless defined $params{year};
+       $params{month} = $thismonth     unless defined $params{month};
+
+       $params{month} = sprintf("%02d", $params{month});
+                       
+       if ($params{type} eq 'month' && $params{year} == $thisyear
+           && $params{month} == $thismonth) {
+               # calendar for current month, updates next midnight
                $pagestate{$params{destpage}}{calendar}{nextchange}=($time
                        + (60 - $now[0])                # seconds
                        + (59 - $now[1]) * 60           # minutes
                        + (23 - $now[2]) * 60 * 60      # hours
                );
-               
-               $params{year}  = 1900 + $now[5] unless defined $params{year};
-               $params{month} = 1    + $now[4] unless defined $params{month};
        }
-       else {
-               delete $pagestate{$params{destpage}}{calendar};
+       elsif ($params{type} eq 'month' &&
+              (($params{year} == $thisyear && $params{month} > $thismonth) ||
+               $params{year} > $thisyear)) {
+               # calendar for upcoming month, updates 1st of that month
+               $pagestate{$params{destpage}}{calendar}{nextchange}=
+                       timelocal(0, 0, 0, 1, $params{month}-1, $params{year});
        }
-
-       # Calculate month names for next month, and previous months
-       my $pmonth = $params{month} - 1;
-       my $nmonth = $params{month} + 1;
-       my $pyear  = $params{year}  - 1;
-       my $nyear  = $params{year}  + 1;
-
-       # Adjust for January and December
-       if ($params{month} == 1) {
-               $pmonth = 12;
-               $pyear--;
+       elsif ($params{type} eq 'year' && $params{year} == $thisyear) {
+               # calendar for current year, updates 1st of next month
+               if ($thismonth < 12) {
+                       $pagestate{$params{destpage}}{calendar}{nextchange}=
+                               timelocal(0, 0, 0, 1, $thismonth+1-1, $params{year});
+               }
+               else {
+                       $pagestate{$params{destpage}}{calendar}{nextchange}=
+                               timelocal(0, 0, 0, 1, 1-1, $params{year}+1);
+               }
        }
-       if ($params{month} == 12) {
-               $nmonth = 1;
-               $nyear++;
+       elsif ($params{type} eq 'year' && $params{year} > $thisyear) {
+               # calendar for upcoming year, updates 1st of that year
+               $pagestate{$params{destpage}}{calendar}{nextchange}=
+                       timelocal(0, 0, 0, 1, 1-1, $params{year});
        }
-
-       $params{pmonth}=$pmonth;
-       $params{nmonth}=$nmonth;
-       $params{pyear} =$pyear;
-       $params{nyear} =$nyear;
-
-       my $calendar="\n";
-       my $pagespec=$params{pages};
-       my $page =$params{page};
-
-       if (! defined $cache{$pagespec}) {
-               foreach my $p (pagespec_match_list([keys %pagesources], $pagespec)) {
-                       my $mtime = $IkiWiki::pagectime{$p};
-                       my $src   = $pagesources{$p};
-                       my @date  = localtime($mtime);
-                       my $mday  = $date[3];
-                       my $month = $date[4] + 1;
-                       my $year  = $date[5] + 1900;
-                       my $mtag  = sprintf("%02d", $month);
-
-                       # Only one posting per day is being linked to.
-                       $linkcache{"$year/$mtag/$mday"} = "$src";
-                       $cache{$pagespec}{"$year"}++;
-                       $cache{$pagespec}{"$year/$mtag"}++;
-                       $cache{$pagespec}{"$year/$mtag/$mday"}++;
-               }
+       else {
+               # calendar for past month or year, does not need
+               # to update any more
+               delete $pagestate{$params{destpage}}{calendar};
        }
 
-       if ($params{type} =~ /month/i) {
+       # Calculate month names for next month, and previous months
+       my $calendar="";
+       if ($params{type} eq 'month') {
                $calendar=format_month(%params);
        }
-       elsif ($params{type} =~ /year/i) {
+       elsif ($params{type} eq 'year') {
                $calendar=format_year(%params);
        }
 
index 20505893b5885847370a99c84c900d6032d72ef9..d550dd9f4b42ba7759b44b9571f0bc959e026423 100644 (file)
@@ -10,6 +10,16 @@ use IkiWiki 3.00;
 sub import {
        hook(type => "preprocess", id => "color", call => \&preprocess);
        hook(type => "format",     id => "color", call => \&format);
+       hook(type => "getsetup",   id => "color", call => \&getsetup);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+                       section => "widget",
+               },
 }
 
 sub preserve_style ($$$) {
index 517e16f9ff8afd0ca3de21df8ace8558a03173bb..98786f4328412448138f578ae0f04834fec39f98 100644 (file)
@@ -38,6 +38,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "web",
                },
                comments_pagespec => {
                        type => 'pagespec',
@@ -171,9 +172,8 @@ sub preprocess {
                else {
                        $commentauthorurl = IkiWiki::cgiurl(
                                do => 'goto',
-                               page => (length $config{userdir}
-                                       ? "$config{userdir}/$commentuser"
-                                       : "$commentuser"));
+                               page => IkiWiki::userpage($commentuser)
+                       );
 
                        $commentauthor = $commentuser;
                }
@@ -224,7 +224,7 @@ sub preprocess {
                $pagestate{$page}{meta}{title} = $params{subject};
        }
 
-       if ($params{page} =~ m/\/(\Q$config{comments_pagename}\E\d+)$/) {
+       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});
        }
@@ -377,8 +377,6 @@ sub editcomment ($$) {
        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?
@@ -410,8 +408,11 @@ sub editcomment ($$) {
        my $subject = $form->field('subject');
        if (defined $subject && length $subject) {
                $subject =~ s/"/&quot;/g;
-               $content .= " subject=\"$subject\"\n";
        }
+       else {
+               $subject = "comment ".(num_comments($page, $config{srcdir}) + 1);
+       }
+       $content .= " subject=\"$subject\"\n";
 
        $content .= " date=\"" . decode_utf8(strftime('%Y-%m-%dT%H:%M:%SZ', gmtime)) . "\"\n";
 
@@ -421,6 +422,8 @@ sub editcomment ($$) {
        $editcontent =~ s/"/\\"/g;
        $content .= " content=\"\"\"\n$editcontent\n\"\"\"]]\n";
 
+       my $location=unique_comment_location($page, $content, $config{srcdir});
+
        # 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
@@ -458,7 +461,7 @@ sub editcomment ($$) {
 
                if (! $ok) {
                        my $penddir=$config{wikistatedir}."/comments_pending";
-                       $location=unique_comment_location($page, $penddir);
+                       $location=unique_comment_location($page, $content, $penddir);
                        writefile("$location._comment", $penddir, $content);
                        IkiWiki::printheader($session);
                        print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
@@ -554,7 +557,7 @@ sub commentmoderation ($$) {
                                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";
+                                       my $dest=unique_comment_location($page, $content, $config{srcdir})."._comment";
                                        writefile($dest, $config{srcdir}, $content);
                                        if ($config{rcs} and $config{comments_commit}) {
                                                IkiWiki::rcs_add($dest);
@@ -733,39 +736,43 @@ sub pagetemplate (@) {
                }
 
                if ($shown && commentsopen($page)) {
-                       my $addcommenturl = IkiWiki::cgiurl(do => 'comment',
-                               page => $page);
-                       $template->param(addcommenturl => $addcommenturl);
+                       $template->param(addcommenturl => addcommenturl($page));
                }
        }
 
-       if ($template->query(name => 'commentsurl')) {
-               if ($shown) {
+       if ($shown) {
+               if ($template->query(name => 'commentsurl')) {
                        $template->param(commentsurl =>
                                urlto($page, undef, 1).'#comments');
                }
-       }
 
-       if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
-               if ($shown) {
+               if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
                        # This will 404 until there are some comments, but I
                        # think that's probably OK...
                        $template->param(atomcommentsurl =>
                                urlto($page, undef, 1).'comments.atom');
                }
-       }
 
-       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"),
+               if ($template->query(name => 'commentslink')) {
+                       my $num=num_comments($page, $config{srcdir});
+                       my $link;
+                       if ($num > 0) {
+                               $link = htmllink($page, $params{destpage}, $page,
+                                       linktext => sprintf(ngettext("%i comment", "%i comments", $num), $num),
                                        anchor => "comments",
-                                       noimageinline => 1));
+                                       noimageinline => 1
+                               );
+                       }
+                       elsif (commentsopen($page)) {
+                               $link = "<a href=\"".addcommenturl($page)."\">".
+                                       #translators: Here "Comment" is a verb;
+                                       #translators: the user clicks on it to
+                                       #translators: post a comment.
+                                       gettext("Comment").
+                                       "</a>";
+                       }
+                       $template->param(commentslink => $link)
+                               if defined $link;
                }
        }
 
@@ -813,15 +820,34 @@ sub pagetemplate (@) {
        }
 }
 
-sub unique_comment_location ($) {
+sub addcommenturl ($) {
        my $page=shift;
+
+       return IkiWiki::cgiurl(do => 'comment', page => $page);
+}
+
+sub num_comments ($$) {
+       my $page=shift;
+       my $dir=shift;
+
+       my @comments=glob("$dir/$page/$config{comments_pagename}*._comment");
+       return @comments;
+}
+
+sub unique_comment_location ($$$) {
+       my $page=shift;
+
+       eval q{use Digest::MD5 'md5_hex'};
+       error($@) if $@;
+       my $content_md5=md5_hex(Encode::encode_utf8(shift));
+
        my $dir=shift;
 
        my $location;
-       my $i = 0;
+       my $i = num_comments($page, $dir);
        do {
                $i++;
-               $location = "$page/$config{comments_pagename}$i";
+               $location = "$page/$config{comments_pagename}${i}_${content_md5}";
        } while (-e "$dir/$location._comment");
 
        return $location;
@@ -829,14 +855,14 @@ sub unique_comment_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
+       # attribute 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);
+       return "comment-".md5_hex(Encode::encode_utf8(($page)));
 }
        
 package IkiWiki::PageSpec;
index 7445dbdad71420bb4228f573543ac673732b197c..892b1cff9e1d9958f19c9916f805415442cbce41 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -29,11 +30,10 @@ sub preprocess_if (@) {
        }
 
        my $result=0;
-       if ((exists $params{all} && lc $params{all} eq "no") ||
-               # An optimisation to avoid needless looping over every page
-               # and adding of dependencies for simple uses of some of the
-               # tests.
-               $params{test} =~ /^([\s\!()]*((enabled|sourcepage|destpage|included)\([^)]*\)|(and|or))[\s\!()]*)+$/) {
+       if (! IkiWiki::yesno($params{all}) ||
+           # An optimisation to avoid needless looping over every page
+           # for simple uses of some of the tests.
+           $params{test} =~ /^([\s\!()]*((enabled|sourcepage|destpage|included)\([^)]*\)|(and|or))[\s\!()]*)+$/) {
                add_depends($params{page}, "($params{test}) and $params{page}");
                $result=pagespec_match($params{page}, $params{test},
                                location => $params{page},
@@ -41,17 +41,12 @@ sub preprocess_if (@) {
                                destpage => $params{destpage});
        }
        else {
-               add_depends($params{page}, $params{test});
-
-               foreach my $page (keys %pagesources) {
-                       if (pagespec_match($page, $params{test}, 
-                                       location => $params{page},
-                                       sourcepage => $params{page},
-                                       destpage => $params{destpage})) {
-                               $result=1;
-                               last;
-                       }
-               }
+               $result=pagespec_match_list($params{page}, $params{test},
+                       # stop after first match
+                       num => 1,
+                       sourcepage => $params{page},
+                       destpage => $params{destpage},
+               );
        }
 
        my $ret;
index 425e71043f0133f5b855c32932bc114542c83d7d..a1e4b31d326c7d5d9f2480be501a09c1f43e0bbb 100644 (file)
@@ -17,6 +17,7 @@ sub getsetup {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
 }
 
index 417442f34e51d3e089186cd9f6839c001efb3bee..01e9ce043c90f2eb059f7abc6eb8093de717fb18 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index 1a0bad75fa3e9a272c7a4bdc42e31306931256ca..26a3e9dd291edf8e74c1aa6fdfbb91617f4bfd2d 100644 (file)
@@ -85,6 +85,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                cvsrepo => {
                        type => "string",
@@ -322,7 +323,7 @@ sub rcs_recentchanges($) {
        eval q{use File::ReadBackwards};
        error($@) if $@;
 
-       my (undef, $tmpfile) = tempfile(OPEN=>0);
+       my ($tmphandle, $tmpfile) = tempfile();
        system("env TZ=UTC cvsps -q --cvs-direct -z 30 -x >$tmpfile");
        if ($? == -1) {
                error "couldn't run cvsps: $!\n";
index 2448673ac49169024aea08b0e8305d8a8622d414..1c9538e83efb490a637b21bf2da818ddbe682bd6 100644 (file)
@@ -73,7 +73,7 @@ sub darcs_rev($) {
        my $file = shift; # Relative to the repodir.
        my $repodir = $config{srcdir};
 
-       return "" if (! file_in_vc($repodir, $file));
+       return "" unless file_in_vc($repodir, $file);
        my $hash = darcs_info('hash', $repodir, $file);
        return defined $hash ? $hash : "";
 }
@@ -92,6 +92,7 @@ sub getsetup() {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                darcs_wrapper => {
                        type => "string",
diff --git a/IkiWiki/Plugin/date.pm b/IkiWiki/Plugin/date.pm
new file mode 100644 (file)
index 0000000..ea5c9a9
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::date;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "getsetup", id => "date", call => \&getsetup);
+       hook(type => "preprocess", id => "date", call => \&preprocess);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+                       section => "widget",
+               },
+}
+
+sub preprocess (@) {
+       my $str=shift;
+
+       eval q{use Date::Parse};
+       error $@ if $@;
+       my $time = str2time($str);
+       if (! defined $time) {
+               error("unable to parse $str");
+       }
+       return displaytime($time);
+}
+
+1
index 7df6a9ffb42f53960f4881b43b34b86f49f6e798..d8f53a42ee6031b072dab134ec6c6740c156be3c 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "web",
                },
 }
 
index fca970c60be3a13199298ddf736c70d14dd2528d..44fe5514a7cf0017ce3a3f5c1193ed78c2af1108 100644 (file)
@@ -17,6 +17,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "core",
                },
 }
 
@@ -245,8 +246,9 @@ sub cgi_editpage ($$) {
                                        push @page_locs, $dir.$page;
                                }
                        
-                               push @page_locs, "$config{userdir}/$page"
-                                       if length $config{userdir};
+                               my $userpage=IkiWiki::userpage($page);
+                               push @page_locs, $userpage
+                                       if ! grep { $_ eq $userpage } @page_locs;
                        }
 
                        @page_locs = grep {
@@ -271,8 +273,10 @@ sub cgi_editpage ($$) {
                                check_canedit($_, $q, $session, 1)
                        } @page_locs;
                        if (! @editable_locs) {
-                               # let it throw an error this time
-                               map { check_canedit($_, $q, $session) } @page_locs;
+                               # now let it throw an error, or prompt for
+                               # login
+                               map { check_canedit($_, $q, $session) }
+                                       ($best_loc, @page_locs);
                        }
                        
                        my @page_types;
index 0bafc95d06d854b860e566a8c14134119d51db17..5f0551d9272972d34d685df5ecc57e3802ca054f 100644 (file)
@@ -23,6 +23,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "web",
                },
 }
 
@@ -55,10 +56,11 @@ sub preprocess (@) {
        }
 
        my $link=linkpage($params{template});
-       $pagestate{$params{page}}{edittemplate}{$params{match}}=$link;
+       my $bestlink=bestlink($params{page}, $link);
+       $pagestate{$params{page}}{edittemplate}{$params{match}}=$bestlink;
 
        return "" if ($params{silent} && IkiWiki::yesno($params{silent}));
-       add_depends($params{page}, $link);
+       add_depends($params{page}, $link, deptype("presence"));
        return sprintf(gettext("edittemplate %s registered for %s"),
                htmllink($params{page}, $params{destpage}, $link),
                $params{match});
@@ -82,10 +84,13 @@ sub formbuilder (@) {
        foreach my $field ($form->field) {
                if ($field eq 'page') {
                        @page_locs=$field->def_value;
-                       push @page_locs, $field->options;
+
+                       # FormBuilder is on the bad crack. See #551499
+                       my @options=map { ref $_ ? @$_ : $_ } $field->options;
+
+                       push @page_locs, @options;
                }
        }
-
        foreach my $p (@page_locs) {
                foreach my $registering_page (keys %pagestate) {
                        if (exists $pagestate{$registering_page}{edittemplate}) {
index 0d292dfc2520e0020e5eee164084d4ab93751a10..ec91c79db2149a1b58a63f34aedc4b83b7a76a4a 100644 (file)
@@ -8,7 +8,6 @@ use warnings;
 use strict;
 use IkiWiki 3.00;
 use RPC::XML;
-use RPC::XML::Parser;
 use IPC::Open2;
 use IO::Handle;
 
@@ -55,7 +54,19 @@ sub rpc_call ($$;@) {
                $plugin->{accum}.=$_;
                while ($plugin->{accum} =~ /^\s*(<\?xml\s.*?<\/(?:methodCall|methodResponse)>)\n(.*)/s) {
                        $plugin->{accum}=$2;
-                       my $r = RPC::XML::Parser->new->parse($1);
+                       my $parser;
+                       eval q{
+                               use RPC::XML::ParserFactory;
+                               $parser = RPC::XML::ParserFactory->new;
+                       };
+                       if ($@) {
+                               # old interface
+                               eval q{
+                                       use RPC::XML::Parser;
+                                       $parser = RPC::XML::Parser->new;
+                               };
+                       }
+                       my $r=$parser->parse($1);
                        error("XML RPC parser failure: $r") unless ref $r;
                        if ($r->isa('RPC::XML::response')) {
                                my $value=$r->value;
@@ -72,9 +83,9 @@ sub rpc_call ($$;@) {
 
                                        # XML-RPC v1 does not allow for
                                        # nil/null/None/undef values to be
-                                       # transmitted, so until
-                                       # XML::RPC::Parser honours v2
-                                       # (<nil/>), external plugins send
+                                       # transmitted. The <nil/> extension
+                                       # is the right fix, but for
+                                       # back-compat, let external plugins send
                                        # a hash with one key "null" pointing
                                        # to an empty string.
                                        if (exists $hash{null} &&
index 1513cbed72a67447fa8bcedd9bff1f10ce076262..d54e7113198093a2a939315077f7f99d34c529a8 100644 (file)
@@ -7,6 +7,16 @@ use IkiWiki 3.00;
 
 sub import {
        hook(type => "preprocess", id => "format", call => \&preprocess);
+       hook(type => "getsetup",   id => "format", call => \&getsetup);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => undef,
+                       section => "widget",
+               },
 }
 
 sub preprocess (@) {
index 17e57dea14fccb4c3f9e1c21a5926ef4880033cd..f481c7eacea7240b3b8032311d3c4e9b307bfe63 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index ae9ea3cc7af4ffe27b46d65528d380420ac5b368..b362de7264175d9468c4207dcacf9153ade356a5 100644 (file)
@@ -17,6 +17,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "web",
                },
                getsource_mimetype => {
                        type => "string",
@@ -58,7 +59,8 @@ sub cgi_getsource ($) {
 
        if (! exists $pagesources{$page}) {
                IkiWiki::cgi_custom_failure(
-                       $cgi->header(-status => "404 Not Found"),
+                       $cgi,
+                       "404 Not Found",
                        IkiWiki::misctemplate(gettext("missing page"),
                                "<p>".
                                sprintf(gettext("The page %s does not exist."),
index 1d94b927922de5f6263fb9a433423ec3a0a29a6d..e3e1448d357ac11ea611f4c14d9b81472258861d 100644 (file)
@@ -52,6 +52,9 @@ sub checkconfig () {
                        wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
                };
        }
+
+       # Avoid notes, parser does not handle and they only slow things down.
+       $ENV{GIT_NOTES_REF}="";
        
        # Run receive test only if being called by the wrapper, and not
        # when generating same.
@@ -66,6 +69,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                git_wrapper => {
                        type => "string",
@@ -420,7 +424,10 @@ sub git_sha1 (;$) {
                '--', $file);
        if ($sha1) {
                ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
-       } else { debug("Empty sha1sum for '$file'.") }
+       }
+       else {
+               debug("Empty sha1sum for '$file'.");
+       }
        return defined $sha1 ? $sha1 : q{};
 }
 
@@ -615,9 +622,15 @@ sub rcs_getctime ($) {
        # Remove srcdir prefix
        $file =~ s/^\Q$config{srcdir}\E\/?//;
 
-       my @sha1s = run_or_non('git', 'rev-list', 'HEAD', '--', $file);
-       my $ci    = git_commit_info($sha1s[$#sha1s], 1);
-       my $ctime = $ci->{'author_epoch'};
+       my @raw_lines = run_or_die('git', 'log', 
+               '--follow', '--no-merges',
+               '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
+               '-r', '--', $file);
+       my @ci;
+       while (my $parsed = parse_diff_tree("", \@raw_lines)) {
+               push @ci, $parsed;
+       }
+       my $ctime = $ci[$#ci]->{'author_epoch'};
        debug("ctime for '$file': ". localtime($ctime));
 
        return $ctime;
index 1683220e7ed659c8857ae2aae0fcf8ff966969f7..48ad4c8cea058f9a024bfdf99c01f5fcca8f4ca8 100644 (file)
@@ -6,8 +6,6 @@ use strict;
 use IkiWiki 3.00;
 use URI;
 
-my $host;
-
 sub import {
        hook(type => "getsetup", id => "google", call => \&getsetup);
        hook(type => "checkconfig", id => "google", call => \&checkconfig);
@@ -19,6 +17,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "web",
                },
 }
 
@@ -26,11 +25,6 @@ sub checkconfig () {
        if (! length $config{url}) {
                error(sprintf(gettext("Must specify %s when using the %s plugin"), "url", 'google'));
        }
-       my $uri=URI->new($config{url});
-       if (! $uri || ! defined $uri->host) {
-               error(gettext("Failed to parse url, cannot determine domain name"));
-       }
-       $host=$uri->host;
 }
 
 my $form;
@@ -43,7 +37,7 @@ sub pagetemplate (@) {
        if ($template->query(name => "searchform")) {
                if (! defined $form) {
                        my $searchform = template("googleform.tmpl", blind_cache => 1);
-                       $searchform->param(sitefqdn => $host);
+                       $searchform->param(url => $config{url});
                        $form=$searchform->output;
                }
 
index 2e2dc04a111a164745fb628785b509d40e024e6c..03bd682b3fed5114d6d43a52d603feb6c3e11348 100644 (file)
@@ -14,6 +14,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "web",
                }
 }
 
@@ -51,7 +52,8 @@ sub cgi_goto ($;$) {
 
        if (! length $link) {
                IkiWiki::cgi_custom_failure(
-                       $q->header(-status => "404 Not Found"),
+                       $q,
+                       "404 Not Found",
                        IkiWiki::misctemplate(gettext("missing page"),
                                "<p>".
                                sprintf(gettext("The page %s does not exist."),
index 32e994d6b96c4d10dce2998db005ac22729a7ce5..bec12207696ed5639b71dfd773bf261b8b1658b7 100644 (file)
@@ -18,6 +18,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index 5a062a27606be6a0cb8d9a5a4f06ce8c0ec5cd6a..bf23dce673f4b93a264545a4ab4c4156ef869eef 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index 9bdde85ae3bfd725ee83265b923eb445021a15c4..e517ac5c06aa425771dcac7256a8e3127da8d3bb 100644 (file)
@@ -23,6 +23,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
                tohighlight => {
                        type => "string",
@@ -79,7 +80,7 @@ my %highlighters;
 
 # Parse highlight's config file to get extension => language mappings.
 sub read_filetypes () {
-       open (IN, $filetypes);
+       open (IN, $filetypes) || error("$filetypes: $!");
        while (<IN>) {
                chomp;
                if (/^\$ext\((.*)\)=(.*)$/) {
index bd2177a06a1217de57700c40de641e9794133b5f..32c9cf3ada5b1ed3ed65114177fbcade05d0eaf2 100644 (file)
@@ -23,6 +23,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
 }
 
index a7d5e8ce91af28d9053b9b831564e9b1fc13a7b3..4dbae081bd9476c154728d32efe4c054e1e954f9 100644 (file)
@@ -21,6 +21,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
 }
 
index a249cdf7a43b2986b5ca519f88c01cc6fcf85141..26e18ffc753c537158ceb86cca80d03f5b1cca2e 100644 (file)
@@ -30,9 +30,9 @@ sub import {
                "msnim", "notes", "rsync", "secondlife", "skype", "ssh",
                "sftp", "smb", "sms", "snews", "webcal", "ymsgr",
        );
-       # 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;
+       # data is a special case. Allow a few data:image/ types,
+       # but disallow data:text/javascript and everything else.
+       $safe_url_regexp=qr/^(?:(?:$uri_schemes):|data:image\/(?:png|jpeg|gif)|[^:]+(?:$|\/))/i;
 }
 
 sub getsetup () {
@@ -40,6 +40,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "core",
                },
                htmlscrubber_skip => {
                        type => "pagespec",
index c2e55b015bba003701522130b0ca6dfd376154cf..0bdc4a75423a4156f1312d2d20c3872c738d7514 100644 (file)
@@ -10,6 +10,10 @@ use Data::Dumper;
 sub import {
        hook(type => "getsetup", id => "httpauth", call => \&getsetup);
        hook(type => "auth", id => "httpauth", call => \&auth);
+       hook(type => "formbuilder_setup", id => "httpauth",
+               call => \&formbuilder_setup);
+       hook(type => "canedit", id => "httpauth", call => \&canedit,
+               first => 1);
 }
 
 sub getsetup () {
@@ -17,8 +21,33 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
+               },
+               cgiauthurl => {
+                       type => "string",
+                       example => "http://example.com/wiki/auth/ikiwiki.cgi",
+                       description => "url to redirect to when authentication is needed",
+                       safe => 1,
+                       rebuild => 0,
+               },
+               httpauth_pagespec => {
+                       type => "pagespec",
+                       example => "!*/Discussion",
+                       description => "PageSpec of pages where only httpauth will be used for authentication",
+                       safe => 0,
+                       rebuild => 0,
                },
 }
+                       
+sub redir_cgiauthurl ($;@) {
+       my $cgi=shift;
+
+       IkiWiki::redirect($cgi, 
+               @_ > 1 ? IkiWiki::cgiurl(cgiurl => $config{cgiauthurl}, @_)
+                      : $config{cgiauthurl}."?@_"
+       );
+       exit;
+}
 
 sub auth ($$) {
        my $cgi=shift;
@@ -36,4 +65,52 @@ sub auth ($$) {
        }
 }
 
+sub formbuilder_setup (@) {
+       my %params=@_;
+
+       my $form=$params{form};
+       my $session=$params{session};
+       my $cgi=$params{cgi};
+       my $buttons=$params{buttons};
+
+       if ($form->title eq "signin" &&
+           ! defined $cgi->remote_user() && defined $config{cgiauthurl}) {
+               my $button_text="Login with HTTP auth";
+               push @$buttons, $button_text;
+
+               if ($form->submitted && $form->submitted eq $button_text) {
+                       # bounce thru cgiauthurl and then back to
+                       # the stored postsignin action
+                       redir_cgiauthurl($cgi, do => "postsignin");
+               }
+       }
+}
+
+sub test_httpauth_pagespec ($) {
+       my $page=shift;
+
+       return (
+       );
+}
+
+sub canedit ($$$) {
+       my $page=shift;
+       my $cgi=shift;
+       my $session=shift;
+
+       if (! defined $cgi->remote_user() &&
+           defined $config{httpauth_pagespec} &&
+           length $config{httpauth_pagespec} &&
+           defined $config{cgiauthurl} &&
+           pagespec_match($page, $config{httpauth_pagespec})) {
+               return sub {
+                       # bounce thru cgiauthurl and back to edit action
+                       redir_cgiauthurl($cgi, $cgi->query_string());
+               };
+       }
+       else {
+               return undef;
+       }
+}
+
 1
index 9ae85c4e682839d7a2179785e1c4e504d6ecc866..f06121578266bedc92027a0624cd05a21cdf6c0f 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -26,6 +27,10 @@ sub preprocess (@) {
        my ($image) = $_[0] =~ /$config{wiki_file_regexp}/; # untaint
        my %params=@_;
 
+       if (! defined $image) {
+               error("bad image filename");
+       }
+
        if (exists $imgdefaults{$params{page}}) {
                foreach my $key (keys %{$imgdefaults{$params{page}}}) {
                        if (! exists $params{$key}) {
@@ -44,6 +49,7 @@ sub preprocess (@) {
        }
 
        add_link($params{page}, $image);
+       add_depends($params{page}, $image);
 
        # optimisation: detect scan mode, and avoid generating the image
        if (! defined wantarray) {
@@ -63,80 +69,81 @@ sub preprocess (@) {
        error gettext("Image::Magick is not installed") if $@;
        my $im = Image::Magick->new;
        my $imglink;
-       my $r;
-
+       my $r = $im->Read($srcfile);
+       error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
+       
        my ($dwidth, $dheight);
 
        if ($params{size} ne 'full') {
-               add_depends($params{page}, $image);
-
                my ($w, $h) = ($params{size} =~ /^(\d*)x(\d*)$/);
                error sprintf(gettext('wrong size format "%s" (should be WxH)'), $params{size})
                        unless (defined $w && defined $h &&
                                (length $w || length $h));
-
-               my $outfile = "$config{destdir}/$dir/${w}x${h}-$base";
-               $imglink = "$dir/${w}x${h}-$base";
                
-               will_render($params{page}, $imglink);
-
-               if (-e $outfile && (-M $srcfile >= -M $outfile)) {
-                       $r = $im->Read($outfile);
-                       error sprintf(gettext("failed to read %s: %s"), $outfile, $r) if $r;
+               if ((length $w && $w > $im->Get("width")) ||
+                   (length $h && $h > $im->Get("height"))) {
+                       # resizing larger
+                       $imglink = $file;
+
+                       # don't generate larger image, just set display size
+                       if (length $w && length $h) {
+                               ($dwidth, $dheight)=($w, $h);
+                       }
+                       # avoid division by zero on 0x0 image
+                       elsif ($im->Get("width") == 0 || $im->Get("height") == 0) {
+                               ($dwidth, $dheight)=(0, 0);
+                       }
+                       # calculate unspecified size from the other one, preserving
+                       # aspect ratio
+                       elsif (length $w) {
+                               $dwidth=$w;
+                               $dheight=$w / $im->Get("width") * $im->Get("height");
+                       }
+                       elsif (length $h) {
+                               $dheight=$h;
+                               $dwidth=$h / $im->Get("height") * $im->Get("width");
+                       }
                }
                else {
-                       $r = $im->Read($srcfile);
-                       error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
-
-                       # don't resize any larger
-                       my ($rw, $rh) = ($w, $h);
-                       if ((length $rw && $rw > $im->Get("width")) ||
-                           (length $rh && $rh > $im->Get("height"))) {
-                               $rw=$im->Get("width");
-                               $rh=$im->Get("height");
-                       }
-
-                       $r = $im->Resize(geometry => "${rw}x${rh}");
-                       error sprintf(gettext("failed to resize: %s"), $r) if $r;
+                       # resizing smaller
+                       my $outfile = "$config{destdir}/$dir/${w}x${h}-$base";
+                       $imglink = "$dir/${w}x${h}-$base";
+               
+                       will_render($params{page}, $imglink);
 
-                       # don't actually write file in preview mode
-                       if (! $params{preview}) {
-                               my @blob = $im->ImageToBlob();
-                               writefile($imglink, $config{destdir}, $blob[0], 1);
+                       if (-e $outfile && (-M $srcfile >= -M $outfile)) {
+                               $im = Image::Magick->new;
+                               $r = $im->Read($outfile);
+                               error sprintf(gettext("failed to read %s: %s"), $outfile, $r) if $r;
+               
+                               $dwidth = $im->Get("width");
+                               $dheight = $im->Get("height");
                        }
                        else {
-                               $imglink = $file;
+                               ($dwidth, $dheight)=($w, $h);
+                               $r = $im->Resize(geometry => "${w}x${h}");
+                               error sprintf(gettext("failed to resize: %s"), $r) if $r;
+
+                               # don't actually write file in preview mode
+                               if (! $params{preview}) {
+                                       my @blob = $im->ImageToBlob();
+                                       writefile($imglink, $config{destdir}, $blob[0], 1);
+                               }
+                               else {
+                                       $imglink = $file;
+                               }
                        }
                }
-
-               # since we don't really resize larger, set the display
-               # size, so the browser can scale the image up if necessary
-               if (length $w && length $h) {
-                       ($dwidth, $dheight)=($w, $h);
-               }
-               # avoid division by zero on 0x0 image
-               elsif ($im->Get("width") == 0 || $im->Get("height") == 0) {
-                       ($dwidth, $dheight)=(0, 0);
-               }
-               # calculate unspecified size from the other one, preserving
-               # aspect ratio
-               elsif (length $w) {
-                       $dwidth=$w;
-                       $dheight=$w / $im->Get("width") * $im->Get("height");
-               }
-               elsif (length $h) {
-                       $dheight=$h;
-                       $dwidth=$h / $im->Get("height") * $im->Get("width");
-               }
-
        }
        else {
-               $r = $im->Read($srcfile);
-               error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
                $imglink = $file;
                $dwidth = $im->Get("width");
                $dheight = $im->Get("height");
        }
+       
+       if (! defined($dwidth) || ! defined($dheight)) {
+               error sprintf(gettext("failed to determine size of image %s"), $file)
+       }
 
        my ($fileurl, $imgurl);
        if (! $params{preview}) {
@@ -148,39 +155,43 @@ sub preprocess (@) {
                $imgurl="$config{url}/$imglink";
        }
 
-       if (! defined($im->Get("width")) || ! defined($im->Get("height"))) {
-               error sprintf(gettext("failed to determine size of image %s"), $file)
-       }
-
        my $imgtag='<img src="'.$imgurl.
                '" width="'.$dwidth.
                '" height="'.$dheight.'"'.
                (exists $params{alt} ? ' alt="'.$params{alt}.'"' : '').
                (exists $params{title} ? ' title="'.$params{title}.'"' : '').
-               (exists $params{align} ? ' align="'.$params{align}.'"' : '').
                (exists $params{class} ? ' class="'.$params{class}.'"' : '').
+               (exists $params{align} && ! exists $params{caption} ? ' align="'.$params{align}.'"' : '').
                (exists $params{id} ? ' id="'.$params{id}.'"' : '').
                ' />';
 
-       if (! defined $params{link} || lc($params{link}) eq 'yes') {
-               $imgtag='<a href="'.$fileurl.'">'.$imgtag.'</a>';
+       my $link;
+       if (! defined $params{link}) {
+               $link=$fileurl;
        }
        elsif ($params{link} =~ /^\w+:\/\//) {
-               $imgtag='<a href="'.$params{link}.'">'.$imgtag.'</a>';
+               $link=$params{link};
+       }
+
+       if (defined $link) {
+               $imgtag='<a href="'.$link.'">'.$imgtag.'</a>';
        }
        else {
                my $b = bestlink($params{page}, $params{link});
        
                if (length $b) {
-                       add_depends($params{page}, $b);
+                       add_depends($params{page}, $b, deptype("presence"));
                        $imgtag=htmllink($params{page}, $params{destpage},
                                $params{link}, linktext => $imgtag,
-                               noimageinline => 1);
+                               noimageinline => 1,
+                       );
                }
        }
 
        if (exists $params{caption}) {
-               return '<table class="img">'.
+               return '<table class="img'.
+                       (exists $params{align} ? " align-$params{align}" : "").
+                       '">'.
                        '<caption>'.$params{caption}.'</caption>'.
                        '<tr><td>'.$imgtag.'</td></tr>'.
                        '</table>';
index ccfadfd699929a8be1764546118d89ee9f958f56..44919e58c35d658535fbb6e8e2e6f745e3c69311 100644 (file)
@@ -49,6 +49,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "core",
                },
                rss => {
                        type => "boolean",
@@ -159,7 +160,7 @@ sub preprocess_inline (@) {
        my $rss=(($config{rss} || $config{allowrss}) && exists $params{rss}) ? yesno($params{rss}) : $config{rss};
        my $atom=(($config{atom} || $config{allowatom}) && exists $params{atom}) ? yesno($params{atom}) : $config{atom};
        my $quick=exists $params{quick} ? yesno($params{quick}) : 0;
-       my $feeds=exists $params{feeds} ? yesno($params{feeds}) : !$quick;
+       my $feeds=! $nested && (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) {
@@ -195,41 +196,38 @@ sub preprocess_inline (@) {
 
                @list = map { bestlink($params{page}, $_) }
                        split ' ', $params{pagenames};
-       }
-       else {
-               add_depends($params{page}, $params{pages});
 
-               @list = pagespec_match_list(
-                       [ grep { $_ ne $params{page} } keys %pagesources ],
-                       $params{pages}, location => $params{page});
-
-               if (exists $params{sort} && $params{sort} eq 'title') {
-                       @list=sort { pagetitle(basename($a)) cmp pagetitle(basename($b)) } @list;
+               if (yesno($params{reverse})) {
+                       @list=reverse(@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;
+
+               foreach my $p (@list) {
+                       add_depends($params{page}, $p, deptype($quick ? "presence" : "content"));
                }
-               elsif (exists $params{sort} && $params{sort} eq 'mtime') {
-                       @list=sort { $pagemtime{$b} <=> $pagemtime{$a} } @list;
+       }
+       else {
+               my $num=0;
+               if ($params{show}) {
+                       $num=$params{show};
                }
-               elsif (! exists $params{sort} || $params{sort} eq 'age') {
-                       @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
+               if ($params{feedshow} && $num < $params{feedshow} && $num > 0) {
+                       $num=$params{feedshow};
                }
-               else {
-                       error sprintf(gettext("unknown sort type %s"), $params{sort});
+               if ($params{skip} && $num) {
+                       $num+=$params{skip};
                }
-       }
 
-       if (yesno($params{reverse})) {
-               @list=reverse(@list);
+               @list = pagespec_match_list($params{page}, $params{pages},
+                       deptype => deptype($quick ? "presence" : "content"),
+                       filter => sub { $_[0] eq $params{page} },
+                       sort => exists $params{sort} ? $params{sort} : "age",
+                       reverse => yesno($params{reverse}),
+                       ($num ? (num => $num) : ()),
+               );
        }
 
        if (exists $params{skip}) {
-               @list=@list[$params{skip} .. scalar @list - 1];
+               @list=@list[$params{skip} .. $#list];
        }
        
        my @feedlist;
@@ -247,15 +245,12 @@ sub preprocess_inline (@) {
                @list=@list[0..$params{show} - 1];
        }
 
-       # Explicitly add all currently displayed pages as dependencies, so
-       # that if they are removed or otherwise changed, the inline will be
-       # sure to be updated.
-       foreach my $p ($#list >= $#feedlist ? @list : @feedlist) {
-               add_depends($params{page}, $p);
-       }
-       
        if ($feeds && exists $params{feedpages}) {
-               @feedlist=pagespec_match_list(\@feedlist, $params{feedpages}, location => $params{page});
+               @feedlist = pagespec_match_list(
+                       $params{page}, "($params{pages}) and ($params{feedpages})",
+                       deptype => deptype($quick ? "presence" : "content"),
+                       list => \@feedlist,
+               );
        }
 
        my ($feedbase, $feednum);
@@ -338,12 +333,13 @@ sub preprocess_inline (@) {
                        error sprintf(gettext("nonexistant template %s"), $params{template});
                }
                my $template=HTML::Template->new(@params) unless $raw;
+               my $needcontent=$raw || (!($archive && $quick) && $template->query(name => 'content'));
        
                foreach my $page (@list) {
                        my $file = $pagesources{$page};
                        my $type = pagetype($file);
-                       if (! $raw || ($raw && ! defined $type)) {
-                               unless ($archive && $quick) {
+                       if (! $raw) {
+                               if ($needcontent) {
                                        # Get the content before populating the
                                        # template, since getting the content uses
                                        # the same template if inlines are nested.
@@ -362,9 +358,9 @@ sub preprocess_inline (@) {
                                        my $file = $pagesources{$page};
                                        my $type = pagetype($file);
                                        if ($config{discussion}) {
-                                               if ($page !~ /.*\/\Q$config{discussionpage}\E$/ &&
+                                               if ($page !~ /.*\/\Q$config{discussionpage}\E$/i &&
                                                    (length $config{cgiurl} ||
-                                                    exists $links{$page."/".$config{discussionpage}})) {
+                                                    exists $pagesources{$page."/".lc($config{discussionpage})})) {
                                                        $template->param(have_actions => 1);
                                                        $template->param(discussionlink =>
                                                                htmllink($page,
@@ -374,9 +370,12 @@ sub preprocess_inline (@) {
                                                                        forcesubpage => 1));
                                                }
                                        }
-                                       if (length $config{cgiurl} && defined $type) {
+                                       if (length $config{cgiurl} &&
+                                           defined $type &&
+                                           IkiWiki->can("cgi_editpage")) {
                                                $template->param(have_actions => 1);
                                                $template->param(editurl => cgiurl(do => "edit", page => $page));
+
                                        }
                                }
        
@@ -396,6 +395,10 @@ sub preprocess_inline (@) {
                                              filter($page, $params{destpage},
                                              readfile(srcfile($file)))));
                                }
+                               else {
+                                       $ret.="\n".
+                                             readfile(srcfile($file));
+                               }
                        }
                }
        }
@@ -424,6 +427,8 @@ sub preprocess_inline (@) {
                }
        }
        
+       clear_inline_content_cache();
+
        return $ret if $raw || $nested;
        push @inline, $ret;
        return "<div class=\"inline\" id=\"$#inline\"></div>\n\n";
@@ -438,25 +443,42 @@ sub pagetemplate_inline (@) {
                if exists $feedlinks{$page} && $template->query(name => "feedlinks");
 }
 
+{
+my %inline_content;
+my $cached_destpage="";
+
 sub get_inline_content ($$) {
        my $page=shift;
        my $destpage=shift;
        
+       if (exists $inline_content{$page} && $cached_destpage eq $destpage) {
+               return $inline_content{$page};
+       }
+
        my $file=$pagesources{$page};
        my $type=pagetype($file);
+       my $ret="";
        if (defined $type) {
                $nested++;
-               my $ret=htmlize($page, $destpage, $type,
+               $ret=htmlize($page, $destpage, $type,
                       linkify($page, $destpage,
                       preprocess($page, $destpage,
                       filter($page, $destpage,
                       readfile(srcfile($file))))));
                $nested--;
-               return $ret;
        }
-       else {
-               return "";
+       
+       if ($cached_destpage ne $destpage) {
+               clear_inline_content_cache();
+               $cached_destpage=$destpage;
        }
+       return $inline_content{$page}=$ret;
+}
+
+sub clear_inline_content_cache () {
+       %inline_content=();
+}
+
 }
 
 sub date_822 ($) {
index 4c1add9853a3b4053f34b8d927e52ea0e7e4d1f4..3838aec09708450d8d3f9ba338b3cb3b09ee6892 100644 (file)
@@ -20,6 +20,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "core",
                },
 }
 
index 941ed5f3672145bb6111c5a6650fb14431641297..ac26e072e9dc7afa18ad33d5fa2049d347f291bb 100644 (file)
@@ -9,7 +9,6 @@ use IPC::Open2;
 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 () {
@@ -17,50 +16,26 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
 my $mapnum=0;
-my %maps;
 
 sub preprocess (@) {
        my %params=@_;
 
        $params{pages}="*" unless defined $params{pages};
        
-       # Needs to update whenever a page is added or removed, so
-       # register a dependency.
-       add_depends($params{page}, $params{pages});
-       
-       # Can't just return the linkmap here, since the htmlscrubber
-       # scrubs out all <object> tags (with good reason!)
-       # Instead, insert a placeholder tag, which will be expanded during
-       # formatting.
        $mapnum++;
-       $maps{$mapnum}=\%params;
-       return "<div class=\"linkmap$mapnum\"></div>";
-}
-
-sub format (@) {
-        my %params=@_;
-
-       $params{content}=~s/<div class=\"linkmap(\d+)"><\/div>/genmap($1)/eg;
-
-        return $params{content};
-}
-
-sub genmap ($) {
-       my $mapnum=shift;
-       return "" unless exists $maps{$mapnum};
-       my %params=%{$maps{$mapnum}};
+       my $connected=IkiWiki::yesno($params{connected});
 
        # Get all the items to map.
-       my %mapitems = ();
-       foreach my $item (keys %links) {
-               if (pagespec_match($item, $params{pages}, location => $params{page})) {
-                       $mapitems{$item}=urlto($item, $params{destpage});
-               }
-       }
+       my %mapitems = map { $_ => urlto($_, $params{destpage}) }
+               pagespec_match_list($params{page}, $params{pages},
+                       # update when a page is added or removed, or its
+                       # links change
+                       deptype => deptype("presence", "links"));
 
        my $dest=$params{page}."/linkmap.png";
 
@@ -84,24 +59,38 @@ sub genmap ($) {
        print OUT "charset=\"utf-8\";\n";
        print OUT "ratio=compress;\nsize=\"".($params{width}+0).", ".($params{height}+0)."\";\n"
                if defined $params{width} and defined $params{height};
+       my %shown;
+       my $show=sub {
+               my $item=shift;
+               if (! $shown{$item}) {
+                       print OUT "\"$item\" [shape=box,href=\"$mapitems{$item}\"];\n";
+                       $shown{$item}=1;
+               }
+       };
        foreach my $item (keys %mapitems) {
-               print OUT "\"$item\" [shape=box,href=\"$mapitems{$item}\"];\n";
+               $show->($item) unless $connected;
                foreach my $link (map { bestlink($item, $_) } @{$links{$item}}) {
-                       print OUT "\"$item\" -> \"$link\";\n"
-                               if $mapitems{$link};
+                       next unless length $link and $mapitems{$link};
+                       foreach my $endpoint ($item, $link) {
+                               $show->($endpoint);
+                       }
+                       print OUT "\"$item\" -> \"$link\";\n";
                }
        }
        print OUT "}\n";
-       close OUT;
+       close OUT || error gettext("failed to run dot");
 
        local $/=undef;
-       my $ret="<object data=\"".urlto($dest, $params{destpage}).
-              "\" type=\"image/png\" usemap=\"#linkmap$mapnum\">\n".
-               <IN>.
-               "</object>";
-       close IN;
+       my $ret="<img src=\"".urlto($dest, $params{destpage}).
+              "\" alt=\"".gettext("linkmap").
+              "\" usemap=\"#linkmap$mapnum\" />\n".
+               <IN>;
+       close IN || error gettext("failed to run dot");
        
        waitpid $pid, 0;
+       if ($?) {
+               error gettext("failed to run dot");
+       }
        $SIG{PIPE}="DEFAULT";
        error gettext("failed to run dot") if $sigpipe;
 
index bd73f1a04e728638c19994c0d64a4f288a120150..8a67f716026003e8b00135f4de5f1f7da60794a2 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
                directive_description_dir => {
                        type => "string",
@@ -84,7 +85,7 @@ sub preprocess (@) {
        foreach my $plugin (@pluginlist) {
                $result .= '<li class="listdirectives">';
                my $link=linkpage($config{directive_description_dir}."/".$plugin);
-               add_depends($params{page}, $link);
+               add_depends($params{page}, $link, deptype("presence"));
                $result .= htmllink($params{page}, $params{destpage}, $link);
                $result .= '</li>';
        }
diff --git a/IkiWiki/Plugin/localstyle.pm b/IkiWiki/Plugin/localstyle.pm
new file mode 100644 (file)
index 0000000..111f4dc
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+package IkiWiki::Plugin::localstyle;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "getsetup", id => "localstyle", call => \&getsetup);
+       hook(type => "pagetemplate", id => "localstyle", call => \&pagetemplate);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 1,
+               },
+}
+
+sub pagetemplate (@) {
+       my %params=@_;
+       
+       my $template=$params{template};
+       
+       if ($template->query(name => "local_css")) {
+               my $best=bestlink($params{page}, 'local.css');
+               if ($best) {
+                       $template->param(local_css => $best);
+               }
+       }
+}
+
+1
index 0fa329251f0b7eb5e6814e50f68d020eaf047eb8..1466e8337f5f16c74c6f809f7af7a62bfadfb56e 100644 (file)
@@ -15,6 +15,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
                locked_pages => {
                        type => "pagespec",
@@ -39,8 +40,9 @@ sub canedit ($$) {
                    user => $session->param("name"),
                    ip => $ENV{REMOTE_ADDR},
            )) {
-               if (! defined $user ||
-                   ! IkiWiki::userinfo_get($session->param("name"), "regdate")) {
+               if ((! defined $user ||
+                   ! IkiWiki::userinfo_get($session->param("name"), "regdate")) &&
+                   exists $IkiWiki::hooks{auth}) {
                        return sub { IkiWiki::needsignin($cgi, $session) };
                }
                else {
index 54146dc467bdcb513e426257a6fd0879005cd35a..ce3ac1d24e93be888ca9e81f597f55d8b2f41424 100644 (file)
@@ -21,6 +21,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -28,12 +29,16 @@ sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
+       # Needs to update whenever a page is added or removed (or in some
+       # cases, when its content changes, if show= is specified).
+       my $deptype=deptype(exists $params{show} ? "content" : "presence");
+       
        my $common_prefix;
 
        # Get all the items to map.
        my %mapitems;
-       foreach my $page (pagespec_match_list([keys %pagesources],
-                               $params{pages}, location => $params{page})) {
+       foreach my $page (pagespec_match_list($params{page}, $params{pages},
+                                       deptype => $deptype)) {
                if (exists $params{show} && 
                    exists $pagestate{$page} &&
                    exists $pagestate{$page}{meta}{$params{show}}) {
@@ -67,16 +72,6 @@ sub preprocess (@) {
                $common_prefix=IkiWiki::dirname($common_prefix);
        }
 
-       # Needs to update whenever a page is added or removed (or in some
-       # cases, when its content changes, if show=title), so register a
-       # dependency.
-       add_depends($params{page}, $params{pages});
-       # Explicitly add all currently shown pages, to detect when pages
-       # are removed.
-       foreach my $item (keys %mapitems) {
-               add_depends($params{page}, $item);
-       }
-
        # Create the map.
        my $parent="";
        my $indent=0;
@@ -84,12 +79,12 @@ sub preprocess (@) {
        my $addparent="";
        my $map = "<div class='map'>\n";
 
-       # Return empty div if %mapitems is empty
-       if (!scalar(keys %mapitems)) {
+       if (! keys %mapitems) {
+               # return empty div for empty map
                $map .= "</div>\n";
                return $map; 
        } 
-       else { # continue populating $map
+       else {
                $map .= "<ul>\n";
        }
 
index 52cfd8eebac3f32470b8a99170586195c6b03647..68765c6b8c0c71fb4a1d75992a51290522134d90 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
                multimarkdown => {
                        type => "boolean",
@@ -43,8 +44,10 @@ sub htmlize (@) {
                        if ($@) {
                                debug(gettext("multimarkdown is enabled, but Text::MultiMarkdown is not installed"));
                        }
-                       $markdown_sub=sub {
-                               Text::MultiMarkdown::markdown(shift, {use_metadata => 0});
+                       else {
+                               $markdown_sub=sub {
+                                       Text::MultiMarkdown::markdown(shift, {use_metadata => 0});
+                               }
                        }
                }
                if (! defined $markdown_sub) {
index 11fdec529373c6b430a8e77bebb2c0a3aa6972b7..ea00a33648431daadb94efa398e47c3c224a6f89 100644 (file)
@@ -36,6 +36,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                mercurial_wrapper => {
                        type => "string",
index 514b0936907ce58edabcbafcb44d5559a154eec9..5f046cb2a06e90fdc53939ae2d2b3490d2d4d30e 100644 (file)
@@ -20,6 +20,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "core",
                },
 }
 
@@ -88,7 +89,7 @@ sub preprocess (@) {
        # Metadata collection that needs to happen during the scan pass.
        if ($key eq 'title') {
                $pagestate{$page}{meta}{title}=HTML::Entities::encode_numeric($value);
-               # fallthrough
+               return "";
        }
        elsif ($key eq 'description') {
                $pagestate{$page}{meta}{description}=HTML::Entities::encode_numeric($value);
@@ -121,6 +122,10 @@ sub preprocess (@) {
                $pagestate{$page}{meta}{authorurl}=$value if safeurl($value);
                # fallthrough
        }
+       elsif ($key eq 'permalink') {
+               $pagestate{$page}{meta}{permalink}=$value if safeurl($value);
+               # fallthrough
+       }
        elsif ($key eq 'date') {
                eval q{use Date::Parse};
                if (! $@) {
@@ -141,10 +146,9 @@ sub preprocess (@) {
                return;
        }
 
-       # Metadata collection that happens only during preprocessing pass.
+       # Metadata handling that happens only during preprocessing pass.
        if ($key eq 'permalink') {
                if (safeurl($value)) {
-                       $pagestate{$page}{meta}{permalink}=$value;
                        push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />', $destpage);
                }
        }
@@ -195,7 +199,7 @@ sub preprocess (@) {
                        if (! length $link) {
                                error gettext("redir page not found")
                        }
-                       add_depends($page, $link);
+                       add_depends($page, $link, deptype("presence"));
 
                        $value=urlto($link, $page);
                        $value.='#'.$redir_anchor if defined $redir_anchor;
@@ -236,6 +240,10 @@ sub preprocess (@) {
                push @{$metaheaders{$page}}, '<meta name="robots"'.
                        ' content="'.encode_entities($value).'" />';
        }
+       elsif ($key eq 'description') {
+               push @{$metaheaders{$page}}, '<meta name="'.encode_entities($key).
+                       '" content="'.encode_entities($value).'" />';
+       }
        else {
                push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key).
                        '" content="'.encode_entities($value).'" />', $destpage);
@@ -260,7 +268,7 @@ sub pagetemplate (@) {
                $template->param(title_overridden => 1);
        }
 
-       foreach my $field (qw{author authorurl permalink}) {
+       foreach my $field (qw{author authorurl description permalink}) {
                $template->param($field => $pagestate{$page}{meta}{$field})
                        if exists $pagestate{$page}{meta}{$field} && $template->query(name => $field);
        }
@@ -291,21 +299,21 @@ sub match {
 
        if (defined $val) {
                if ($val=~/^$re$/i) {
-                       return IkiWiki::SuccessReason->new("$re matches $field of $page");
+                       return IkiWiki::SuccessReason->new("$re matches $field of $page", $page => $IkiWiki::DEPEND_CONTENT, "" => 1);
                }
                else {
-                       return IkiWiki::FailReason->new("$re does not match $field of $page");
+                       return IkiWiki::FailReason->new("$re does not match $field of $page", "" => 1);
                }
        }
        else {
-               return IkiWiki::FailReason->new("$page does not have a $field");
+               return IkiWiki::FailReason->new("$page does not have a $field", "" => 1);
        }
 }
 
 package IkiWiki::PageSpec;
 
 sub match_title ($$;@) {
-       IkiWiki::Plugin::meta::match("title", @_);      
+       IkiWiki::Plugin::meta::match("title", @_);
 }
 
 sub match_author ($$;@) {
index 737dcf767379e69819bc71c4f7d02800be5b62f6..92be7913efaf871929d8c3e0746191888aa1f513 100644 (file)
@@ -15,6 +15,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "web",
                },
                mirrorlist => {
                        type => "string",
@@ -29,7 +30,8 @@ sub pagetemplate (@) {
        my %params=@_;
         my $template=$params{template};
        
-       if ($template->query(name => "extrafooter")) {
+       if ($template->query(name => "extrafooter") &&
+           keys %{$config{mirrorlist}} > 0) {
                my $value=$template->param("extrafooter");
                $value.=mirrorlist($params{page});
                $template->param(extrafooter => $value);
diff --git a/IkiWiki/Plugin/moderatedcomments.pm b/IkiWiki/Plugin/moderatedcomments.pm
new file mode 100644 (file)
index 0000000..b0a328a
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::moderatedcomments;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+       hook(type => "getsetup", id => "moderatedcomments",  call => \&getsetup);
+       hook(type => "checkcontent", id => "moderatedcomments", call => \&checkcontent);
+}
+
+sub getsetup () {
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 0,
+                       section => "auth",
+               },
+               moderate_pagespec => {
+                       type => 'pagespec',
+                       example => 'user(http://*)',
+                       description => 'PageSpec matching users or comment locations to moderate',
+                       link => 'ikiwiki/PageSpec',
+                       safe => 1,
+                       rebuild => 0,
+               },
+}
+
+sub checkcontent (@) {
+       my %params=@_;
+       
+       # only handle comments  
+       return undef unless pagespec_match($params{page}, "postcomment(*)",
+                               location => $params{page});
+       
+       # backwards compatability
+       if (exists $config{moderate_users} &&
+           ! exists $config{moderate_pagespec}) {
+               $config{moderate_pagespec} = $config{moderate_users}
+                       ? "!admin()"
+                       : "!user(*)";
+       }
+
+       # default is to moderate all except admins
+       if (! exists $config{moderate_pagespec}) {
+               $config{moderate_pagespec}="!admin()";
+       }
+
+       my $session=$params{session};
+       my $user=$session->param("name") if $session;
+       if (pagespec_match($params{page}, $config{moderate_pagespec},
+                       location => $params{page},
+                       (defined $user ? (user => $user) : ()),
+                       (defined $ENV{REMOTE_ADDR} ? (ip => $ENV{REMOTE_ADDR}) : ()),
+       )) {
+               return gettext("comment needs moderation");
+       }
+       else {
+               return undef;
+       }
+}
+
+1
index 05c5a514dc3f22c6b58de298b007c16a9208d89f..c33cf7e3a0dad0c0f052400c00da2b928f8fd289 100644 (file)
@@ -68,6 +68,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                mtn_wrapper => {
                        type => "string",
@@ -228,7 +229,7 @@ sub read_certs ($$) {
        my @ret;
 
        my $line = $results[0];
-       while ($line =~ m/\s+key\s"(.*?)"\nsignature\s"(ok|bad|unknown)"\n\s+name\s"(.*?)"\n\s+value\s"(.*?)"\n\s+trust\s"(trusted|untrusted)"\n/sg) {
+       while ($line =~ m/\s+key\s["\[](.*?)[\]"]\nsignature\s"(ok|bad|unknown)"\n\s+name\s"(.*?)"\n\s+value\s"(.*?)"\n\s+trust\s"(trusted|untrusted)"\n/sg) {
                push @ret, {
                        key => $1,
                        signature => $2,
@@ -558,7 +559,8 @@ sub rcs_recentchanges ($) {
                                        # from the changelog
                                        if ($cert->{key} eq $config{mtnkey}) {
                                                $committype = "web";
-                                       } else {
+                                       }
+                                       else {
                                                $committype = "mtn";
                                        }
                                } elsif ($cert->{name} eq "date") {
index 77d5fb0772846dde323fd78a809f936365224fa5..266c8e1d0937dc9aefc677d536cc26a8d18e66c7 100644 (file)
@@ -17,6 +17,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index bfe84c0e1ebc15961986ce57a59be9fc26c53290..e6a05a3c5d855d89691414001996070c5f8f9c2c 100644 (file)
@@ -25,6 +25,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => 0,
+                       section => "rcs",
                },
 }
 
index 1bec4b013a9be6686f08a29b2c1a6658b353c635..2805f60efdb6d415a19aeb17195df8ff2543487b 100644 (file)
@@ -7,7 +7,8 @@ use IkiWiki 3.00;
 
 sub import {
        hook(type => "getsetup", id => "opendiscussion", call => \&getsetup);
-       hook(type => "canedit", id => "opendiscussion", call => \&canedit);
+       hook(type => "canedit", id => "opendiscussion", call => \&canedit,
+               first => 1);
 }
 
 sub getsetup () {
@@ -15,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
 }
 
@@ -23,7 +25,8 @@ sub canedit ($$) {
        my $cgi=shift;
        my $session=shift;
 
-       return "" if $page=~/(\/|^)\Q$config{discussionpage}\E$/;
+       return "" if $page=~/(\/|^)\Q$config{discussionpage}\E$/i;
+       return "" if pagespec_match($page, "postcomment(*)");
        return undef;
 }
 
index dc0e0f48ee98e70313abce4d195092989e5537c6..bb99446b4db2138f82dcce277caa097bff9e5ca1 100644 (file)
@@ -26,6 +26,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
                openidsignup => {
                        type => "string",
@@ -56,7 +57,7 @@ sub formbuilder_setup (@) {
                # OpenID fieldset.
                $form->fieldsets("OpenID");
 
-               $form->field(
+               $form->field(
                        name => "openid_url",
                        label => gettext("Log in with")." ".htmllink("", "", "ikiwiki/OpenID", noimageinline => 1),
                        fieldset => "OpenID",
@@ -82,13 +83,13 @@ sub formbuilder_setup (@) {
                        }
                }
        }
-       elsif ($form->title eq "preferences") {
-               if (! defined $form->field(name => "name")) {
-                       $form->field(name => "OpenID", disabled => 1,
-                               value => $session->param("name"), 
-                               size => 50, force => 1,
-                               fieldset => "login");
-               }
+       elsif ($form->title eq "preferences" &&
+              IkiWiki::openiduser($session->param("name"))) {
+               $form->field(name => "openid_url", disabled => 1,
+                       label => htmllink("", "", "ikiwiki/OpenID", noimageinline => 1),
+                       value => $session->param("name"), 
+                       size => 50, force => 1,
+                       fieldset => "login");
        }
 }
 
index 71122677273275d3e2f160bde3c8b44a8f333e49..e3cc3c940882dd27ec7576f8ff8ee63eb8dd845e 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -23,24 +24,34 @@ sub preprocess (@) {
        my %params=@_;
        $params{pages}="*" unless defined $params{pages};
        
-       # Needs to update whenever a page is added or removed, so
-       # register a dependency.
-       add_depends($params{page}, $params{pages});
+       # Needs to update whenever a link changes, on any page
+       # since any page could link to one of the pages we're
+       # considering as orphans.
+       add_depends($params{page}, "*", deptype("links"));
        
-       my @orphans;
-       foreach my $page (pagespec_match_list(
-                       [ grep { ! IkiWiki::backlink_pages($_) && $_ ne 'index' }
-                               keys %pagesources ],
-                       $params{pages}, location => $params{page})) {
-               # If the page has a link to some other page, it's
-               # indirectly linked to a page via that page's backlinks.
-               next if grep { 
-                       length $_ &&
-                       ($_ !~ /\/\Q$config{discussionpage}\E$/i || ! $config{discussion}) &&
-                       bestlink($page, $_) !~ /^(\Q$page\E|)$/ 
-               } @{$links{$page}};
-               push @orphans, $page;
-       }
+       my @orphans=pagespec_match_list($params{page}, $params{pages},
+               # update when orphans are added/removed
+               deptype => deptype("presence"),
+               filter => sub {
+                       my $page=shift;
+
+                       # Filter out pages that other pages link to.
+                       return 1 if IkiWiki::backlink_pages($page);
+
+                       # Toplevel index is assumed to never be orphaned.
+                       return 1 if $page eq 'index';
+
+                       # If the page has a link to some other page, it's
+                       # indirectly linked via that page's backlinks.
+                       return 1 if grep {
+                               length $_ &&
+                               ($_ !~ /\/\Q$config{discussionpage}\E$/i || ! $config{discussion}) &&
+                               bestlink($page, $_) !~ /^(\Q$page\E|)$/ 
+                       } @{$links{$page}};
+                       
+                       return 0;
+               },
+       );
        
        return gettext("All pages have other pages linking to them.") unless @orphans;
        return "<ul>\n".
index c68fcbbe358762127411faec18840070f5bf8bd1..3801a6ec2417d225f3cf541a505ff79adedec8ef 100644 (file)
@@ -9,9 +9,7 @@ use open qw{:utf8 :std};
 
 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 () {
@@ -19,25 +17,20 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
 }
 
-sub filter (@) {
+sub htmlize (@) {
        my %params=@_;
-        
-       # Munge up check boxes to look a little bit better. This is a hack.
+       
+       # Munge up check boxes to look a little bit better.
        my $checked=htmllink($params{page}, $params{page},
                "smileys/star_on.png", linktext => "[X]");
        my $unchecked=htmllink($params{page}, $params{page},
                "smileys/star_off.png", linktext => "[_]");
        $params{content}=~s/^(\s*)\[X\]\s/${1}$checked /mg;
        $params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg;
-        
-       return $params{content};
-}
-
-sub htmlize (@) {
-       my %params=@_;
 
        # Can't use open2 since otl2html doesn't play nice with buffering.
        # Instead, fork off a child process that will run otl2html and feed
index 5a2301af49232943d4f0889c0f3b9ba28f05396f..dd5de3c83102aac6b806eae75a2517c622ac10e2 100644 (file)
@@ -15,25 +15,26 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
 sub preprocess (@) {
        my %params=@_;
-       $params{pages}="*" unless defined $params{pages};
+       my $pages=defined $params{pages} ? $params{pages} : "*";
        
-       # Needs to update count whenever a page is added or removed, so
-       # register a dependency.
-       add_depends($params{page}, $params{pages});
-       
-       my @pages;
-       if ($params{pages} eq "*") {
-               @pages=keys %pagesources;
-       }
-       else {
-               @pages=pagespec_match_list([keys %pagesources], $params{pages}, location => $params{page});
+       # Just get a list of all the pages, and count the items in it.
+       # Use a presence dependency to only update when pages are added
+       # or removed.
+
+       if ($pages eq '*') {
+               # optimisation to avoid needing to try matching every page
+               add_depends($params{page}, $pages, deptype("presence"));
+               return scalar keys %pagesources;
        }
-       return $#pages+1;
+
+       return scalar pagespec_match_list($params{page}, $pages,
+               deptype => deptype("presence"));
 }
 
 1
index 874ead7e6de669c1d33c66b74984ef90504f9b8e..1c0b46830163da3872a0e4b62f0db4960ca3605c 100644 (file)
@@ -27,6 +27,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -35,28 +36,44 @@ sub preprocess (@) {
        $params{pages}="*" unless defined $params{pages};
        my $style = ($params{style} or 'cloud');
        
-       # Needs to update whenever a page is added or removed, so
-       # register a dependency.
-       add_depends($params{page}, $params{pages});
-       add_depends($params{page}, $params{among}) if exists $params{among};
-       
        my %counts;
        my $max = 0;
-       foreach my $page (pagespec_match_list([keys %links],
-                       $params{pages}, location => $params{page})) {
+       foreach my $page (pagespec_match_list($params{page}, $params{pages},
+                                 # update when a displayed page is added/removed
+                                 deptype => deptype("presence"))) {
                use IkiWiki::Render;
 
                my @backlinks = IkiWiki::backlink_pages($page);
 
                if (exists $params{among}) {
-                       @backlinks = pagespec_match_list(\@backlinks,
-                               $params{among}, location => $params{page});
+                       # only consider backlinks from the amoung pages
+                       @backlinks = pagespec_match_list(
+                               $params{page}, $params{among},
+                               # update whenever links on those pages change
+                               deptype => deptype("links"),
+                               list => \@backlinks
+                       );
+               }
+               else {
+                       # update when any page with links changes,
+                       # in case the links point to our displayed pages
+                       add_depends($params{page}, "*", deptype("links"));
                }
 
                $counts{$page} = scalar(@backlinks);
                $max = $counts{$page} if $counts{$page} > $max;
        }
 
+       if (exists $params{show}) {
+               my $i=0;
+               my %show;
+               foreach my $key (sort { $counts{$b} <=> $counts{$a} } keys %counts) {
+                       last if ++$i > $params{show};
+                       $show{$key}=$counts{$key};
+               }
+               %counts=%show;
+       }
+
        if ($style eq 'table') {
                return "<table class='pageStats'>\n".
                        join("\n", map {
index b24eff612ee1146635aede561479df836762d5cd..bdf678069877b3c09bd29894d3f5d6b0353d2619 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "core",
                },
 }
 
@@ -60,8 +61,11 @@ sub pagetemplate (@) {
         my $page=$params{page};
         my $template=$params{template};
 
-       if ($template->query(name => "parentlinks")) {
-               $template->param(parentlinks => [parentlinks($page)]);
+       if ($template->query(name => "parentlinks") ||
+          $template->query(name => "has_parentlinks")) {
+               my @links=parentlinks($page);
+               $template->param(parentlinks => \@links);
+               $template->param(has_parentlinks => (@links > 0));
        }
 }
 
index 8cf5af51ed03d47ff90963dd1aece3c9ea773cbb..4848b47bbac53726aeefde96d41beb21e9949d45 100644 (file)
@@ -19,6 +19,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
                account_creation_password => {
                        type => "string",
@@ -104,11 +105,11 @@ sub formbuilder_setup (@) {
        my $session=$params{session};
        my $cgi=$params{cgi};
 
-       if ($form->title eq "signin" || $form->title eq "register") {
+       if ($form->title eq "signin" || $form->title eq "register" || $cgi->param("do") eq "register") {
                $form->field(name => "name", required => 0);
                $form->field(name => "password", type => "password", required => 0);
                
-               if ($form->submitted eq "Register" || $form->submitted eq "Create Account") {
+               if ($form->submitted eq "Register" || $form->submitted eq "Create Account" || $cgi->param("do") eq "register") {
                        $form->field(name => "confirm_password", type => "password");
                        $form->field(name => "account_creation_password", type => "password")
                                 if (defined $config{account_creation_password} &&
@@ -207,19 +208,34 @@ sub formbuilder_setup (@) {
                }
        }
        elsif ($form->title eq "preferences") {
-               $form->field(name => "name", disabled => 1, 
-                       value => $session->param("name"), force => 1,
-                       fieldset => "login");
-               $form->field(name => "password", type => "password",
-                       fieldset => "login",
-                       validate => sub {
-                               shift eq $form->field("confirm_password");
-                       }),
-               $form->field(name => "confirm_password", type => "password",
-                       fieldset => "login",
-                       validate => sub {
-                               shift eq $form->field("password");
-                       }),
+               my $user=$session->param("name");
+               if (! IkiWiki::openiduser($user)) {
+                       $form->field(name => "name", disabled => 1, 
+                               value => $user, force => 1,
+                               fieldset => "login");
+                       $form->field(name => "password", type => "password",
+                               fieldset => "login",
+                               validate => sub {
+                                       shift eq $form->field("confirm_password");
+                               });
+                       $form->field(name => "confirm_password", type => "password",
+                               fieldset => "login",
+                               validate => sub {
+                                       shift eq $form->field("password");
+                               });
+                       
+                       my $userpage=IkiWiki::userpage($user);
+                       if (exists $pagesources{$userpage}) {
+                               $form->text(gettext("Your user page: ").
+                                       htmllink("", "", $userpage,
+                                               noimageinline => 1));
+                       }
+                       else {
+                               $form->text("<a href=\"".
+                                       IkiWiki::cgiurl(do => "edit", page => $userpage).
+                                       "\">".gettext("Create your user page")."</a>");
+                       }
+               }
        }
 }
 
@@ -232,7 +248,7 @@ sub formbuilder (@) {
        my $buttons=$params{buttons};
 
        if ($form->title eq "signin" || $form->title eq "register") {
-               if ($form->submitted && $form->validate) {
+               if (($form->submitted && $form->validate) || $cgi->param("do") eq "register") {
                        if ($form->submitted eq 'Login') {
                                $session->param("name", $form->field("name"));
                                IkiWiki::cgi_postsignin($cgi, $session);
@@ -295,7 +311,7 @@ sub formbuilder (@) {
                                $form->field(name => "name", required => 0);
                                push @$buttons, "Reset Password";
                        }
-                       elsif ($form->submitted eq "Register") {
+                       elsif ($form->submitted eq "Register" || $cgi->param("do") eq "register") {
                                @$buttons="Create Account";
                        }
                }
@@ -336,6 +352,14 @@ sub sessioncgi ($$) {
                IkiWiki::cgi_prefs($q, $session);
                exit;
        }
+       elsif ($q->param("do") eq "register") {
+               # After registration, need to go somewhere, so show prefs page.
+               $session->param(postsignin => "do=prefs");
+               # Due to do=register, this will run in registration-only
+               # mode.
+               IkiWiki::cgi_signin($q, $session);
+               exit;
+       }
 }
 
 sub auth ($$) {
index 5d0d9e79dd26074344a642f524d098101e4a21c8..2cbfb0a459a91c37469b3429d437cdae5433bbc1 100644 (file)
@@ -85,7 +85,8 @@ sub getsetup () {
        return
                plugin => {
                        safe => 0,
-                       rebuild => 1,
+                       rebuild => 1, # format plugin
+                       section => "format",
                },
                po_master_language => {
                        type => "string",
@@ -386,31 +387,32 @@ sub change (@) {
                resetalreadyfiltered();
                require IkiWiki::Render;
                foreach my $file (@rendered) {
-                       debug(sprintf(gettext("building %s"), $file));
-                       IkiWiki::render($file);
+                       IkiWiki::render($file, sprintf(gettext("building %s"), $file));
                }
        }
 
        my $updated_po_files=0;
 
        # Refresh/create POT and PO files as needed.
-       # (But avoid doing so if they are in an underlay directory.)
        foreach my $file (grep {istranslatablefile($_)} @rendered) {
                my $masterfile=srcfile($file);
                my $page=pagename($file);
                my $updated_pot_file=0;
+
+               # Avoid touching underlay files.
+               next if $masterfile ne "$config{srcdir}/$file";
+
                # Only refresh POT file if it does not exist, or if
-               # $pagesources{$page} was changed: don't if only the HTML was
+               # the source was changed: don't if only the HTML was
                # refreshed, e.g. because of a dependency.
-               if ($masterfile eq "$config{srcdir}/$file" &&
-                  ((grep { $_ eq $pagesources{$page} } @origneedsbuild)
-                   || ! -e potfile($masterfile))) {
+               if ((grep { $_ eq $pagesources{$page} } @origneedsbuild) ||
+                   ! -e potfile($masterfile)) {
                        refreshpot($masterfile);
                        $updated_pot_file=1;
                }
                my @pofiles;
                foreach my $po (pofiles($masterfile)) {
-                       next if ! $updated_pot_file && -e $po;
+                       next if ! $updated_pot_file && -e $po;
                        next if grep { $po=~/\Q$_\E/ } @{$config{underlaydirs}};
                        push @pofiles, $po;
                }
@@ -1056,11 +1058,8 @@ sub commit_and_refresh ($$) {
        IkiWiki::saveindex();
 }
 
-# on success, returns the filtered content.
-# on error, if $nonfatal, warn and return undef; else, error out.
-sub po_to_markup ($$;$) {
+sub po_to_markup ($$) {
        my ($page, $content) = (shift, shift);
-       my $nonfatal = shift;
 
        $content = '' unless defined $content;
        $content = decode_utf8(encode_utf8($content));
@@ -1083,10 +1082,6 @@ sub po_to_markup ($$;$) {
 
        my $fail = sub ($) {
                my $msg = "po(po_to_markup) - $page : " . shift;
-               if ($nonfatal) {
-                       warn $msg;
-                       return undef;
-               }
                error($msg, sub { unlink $infile, $outfile});
        };
 
@@ -1107,8 +1102,7 @@ sub po_to_markup ($$;$) {
        $doc->write($outfile)
                or return $fail->(sprintf(gettext("failed to write %s"), $outfile));
 
-       $content = readfile($outfile)
-               or return $fail->(sprintf(gettext("failed to read %s"), $outfile));
+       $content = readfile($outfile);
 
        # Unlinking should happen automatically, thanks to File::Temp,
        # but it does not work here, probably because of the way writefile()
index bc1e3501e5e6b7c9c4a0d1568367e5d60bbf61cb..6bc4579c2547a34691b0274bdeec7b054336a651 100644 (file)
@@ -17,6 +17,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index bc21d71c725f892d3432dfa5ac22feb1241cfd97..78e3611e1c1aa9a592ff6f156d3b796a01b9a5bd 100644 (file)
@@ -20,6 +20,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index d2e5c23788678efb7819e10c59964bd852663e06..2fae9c5fee90ab266aa0be0d0b2fb4a5267afbb3 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -30,11 +31,16 @@ sub preprocess (@) {
                return "";
        }
 
+       my $deptype;
        if (! exists $params{time} || $params{time} ne 'mtime') {
                $params{timehash} = \%IkiWiki::pagectime;
+               # need to update when pages are added or removed
+               $deptype = deptype("presence");
        }
        else {
                $params{timehash} = \%IkiWiki::pagemtime;
+               # need to update when pages are changed
+               $deptype = deptype("content");
        }
 
        if (! exists $params{formula}) {
@@ -48,12 +54,11 @@ sub preprocess (@) {
                error gettext("unknown formula");
        }
 
-       add_depends($params{page}, $params{pages});
-
        my @list=sort { $params{timehash}->{$b} <=> $params{timehash}->{$a} } 
-               pagespec_match_list(
-                       [ grep { $_ ne $params{page} } keys %pagesources],
-                       $params{pages}, location => $params{page});
+               pagespec_match_list($params{page}, $params{pages},
+                       deptype => $deptype,
+                       filter => sub { $_[0] eq $params{page} },
+               );
 
        my @data=eval qq{IkiWiki::Plugin::postsparkline::formula::$formula(\\\%params, \@list)};
        if ($@) {
index 76d994acc7ad0f9d49c63c32d3d5d8dd54db5554..d27df5ca894b3aacf77fb441901fb5e47cf359b9 100644 (file)
@@ -18,6 +18,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -36,16 +37,12 @@ sub preprocess (@) {
                $fill.="%";
        }
        elsif (defined $params{totalpages} and defined $params{donepages}) {
-               add_depends($params{page}, $params{totalpages});
-               add_depends($params{page}, $params{donepages});
-
-               my @pages=keys %pagesources;
-               my $totalcount=0;
-               my $donecount=0;
-               foreach my $page (@pages) {
-                       $totalcount++ if pagespec_match($page, $params{totalpages}, location => $params{page});
-                       $donecount++ if pagespec_match($page, $params{donepages}, location => $params{page});
-               }
+               my $totalcount=pagespec_match_list(
+                       $params{page}, $params{totalpages},
+                       deptype => deptype("presence"));
+               my $donecount=pagespec_match_list(
+                       $params{page}, $params{donepages},
+                       deptype => deptype("presence"));
                
                if ($totalcount == 0) {
                        $fill = "100%";
index ad8a610c1420f73a3ce0eabf30f9300afcdff5a4..0838bcb225a538c5c21cf05d26bad778860d0fdd 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1, # changes file types
+                       section => "format",
                },
 }
 
index fa851e46678f208efa04def72e988366df6ea87d..5c7b71aaa64bd02e310b6c5428224ce68ba0679a 100644 (file)
@@ -124,7 +124,7 @@ sub store ($$$) {
        elsif (length $config{cgiurl}) {
                $change->{authorurl} = IkiWiki::cgiurl(
                        do => "goto",
-                       page => (length $config{userdir} ? "$config{userdir}/" : "").$change->{author},
+                       page => IkiWiki::userpage($change->{author}),
                );
        }
 
index 3e33cd5c358d42c56348bbaafa64daea6d8bb2c7..06df2efd58cba5697a20f99be8730bd61a06e702 100644 (file)
@@ -26,7 +26,7 @@ sub getsetup () {
 sub format (@) {
         my %params=@_;
 
-       if (! ($params{content}=~s!^(<body>)!$1.include_javascript($params{page})!em)) {
+       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};
        }
index cbc8a0f2ce70719e770fc64853feaaa37252f23b..f59d0269e4cc747da68db81b56afd82cdc304cee 100644 (file)
@@ -18,6 +18,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "web",
                },
 }
 
@@ -51,7 +52,7 @@ sub check_canremove ($$$) {
                        IkiWiki::Plugin::attachment::check_canattach($session, $page, $file);
                }
                else {
-                       error("renaming of attachments is not allowed");
+                       error("removal of attachments is not allowed");
                }
        }
 
@@ -166,7 +167,7 @@ sub formbuilder (@) {
                        removal_confirm($q, $session, 0, $form->field("page"));
                }
                elsif ($form->submitted eq "Remove Attachments") {
-                       my @selected=$q->param("attachment_select");
+                       my @selected=map { Encode::decode_utf8($_) } $q->param("attachment_select");
                        if (! @selected) {
                                error(gettext("Please select the attachments to remove."));
                        }
@@ -187,7 +188,7 @@ sub sessioncgi ($$) {
                        postremove($session);
                }
                elsif ($form->submitted eq 'Remove' && $form->validate) {
-                       my @pages=$q->param("page");
+                       my @pages=$form->field("page");
        
                        # Validate removal by checking that the page exists,
                        # and that the user is allowed to edit(/remove) it.
@@ -237,7 +238,7 @@ sub sessioncgi ($$) {
                        }
                }
                else {
-                       removal_confirm($q, $session, 0, $q->param("page"));
+                       removal_confirm($q, $session, 0, $form->field("page"));
                }
 
                exit 0;
index c3e03496fec167591ad6564e97bff45c3e544641..3908443cabd720bdd644d37c1ebbc8731b1b1035 100644 (file)
@@ -18,6 +18,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "web",
                },
 }
 
@@ -235,6 +236,7 @@ sub formbuilder (@) {
 
        if (defined $form->field("do") && ($form->field("do") eq "edit" ||
            $form->field("do") eq "create")) {
+               IkiWiki::decode_form_utf8($form);
                my $q=$params{cgi};
                my $session=$params{session};
 
@@ -242,7 +244,7 @@ sub formbuilder (@) {
                        rename_start($q, $session, 0, $form->field("page"));
                }
                elsif ($form->submitted eq "Rename Attachment") {
-                       my @selected=$q->param("attachment_select");
+                       my @selected=map { Encode::decode_utf8($_) } $q->param("attachment_select");
                        if (@selected > 1) {
                                error(gettext("Only one attachment can be renamed at a time."));
                        }
@@ -278,7 +280,7 @@ sub sessioncgi ($$) {
 
        if ($q->param("do") eq 'rename') {
                my $session=shift;
-               my ($form, $buttons)=rename_form($q, $session, $q->param("page"));
+               my ($form, $buttons)=rename_form($q, $session, Encode::decode_utf8($q->param("page")));
                IkiWiki::decode_form_utf8($form);
 
                if ($form->submitted eq 'Cancel') {
@@ -290,9 +292,9 @@ sub sessioncgi ($$) {
 
                        # These untaints are safe because of the checks
                        # performed in check_canrename later.
-                       my $src=$q->param("page");
+                       my $src=$form->field("page");
                        my $srcfile=IkiWiki::possibly_foolish_untaint($pagesources{$src});
-                       my $dest=IkiWiki::possibly_foolish_untaint(titlepage($q->param("new_name")));
+                       my $dest=IkiWiki::possibly_foolish_untaint(titlepage($form->field("new_name")));
                        my $destfile=$dest;
                        if (! $q->param("attachment")) {
                                my $type=$q->param('type');
index f69ec398880d4b2955e6e298ddc1d37cfd9141c3..ba7c5f0aa0e895087d9d1cba08d031cd29bc8764 100644 (file)
@@ -15,6 +15,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "web",
                },
                repositories => {
                        type => "string",
index 393c17e0fe8cf6b9ec137ba7cfc8ac64e008cd4b..c0e8703d8ba8fcd9ef5cd21fa5ec3db5219b2e78 100644 (file)
@@ -20,6 +20,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "web",
                },
                omega_cgi => {
                        type => "string",
@@ -109,6 +110,7 @@ sub index (@) {
        # data used by omega
        # Decode html entities in it, since omega re-encodes them.
        eval q{use HTML::Entities};
+       error $@ if $@;
        $doc->set_data(
                "url=".urlto($params{page}, "")."\n".
                "sample=".decode_entities($sample)."\n".
@@ -213,9 +215,19 @@ sub setupfiles () {
                writefile("omega.conf", $config{wikistatedir}."/xapian",
                        "database_dir .\n".
                        "template_dir ./templates\n");
+               
+               # Avoid omega interpreting anything in the misctemplate
+               # as an omegascript command.
+               my $misctemplate=IkiWiki::misctemplate(gettext("search"), "\0");
+               eval q{use HTML::Entities};
+               error $@ if $@;
+               $misctemplate=encode_entities($misctemplate, '\$');
+
+               my $querytemplate=readfile(IkiWiki::template_file("searchquery.tmpl"));
+               $misctemplate=~s/\0/$querytemplate/;
+
                writefile("query", $config{wikistatedir}."/xapian/templates",
-                       IkiWiki::misctemplate(gettext("search"),
-                               readfile(IkiWiki::template_file("searchquery.tmpl"))));
+                       $misctemplate);
                $setup=1;
        }
 }
index 1840a5722a6300d7ce30d14cd4534ef2bc16a48d..0cedbe447480f7f7e01a24476c1cc40e856bccc5 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index 032a0034c0c4e3354ea8274a6259fb0478ad949e..31160c02ffb581ad28da533e42737db8761295fe 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
                },
 }
 
@@ -29,6 +30,7 @@ sub canedit ($$$) {
        # signin can override this.
         if (! defined $session->param("name") ||
             ! IkiWiki::userinfo_get($session->param("name"), "regdate")) {
+               return "" unless exists $IkiWiki::hooks{auth};
                return sub { IkiWiki::needsignin($cgi, $session) };
        }
        else {
index c1f016ffd0e7055bae3f5ba72f9f04b643285c01..42665ac63699efe2752dd177fdf1f998068aa418 100644 (file)
@@ -24,6 +24,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
@@ -149,7 +150,7 @@ sub preprocess (@) {
 
                waitpid $pid, 0;
                $SIG{PIPE}="DEFAULT";
-               if ($sigpipe) {
+               if ($sigpipe || ! defined $png) {
                        error gettext("failed to run php");
                }
 
index 06b987f51ce756676aa977c2c95af0aa4628e952..7d27ec8427b1b341c1dc7e9d3d3b92f2a4e838a1 100644 (file)
@@ -44,6 +44,7 @@ sub getsetup () {
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                svnrepo => {
                        type => "string",
index 96d63f455f886e9111f0e7bd26558b020c1de61b..2edd1eacd11a329d71d81add93c431462685ef03 100644 (file)
@@ -16,6 +16,7 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
index b6097bb49d26133a54dc2fa27c3fc98e59d657bb..3e024c5f81b11db1c7791fe8ef214d06f186cb09 100644 (file)
@@ -19,12 +19,17 @@ sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => undef,
+                       section => "widget",
                },
 }
 
 sub preprocess (@) {
        my %params=@_;
 
+       # This needs to run even in scan mode, in order to process
+       # links and other metadata included via the template.
+       my $scan=! defined wantarray;
+
        if (! exists $params{id}) {
                error gettext("missing id parameter")
        }
@@ -58,24 +63,23 @@ sub preprocess (@) {
        $params{basename}=IkiWiki::basename($params{page});
 
        foreach my $param (keys %params) {
+               my $value=IkiWiki::preprocess($params{page}, $params{destpage},
+                         IkiWiki::filter($params{page}, $params{destpagea},
+                         $params{$param}), $scan);
                if ($template->query(name => $param)) {
                        $template->param($param =>
                                IkiWiki::htmlize($params{page}, $params{destpage},
                                        pagetype($pagesources{$params{page}}),
-                                       $params{$param}));
+                                       $value));
                }
                if ($template->query(name => "raw_$param")) {
-                       $template->param("raw_$param" => $params{$param});
+                       $template->param("raw_$param" => $value);
                }
        }
 
-       # 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), $scan);
+              IkiWiki::filter($params{page}, $params{destpage},
+              $template->output), $scan);
 }
 
 1
index f92ed01326b7df203b59e4e05e423ce4f6f8209f..521af499fc77