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);
|
|
|
|
hook(type => "preprocess", id => "meta", call => \&preprocess);
|
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;
|
|
|
|
my $text = shift;
|
|
|
|
|
|
|
|
$text=IkiWiki::htmlize($page, pagetype($pagesources{$page}),
|
|
|
|
IkiWiki::linkify($page, $destpage,
|
|
|
|
IkiWiki::preprocess($page, $destpage, $text)));
|
|
|
|
|
|
|
|
# hack to get rid of enclosing junk added by markdown
|
|
|
|
$text=~s!^<p>!!;
|
|
|
|
$text=~s!</p>$!!;
|
|
|
|
chomp $text;
|
|
|
|
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
elsif ($key eq 'permalink') {
|
|
|
|
$permalink{$page}=$value;
|
|
|
|
push @{$meta{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
|
|
|
|
}
|
|
|
|
elsif ($key eq 'date') {
|
|
|
|
eval q{use Date::Parse};
|
|
|
|
if (! $@) {
|
|
|
|
my $time = str2time($value);
|
|
|
|
$IkiWiki::pagectime{$page}=$time if defined $time;
|
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
|
|
|
}
|
|
|
|
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" />';
|
|
|
|
}
|
|
|
|
elsif ($key eq 'license') {
|
|
|
|
push @{$meta{$page}}, '<link rel="license" href="#page_license" />';
|
|
|
|
$license{$page}=$value;
|
|
|
|
}
|
|
|
|
elsif ($key eq 'copyright') {
|
|
|
|
push @{$meta{$page}}, '<link rel="copyright" href="#page_copyright" />';
|
|
|
|
$copyright{$page}=$value;
|
2006-06-02 06:49:12 +02:00
|
|
|
}
|
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') {
|
|
|
|
return "[[meta ".gettext("link is no longer supported")."]]";
|
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-08-04 02:01:51 +02:00
|
|
|
if ($key eq 'author') {
|
|
|
|
$author{$page}=$value;
|
|
|
|
}
|
2006-08-04 02:47:28 +02:00
|
|
|
elsif ($key eq 'authorurl') {
|
|
|
|
$authorurl{$page}=$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-15 02:23:08 +02:00
|
|
|
|
|
|
|
if ($page ne $destpage &&
|
|
|
|
((exists $license{$page} && ! exists $license{$destpage}) ||
|
|
|
|
(exists $copyright{$page} && ! exists $copyright{$destpage}))) {
|
|
|
|
# Force a scan of the destpage to get its copyright/license
|
|
|
|
# info. If the info is declared after an inline, it will
|
|
|
|
# otherwise not be available at this point.
|
|
|
|
IkiWiki::scan($pagesources{$destpage});
|
|
|
|
}
|
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
|