2006-06-02 06:49:12 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
# Ikiwiki metadata plugin.
|
|
|
|
package IkiWiki::Plugin::meta;
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
2007-04-27 04:55:52 +02:00
|
|
|
use IkiWiki 2.00;
|
2006-06-02 06:49:12 +02:00
|
|
|
|
|
|
|
my %meta;
|
|
|
|
my %title;
|
2006-08-04 02:01:51 +02:00
|
|
|
my %permalink;
|
|
|
|
my %author;
|
2006-08-04 02:47:28 +02:00
|
|
|
my %authorurl;
|
2007-09-14 20:11:10 +02:00
|
|
|
my %license;
|
|
|
|
my %copyright;
|
2006-06-02 06:49:12 +02:00
|
|
|
|
|
|
|
sub import { #{{{
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
hook(type => "needsbuild", id => "meta", call => \&needsbuild);
|
2008-01-09 08:38:43 +01:00
|
|
|
hook(type => "preprocess", id => "meta", call => \&preprocess, scan => 1);
|
2006-09-10 00:50:27 +02:00
|
|
|
hook(type => "pagetemplate", id => "meta", call => \&pagetemplate);
|
2006-06-02 06:49:12 +02:00
|
|
|
} # }}}
|
|
|
|
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
sub needsbuild (@) { #{{{
|
|
|
|
my $needsbuild=shift;
|
|
|
|
foreach my $page (keys %pagestate) {
|
|
|
|
if (exists $pagestate{$page}{meta}) {
|
|
|
|
if (grep { $_ eq $pagesources{$page} } @$needsbuild) {
|
|
|
|
# remove state, it will be re-added
|
|
|
|
# if the preprocessor directive is still
|
|
|
|
# there during the rebuild
|
|
|
|
delete $pagestate{$page}{meta};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-31 00:58:48 +02:00
|
|
|
|
2007-03-21 19:52:56 +01:00
|
|
|
sub scrub ($) { #{{{
|
|
|
|
if (IkiWiki::Plugin::htmlscrubber->can("sanitize")) {
|
|
|
|
return IkiWiki::Plugin::htmlscrubber::sanitize(content => shift);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return shift;
|
|
|
|
}
|
|
|
|
} #}}}
|
|
|
|
|
2008-01-09 07:05:54 +01:00
|
|
|
sub htmlize ($$$) { #{{{
|
|
|
|
my $page = shift;
|
|
|
|
my $destpage = shift;
|
|
|
|
|
2008-01-09 20:35:23 +01:00
|
|
|
return IkiWiki::htmlize($page, pagetype($pagesources{$page}),
|
2008-01-09 07:05:54 +01:00
|
|
|
IkiWiki::linkify($page, $destpage,
|
2008-01-09 20:35:23 +01:00
|
|
|
IkiWiki::preprocess($page, $destpage, shift)));
|
2008-01-09 07:05:54 +01:00
|
|
|
}
|
|
|
|
|
2006-06-02 06:49:12 +02:00
|
|
|
sub preprocess (@) { #{{{
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
return "" unless @_;
|
2006-06-02 06:49:12 +02:00
|
|
|
my %params=@_;
|
|
|
|
my $key=shift;
|
|
|
|
my $value=$params{$key};
|
|
|
|
delete $params{$key};
|
|
|
|
my $page=$params{page};
|
|
|
|
delete $params{page};
|
2007-12-08 20:37:41 +01:00
|
|
|
my $destpage=$params{destpage};
|
2006-07-28 01:47:13 +02:00
|
|
|
delete $params{destpage};
|
2007-03-07 06:53:47 +01:00
|
|
|
delete $params{preview};
|
2006-06-02 06:49:12 +02:00
|
|
|
|
2006-07-31 00:58:48 +02:00
|
|
|
eval q{use HTML::Entities};
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
# Always decode, even if encoding later, since it might not be
|
2006-07-31 00:58:48 +02:00
|
|
|
# fully encoded.
|
|
|
|
$value=decode_entities($value);
|
2006-06-02 08:11:22 +02:00
|
|
|
|
2008-01-09 08:38:43 +01:00
|
|
|
# Metadata collection that needs to happen during the scan pass.
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
if ($key eq 'title') {
|
|
|
|
$title{$page}=HTML::Entities::encode_numeric($value);
|
|
|
|
}
|
2008-01-09 08:38:43 +01:00
|
|
|
elsif ($key eq 'license') {
|
|
|
|
push @{$meta{$page}}, '<link rel="license" href="#page_license" />';
|
|
|
|
$license{$page}=$value;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
elsif ($key eq 'copyright') {
|
|
|
|
push @{$meta{$page}}, '<link rel="copyright" href="#page_copyright" />';
|
|
|
|
$copyright{$page}=$value;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
elsif ($key eq 'link' && ! %params) {
|
|
|
|
# hidden WikiLink
|
|
|
|
push @{$links{$page}}, $value;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
elsif ($key eq 'author') {
|
|
|
|
$author{$page}=$value;
|
|
|
|
# fallthorough
|
|
|
|
}
|
|
|
|
elsif ($key eq 'authorurl') {
|
|
|
|
$authorurl{$page}=$value;
|
|
|
|
# fallthrough
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! defined wantarray) {
|
|
|
|
# avoid collecting duplicate data during scan pass
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Metadata collection that happens only during preprocessing pass.
|
2008-01-09 08:41:38 +01:00
|
|
|
if ($key eq 'date') {
|
|
|
|
eval q{use Date::Parse};
|
|
|
|
if (! $@) {
|
|
|
|
my $time = str2time($value);
|
|
|
|
$IkiWiki::pagectime{$page}=$time if defined $time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
elsif ($key eq 'permalink') {
|
2008-01-09 08:38:43 +01:00
|
|
|
$permalink{$page}=$value;
|
|
|
|
push @{$meta{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
|
|
|
|
}
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
elsif ($key eq 'stylesheet') {
|
|
|
|
my $rel=exists $params{rel} ? $params{rel} : "alternate stylesheet";
|
|
|
|
my $title=exists $params{title} ? $params{title} : $value;
|
|
|
|
# adding .css to the value prevents using any old web
|
|
|
|
# editable page as a stylesheet
|
|
|
|
my $stylesheet=bestlink($page, $value.".css");
|
|
|
|
if (! length $stylesheet) {
|
|
|
|
return "[[meta ".gettext("stylesheet not found")."]]";
|
|
|
|
}
|
|
|
|
push @{$meta{$page}}, '<link href="'.urlto($stylesheet, $page).
|
|
|
|
'" rel="'.encode_entities($rel).
|
|
|
|
'" title="'.encode_entities($title).
|
|
|
|
"\" type=\"text/css\" />";
|
|
|
|
}
|
|
|
|
elsif ($key eq 'openid') {
|
|
|
|
if (exists $params{server}) {
|
|
|
|
push @{$meta{$page}}, '<link href="'.encode_entities($params{server}).
|
|
|
|
'" rel="openid.server" />';
|
2006-06-02 06:49:12 +02:00
|
|
|
}
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
push @{$meta{$page}}, '<link href="'.encode_entities($value).
|
|
|
|
'" rel="openid.delegate" />';
|
|
|
|
}
|
2007-12-08 20:58:29 +01:00
|
|
|
elsif ($key eq 'redir') {
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
return "" if $page ne $destpage;
|
2007-12-08 20:58:29 +01:00
|
|
|
my $safe=0;
|
2007-12-08 21:17:37 +01:00
|
|
|
if ($value !~ /^\w+:\/\//) {
|
2007-12-22 16:21:00 +01:00
|
|
|
my ($redir_page, $redir_anchor) = split /\#/, $value;
|
|
|
|
|
|
|
|
add_depends($page, $redir_page);
|
|
|
|
my $link=bestlink($page, $redir_page);
|
2007-12-08 20:58:29 +01:00
|
|
|
if (! length $link) {
|
|
|
|
return "[[meta ".gettext("redir page not found")."]]";
|
|
|
|
}
|
2007-12-09 01:39:32 +01:00
|
|
|
|
|
|
|
$value=urlto($link, $page);
|
2007-12-22 16:21:00 +01:00
|
|
|
$value.='#'.$redir_anchor if defined $redir_anchor;
|
2007-12-09 01:39:32 +01:00
|
|
|
$safe=1;
|
|
|
|
|
|
|
|
# redir cycle detection
|
2007-12-08 23:40:50 +01:00
|
|
|
$pagestate{$page}{meta}{redir}=$link;
|
2007-12-09 01:39:32 +01:00
|
|
|
my $at=$page;
|
|
|
|
my %seen;
|
|
|
|
while (exists $pagestate{$at}{meta}{redir}) {
|
|
|
|
if ($seen{$at}) {
|
|
|
|
return "[[meta ".gettext("redir cycle is not allowed")."]]";
|
|
|
|
}
|
|
|
|
$seen{$at}=1;
|
|
|
|
$at=$pagestate{$at}{meta}{redir};
|
2007-12-08 23:40:50 +01:00
|
|
|
}
|
2007-12-08 20:58:29 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$value=encode_entities($value);
|
|
|
|
}
|
|
|
|
my $delay=int(exists $params{delay} ? $params{delay} : 0);
|
|
|
|
my $redir="<meta http-equiv=\"refresh\" content=\"$delay; URL=$value\">";
|
|
|
|
if (! $safe) {
|
|
|
|
$redir=scrub($redir);
|
|
|
|
}
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
push @{$meta{$page}}, $redir;
|
2007-03-21 19:52:56 +01:00
|
|
|
}
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
elsif ($key eq 'link') {
|
2008-01-09 08:38:43 +01:00
|
|
|
if (%params) {
|
2008-01-09 20:35:23 +01:00
|
|
|
push @{$meta{$page}}, scrub("<link href=\"".encode_entities($value)."\" ".
|
2008-01-09 08:38:43 +01:00
|
|
|
join(" ", map {
|
|
|
|
encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
|
|
|
|
} keys %params).
|
|
|
|
" />\n");
|
|
|
|
}
|
2007-09-14 20:11:10 +02:00
|
|
|
}
|
2006-06-02 06:49:12 +02:00
|
|
|
else {
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
push @{$meta{$page}}, scrub('<meta name="'.encode_entities($key).
|
|
|
|
'" content="'.encode_entities($value).'" />');
|
2006-06-02 06:49:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
} # }}}
|
|
|
|
|
2006-07-28 01:41:58 +02:00
|
|
|
sub pagetemplate (@) { #{{{
|
|
|
|
my %params=@_;
|
|
|
|
my $page=$params{page};
|
2007-09-14 21:09:16 +02:00
|
|
|
my $destpage=$params{destpage};
|
2006-07-28 01:41:58 +02:00
|
|
|
my $template=$params{template};
|
2006-06-02 06:49:12 +02:00
|
|
|
|
* meta: Drop support for "meta link", since supporting this for internal
links required meta to be run during scan, which complicated its data
storage, since it had to clear data stored during the scan pass to avoid
duplicating it during the normal preprocessing pass.
* If you used "meta link", you should switch to either "meta openid" (for
openid delegations), or tags (for internal, invisible links). I assume
that nobody really used "meta link" for external, non-openid links, since
the htmlscrubber ate those. (Tell me differently and I'll consider bringing
back that support.)
* meta: Improved data storage.
* meta: Drop the hackish filter hook that was used to clear
stored data before preprocessing, this hack was ugly, and broken (cf:
liw's disappearing openids).
* aggregate: Convert filter hook to a needsbuild hook.
2007-12-16 21:56:09 +01:00
|
|
|
if (exists $meta{$page} && $template->query(name => "meta")) {
|
|
|
|
# avoid duplicate meta lines
|
|
|
|
my %seen;
|
|
|
|
$template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$meta{$page}}));
|
|
|
|
}
|
2006-08-12 19:51:32 +02:00
|
|
|
if (exists $title{$page} && $template->query(name => "title")) {
|
|
|
|
$template->param(title => $title{$page});
|
|
|
|
$template->param(title_overridden => 1);
|
|
|
|
}
|
2006-08-04 02:01:51 +02:00
|
|
|
$template->param(permalink => $permalink{$page})
|
|
|
|
if exists $permalink{$page} && $template->query(name => "permalink");
|
|
|
|
$template->param(author => $author{$page})
|
|
|
|
if exists $author{$page} && $template->query(name => "author");
|
2006-08-04 02:47:28 +02:00
|
|
|
$template->param(authorurl => $authorurl{$page})
|
|
|
|
if exists $authorurl{$page} && $template->query(name => "authorurl");
|
2007-09-14 21:09:16 +02:00
|
|
|
|
|
|
|
if (exists $license{$page} && $template->query(name => "license") &&
|
2007-09-15 02:23:08 +02:00
|
|
|
($page eq $destpage || ! exists $license{$destpage} ||
|
|
|
|
$license{$page} ne $license{$destpage})) {
|
2008-01-09 07:05:54 +01:00
|
|
|
$template->param(license => htmlize($page, $destpage, $license{$page}));
|
2007-09-14 21:09:16 +02:00
|
|
|
}
|
|
|
|
if (exists $copyright{$page} && $template->query(name => "copyright") &&
|
2007-09-15 02:23:08 +02:00
|
|
|
($page eq $destpage || ! exists $copyright{$destpage} ||
|
|
|
|
$copyright{$page} ne $copyright{$destpage})) {
|
2008-01-09 07:05:54 +01:00
|
|
|
$template->param(copyright => htmlize($page, $destpage, $copyright{$page}));
|
2007-09-14 21:09:16 +02:00
|
|
|
}
|
2006-06-02 06:49:12 +02:00
|
|
|
} # }}}
|
|
|
|
|
|
|
|
1
|