2006-07-27 23:38:02 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
# Ikiwiki tag plugin.
|
|
|
|
package IkiWiki::Plugin::tag;
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
2008-12-23 22:34:19 +01:00
|
|
|
use IkiWiki 3.00;
|
2006-07-27 23:38:02 +02:00
|
|
|
|
2006-07-28 01:08:03 +02:00
|
|
|
my %tags;
|
2006-07-27 23:38:02 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub import {
|
2006-09-10 00:50:27 +02:00
|
|
|
hook(type => "getopt", id => "tag", call => \&getopt);
|
2008-07-26 06:38:13 +02:00
|
|
|
hook(type => "getsetup", id => "tag", call => \&getsetup);
|
2007-09-20 20:59:27 +02:00
|
|
|
hook(type => "preprocess", id => "tag", call => \&preprocess_tag, scan => 1);
|
|
|
|
hook(type => "preprocess", id => "taglink", call => \&preprocess_taglink, scan => 1);
|
2006-09-10 00:50:27 +02:00
|
|
|
hook(type => "pagetemplate", id => "tag", call => \&pagetemplate);
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-07-27 23:38:02 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub getopt () {
|
2006-07-28 07:26:49 +02:00
|
|
|
eval q{use Getopt::Long};
|
2006-11-08 22:03:33 +01:00
|
|
|
error($@) if $@;
|
2006-07-28 07:26:49 +02:00
|
|
|
Getopt::Long::Configure('pass_through');
|
2006-09-10 00:50:27 +02:00
|
|
|
GetOptions("tagbase=s" => \$config{tagbase});
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-07-28 07:26:49 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub getsetup () {
|
2008-07-26 06:38:13 +02:00
|
|
|
return
|
2008-08-04 01:35:35 +02:00
|
|
|
plugin => {
|
|
|
|
safe => 1,
|
|
|
|
rebuild => undef,
|
|
|
|
},
|
2008-07-26 06:38:13 +02:00
|
|
|
tagbase => {
|
|
|
|
type => "string",
|
|
|
|
example => "tag",
|
|
|
|
description => "parent page tags are located under",
|
|
|
|
safe => 1,
|
|
|
|
rebuild => 1,
|
|
|
|
},
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2008-07-26 06:38:13 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub tagpage ($) {
|
2006-07-29 09:25:17 +02:00
|
|
|
my $tag=shift;
|
|
|
|
|
2008-07-21 23:01:11 +02:00
|
|
|
if ($tag !~ m{^\.?/} &&
|
2006-09-10 00:50:27 +02:00
|
|
|
defined $config{tagbase}) {
|
2008-10-21 00:17:03 +02:00
|
|
|
$tag="/".$config{tagbase}."/".$tag;
|
2008-11-11 01:48:58 +01:00
|
|
|
$tag=~y#/#/#s; # squash dups
|
2006-07-29 09:25:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return $tag;
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-07-29 09:25:17 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub taglink ($$$;@) {
|
2008-09-26 02:25:07 +02:00
|
|
|
my $page=shift;
|
|
|
|
my $destpage=shift;
|
|
|
|
my $tag=shift;
|
|
|
|
my %opts=@_;
|
|
|
|
|
2008-11-11 03:47:29 +01:00
|
|
|
return htmllink($page, $destpage, tagpage($tag), %opts);
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2008-09-26 02:25:07 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub preprocess_tag (@) {
|
2006-07-27 23:38:02 +02:00
|
|
|
if (! @_) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
my %params=@_;
|
|
|
|
my $page = $params{page};
|
|
|
|
delete $params{page};
|
2006-07-28 01:47:13 +02:00
|
|
|
delete $params{destpage};
|
2007-03-07 06:53:47 +01:00
|
|
|
delete $params{preview};
|
2006-07-27 23:38:02 +02:00
|
|
|
|
|
|
|
foreach my $tag (keys %params) {
|
2008-09-27 20:14:36 +02:00
|
|
|
$tag=linkpage($tag);
|
2007-02-14 05:05:08 +01:00
|
|
|
$tags{$page}{$tag}=1;
|
2006-07-27 23:38:02 +02:00
|
|
|
# hidden WikiLink
|
Avoid %links accumulating duplicates. (For TOVA)
This is sorta an optimisation, and sorta a bug fix. In one
test case I have available, it can speed a page build up from 3
minutes to 3 seconds.
The root of the problem is that $links{$page} contains arrays of
links, rather than hashes of links. And when a link is found,
it is just pushed onto the array, without checking for dups.
Now, the array is emptied before scanning a page, so there
should not be a lot of opportunity for lots of duplicate links
to pile up in it. But, in some cases, they can, and if there
are hundreds of duplicate links in the array, then scanning it
for matching links, as match_link and some other code does,
becomes much more expensive than it needs to be.
Perhaps the real right fix would be to change the data structure
to a hash. But, the list of links is never accessed like that,
you always want to iterate through it.
I also looked at deduping the list in saveindex, but that does
a lot of unnecessary work, and doesn't completly solve the problem.
So, finally, I decided to add an add_link function that handles deduping,
and make ikiwiki-transition remove the old dup links.
2009-05-06 05:40:09 +02:00
|
|
|
add_link($page, tagpage($tag));
|
2006-07-27 23:38:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-07-27 23:38:02 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub preprocess_taglink (@) {
|
2007-09-20 20:59:27 +02:00
|
|
|
if (! @_) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
my %params=@_;
|
2007-09-22 19:07:51 +02:00
|
|
|
return join(" ", map {
|
|
|
|
if (/(.*)\|(.*)/) {
|
2008-09-27 20:14:36 +02:00
|
|
|
my $tag=linkpage($2);
|
2007-09-22 19:07:51 +02:00
|
|
|
$tags{$params{page}}{$tag}=1;
|
Avoid %links accumulating duplicates. (For TOVA)
This is sorta an optimisation, and sorta a bug fix. In one
test case I have available, it can speed a page build up from 3
minutes to 3 seconds.
The root of the problem is that $links{$page} contains arrays of
links, rather than hashes of links. And when a link is found,
it is just pushed onto the array, without checking for dups.
Now, the array is emptied before scanning a page, so there
should not be a lot of opportunity for lots of duplicate links
to pile up in it. But, in some cases, they can, and if there
are hundreds of duplicate links in the array, then scanning it
for matching links, as match_link and some other code does,
becomes much more expensive than it needs to be.
Perhaps the real right fix would be to change the data structure
to a hash. But, the list of links is never accessed like that,
you always want to iterate through it.
I also looked at deduping the list in saveindex, but that does
a lot of unnecessary work, and doesn't completly solve the problem.
So, finally, I decided to add an add_link function that handles deduping,
and make ikiwiki-transition remove the old dup links.
2009-05-06 05:40:09 +02:00
|
|
|
add_link($params{page}, tagpage($tag));
|
2008-09-26 02:25:07 +02:00
|
|
|
return taglink($params{page}, $params{destpage}, $tag,
|
2008-09-27 20:14:36 +02:00
|
|
|
linktext => pagetitle($1));
|
2007-09-22 19:07:51 +02:00
|
|
|
}
|
|
|
|
else {
|
2008-09-27 20:14:36 +02:00
|
|
|
my $tag=linkpage($_);
|
2007-09-22 19:07:51 +02:00
|
|
|
$tags{$params{page}}{$tag}=1;
|
Avoid %links accumulating duplicates. (For TOVA)
This is sorta an optimisation, and sorta a bug fix. In one
test case I have available, it can speed a page build up from 3
minutes to 3 seconds.
The root of the problem is that $links{$page} contains arrays of
links, rather than hashes of links. And when a link is found,
it is just pushed onto the array, without checking for dups.
Now, the array is emptied before scanning a page, so there
should not be a lot of opportunity for lots of duplicate links
to pile up in it. But, in some cases, they can, and if there
are hundreds of duplicate links in the array, then scanning it
for matching links, as match_link and some other code does,
becomes much more expensive than it needs to be.
Perhaps the real right fix would be to change the data structure
to a hash. But, the list of links is never accessed like that,
you always want to iterate through it.
I also looked at deduping the list in saveindex, but that does
a lot of unnecessary work, and doesn't completly solve the problem.
So, finally, I decided to add an add_link function that handles deduping,
and make ikiwiki-transition remove the old dup links.
2009-05-06 05:40:09 +02:00
|
|
|
add_link($params{page}, tagpage($tag));
|
2008-09-26 02:25:07 +02:00
|
|
|
return taglink($params{page}, $params{destpage}, $tag);
|
2007-09-22 19:07:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
grep {
|
|
|
|
$_ ne 'page' && $_ ne 'destpage' && $_ ne 'preview'
|
|
|
|
} keys %params);
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2007-09-20 20:59:27 +02:00
|
|
|
|
2008-12-17 21:22:16 +01:00
|
|
|
sub pagetemplate (@) {
|
2006-07-28 01:41:58 +02:00
|
|
|
my %params=@_;
|
|
|
|
my $page=$params{page};
|
|
|
|
my $destpage=$params{destpage};
|
|
|
|
my $template=$params{template};
|
2006-07-28 01:08:03 +02:00
|
|
|
|
2006-07-28 02:21:13 +02:00
|
|
|
$template->param(tags => [
|
2006-07-29 09:25:17 +02:00
|
|
|
map {
|
2008-09-26 02:25:07 +02:00
|
|
|
link => taglink($page, $destpage, $_, rel => "tag")
|
2007-02-14 05:05:08 +01:00
|
|
|
}, sort keys %{$tags{$page}}
|
|
|
|
]) if exists $tags{$page} && %{$tags{$page}} && $template->query(name => "tags");
|
2006-07-29 09:25:17 +02:00
|
|
|
|
2007-01-14 21:14:36 +01:00
|
|
|
if ($template->query(name => "categories")) {
|
|
|
|
# It's an rss/atom template. Add any categories.
|
2007-02-14 05:05:08 +01:00
|
|
|
if (exists $tags{$page} && %{$tags{$page}}) {
|
|
|
|
$template->param(categories => [map { category => $_ },
|
|
|
|
sort keys %{$tags{$page}}]);
|
2006-07-29 09:25:17 +02:00
|
|
|
}
|
|
|
|
}
|
2008-12-17 21:22:16 +01:00
|
|
|
}
|
2006-07-28 01:08:03 +02:00
|
|
|
|
2009-02-20 00:49:30 +01:00
|
|
|
package IkiWiki::PageSpec;
|
|
|
|
|
2009-02-20 00:54:25 +01:00
|
|
|
sub match_tagged ($$;@) {
|
2009-02-20 00:49:30 +01:00
|
|
|
my $page = shift;
|
|
|
|
my $glob = shift;
|
|
|
|
return match_link($page, IkiWiki::Plugin::tag::tagpage($glob));
|
|
|
|
}
|
|
|
|
|
2006-07-27 23:38:02 +02:00
|
|
|
1
|