aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2006-05-02 02:34:33 +0000
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>2006-05-02 02:34:33 +0000
commit54d5308cd83c67e7e9c32450c776ef0dac63549f (patch)
tree0352882349bca8952a59fd322099470b7952e0c8 /IkiWiki
parent457d6bbbbfbb0474749a0d68e959613c86facf72 (diff)
downloadikiwiki-54d5308cd83c67e7e9c32450c776ef0dac63549f.tar
ikiwiki-54d5308cd83c67e7e9c32450c776ef0dac63549f.tar.gz
* Added plugin system, currently only supporting for PreProcessorDirectives.
* Added a pagecount plugin, enabled by default. * Support PreProcessorDirectives with no parameters, ie "[[pagecount ]]". * Fixed/optimised backlinks code, to avoid rebuilding pages to update backlinks when the backlinks hadn't really changed. * Moved inline page support, rss generation etc into the inline plugin, enabled by default. * Added brokenlinks plugin, not enabled by default, but rather handy. * Fix several broken links in the doc wiki.
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/Plugin/brokenlinks.pm39
-rw-r--r--IkiWiki/Plugin/inline.pm161
-rw-r--r--IkiWiki/Plugin/pagecount.pm29
-rw-r--r--IkiWiki/Plugin/skeleton.pm19
-rw-r--r--IkiWiki/Render.pm166
5 files changed, 262 insertions, 152 deletions
diff --git a/IkiWiki/Plugin/brokenlinks.pm b/IkiWiki/Plugin/brokenlinks.pm
new file mode 100644
index 000000000..9485da398
--- /dev/null
+++ b/IkiWiki/Plugin/brokenlinks.pm
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+# Provides a list of broken links.
+package IkiWiki::Plugin::brokenlinks;
+
+use warnings;
+use strict;
+
+sub import { #{{{
+ IkiWiki::register_plugin("preprocess", "brokenlinks", \&preprocess);
+} # }}}
+
+sub preprocess (@) { #{{{
+ my %params=@_;
+ $params{pages}="*" unless defined $params{pages};
+
+ # Needs to update whenever a page is added or removed, so
+ # register a dependency.
+ IkiWiki::add_depends($params{page}, $params{pages});
+
+ my @broken;
+ foreach my $page (%IkiWiki::links) {
+ if (IkiWiki::globlist_match($page, $params{pages})) {
+ foreach my $link (@{$IkiWiki::links{$page}}) {
+ next if $link =~ /.*\/discussion/i;
+ my $bestlink=IkiWiki::bestlink($page, $link);
+ next if length $bestlink;
+ push @broken,
+ IkiWiki::htmllink($page, $link, 1).
+ " in ".
+ IkiWiki::htmllink($params{page}, $page, 1);
+ }
+ }
+ }
+
+ return "There are no broken links!" unless @broken;
+ return "<ul>\n".join("\n", map { "<li>$_</li>" } sort @broken)."</ul>\n";
+} # }}}
+
+1
diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm
new file mode 100644
index 000000000..53ea5bf18
--- /dev/null
+++ b/IkiWiki/Plugin/inline.pm
@@ -0,0 +1,161 @@
+#!/usr/bin/perl
+# Page inlining and blogging.
+package IkiWiki::Plugin::inline;
+
+use warnings;
+use strict;
+
+sub import { #{{{
+ IkiWiki::register_plugin("preprocess", "inline", \&IkiWiki::preprocess_inline);
+} # }}}
+
+# Back to ikiwiki namespace for the rest, this code is very much
+# internal to ikiwiki even though it's separated into a plugin.
+package IkiWiki;
+
+sub preprocess_inline (@) { #{{{
+ my %params=@_;
+
+ if (! exists $params{pages}) {
+ return "";
+ }
+ if (! exists $params{archive}) {
+ $params{archive}="no";
+ }
+ if (! exists $params{show} && $params{archive} eq "no") {
+ $params{show}=10;
+ }
+ add_depends($params{page}, $params{pages});
+
+ my $ret="";
+
+ if (exists $params{rootpage}) {
+ # Add a blog post form, with a rss link button.
+ my $formtemplate=HTML::Template->new(blind_cache => 1,
+ filename => "$config{templatedir}/blogpost.tmpl");
+ $formtemplate->param(cgiurl => $config{cgiurl});
+ $formtemplate->param(rootpage => $params{rootpage});
+ if ($config{rss}) {
+ $formtemplate->param(rssurl => rsspage(basename($params{page})));
+ }
+ $ret.=$formtemplate->output;
+ }
+ elsif ($config{rss}) {
+ # Add a rss link button.
+ my $linktemplate=HTML::Template->new(blind_cache => 1,
+ filename => "$config{templatedir}/rsslink.tmpl");
+ $linktemplate->param(rssurl => rsspage(basename($params{page})));
+ $ret.=$linktemplate->output;
+ }
+
+ my $template=HTML::Template->new(blind_cache => 1,
+ filename => (($params{archive} eq "no")
+ ? "$config{templatedir}/inlinepage.tmpl"
+ : "$config{templatedir}/inlinepagetitle.tmpl"));
+
+ my @pages;
+ foreach my $page (blog_list($params{pages}, $params{show})) {
+ next if $page eq $params{page};
+ push @pages, $page;
+ $template->param(pagelink => htmllink($params{page}, $page));
+ $template->param(content => get_inline_content($params{page}, $page))
+ if $params{archive} eq "no";
+ $template->param(ctime => scalar(gmtime($pagectime{$page})));
+ $ret.=$template->output;
+ }
+
+ # TODO: should really add this to renderedfiles and call
+ # check_overwrite, but currently renderedfiles
+ # only supports listing one file per page.
+ if ($config{rss}) {
+ writefile(rsspage($params{page}), $config{destdir},
+ genrss($params{page}, @pages));
+ }
+
+ return $ret;
+} #}}}
+
+sub blog_list ($$) { #{{{
+ my $globlist=shift;
+ my $maxitems=shift;
+
+ my @list;
+ foreach my $page (keys %pagesources) {
+ if (globlist_match($page, $globlist)) {
+ push @list, $page;
+ }
+ }
+
+ @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
+ return @list if ! $maxitems || @list <= $maxitems;
+ return @list[0..$maxitems - 1];
+} #}}}
+
+sub get_inline_content ($$) { #{{{
+ my $parentpage=shift;
+ my $page=shift;
+
+ my $file=$pagesources{$page};
+ my $type=pagetype($file);
+ if ($type ne 'unknown') {
+ return htmlize($type, linkify(readfile(srcfile($file)), $parentpage));
+ }
+ else {
+ return "";
+ }
+} #}}}
+
+sub date_822 ($) { #{{{
+ my $time=shift;
+
+ eval q{use POSIX};
+ return POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time));
+} #}}}
+
+sub absolute_urls ($$) { #{{{
+ # sucky sub because rss sucks
+ my $content=shift;
+ my $url=shift;
+
+ $url=~s/[^\/]+$//;
+
+ $content=~s/<a\s+href="(?!http:\/\/)([^"]+)"/<a href="$url$1"/ig;
+ $content=~s/<img\s+src="(?!http:\/\/)([^"]+)"/<img src="$url$1"/ig;
+ return $content;
+} #}}}
+
+sub rsspage ($) { #{{{
+ my $page=shift;
+
+ return $page.".rss";
+} #}}}
+
+sub genrss ($@) { #{{{
+ my $page=shift;
+ my @pages=@_;
+
+ my $url="$config{url}/".htmlpage($page);
+
+ my $template=HTML::Template->new(blind_cache => 1,
+ filename => "$config{templatedir}/rsspage.tmpl");
+
+ my @items;
+ foreach my $p (@pages) {
+ push @items, {
+ itemtitle => pagetitle(basename($p)),
+ itemurl => "$config{url}/$renderedfiles{$p}",
+ itempubdate => date_822($pagectime{$p}),
+ itemcontent => absolute_urls(get_inline_content($page, $p), $url),
+ } if exists $renderedfiles{$p};
+ }
+
+ $template->param(
+ title => $config{wikiname},
+ pageurl => $url,
+ items => \@items,
+ );
+
+ return $template->output;
+} #}}}
+
+1
diff --git a/IkiWiki/Plugin/pagecount.pm b/IkiWiki/Plugin/pagecount.pm
new file mode 100644
index 000000000..865ab4c39
--- /dev/null
+++ b/IkiWiki/Plugin/pagecount.pm
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+# Provides [[pagecount ]] to count the number of pages.
+package IkiWiki::Plugin::pagecount;
+
+use warnings;
+use strict;
+
+sub import { #{{{
+ IkiWiki::register_plugin("preprocess", "pagecount", \&preprocess);
+} # }}}
+
+sub preprocess (@) { #{{{
+ my %params=@_;
+ $params{pages}="*" unless defined $params{pages};
+
+ # Needs to update count whenever a page is added or removed, so
+ # register a dependency.
+ IkiWiki::add_depends($params{page}, $params{pages});
+
+ my @pages=keys %IkiWiki::pagesources;
+ return $#pages+1 if $params{pages} eq "*"; # optimisation
+ my $count=0;
+ foreach my $page (@pages) {
+ $count++ if IkiWiki::globlist_match($page, $params{pages});
+ }
+ return $count;
+} # }}}
+
+1
diff --git a/IkiWiki/Plugin/skeleton.pm b/IkiWiki/Plugin/skeleton.pm
new file mode 100644
index 000000000..e8d3db0cc
--- /dev/null
+++ b/IkiWiki/Plugin/skeleton.pm
@@ -0,0 +1,19 @@
+#!/usr/bin/perl
+# Ikiwiki skeleton plugin. Replace "skeleton" with the name of your plugin
+# in the lines below, and flesh out the methods to make it do something.
+package IkiWiki::Plugin::skeleton;
+
+use warnings;
+use strict;
+
+sub import { #{{{
+ IkiWiki::register_plugin("preprocess", "skeleton", \&preprocess);
+} # }}}
+
+sub preprocess (@) { #{{{
+ my %params=@_;
+
+ return "skeleton plugin result";
+} # }}}
+
+1
diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
index 3006b64d4..f9730193b 100644
--- a/IkiWiki/Render.pm
+++ b/IkiWiki/Render.pm
@@ -122,18 +122,10 @@ sub parentlinks ($) { #{{{
return @ret;
} #}}}
-sub rsspage ($) { #{{{
- my $page=shift;
-
- return $page.".rss";
-} #}}}
-
sub preprocess ($$) { #{{{
my $page=shift;
my $content=shift;
- my %commands=(inline => \&preprocess_inline);
-
my $handle=sub {
my $escape=shift;
my $command=shift;
@@ -141,12 +133,12 @@ sub preprocess ($$) { #{{{
if (length $escape) {
return "[[$command $params]]";
}
- elsif (exists $commands{$command}) {
+ elsif (exists $plugins{preprocess}{$command}) {
my %params;
while ($params =~ /(\w+)=\"([^"]+)"(\s+|$)/g) {
$params{$1}=$2;
}
- return $commands{$command}->(page => $page, %params);
+ return $plugins{preprocess}{$command}->(page => $page, %params);
}
else {
return "[[bad directive $command]]";
@@ -157,102 +149,17 @@ sub preprocess ($$) { #{{{
return $content;
} #}}}
-sub blog_list ($$) { #{{{
- my $globlist=shift;
- my $maxitems=shift;
-
- my @list;
- foreach my $page (keys %pagesources) {
- if (globlist_match($page, $globlist)) {
- push @list, $page;
- }
- }
-
- @list=sort { $pagectime{$b} <=> $pagectime{$a} } @list;
- return @list if ! $maxitems || @list <= $maxitems;
- return @list[0..$maxitems - 1];
-} #}}}
-
-sub get_inline_content ($$) { #{{{
- my $parentpage=shift;
+sub add_depends ($$) { #{{{
my $page=shift;
+ my $globlist=shift;
- my $file=$pagesources{$page};
- my $type=pagetype($file);
- if ($type ne 'unknown') {
- return htmlize($type, linkify(readfile(srcfile($file)), $parentpage));
- }
- else {
- return "";
- }
-} #}}}
-
-sub preprocess_inline ($@) { #{{{
- my %params=@_;
-
- if (! exists $params{pages}) {
- return "";
- }
- if (! exists $params{archive}) {
- $params{archive}="no";
- }
- if (! exists $params{show} && $params{archive} eq "no") {
- $params{show}=10;
- }
- if (! exists $depends{$params{page}}) {
- $depends{$params{page}}=$params{pages};
+ if (! exists $depends{$page}) {
+ $depends{$page}=$globlist;
}
else {
- $depends{$params{page}}.=" ".$params{pages};
- }
-
- my $ret="";
-
- if (exists $params{rootpage}) {
- # Add a blog post form, with a rss link button.
- my $formtemplate=HTML::Template->new(blind_cache => 1,
- filename => "$config{templatedir}/blogpost.tmpl");
- $formtemplate->param(cgiurl => $config{cgiurl});
- $formtemplate->param(rootpage => $params{rootpage});
- if ($config{rss}) {
- $formtemplate->param(rssurl => rsspage(basename($params{page})));
- }
- $ret.=$formtemplate->output;
- }
- elsif ($config{rss}) {
- # Add a rss link button.
- my $linktemplate=HTML::Template->new(blind_cache => 1,
- filename => "$config{templatedir}/rsslink.tmpl");
- $linktemplate->param(rssurl => rsspage(basename($params{page})));
- $ret.=$linktemplate->output;
- }
-
- my $template=HTML::Template->new(blind_cache => 1,
- filename => (($params{archive} eq "no")
- ? "$config{templatedir}/inlinepage.tmpl"
- : "$config{templatedir}/inlinepagetitle.tmpl"));
-
- my @pages;
- foreach my $page (blog_list($params{pages}, $params{show})) {
- next if $page eq $params{page};
- push @pages, $page;
- $template->param(pagelink => htmllink($params{page}, $page));
- $template->param(content => get_inline_content($params{page}, $page))
- if $params{archive} eq "no";
- $template->param(ctime => scalar(gmtime($pagectime{$page})));
- $ret.=$template->output;
- }
-
- # TODO: should really add this to renderedfiles and call
- # check_overwrite, but currently renderedfiles
- # only supports listing one file per page.
- if ($config{rss}) {
- writefile(rsspage($params{page}), $config{destdir},
- genrss($params{page}, @pages));
+ $depends{$page}.=" ".$globlist;
}
-
- return $ret;
-} #}}}
+} # }}}
sub genpage ($$$) { #{{{
my $content=shift;
@@ -295,53 +202,6 @@ sub genpage ($$$) { #{{{
return $template->output;
} #}}}
-sub date_822 ($) { #{{{
- my $time=shift;
-
- eval q{use POSIX};
- return POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time));
-} #}}}
-
-sub absolute_urls ($$) { #{{{
- # sucky sub because rss sucks
- my $content=shift;
- my $url=shift;
-
- $url=~s/[^\/]+$//;
-
- $content=~s/<a\s+href="(?!http:\/\/)([^"]+)"/<a href="$url$1"/ig;
- $content=~s/<img\s+src="(?!http:\/\/)([^"]+)"/<img src="$url$1"/ig;
- return $content;
-} #}}}
-
-sub genrss ($@) { #{{{
- my $page=shift;
- my @pages=@_;
-
- my $url="$config{url}/".htmlpage($page);
-
- my $template=HTML::Template->new(blind_cache => 1,
- filename => "$config{templatedir}/rsspage.tmpl");
-
- my @items;
- foreach my $p (@pages) {
- push @items, {
- itemtitle => pagetitle(basename($p)),
- itemurl => "$config{url}/$renderedfiles{$p}",
- itempubdate => date_822($pagectime{$p}),
- itemcontent => absolute_urls(get_inline_content($page, $p), $url),
- } if exists $renderedfiles{$p};
- }
-
- $template->param(
- title => $config{wikiname},
- pageurl => $url,
- items => \@items,
- );
-
- return $template->output;
-} #}}}
-
sub check_overwrite ($$) { #{{{
# Important security check. Make sure to call this before saving
# any files to the source directory.
@@ -400,6 +260,7 @@ sub render ($) { #{{{
else {
my $content=readfile($srcfile, 1);
$links{$file}=[];
+ delete $depends{$file};
check_overwrite("$config{destdir}/$file", $file);
writefile($file, $config{destdir}, $content, 1);
$oldpagemtime{$file}=time;
@@ -588,6 +449,7 @@ FILE: foreach my $file (@files) {
my $p=pagename($f);
if (exists $depends{$p}) {
foreach my $file (keys %rendered, @del) {
+ next if $f eq $file;
my $page=pagename($file);
if (globlist_match($page, $depends{$p})) {
debug("rendering $f, which depends on $page");
@@ -606,8 +468,8 @@ FILE: foreach my $file (@files) {
if (exists $links{$page}) {
foreach my $link (map { bestlink($page, $_) } @{$links{$page}}) {
if (length $link &&
- ! exists $oldlinks{$page} ||
- ! grep { $_ eq $link } @{$oldlinks{$page}}) {
+ (! exists $oldlinks{$page} ||
+ ! grep { bestlink($page, $_) eq $link } @{$oldlinks{$page}})) {
$linkchanged{$link}=1;
}
}
@@ -615,8 +477,8 @@ FILE: foreach my $file (@files) {
if (exists $oldlinks{$page}) {
foreach my $link (map { bestlink($page, $_) } @{$oldlinks{$page}}) {
if (length $link &&
- ! exists $links{$page} ||
- ! grep { $_ eq $link } @{$links{$page}}) {
+ (! exists $links{$page} ||
+ ! grep { bestlink($page, $_) eq $link } @{$links{$page}})) {
$linkchanged{$link}=1;
}
}