From 7833fc9677146ef596744bdc69fb35cb6d2aa8c9 Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 20:54:03 +0000 Subject: [PATCH 01/16] web commit by joey --- doc/todo/plugin.mdwn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 284ed7a06..be980ea2d 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -14,3 +14,5 @@ Considering ikiwiki plugins, one idea I have is to make the [[PreProcessorDirect Since preprocessing happens before htmlization but after a page is loaded and linkified, it should be possible to use it to create something like a link map or lists, or a page index. Page inlining and rss generation is already done via preprocessor directives and seems a natureal as a plugin too. Note that things like a link map or a broken link list page would need to be updated whenever a set (or all) pages change; the %inlinepages hash already allows for pages to register this, although it might need to be renamed. + +I need to look at the range of things that other wikis use their plugin systems for, but preprocessor directives as plugins certianly seems useful, even if it's not a complete solution. \ No newline at end of file -- 2.39.5 From 2bea9c696e9fb66c0377379b6467f9b018f952ba Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:07:08 +0000 Subject: [PATCH 02/16] web commit by joey --- doc/todo/plugin.mdwn | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index be980ea2d..f8f8d88f6 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -7,12 +7,28 @@ A plugin system should ideally support things like: * [[todo/sigs]] * [[pageindexes]] * Wiki stats, such as the total number of pages, total number of links, most linked to pages, etc, etc. +* wiki info page, giving the ikiwiki version etc * etc +Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. + +## preprocessor plugins + Considering ikiwiki plugins, one idea I have is to make the [[PreProcessorDirective]]s be a plugin. A setting in the config file would enable various plusins, which are perl modules, that each provide one or more preprocessor directives. Since preprocessing happens before htmlization but after a page is loaded and linkified, it should be possible to use it to create something like a link map or lists, or a page index. Page inlining and rss generation is already done via preprocessor directives and seems a natureal as a plugin too. Note that things like a link map or a broken link list page would need to be updated whenever a set (or all) pages change; the %inlinepages hash already allows for pages to register this, although it might need to be renamed. -I need to look at the range of things that other wikis use their plugin systems for, but preprocessor directives as plugins certianly seems useful, even if it's not a complete solution. \ No newline at end of file +I need to look at the full range of things that other wikis use their plugin systems for, but preprocessor directives as plugins certianly seems useful, even if it's not a complete solution. + +## case study: Moin Moin plugins + +See + +6 different types of plugins: + +* *actions* are possibly out of scope for ikiwiki, this is probably what it uses for cgi script type stuff. Unless ikiwiki wants to allow pluggable CGI script stuff, it doesn't need these. +* *parsers* and *formatters* are basically what I've been calling [[PluggableRenderers]]. MoinMoin separates these, so that a page is parsed to (presumbly) some intermediate form before being output as html or some other form. That's a nice separation, but what to do about things like markdown that are both a parser and a formatter? +* *macros* and *processors* are analagous to preprocessor directives. A processor can operate on a large block of text though. +* *themes* should be irrellevant (ikiwiki has [[templates]]). -- 2.39.5 From 02430a23a65927916603213808f086bf5af8f103 Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:12:06 +0000 Subject: [PATCH 03/16] web commit by joey --- doc/todo/plugin.mdwn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index f8f8d88f6..8b1487df2 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -8,6 +8,7 @@ A plugin system should ideally support things like: * [[pageindexes]] * Wiki stats, such as the total number of pages, total number of links, most linked to pages, etc, etc. * wiki info page, giving the ikiwiki version etc +* would it be useful to reimplement the hyperestradier search integration as a plugin? * etc Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. @@ -32,3 +33,6 @@ See * *parsers* and *formatters* are basically what I've been calling [[PluggableRenderers]]. MoinMoin separates these, so that a page is parsed to (presumbly) some intermediate form before being output as html or some other form. That's a nice separation, but what to do about things like markdown that are both a parser and a formatter? * *macros* and *processors* are analagous to preprocessor directives. A processor can operate on a large block of text though. * *themes* should be irrellevant (ikiwiki has [[templates]]). + +## case study: pybloxsom plugins + -- 2.39.5 From 7a5c8c632b24a703031375a986b0dc2821944ec5 Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:14:30 +0000 Subject: [PATCH 04/16] web commit by joey --- doc/todo/plugin.mdwn | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 8b1487df2..e4abc6068 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -33,6 +33,3 @@ See * *parsers* and *formatters* are basically what I've been calling [[PluggableRenderers]]. MoinMoin separates these, so that a page is parsed to (presumbly) some intermediate form before being output as html or some other form. That's a nice separation, but what to do about things like markdown that are both a parser and a formatter? * *macros* and *processors* are analagous to preprocessor directives. A processor can operate on a large block of text though. * *themes* should be irrellevant (ikiwiki has [[templates]]). - -## case study: pybloxsom plugins - -- 2.39.5 From 88415ffef96877a53c7b08f524309642a445873e Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:18:58 +0000 Subject: [PATCH 05/16] web commit by joey --- doc/todo/plugin.mdwn | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index e4abc6068..1d49de66a 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -9,6 +9,7 @@ A plugin system should ideally support things like: * Wiki stats, such as the total number of pages, total number of links, most linked to pages, etc, etc. * wiki info page, giving the ikiwiki version etc * would it be useful to reimplement the hyperestradier search integration as a plugin? +* Maybe it would be possible to make RecentChanges a regular wiki page, by making it a page that renders statically, but somehow runs the cgi at view time to dyamically render the changes? Then this could be a plugin too. How would this be accomplished in html though? Only way I know is via server side includes.. * etc Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. -- 2.39.5 From 6637d5bb25703dd90df0f11085566a7ba958c310 Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:21:02 +0000 Subject: [PATCH 06/16] web commit by joey --- doc/bugs.mdwn | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/bugs.mdwn b/doc/bugs.mdwn index a8e9ae679..6e02e4533 100644 --- a/doc/bugs.mdwn +++ b/doc/bugs.mdwn @@ -14,8 +14,6 @@ EUID/Real UID screwage. * Can't put the source in a directory named .source; the page finder skips that due to too broad exclusion of any dotfile in a path. -* RecentChanges is a regular page, perhaps it should be automatically - replaced with a link to the [[CGI]]? * [[ikiwiki]] should go to the same place as [[index]] (on this wiki). * Web browsers don't word-wrap lines in submitted text, which makes editing a page that someone wrote in a web browser annoying (`gqip` is vim user's -- 2.39.5 From d29786a5fbb69dd10faa6e914a9944b7bc5a592e Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:26:04 +0000 Subject: [PATCH 07/16] web commit by joey --- doc/todo/plugin.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 1d49de66a..ca3391f8a 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -9,7 +9,7 @@ A plugin system should ideally support things like: * Wiki stats, such as the total number of pages, total number of links, most linked to pages, etc, etc. * wiki info page, giving the ikiwiki version etc * would it be useful to reimplement the hyperestradier search integration as a plugin? -* Maybe it would be possible to make RecentChanges a regular wiki page, by making it a page that renders statically, but somehow runs the cgi at view time to dyamically render the changes? Then this could be a plugin too. How would this be accomplished in html though? Only way I know is via server side includes.. +* Support [[RecentChanges]] as a regular page containing a plugin that updates each time there is a change, and statically builds the recent changes list. (Would this be too expensive? There might be other ways to do it as a plugin, like making all links to RecentChanges link to the cgi and have the cgi render it on demand.) * etc Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. -- 2.39.5 From 3de6aab0a42bbcfa5fbf69a417b3f2023f8b684e Mon Sep 17 00:00:00 2001 From: www-data Date: Mon, 1 May 2006 21:26:43 +0000 Subject: [PATCH 08/16] web commit by joey --- doc/todo/plugin.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index ca3391f8a..5f070dd92 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -9,7 +9,7 @@ A plugin system should ideally support things like: * Wiki stats, such as the total number of pages, total number of links, most linked to pages, etc, etc. * wiki info page, giving the ikiwiki version etc * would it be useful to reimplement the hyperestradier search integration as a plugin? -* Support [[RecentChanges]] as a regular page containing a plugin that updates each time there is a change, and statically builds the recent changes list. (Would this be too expensive? There might be other ways to do it as a plugin, like making all links to RecentChanges link to the cgi and have the cgi render it on demand.) +* Support [[RecentChanges]] as a regular page containing a plugin that updates each time there is a change, and statically builds the recent changes list. (Would this be too expensive/inflexible? There might be other ways to do it as a plugin, like making all links to RecentChanges link to the cgi and have the cgi render it on demand.) * etc Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. -- 2.39.5 From 819a31ed24cfb95da7e37a7524ecf0655e106903 Mon Sep 17 00:00:00 2001 From: joey Date: Mon, 1 May 2006 22:27:37 +0000 Subject: [PATCH 09/16] * Rename inlinepage to depends, so that it can be used to refer to more dependency relationships than just inlining. This will require a rebuild on upgrade to this version. * Move the rss link, put it in the blogpost form if there is one and at the top if not. This is both nicer because easier to find, and it cleans up the code which had used inlinepage as a flag for adding the link later. * Allow the depends GlobList to be built up from multiple sources (such as plugins) during a page render. * Which means that more than one blog is now supported to appear on a single page. (With some limitations.) --- IkiWiki/Render.pm | 41 +++++++++++++++++++++------------- basewiki/helponformatting.mdwn | 2 +- debian/changelog | 15 +++++++++++++ debian/postinst | 2 +- doc/bugs.mdwn | 2 -- doc/news.mdwn | 6 +++-- doc/templates.mdwn | 2 ++ doc/todo.mdwn | 6 +++++ doc/todo/plugin.mdwn | 6 ++++- ikiwiki | 10 ++++----- templates/blogpost.tmpl | 3 +++ templates/page.tmpl | 3 --- templates/rsslink.tmpl | 5 +++++ 13 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 templates/rsslink.tmpl diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index d0d28e802..f9da33e30 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -139,17 +139,17 @@ sub preprocess ($$) { #{{{ my $command=shift; my $params=shift; if (length $escape) { - "[[$command $params]]"; + return "[[$command $params]]"; } elsif (exists $commands{$command}) { my %params; while ($params =~ /(\w+)=\"([^"]+)"(\s+|$)/g) { $params{$1}=$2; } - $commands{$command}->($page, %params); + return $commands{$command}->($page, %params); } else { - "[[bad directive $command]]"; + return "[[bad directive $command]]"; } }; @@ -200,17 +200,32 @@ sub preprocess_inline ($@) { #{{{ if (! exists $params{show} && $params{archive} eq "no") { $params{show}=10; } - $inlinepages{$parentpage}=$params{pages}; + if (! exists $depends{$parentpage}) { + $depends{$parentpage}=$params{pages}; + } + else { + $depends{$parentpage}.=" ".$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}); - my $form=$formtemplate->output; - $ret.=$form; + if ($config{rss}) { + $formtemplate->param(rssurl => rsspage(basename($parentpage))); + } + $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($parentpage))); + $ret.=$linktemplate->output; } my $template=HTML::Template->new(blind_cache => 1, @@ -267,10 +282,6 @@ sub genpage ($$$) { #{{{ $template->param(hyperestraierurl => cgiurl()); } - if ($config{rss} && $inlinepages{$page}) { - $template->param(rssurl => rsspage(basename($page))); - } - $template->param( title => $title, wikiname => $config{wikiname}, @@ -375,7 +386,7 @@ sub render ($) { #{{{ my $page=pagename($file); $links{$page}=[findlinks($content, $page)]; - delete $inlinepages{$page}; + delete $depends{$page}; $content=linkify($content, $page); $content=preprocess($page, $content); @@ -569,18 +580,18 @@ FILE: foreach my $file (@files) { } # Handle backlinks; if a page has added/removed links, update the - # pages it links to. Also handle inlining here. + # pages it links to. Also handles rebuilding dependat pages. # TODO: inefficient; pages may get rendered above and again here; # problem is the backlinks could be wrong in the first pass render # above if (%rendered || @del) { foreach my $f (@files) { my $p=pagename($f); - if (exists $inlinepages{$p}) { + if (exists $depends{$p}) { foreach my $file (keys %rendered, @del) { my $page=pagename($file); - if (globlist_match($page, $inlinepages{$p})) { - debug("rendering $f, which inlines $page"); + if (globlist_match($page, $depends{$p})) { + debug("rendering $f, which depends on $page"); render($f); $rendered{$f}=1; last; diff --git a/basewiki/helponformatting.mdwn b/basewiki/helponformatting.mdwn index 286946169..9f7bcd9d1 100644 --- a/basewiki/helponformatting.mdwn +++ b/basewiki/helponformatting.mdwn @@ -38,7 +38,7 @@ To quote someone, prefix the quote with ">": > To be or not to be, > that is the question. -To write a code block, indent each line with a tab: +To write a code block, indent each line with a tab or 8 spaces: 10 PRINT "Hello, world!" 20 GOTO 10 diff --git a/debian/changelog b/debian/changelog index e1eb57710..28011339b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +ikiwiki (1.1) UNRELEASED; urgency=low + + * Rename inlinepage to depends, so that it can be used to refer to more + dependency relationships than just inlining. This will require a rebuild + on upgrade to this version. + * Move the rss link, put it in the blogpost form if there is one and at the + top if not. This is both nicer because easier to find, and it cleans up + the code which had used inlinepage as a flag for adding the link later. + * Allow the depends GlobList to be built up from multiple sources (such as + plugins) during a page render. + * Which means that more than one blog is now supported to appear on a + single page. (With some limitations.) + + -- Joey Hess Mon, 1 May 2006 18:21:16 -0400 + ikiwiki (1.0) unstable; urgency=low * First official release. diff --git a/debian/postinst b/debian/postinst index be5f53939..b9630b525 100755 --- a/debian/postinst +++ b/debian/postinst @@ -4,7 +4,7 @@ set -e # Change this when some incompatible change is made that requires # rebuilding all wikis. -firstcompat=0.2 +firstcompat=1.1 wikilist=/etc/ikiwiki/wikilist diff --git a/doc/bugs.mdwn b/doc/bugs.mdwn index 6e02e4533..47799676a 100644 --- a/doc/bugs.mdwn +++ b/doc/bugs.mdwn @@ -23,8 +23,6 @@ pages generated from the underlaydir as it can never work for them. * If a page stops inlining anthing, its rss feed file will linger around and not be deleted. -* Currently only one blog is supported per page. Attempts to add more - will make it only update one of the blogs on the page. * RSS output contains relative links. Ie. http://kitenet.net/~joey/blog/index.rss contains a link to http://kitenet.net/~joey/blog/../blog.html * If a file in the srcdir is removed, exposing a file in the underlaydir, ikiwiki will not notice the change and rebuild it until the file in the diff --git a/doc/news.mdwn b/doc/news.mdwn index cc2adcbc1..2141ca286 100644 --- a/doc/news.mdwn +++ b/doc/news.mdwn @@ -1,5 +1,7 @@ -This is where annoucements of new releases, features, and other news is posted. [[IkiWikiUsers]] are recommended to subscribe to this page's RSS feed. +This is where annoucements of new releases, features, and other news is +posted. [[IkiWikiUsers]] are recommended to subscribe to this page's RSS +feed. [[inline pages="news/* !*/Discussion" rootpage="news" show="30"]] -By the way, some other pages with RSS feeds about ikiwiki include [[TODO]] and [[TODO/done]]. \ No newline at end of file +By the way, some other pages with RSS feeds about ikiwiki include [[TODO]] and [[TODO/done]]. diff --git a/doc/templates.mdwn b/doc/templates.mdwn index 97a91d28b..cb07f27ad 100644 --- a/doc/templates.mdwn +++ b/doc/templates.mdwn @@ -24,6 +24,8 @@ It ships with some basic templates which can be customised: * `estseek.conf` - Not a html template, this is actually a template for a config file for the [[HyperEstraier]] search engine. If you like you can read the [[HyperEstraier]] docs and configure it using this. +* `blogpost.tmpl` - Used for a form to add a post to a blog (and a rss link) +* `rsslink.tmpl` - Used to add a rss link if blogpost.tmpl is not used. If you like, you can add these to further customise it: diff --git a/doc/todo.mdwn b/doc/todo.mdwn index 4bf9eb4c0..764872eea 100644 --- a/doc/todo.mdwn +++ b/doc/todo.mdwn @@ -7,3 +7,9 @@ Welcome to ikiwiki's todo list. Items are moved to [[todo/done]] when done. # Full list of open items: [[inline pages="todo/* !todo/done* !*/Discussion" archive="yes"]] + +---- + +Test: + +[[inline pages="news/* !*/Discussion" rootpage="news" show="30"]] diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 5f070dd92..0a8a0942e 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -20,7 +20,11 @@ Considering ikiwiki plugins, one idea I have is to make the [[PreProcessorDirect Since preprocessing happens before htmlization but after a page is loaded and linkified, it should be possible to use it to create something like a link map or lists, or a page index. Page inlining and rss generation is already done via preprocessor directives and seems a natureal as a plugin too. -Note that things like a link map or a broken link list page would need to be updated whenever a set (or all) pages change; the %inlinepages hash already allows for pages to register this, although it might need to be renamed. +Note that things like a link map or a broken link list page would need to +be updated whenever a set (or all) pages change; the %depends hash +already allows for pages to register this, although there could be some +strange behavior if mixing multiple directives some of which exclude pages +that others might want to include. I need to look at the full range of things that other wikis use their plugin systems for, but preprocessor directives as plugins certianly seems useful, even if it's not a complete solution. diff --git a/ikiwiki b/ikiwiki index 6c157132f..dfb484f64 100755 --- a/ikiwiki +++ b/ikiwiki @@ -9,7 +9,7 @@ use HTML::Template; use lib '.'; # For use without installation, removed by Makefile. use vars qw{%config %links %oldlinks %oldpagemtime %pagectime - %renderedfiles %pagesources %inlinepages}; + %renderedfiles %pagesources %depends}; sub usage () { #{{{ die "usage: ikiwiki [options] source dest\n"; @@ -399,8 +399,8 @@ sub loadindex () { #{{{ $oldpagemtime{$page}=$items{mtime}[0]; $oldlinks{$page}=[@{$items{link}}]; $links{$page}=[@{$items{link}}]; - $inlinepages{$page}=join(" ", @{$items{inlinepage}}) - if exists $items{inlinepage}; + $depends{$page}=join(" ", @{$items{depends}}) + if exists $items{depends}; $renderedfiles{$page}=$items{dest}[0]; } $pagectime{$page}=$items{ctime}[0]; @@ -421,8 +421,8 @@ sub saveindex () { #{{{ "src=$pagesources{$page} ". "dest=$renderedfiles{$page}"; $line.=" link=$_" foreach @{$links{$page}}; - if (exists $inlinepages{$page}) { - $line.=" inlinepage=$_" foreach split " ", $inlinepages{$page}; + if (exists $depends{$page}) { + $line.=" depends=$_" foreach split " ", $depends{$page}; } print OUT $line."\n"; } diff --git a/templates/blogpost.tmpl b/templates/blogpost.tmpl index 22253d60b..1b93adc14 100644 --- a/templates/blogpost.tmpl +++ b/templates/blogpost.tmpl @@ -1,5 +1,8 @@
+ +RSS + diff --git a/templates/page.tmpl b/templates/page.tmpl index c9ec2a34f..4dc8e1139 100644 --- a/templates/page.tmpl +++ b/templates/page.tmpl @@ -67,9 +67,6 @@ Links: Last edited - -RSS -
diff --git a/templates/rsslink.tmpl b/templates/rsslink.tmpl new file mode 100644 index 000000000..f70c959d6 --- /dev/null +++ b/templates/rsslink.tmpl @@ -0,0 +1,5 @@ + -- 2.39.5 From 258af4c179f8bdd10c481efcf11617e368864457 Mon Sep 17 00:00:00 2001 From: joey Date: Mon, 1 May 2006 22:40:46 +0000 Subject: [PATCH 10/16] remove templates/ from filenames --- debian/changelog | 3 ++- doc/templates.mdwn | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 28011339b..72299ec59 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,7 +9,8 @@ ikiwiki (1.1) UNRELEASED; urgency=low * Allow the depends GlobList to be built up from multiple sources (such as plugins) during a page render. * Which means that more than one blog is now supported to appear on a - single page. (With some limitations.) + single page. (With some limitations, like only the last one getting an + rss file.) -- Joey Hess Mon, 1 May 2006 18:21:16 -0400 diff --git a/doc/templates.mdwn b/doc/templates.mdwn index cb07f27ad..10f715d9d 100644 --- a/doc/templates.mdwn +++ b/doc/templates.mdwn @@ -6,20 +6,20 @@ The aim is to keep almost all html out of ikiwiki and in the templates. It ships with some basic templates which can be customised: -* `templates/page.tmpl` - Used for displaying all regular wiki pages. -* `templates/misc.tmpl` - Generic template used for any page that doesn't +* `page.tmpl` - Used for displaying all regular wiki pages. +* `misc.tmpl` - Generic template used for any page that doesn't have a custom template. -* `templates/recentchanges.tmpl` - Used for the RecentChanges page. -* `templates/editpage.tmpl` - Create/edit page. -* `templates/notifymail.tmpl` - Not a html template, this is used to +* `recentchanges.tmpl` - Used for the RecentChanges page. +* `editpage.tmpl` - Create/edit page. +* `notifymail.tmpl` - Not a html template, this is used to generate change notification mails for users who have subscribed to changes to a page. -* `templates/passwordmail.tmpl` - Not a html template, this is used to +* `passwordmail.tmpl` - Not a html template, this is used to generate the mail with the user's password in it. -* `templates/rsspage.tmpl` - Used for generating rss feeds for [[blog]]s. -* `templates/inlinepage.tmpl` - Used for adding a page inline in a blog +* `rsspage.tmpl` - Used for generating rss feeds for [[blog]]s. +* `inlinepage.tmpl` - Used for adding a page inline in a blog page. -* `templates/inlinepagetitle.tmpl` - Used for listing a page inline in a blog +* `inlinepagetitle.tmpl` - Used for listing a page inline in a blog archive page. * `estseek.conf` - Not a html template, this is actually a template for a config file for the [[HyperEstraier]] search engine. If you like you @@ -29,10 +29,10 @@ It ships with some basic templates which can be customised: If you like, you can add these to further customise it: -* `templates/signin.tmpl` - If it exists, it is used for customising the +* `signin.tmpl` - If it exists, it is used for customising the layout of the SignIn form and all assciated forms. The misc.tmpl is wrapped around this, so it should only be a template for the form. -* `templates/prefs.tmpl` - If it exists, it is used for customising the +* `prefs.tmpl` - If it exists, it is used for customising the layout of the Prefs form and all assciated forms. The misc.tmpl is wrapped around this, so it should only be a template for the form. -- 2.39.5 From 457d6bbbbfbb0474749a0d68e959613c86facf72 Mon Sep 17 00:00:00 2001 From: joey Date: Mon, 1 May 2006 23:18:09 +0000 Subject: [PATCH 11/16] change calling convention for preprocessor functions --- IkiWiki/Render.pm | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index f9da33e30..3006b64d4 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -146,7 +146,7 @@ sub preprocess ($$) { #{{{ while ($params =~ /(\w+)=\"([^"]+)"(\s+|$)/g) { $params{$1}=$2; } - return $commands{$command}->($page, %params); + return $commands{$command}->(page => $page, %params); } else { return "[[bad directive $command]]"; @@ -188,7 +188,6 @@ sub get_inline_content ($$) { #{{{ } #}}} sub preprocess_inline ($@) { #{{{ - my $parentpage=shift; my %params=@_; if (! exists $params{pages}) { @@ -200,11 +199,11 @@ sub preprocess_inline ($@) { #{{{ if (! exists $params{show} && $params{archive} eq "no") { $params{show}=10; } - if (! exists $depends{$parentpage}) { - $depends{$parentpage}=$params{pages}; + if (! exists $depends{$params{page}}) { + $depends{$params{page}}=$params{pages}; } else { - $depends{$parentpage}.=" ".$params{pages}; + $depends{$params{page}}.=" ".$params{pages}; } my $ret=""; @@ -216,7 +215,7 @@ sub preprocess_inline ($@) { #{{{ $formtemplate->param(cgiurl => $config{cgiurl}); $formtemplate->param(rootpage => $params{rootpage}); if ($config{rss}) { - $formtemplate->param(rssurl => rsspage(basename($parentpage))); + $formtemplate->param(rssurl => rsspage(basename($params{page}))); } $ret.=$formtemplate->output; } @@ -224,7 +223,7 @@ sub preprocess_inline ($@) { #{{{ # Add a rss link button. my $linktemplate=HTML::Template->new(blind_cache => 1, filename => "$config{templatedir}/rsslink.tmpl"); - $linktemplate->param(rssurl => rsspage(basename($parentpage))); + $linktemplate->param(rssurl => rsspage(basename($params{page}))); $ret.=$linktemplate->output; } @@ -235,10 +234,10 @@ sub preprocess_inline ($@) { #{{{ my @pages; foreach my $page (blog_list($params{pages}, $params{show})) { - next if $page eq $parentpage; + next if $page eq $params{page}; push @pages, $page; - $template->param(pagelink => htmllink($parentpage, $page)); - $template->param(content => get_inline_content($parentpage, $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; @@ -248,8 +247,8 @@ sub preprocess_inline ($@) { #{{{ # check_overwrite, but currently renderedfiles # only supports listing one file per page. if ($config{rss}) { - writefile(rsspage($parentpage), $config{destdir}, - genrss($parentpage, @pages)); + writefile(rsspage($params{page}), $config{destdir}, + genrss($params{page}, @pages)); } return $ret; -- 2.39.5 From 54d5308cd83c67e7e9c32450c776ef0dac63549f Mon Sep 17 00:00:00 2001 From: joey Date: Tue, 2 May 2006 02:34:33 +0000 Subject: [PATCH 12/16] * 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. --- IkiWiki/Plugin/brokenlinks.pm | 39 +++++++ IkiWiki/Plugin/inline.pm | 161 +++++++++++++++++++++++++++ IkiWiki/Plugin/pagecount.pm | 29 +++++ IkiWiki/Plugin/skeleton.pm | 19 ++++ IkiWiki/Render.pm | 166 +++------------------------- Makefile.PL | 4 +- basewiki/preprocessordirective.mdwn | 5 +- debian/changelog | 11 +- doc/bugs.mdwn | 7 +- doc/features.mdwn | 7 +- doc/ikiwiki.setup | 2 + doc/plugins.mdwn | 27 +++++ doc/plugins/brokelinks.mdwn | 11 ++ doc/plugins/inline.mdwn | 4 + doc/plugins/pagecount.mdwn | 11 ++ doc/plugins/write.mdwn | 74 +++++++++++++ doc/post-commit.mdwn | 2 +- doc/security.mdwn | 2 +- doc/todo.mdwn | 6 - doc/todo/lists.mdwn | 5 +- doc/todo/plugin.mdwn | 19 +--- doc/usage.mdwn | 28 +++-- ikiwiki | 24 +++- 23 files changed, 466 insertions(+), 197 deletions(-) create mode 100644 IkiWiki/Plugin/brokenlinks.pm create mode 100644 IkiWiki/Plugin/inline.pm create mode 100644 IkiWiki/Plugin/pagecount.pm create mode 100644 IkiWiki/Plugin/skeleton.pm create mode 100644 doc/plugins.mdwn create mode 100644 doc/plugins/brokelinks.mdwn create mode 100644 doc/plugins/inline.mdwn create mode 100644 doc/plugins/pagecount.mdwn create mode 100644 doc/plugins/write.mdwn 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 "
    \n".join("\n", map { "
  • $_
  • " } sort @broken)."
\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/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/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; } } diff --git a/Makefile.PL b/Makefile.PL index 9d31dcb8b..85fc07543 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -13,7 +13,9 @@ pure_install:: extra_install extra_build: ./ikiwiki doc html --templatedir=templates --underlaydir=basewiki \ - --wikiname="ikiwiki" --verbose --nosvn --exclude=/discussion + --wikiname="ikiwiki" --verbose --nosvn \ + --exclude=/discussion --plugin=brokenlinks \ + --plugin=pagecount ./mdwn2man doc/usage.mdwn > ikiwiki.man extra_clean: diff --git a/basewiki/preprocessordirective.mdwn b/basewiki/preprocessordirective.mdwn index a7d1be8c8..ffa3fc7c4 100644 --- a/basewiki/preprocessordirective.mdwn +++ b/basewiki/preprocessordirective.mdwn @@ -6,6 +6,7 @@ contain spaces and parameters. The general form is: This gets expanded before the rest of the page is processed, and can be used to transform the page in various ways. -Currently, these preprocessor directives are available: +Note that if a preprocessor directive has no parameters, a space still must +be put after its name, to avoid confusion with a [[WikiLink]]. For example: -* "inline" to make a [[blog]] +\\[[pagecount ]] diff --git a/debian/changelog b/debian/changelog index 72299ec59..504bf0c9a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,8 +11,17 @@ ikiwiki (1.1) UNRELEASED; urgency=low * Which means that more than one blog is now supported to appear on a single page. (With some limitations, like only the last one getting an rss file.) + * 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. - -- Joey Hess Mon, 1 May 2006 18:21:16 -0400 + -- Joey Hess Mon, 1 May 2006 21:01:12 -0400 ikiwiki (1.0) unstable; urgency=low diff --git a/doc/bugs.mdwn b/doc/bugs.mdwn index 47799676a..c646242aa 100644 --- a/doc/bugs.mdwn +++ b/doc/bugs.mdwn @@ -2,10 +2,11 @@ adding/removing a page. For example, if Foo/Bar links to "Baz", which is Foo/Baz, and Foo/Bar/Baz gets added, it will update the links in Foo/Bar to point to it, but will forget to update the linkbacks in Foo/Baz. - And if Foo/Bar/Baz is then removed, it forgets to update Foo/Bar to link + +* And if Foo/Bar/Baz is then removed, it forgets to update Foo/Bar to link back to Foo/Baz. - -- is this still true? + -- is this still true? (Yes (as of 1.0)) * If I try to do a web commit, to a svn+ssh repo, it fails with "Host key verification failed." @@ -31,4 +32,4 @@ line if --cgi is set, even if it's not yet running as a cgi * if a page containing an rss feed happens to show up in an rss feed, the preprocessor directives won't be expanded (good) but are left in - raw rather than removed (bad) + raw rather than removed (bad). diff --git a/doc/features.mdwn b/doc/features.mdwn index a8b33a75f..f63122edf 100644 --- a/doc/features.mdwn +++ b/doc/features.mdwn @@ -61,7 +61,8 @@ Some of ikiwiki's features: * [[BackLinks]] - Automatically included on pages. Rather faster than eg [[MoinMoin]] and always there to help with navigation. + Automatically included on pages. Rather faster than eg MoinMoin and + always there to help with navigation. * [[PageHistory]] @@ -115,6 +116,10 @@ Some of ikiwiki's features: ikiwiki can be configured to send you commit mails with diffs of changes to selected pages. +* [[Plugins]] + + A plugin system allows extending ikiwiki in arbitrary ways. + ---- It also has some [[TODO]] items and [[Bugs]]. diff --git a/doc/ikiwiki.setup b/doc/ikiwiki.setup index 9775b3194..4a08e1919 100644 --- a/doc/ikiwiki.setup +++ b/doc/ikiwiki.setup @@ -52,4 +52,6 @@ use IkiWiki::Setup::Standard { #hyperestraier => 1, # Sanitize html? sanitize => 1, + # To change the enabled plugins, edit this list + #plugins => [qw{pagecount inline brokenlinks}], } diff --git a/doc/plugins.mdwn b/doc/plugins.mdwn new file mode 100644 index 000000000..e83250f02 --- /dev/null +++ b/doc/plugins.mdwn @@ -0,0 +1,27 @@ +Plugins can be used to add additional features to ikiwiki. It's possible to +[[write]] your own plugins, or you can install and use plugins contributed by +others. + +The ikiiki package includes some standard plugins that are installed and +by default. These include [[inline]], [[pagecount]], and [[brokenlinks]]. +Of these, [[inline]] is enabled by default. + +## Third party plugins + +Plugins are perl modules and should be installed somewhere in the perl +module search path. See the @INC list at the end of the output of `perl -V` +for a list of the directories in that path. All plugins are in the +IkiWiki::Plugin namespace, so they go in a IkiWiki/Plugin subdirectory +inside the perl search path. For example, if your perl looks in +`/usr/local/lib/site_perl` for modules, you can locally install ikiwiki +plugins to `/usr/local/lib/site_perl/IkiWiki/Plugin` + +Once a plugin is installed, you need to configure ikiwiki to load it using +the `--plugin` switch described in [[usage]], or the equivilant line in +[[ikiwiki.setup]]. + +## Plugin directory + +Add your contributed plugins using this form: + +[[inline pages="plugins/* !plugins/write !*/Discussion" archive="yes" rootpage="plugins/contrib" show="30"]] diff --git a/doc/plugins/brokelinks.mdwn b/doc/plugins/brokelinks.mdwn new file mode 100644 index 000000000..05efe2806 --- /dev/null +++ b/doc/plugins/brokelinks.mdwn @@ -0,0 +1,11 @@ +This plugin generates a list of broken links on pages in the wiki. This is +a useful way to find pages that still need to be written, or links that +are written wrong. + +The optional parameter "pages" can be a [[GlobList]] specifying the pages +to search for broken links, default is search them all. + +This plugin is included in ikiwiki, but is not enabled by default. +If it is turned on, here's a list of broken links on this wiki: + +[[brokenlinks ]] diff --git a/doc/plugins/inline.mdwn b/doc/plugins/inline.mdwn new file mode 100644 index 000000000..68f381790 --- /dev/null +++ b/doc/plugins/inline.mdwn @@ -0,0 +1,4 @@ +Allows including one wiki page inside another, generating blogs and RSS +feeds. See [[blog]] for details. + +This plugin is enabled by default. diff --git a/doc/plugins/pagecount.mdwn b/doc/plugins/pagecount.mdwn new file mode 100644 index 000000000..678ac823c --- /dev/null +++ b/doc/plugins/pagecount.mdwn @@ -0,0 +1,11 @@ +Provides a \\[[pagecount ]] [[PreProcessorDirective]] that is replaced with +the total number of pages currently in the wiki. + +The optional parameter "pages" can be a [[GlobList]] specifying the 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, of which [[pagecount pages="*/Discussion"]] are +discussion pages. diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn new file mode 100644 index 000000000..e09ca3510 --- /dev/null +++ b/doc/plugins/write.mdwn @@ -0,0 +1,74 @@ +ikiwiki [[plugins]] are written in perl. Each plugin is a perl module, in +the `IkiWiki::Plugin` namespace. The name of the plugin is typically in +lowercase, such as `IkiWiki::Plugin::inline`. Ikiwiki includes a +`IkiWiki::Plugin::skeleton` that can be fleshed out to make a useful +plugin. `IkiWiki::Plugin::pagecount` is another simple example. + +## Note + +One thing to keep in mind when writing a plugin is that ikiwiki is a wiki +*compiler*. So plugins influence pages when they are built, not when they +are loaded. A plugin that inserts the current time into a page, for +example, will insert the build time. Also, as a compiler, ikiwiki avoids +rebuilding pages unless they have changed, so a plugin that prints some +random or changing thing on a page will generate a static page that won't +change until ikiwiki rebuilds the page for some other reason, like the page +being edited. + +## Registering plugins + +Plugins should, when imported, call IkiWiki::register_plugin to hook into +ikiwiki. The function takes four parameters: + +1. A method type. Use "preprocess" to register a [[PreProcessorDirective]] +2. A command name. This is the bit that will appear inside brackets in a + page. +3. A reference to a subroutine that is run when the plugin is used. + +## Writing a [[PreProcessorDirective]] + +For preprocessor commands, the subroutine is passed named parameters. A +"page" parameter gives the name of the page that embedded the preprocessor +command. All parameters included in the preprocessor command are included +as named parameters as well. Whatever the subroutine returns goes onto the +page in place of the command. + +## Error handing in plugins + +While a plugin can call ikiwiki's error routine for a fatal error, for +errors that aren't intended to halt the entire wiki build, including bad +parameters passed to a [[PreProcessorDirective]], etc, it's better to just +return the error message as the output of the plugin. + +## Html issues + +Note that if [[HTMLSanitization]] is enabled, html in +[[PreProcessorDirective]] output is sanitised, which may limit what your +plugin can do. Also, the rest of the page content is not in html format at +preprocessor time. + +## Wiki configuration + +A plugin can access the wiki's configuration via the `%IkiWiki::config` hash. +The best way to understand the contents of the hash is to look at +[[ikiwiki.setup]], which sets the hash content to configure the wiki. + +## Wiki data + +If your plugin needs to access data about other pages in the wiki. It can +use the following hashes, using a page name as the key: + +* `%IkiWiki::links` lists the names of each page + that is linked to from that page in an array reference. +* `%IkiWiki::pagemtime` contains the last modification time of each page +* `%IkiWiki::pagectime` contains the creation time of each page` +* `%IkiWiki::renderedfiles` contains the name of the file rendered by a + page +* `%IkiWiki::pagesources` contains the name of the source file for a page. +* `%IkiWiki::depends` contains a [[GlobList]] that is used to specify other + pages that a page depends on. If one of its dependencies is updated, the + page will also get rebuilt. + + Many plugins will need to add dependencies to this hash; the best way to do + it is by using the IkiWiki::add_depends function, which takes as its + parameters the page name and a [[GlobList]] of dependencies to add. diff --git a/doc/post-commit.mdwn b/doc/post-commit.mdwn index 780687563..76c8dfeac 100644 --- a/doc/post-commit.mdwn +++ b/doc/post-commit.mdwn @@ -1,7 +1,7 @@ A post-commit hook is run every time you commit a change to your subversion repository. To make the wiki be updated each time a commit is made, it can be run from (or as) a post-commit hook. The best way to run ikiwiki in a [[Subversion]] post-commit hook is using -a [[wrapper]], which can be generated using `ikiwiki --wrapper`. +a wrapper, which can be generated using `ikiwiki --wrapper`. First, set up the subversion checkout that ikiwiki will update and compile into your wiki at each subversion commit. Run ikiwiki a few times by hand diff --git a/doc/security.mdwn b/doc/security.mdwn index 766b8bee4..77552b1b2 100644 --- a/doc/security.mdwn +++ b/doc/security.mdwn @@ -62,7 +62,7 @@ this wiki, BTW. ## page locking can be bypassed via direct svn commits -A [[lock]]ed page can only be edited on the web by an admin, but +A locked page can only be edited on the web by an admin, but anyone who is allowed to commit direct to svn can bypass this. This is by design, although a subversion pre-commit hook could be used to prevent editing of locked pages when using subversion, if you really need to. diff --git a/doc/todo.mdwn b/doc/todo.mdwn index 764872eea..4bf9eb4c0 100644 --- a/doc/todo.mdwn +++ b/doc/todo.mdwn @@ -7,9 +7,3 @@ Welcome to ikiwiki's todo list. Items are moved to [[todo/done]] when done. # Full list of open items: [[inline pages="todo/* !todo/done* !*/Discussion" archive="yes"]] - ----- - -Test: - -[[inline pages="news/* !*/Discussion" rootpage="news" show="30"]] diff --git a/doc/todo/lists.mdwn b/doc/todo/lists.mdwn index 841e3a463..933012493 100644 --- a/doc/todo/lists.mdwn +++ b/doc/todo/lists.mdwn @@ -1,7 +1,8 @@ * list of all missing pages - Could be a [[plugin]]. + done * list of registered users, with the names being links to any userpages. - Could be implemented with a [[preprocessordirective]], which suggests that there needs to be some sort of plugin interface for new preprocessordirectives. Although, how to let the wiki know that the page needs an update whever a new user is added? \ No newline at end of file + Might be a plugin, but how to let the wiki know that the page + needs an update whever a new user is added? diff --git a/doc/todo/plugin.mdwn b/doc/todo/plugin.mdwn index 0a8a0942e..255f0ccf6 100644 --- a/doc/todo/plugin.mdwn +++ b/doc/todo/plugin.mdwn @@ -1,5 +1,3 @@ -For one type of plugin, see [[todo/PluggableRenderers]]. - A plugin system should ideally support things like: * [[todo/lists]] of pages, of mising pages / broken links, of registered users, etc @@ -11,22 +9,15 @@ A plugin system should ideally support things like: * would it be useful to reimplement the hyperestradier search integration as a plugin? * Support [[RecentChanges]] as a regular page containing a plugin that updates each time there is a change, and statically builds the recent changes list. (Would this be too expensive/inflexible? There might be other ways to do it as a plugin, like making all links to RecentChanges link to the cgi and have the cgi render it on demand.) * etc +* For another type of plugin, see [[todo/PluggableRenderers]]. -Another, separate plugin system that already (mostly) exists in ikiwiki is the RCS backend, which allows writing modules to drive other RCS systems than subversion. +Another, separate plugin system that already (mostly) exists in ikiwiki is +the RCS backend, which allows writing modules to drive other RCS systems +than subversion. ## preprocessor plugins -Considering ikiwiki plugins, one idea I have is to make the [[PreProcessorDirective]]s be a plugin. A setting in the config file would enable various plusins, which are perl modules, that each provide one or more preprocessor directives. - -Since preprocessing happens before htmlization but after a page is loaded and linkified, it should be possible to use it to create something like a link map or lists, or a page index. Page inlining and rss generation is already done via preprocessor directives and seems a natureal as a plugin too. - -Note that things like a link map or a broken link list page would need to -be updated whenever a set (or all) pages change; the %depends hash -already allows for pages to register this, although there could be some -strange behavior if mixing multiple directives some of which exclude pages -that others might want to include. - -I need to look at the full range of things that other wikis use their plugin systems for, but preprocessor directives as plugins certianly seems useful, even if it's not a complete solution. +done ## case study: Moin Moin plugins diff --git a/doc/usage.mdwn b/doc/usage.mdwn index 4936039b6..c4d1f5818 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -41,7 +41,7 @@ These options control the mode that ikiwiki is operating in. * --wrapper [file] - Generate a [[wrapper]] binary that is hardcoded to do action specified by + Generate a wrapper binary that is hardcoded to do action specified by the other options, using the specified input files and `destination` directory. The filename to use for the wrapper is optional. @@ -70,13 +70,6 @@ These options configure the wiki. The name of the wiki, default is "wiki". -* --fixctime - - Pull last changed time for all pages out of the revision control system. - This rarely used option provides a way to get the real creation times of - items in weblogs, for example when building a wiki from a new subversion - checkout. It is unoptimised and quite slow. - * --templatedir Specify the directory that the page [[templates]] are stored in. @@ -129,7 +122,7 @@ These options configure the wiki. * --rss, --norss If rss is set, ikiwiki will generate rss feeds for pages that inline - a blog. + a [[blog]]. * --url http://url/ @@ -137,7 +130,8 @@ These options configure the wiki. * --cgiurl http://url/ikiwiki.cgi - Specifies the url to the ikiwiki [[CGI]] script [[wrapper]]. Required when building the wiki for links to the cgi script to be generated. + Specifies the url to the ikiwiki [[CGI]] script wrapper. Required when + building the wiki for links to the cgi script to be generated. * --historyurl http://url/trunk/\[[file]]?root=wiki @@ -172,6 +166,11 @@ These options configure the wiki. Enable [[HtmlSanitization]] of wiki content. On by default, disable with --no-sanitize. +* --plugin name + + Enables the use of the specified plugin in the wiki. See [[plugins]] for + details. Note that plugin names are case sensative. + * --hyperestraier Enables use of the [[HyperEstraier]] search engine for full test page @@ -179,7 +178,14 @@ These options configure the wiki. * --verbose - Be vebose about what it's doing. + Be vebose about what is being done. + +* --fixctime + + Pull last changed time for all pages out of the revision control system. + This rarely used option provides a way to get the real creation times of + items in weblogs, for example when building a wiki from a new subversion + checkout. It is unoptimised and quite slow. # AUTHOR diff --git a/ikiwiki b/ikiwiki index dfb484f64..6c42a7e5d 100755 --- a/ikiwiki +++ b/ikiwiki @@ -9,7 +9,7 @@ use HTML::Template; use lib '.'; # For use without installation, removed by Makefile. use vars qw{%config %links %oldlinks %oldpagemtime %pagectime - %renderedfiles %pagesources %depends}; + %renderedfiles %pagesources %depends %plugins}; sub usage () { #{{{ die "usage: ikiwiki [options] source dest\n"; @@ -20,7 +20,7 @@ sub getconfig () { #{{{ %config=( wiki_file_prune_regexp => qr{((^|/).svn/|\.\.|^\.|\/\.|\.html?$|\.rss$)}, wiki_link_regexp => qr/\[\[(?:([^\s\]\|]+)\|)?([^\s\]]+)\]\]/, - wiki_processor_regexp => qr/\[\[(\w+)\s+([^\]]+)\]\]/, + wiki_processor_regexp => qr/\[\[(\w+)\s+([^\]]*)\]\]/, wiki_file_regexp => qr/(^[-[:alnum:]_.:\/+]+$)/, verbose => 0, wikiname => "wiki", @@ -50,6 +50,7 @@ sub getconfig () { #{{{ setup => undef, adminuser => undef, adminemail => undef, + plugin => [qw{inline}], ); eval q{use Getopt::Long}; @@ -90,6 +91,9 @@ sub getconfig () { #{{{ "wrapper:s" => sub { $config{wrapper}=$_[1] ? $_[1] : "ikiwiki-wrap" }, + "plugin=s@" => sub { + push @{$config{plugin}}, $_[1]; + } ) || usage(); if (! $config{setup}) { @@ -129,6 +133,14 @@ sub checkconfig () { #{{{ require IkiWiki::Rcs::Stub; $config{rcs}=0; } + + foreach my $plugin (@{$config{plugin}}) { + $plugin="IkiWiki::Plugin::".possibly_foolish_untaint($plugin); + eval qq{use $plugin}; + if ($@) { + error("Failed to load plugin $plugin: $@"); + } + } } #}}} sub error ($) { #{{{ @@ -476,6 +488,14 @@ sub globlist_match ($$) { #{{{ return 0; } #}}} +sub register_plugin ($$$) { # {{{ + my $type=shift; + my $command=shift; + my $function=shift; + + $plugins{$type}{$command}=$function; +} # }}} + sub main () { #{{{ getconfig(); -- 2.39.5 From 4f1dc4b47c74ae97e0c26061501751202bf46e1f Mon Sep 17 00:00:00 2001 From: joey Date: Tue, 2 May 2006 02:39:33 +0000 Subject: [PATCH 13/16] fix name --- doc/plugins/{brokelinks.mdwn => brokenlinks.mdwn} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/plugins/{brokelinks.mdwn => brokenlinks.mdwn} (100%) diff --git a/doc/plugins/brokelinks.mdwn b/doc/plugins/brokenlinks.mdwn similarity index 100% rename from doc/plugins/brokelinks.mdwn rename to doc/plugins/brokenlinks.mdwn -- 2.39.5 From 62f734d5e1a2c8d23d75f0df09a8bff9d1e8da97 Mon Sep 17 00:00:00 2001 From: joey Date: Tue, 2 May 2006 02:47:54 +0000 Subject: [PATCH 14/16] fix --- ikiwiki | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ikiwiki b/ikiwiki index 6c42a7e5d..8367e9118 100755 --- a/ikiwiki +++ b/ikiwiki @@ -135,10 +135,10 @@ sub checkconfig () { #{{{ } foreach my $plugin (@{$config{plugin}}) { - $plugin="IkiWiki::Plugin::".possibly_foolish_untaint($plugin); - eval qq{use $plugin}; + my $mod="IkiWiki::Plugin::".possibly_foolish_untaint($plugin); + eval qq{use $mod}; if ($@) { - error("Failed to load plugin $plugin: $@"); + error("Failed to load plugin $mod: $@"); } } } #}}} -- 2.39.5 From f8109304f3d57f7ed2913d80ae003baa1ef815ed Mon Sep 17 00:00:00 2001 From: joey Date: Tue, 2 May 2006 02:49:30 +0000 Subject: [PATCH 15/16] foo --- doc/plugins.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugins.mdwn b/doc/plugins.mdwn index e83250f02..b107c359e 100644 --- a/doc/plugins.mdwn +++ b/doc/plugins.mdwn @@ -22,6 +22,6 @@ the `--plugin` switch described in [[usage]], or the equivilant line in ## Plugin directory -Add your contributed plugins using this form: +Add your contributed plugins here. [[inline pages="plugins/* !plugins/write !*/Discussion" archive="yes" rootpage="plugins/contrib" show="30"]] -- 2.39.5 From a7dd176e48052735268e6a30013a2613e511fb14 Mon Sep 17 00:00:00 2001 From: www-data Date: Tue, 2 May 2006 02:50:16 +0000 Subject: [PATCH 16/16] web commit by joey --- doc/news.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/news.mdwn b/doc/news.mdwn index 2141ca286..b0e1d5764 100644 --- a/doc/news.mdwn +++ b/doc/news.mdwn @@ -4,4 +4,4 @@ feed. [[inline pages="news/* !*/Discussion" rootpage="news" show="30"]] -By the way, some other pages with RSS feeds about ikiwiki include [[TODO]] and [[TODO/done]]. +By the way, some other pages with RSS feeds about ikiwiki include [[plugins]], [[TODO]] and [[TODO/done]]. -- 2.39.5