improve support for internal pages
authorJoey Hess <joey@kodama.kitenet.net>
Tue, 29 Jan 2008 20:05:49 +0000 (15:05 -0500)
committerJoey Hess <joey@kodama.kitenet.net>
Tue, 29 Jan 2008 20:05:49 +0000 (15:05 -0500)
This makes it a lot quicker to deal with lots of recentchanges pages
appearing and disappearing. It avoids needing to clutter up pagespecs with
exclusions for those pages, by making normal pagespecs not match them.

IkiWiki.pm
IkiWiki/Render.pm
debian/changelog
doc/ikiwiki/pagespec.mdwn
doc/plugins/brokenlinks.mdwn
doc/plugins/orphans.mdwn
doc/plugins/pagecount.mdwn
doc/plugins/recentchanges.mdwn
doc/plugins/write.mdwn

index c70307b5f299ae0955e086fd8ebeff937ac895e9..db260567212d426d9b260c8e1212e49342e1c870 100644 (file)
@@ -260,6 +260,12 @@ sub pagetype ($) { #{{{
        return;
 } #}}}
 
+sub isinternal ($) { #{{{
+       my $page=shift;
+       return exists $pagesources{$page} &&
+               $pagesources{$page} =~ /\._([^.]+)$/;
+} #}}}
+
 sub pagename ($) { #{{{
        my $file=shift;
 
@@ -1287,13 +1293,22 @@ sub match_glob ($$;@) { #{{{
        $glob=~s/\\\?/./g;
 
        if ($page=~/^$glob$/i) {
-               return IkiWiki::SuccessReason->new("$glob matches $page");
+               if (! IkiWiki::isinternal($page) || $params{internal}) {
+                       return IkiWiki::SuccessReason->new("$glob matches $page");
+               }
+               else {
+                       return IkiWiki::FailReason->new("$glob matches $page, but the page is an internal page");
+               }
        }
        else {
                return IkiWiki::FailReason->new("$glob does not match $page");
        }
 } #}}}
 
+sub match_internal ($$;@) { #{{{
+       return match_glob($_[0], $_[1], @_, internal => 1)
+} #}}}
+
 sub match_link ($$;@) { #{{{
        my $page=shift;
        my $link=lc(shift);
@@ -1389,19 +1404,4 @@ sub match_creation_year ($$;@) { #{{{
        }
 } #}}}
 
-sub match_user ($$;@) { #{{{
-       shift;
-       my $user=shift;
-       my %params=@_;
-
-       return IkiWiki::FailReason->new('cannot match user')
-               unless exists $params{user};
-       if ($user eq $params{user}) {
-               return IkiWiki::SuccessReason->new("user is $user")
-       }
-       else {
-               return IkiWiki::FailReason->new("user is not $user");
-       }
-} #}}}
-
 1
index aa9b73141e28697181169db083d4151e52c90b74..b5b461499d1a1f9324d1c9a68c9644f72f246eca 100644 (file)
@@ -319,15 +319,19 @@ sub refresh () { #{{{
                }, $dir);
        };
 
-       my %rendered;
+       my (%rendered, @add, @del, @internal);
 
        # check for added or removed pages
-       my @add;
        foreach my $file (@files) {
                my $page=pagename($file);
                $pagesources{$page}=$file;
                if (! $pagemtime{$page}) {
-                       push @add, $file;
+                       if (isinternal($page)) {
+                               push @internal, $file;
+                       }
+                       else {
+                               push @add, $file;
+                       }
                        $pagecase{lc $page}=$page;
                        if ($config{getctime} && -e "$config{srcdir}/$file") {
                                $pagectime{$page}=rcs_getctime("$config{srcdir}/$file");
@@ -337,11 +341,15 @@ sub refresh () { #{{{
                        }
                }
        }
-       my @del;
        foreach my $page (keys %pagemtime) {
                if (! $exists{$page}) {
-                       debug(sprintf(gettext("removing old page %s"), $page));
-                       push @del, $pagesources{$page};
+                       if (isinternal($page)) {
+                               push @internal, $pagesources{$page};
+                       }
+                       else {
+                               debug(sprintf(gettext("removing old page %s"), $page));
+                               push @del, $pagesources{$page};
+                       }
                        $links{$page}=[];
                        $renderedfiles{$page}=[];
                        $pagemtime{$page}=0;
@@ -366,7 +374,12 @@ sub refresh () { #{{{
                    $mtime > $pagemtime{$page} ||
                    $forcerebuild{$page}) {
                        $pagemtime{$page}=$mtime;
-                       push @needsbuild, $file;
+                       if (isinternal($page)) {
+                               push @internal, $file;
+                       }
+                       else {
+                               push @needsbuild, $file;
+                       }
                }
        }
        run_hooks(needsbuild => sub { shift->(\@needsbuild) });
@@ -382,6 +395,15 @@ sub refresh () { #{{{
                render($file);
                $rendered{$file}=1;
        }
+       foreach my $file (@internal) {
+               # internal pages are not rendered
+               my $page=pagename($file);
+               delete $depends{$page};
+               foreach my $old (@{$renderedfiles{$page}}) {
+                       delete $destsources{$old};
+               }
+               $renderedfiles{$page}=[];
+       }
        
        # rebuild pages that link to added or removed pages
        if (@add || @del) {
@@ -397,13 +419,17 @@ sub refresh () { #{{{
                }
        }
 
-       if (%rendered || @del) {
+       if (%rendered || @del || @internal) {
+               my @changed=(keys %rendered, @del);
+
                # rebuild dependant pages
                foreach my $f (@files) {
                        next if $rendered{$f};
                        my $p=pagename($f);
                        if (exists $depends{$p}) {
-                               foreach my $file (keys %rendered, @del) {
+                               # only consider internal files
+                               # if the page explicitly depends on such files
+                               foreach my $file (@changed, $depends{$p}=~/internal\(/ ? @internal : ()) {
                                        next if $f eq $file;
                                        my $page=pagename($file);
                                        if (pagespec_match($page, $depends{$p}, location => $p)) {
@@ -419,7 +445,7 @@ sub refresh () { #{{{
                # handle backlinks; if a page has added/removed links,
                # update the pages it links to
                my %linkchanged;
-               foreach my $file (keys %rendered, @del) {
+               foreach my $file (@changed) {
                        my $page=pagename($file);
                        
                        if (exists $links{$page}) {
@@ -441,6 +467,7 @@ sub refresh () { #{{{
                                }
                        }
                }
+
                foreach my $link (keys %linkchanged) {
                        my $linkfile=$pagesources{$link};
                        if (defined $linkfile) {
index 8530bdd7e0780d4eb761b3a476a29b1be705e534..c608531e1fa47915bd6d156c616dfaae922c0b57 100644 (file)
@@ -22,13 +22,15 @@ ikiwiki (2.21) UNRELEASED; urgency=low
   * prettydate,ddate: Don't ignore time formats passed to displaytime
     function.
   * Pages with extensions starting with "_" are internal-use, and will
-    not be rendered or web-edited.
+    not be rendered or web-edited, or matched by normal pagespecs.
+  * Add "internal()" pagespec that matches internal-use pages.
   * RecentChanges is now a static html page, that's updated whenever a commit
     is made to the wiki. It's built as a blog using inline, so it can have
     an rss feed that users can subscribe to.
   * Removed support for sending commit notification mails. Along with it went
     the svnrepo and notify settings, though both will be ignored if left in
-    setup files.
+    setup files. Also gone with it is the "user()" pagespec.
+  * Add refresh hook.
 
  -- Joey Hess <joeyh@debian.org>  Fri, 11 Jan 2008 15:09:37 -0500
 
index 5c6433ed3391337aaf5d3cd1afea0057e0aa2042..e1a4762024d3769ae8a4aa79d349917bb3c7dbe3 100644 (file)
@@ -33,8 +33,10 @@ functions:
   was created
 * "`created_before(page)`" - match only pages created before the given page
   was created
-* "`user(name)`" - only available in page subscription preferences, match
-  only changes made by this user
+* "`glob(foo)`" - match pages that match the given glob `foo`. Just writing
+  the glob by itself is actually a shorthand for this function.
+* "`internal(foo)`" - like `glob()`, but matches even internal-use 
+  pages that globs do not usually match.
 
 For example, to match all pages in a blog that link to the page about music
 and were written in 2005:
index 5c906e17b8105d968888a98712ae10f7a441612d..208d7120b280ca7593f4635e769bbc0074935f85 100644 (file)
@@ -10,4 +10,4 @@ pages to search for broken links, default is search them all.
 
 If this plugin is turned on, here's a list of broken links on this wiki:
 
-[[brokenlinks pages="* and !recentchanges/change_* and !recentchanges"]]
+[[brokenlinks pages="* and !recentchanges"]]
index 6c6ebd6f931c63527c53e3e0d9e06884e4ee2dc8..74f4bae0826fdc1f2fb97aedb5886e24ac5255b7 100644 (file)
@@ -15,6 +15,6 @@ orphans.
 Here's a list of orphaned pages on this wiki:
 
 [[orphans pages="* and !news/* and !todo/* and !bugs/* and !users/* and
-!recentchanges/change_* and !recentchanges and !examples/* and !tips/* and
-!sandbox/* and !wikiicons/* and !plugins/*"]]
+!recentchanges and !examples/* and !tips/* and !sandbox/* and
+!wikiicons/* and !plugins/*"]]
 """]]
index c4cefd94657b2f1146ef7219699df77b11818109..8f7029df8a4994fa76127d620a746d751bd3e2fe 100644 (file)
@@ -10,5 +10,5 @@ pages to count, default is to count them all.
 This plugin is included in ikiwiki, but is not enabled by default.
 
 If it is turned on it can tell us that this wiki includes
-[[pagecount pages="* and !recentchanges/change_* and !recentchanges"]]
+[[pagecount pages="* and !recentchanges"]]
 pages, of which [[pagecount pages="*/Discussion"]] are discussion pages.
index 9e0d8dc511fbe536b43a69a205eaec923456071a..69073adf08d21851811c3d6928da4a647573239e 100644 (file)
@@ -9,6 +9,8 @@ Typically only the RecentChanges page will use the plugin, but you can
 use it elsewhere too if you like. It's used like this:
 
        \[[recentchanges pages="*" num=100 template=change]]
+       \[[inline pages="internal(recentchanges/change_*)"
+       template=recentchanges show=0]]
 
 The pages describing recent changes will be created as [[subpages|subpage]]
 of the page where the `recentchanges` directive is placed.
index 9e27cc27f8103cecd315d506d4d3f6b2941ccd7a..4de7e434d1173b12a4bf474695c26cb23b3f7354 100644 (file)
@@ -151,11 +151,6 @@ specifies the filename extension that a file must have to be htmlized using
 this plugin. This is how you can add support for new and exciting markup
 languages to ikiwiki.
 
-Note that if you choose a filename extension that starts with "_",
-ikiwiki will not render the page, or allow the page to be edited with the
-web interface. This is useful for certian types of internal-use pages, but
-should generally be avoided.
-
 The function is passed named parameters: "page" and "content" and should
 return the htmlized content.
 
@@ -536,6 +531,19 @@ destination file, as registered by `will_render`.
 Passed a page and an extension, returns the filename that page will be
 rendered to.
 
+## Internal use pages
+
+Sometimes it's useful to put pages in the wiki without having them be
+rendered to individual html files. Such internal use pages are collected
+together to form the RecentChanges page, for example.
+
+To make an internal use page, register a filename extension that starts
+with "_". Internal use pages cannot be edited with the web interface, are
+not scanned for wikilinks (though wikilinks and preprocessor directives can
+still appear on them, this is rarely a good idea), and are not matched by
+regular PageSpecs glob patterns, but instead only by a special `internal()`
+[[ikiwiki/PageSpec]].
+
 ## RCS plugins
 
 ikiwiki's support for [[revision_control_systems|rcs]] also uses pluggable