* meta: Add pagespec functions to match against title, author, authorurl,
license, and copyright. This can be used to create custom RecentChanges. * meta: To support the pagespec functions, metadata about pages has to be retained as pagestate. * Fix encoding bug when pagestate values contained spaces.master
parent
fbfbda614d
commit
64a8c828b8
|
@ -973,7 +973,7 @@ sub saveindex () { #{{{
|
|||
if (exists $pagestate{$page}) {
|
||||
foreach my $id (@hookids) {
|
||||
foreach my $key (keys %{$pagestate{$page}{$id}}) {
|
||||
$line.=' '.$id.'_'.encode_entities($key)."=".encode_entities($pagestate{$page}{$id}{$key});
|
||||
$line.=' '.$id.'_'.encode_entities($key)."=".encode_entities($pagestate{$page}{$id}{$key}, " \t\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,7 @@ use warnings;
|
|||
use strict;
|
||||
use IkiWiki 2.00;
|
||||
|
||||
my %meta;
|
||||
my %title;
|
||||
my %permalink;
|
||||
my %author;
|
||||
my %authorurl;
|
||||
my %license;
|
||||
my %copyright;
|
||||
my %metaheaders;
|
||||
|
||||
sub import { #{{{
|
||||
hook(type => "needsbuild", id => "meta", call => \&needsbuild);
|
||||
|
@ -71,16 +65,16 @@ sub preprocess (@) { #{{{
|
|||
|
||||
# Metadata collection that needs to happen during the scan pass.
|
||||
if ($key eq 'title') {
|
||||
$title{$page}=HTML::Entities::encode_numeric($value);
|
||||
$pagestate{$page}{meta}{title}=HTML::Entities::encode_numeric($value);
|
||||
}
|
||||
elsif ($key eq 'license') {
|
||||
push @{$meta{$page}}, '<link rel="license" href="#page_license" />';
|
||||
$license{$page}=$value;
|
||||
push @{$metaheaders{$page}}, '<link rel="license" href="#page_license" />';
|
||||
$pagestate{$page}{meta}{license}=$value;
|
||||
return "";
|
||||
}
|
||||
elsif ($key eq 'copyright') {
|
||||
push @{$meta{$page}}, '<link rel="copyright" href="#page_copyright" />';
|
||||
$copyright{$page}=$value;
|
||||
push @{$metaheaders{$page}}, '<link rel="copyright" href="#page_copyright" />';
|
||||
$pagestate{$page}{meta}{copyright}=$value;
|
||||
return "";
|
||||
}
|
||||
elsif ($key eq 'link' && ! %params) {
|
||||
|
@ -89,11 +83,11 @@ sub preprocess (@) { #{{{
|
|||
return "";
|
||||
}
|
||||
elsif ($key eq 'author') {
|
||||
$author{$page}=$value;
|
||||
$pagestate{$page}{meta}{author}=$value;
|
||||
# fallthorough
|
||||
}
|
||||
elsif ($key eq 'authorurl') {
|
||||
$authorurl{$page}=$value;
|
||||
$pagestate{$page}{meta}{authorurl}=$value;
|
||||
# fallthrough
|
||||
}
|
||||
|
||||
|
@ -111,8 +105,8 @@ sub preprocess (@) { #{{{
|
|||
}
|
||||
}
|
||||
elsif ($key eq 'permalink') {
|
||||
$permalink{$page}=$value;
|
||||
push @{$meta{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
|
||||
$pagestate{$page}{meta}{permalink}=$value;
|
||||
push @{$metaheaders{$page}}, scrub('<link rel="bookmark" href="'.encode_entities($value).'" />');
|
||||
}
|
||||
elsif ($key eq 'stylesheet') {
|
||||
my $rel=exists $params{rel} ? $params{rel} : "alternate stylesheet";
|
||||
|
@ -123,17 +117,17 @@ sub preprocess (@) { #{{{
|
|||
if (! length $stylesheet) {
|
||||
return "[[meta ".gettext("stylesheet not found")."]]";
|
||||
}
|
||||
push @{$meta{$page}}, '<link href="'.urlto($stylesheet, $page).
|
||||
push @{$metaheaders{$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}).
|
||||
push @{$metaheaders{$page}}, '<link href="'.encode_entities($params{server}).
|
||||
'" rel="openid.server" />';
|
||||
}
|
||||
push @{$meta{$page}}, '<link href="'.encode_entities($value).
|
||||
push @{$metaheaders{$page}}, '<link href="'.encode_entities($value).
|
||||
'" rel="openid.delegate" />';
|
||||
}
|
||||
elsif ($key eq 'redir') {
|
||||
|
@ -172,11 +166,11 @@ sub preprocess (@) { #{{{
|
|||
if (! $safe) {
|
||||
$redir=scrub($redir);
|
||||
}
|
||||
push @{$meta{$page}}, $redir;
|
||||
push @{$metaheaders{$page}}, $redir;
|
||||
}
|
||||
elsif ($key eq 'link') {
|
||||
if (%params) {
|
||||
push @{$meta{$page}}, scrub("<link href=\"".encode_entities($value)."\" ".
|
||||
push @{$metaheaders{$page}}, scrub("<link href=\"".encode_entities($value)."\" ".
|
||||
join(" ", map {
|
||||
encode_entities($_)."=\"".encode_entities(decode_entities($params{$_}))."\""
|
||||
} keys %params).
|
||||
|
@ -184,7 +178,7 @@ sub preprocess (@) { #{{{
|
|||
}
|
||||
}
|
||||
else {
|
||||
push @{$meta{$page}}, scrub('<meta name="'.encode_entities($key).
|
||||
push @{$metaheaders{$page}}, scrub('<meta name="'.encode_entities($key).
|
||||
'" content="'.encode_entities($value).'" />');
|
||||
}
|
||||
|
||||
|
@ -197,32 +191,80 @@ sub pagetemplate (@) { #{{{
|
|||
my $destpage=$params{destpage};
|
||||
my $template=$params{template};
|
||||
|
||||
if (exists $meta{$page} && $template->query(name => "meta")) {
|
||||
if (exists $metaheaders{$page} && $template->query(name => "meta")) {
|
||||
# avoid duplicate meta lines
|
||||
my %seen;
|
||||
$template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$meta{$page}}));
|
||||
$template->param(meta => join("\n", grep { (! $seen{$_}) && ($seen{$_}=1) } @{$metaheaders{$page}}));
|
||||
}
|
||||
if (exists $title{$page} && $template->query(name => "title")) {
|
||||
$template->param(title => $title{$page});
|
||||
if (exists $pagestate{$page}{meta}{title} && $template->query(name => "title")) {
|
||||
$template->param(title => $pagestate{$page}{meta}{title});
|
||||
$template->param(title_overridden => 1);
|
||||
}
|
||||
$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");
|
||||
$template->param(authorurl => $authorurl{$page})
|
||||
if exists $authorurl{$page} && $template->query(name => "authorurl");
|
||||
|
||||
if (exists $license{$page} && $template->query(name => "license") &&
|
||||
($page eq $destpage || ! exists $license{$destpage} ||
|
||||
$license{$page} ne $license{$destpage})) {
|
||||
$template->param(license => htmlize($page, $destpage, $license{$page}));
|
||||
foreach my $field (qw{author authorurl permalink}) {
|
||||
$template->param($field => $pagestate{$page}{meta}{$field})
|
||||
if exists $pagestate{$page}{meta}{$field} && $template->query(name => $field);
|
||||
}
|
||||
if (exists $copyright{$page} && $template->query(name => "copyright") &&
|
||||
($page eq $destpage || ! exists $copyright{$destpage} ||
|
||||
$copyright{$page} ne $copyright{$destpage})) {
|
||||
$template->param(copyright => htmlize($page, $destpage, $copyright{$page}));
|
||||
|
||||
foreach my $field (qw{license copyright}) {
|
||||
if (exists $pagestate{$page}{meta}{$field} && $template->query(name => $field) &&
|
||||
($page eq $destpage || ! exists $pagestate{$destpage}{meta}{$field} ||
|
||||
$pagestate{$page}{meta}{$field} ne $pagestate{$destpage}{meta}{$field})) {
|
||||
$template->param($field => htmlize($page, $destpage, $pagestate{$page}{meta}{$field}));
|
||||
}
|
||||
}
|
||||
} # }}}
|
||||
|
||||
sub match { #{{{
|
||||
my $field=shift;
|
||||
my $page=shift;
|
||||
|
||||
# turn glob into a safe regexp
|
||||
my $re=quotemeta(shift);
|
||||
$re=~s/\\\*/.*/g;
|
||||
$re=~s/\\\?/./g;
|
||||
|
||||
my $val;
|
||||
if (exists $pagestate{$page}{meta}{$field}) {
|
||||
$val=$pagestate{$page}{meta}{$field};
|
||||
}
|
||||
elsif ($field eq 'title') {
|
||||
$val=pagetitle($page);
|
||||
}
|
||||
|
||||
if (defined $val) {
|
||||
if ($val=~/^$re$/i) {
|
||||
return IkiWiki::SuccessReason->new("$re matches $field of $page");
|
||||
}
|
||||
else {
|
||||
return IkiWiki::FailReason->new("$re does not match $field of $page");
|
||||
}
|
||||
}
|
||||
else {
|
||||
return IkiWiki::FailReason->new("$page does not have a $field");
|
||||
}
|
||||
} #}}}
|
||||
|
||||
package IkiWiki::PageSpec;
|
||||
|
||||
sub match_title ($$;@) { #{{{
|
||||
IkiWiki::Plugin::meta::match("title", @_);
|
||||
} #}}}
|
||||
|
||||
sub match_author ($$;@) { #{{{
|
||||
IkiWiki::Plugin::meta::match("author", @_);
|
||||
} #}}}
|
||||
|
||||
sub match_authorurl ($$;@) { #{{{
|
||||
IkiWiki::Plugin::meta::match("authorurl", @_);
|
||||
} #}}}
|
||||
|
||||
sub match_license ($$;@) { #{{{
|
||||
IkiWiki::Plugin::meta::match("license", @_);
|
||||
} #}}}
|
||||
|
||||
sub match_copyright ($$;@) { #{{{
|
||||
IkiWiki::Plugin::meta::match("copyright", @_);
|
||||
} #}}}
|
||||
|
||||
1
|
||||
|
|
|
@ -377,6 +377,7 @@ sub refresh () { #{{{
|
|||
$pagemtime{$page}=$mtime;
|
||||
if (isinternal($page)) {
|
||||
push @internal, $file;
|
||||
scan($file);
|
||||
}
|
||||
else {
|
||||
push @needsbuild, $file;
|
||||
|
|
|
@ -31,6 +31,11 @@ ikiwiki (2.21) UNRELEASED; urgency=low
|
|||
the svnrepo and notify settings, though both will be ignored if left in
|
||||
setup files. Also gone with it is the "user()" pagespec.
|
||||
* Add refresh hook.
|
||||
* meta: Add pagespec functions to match against title, author, authorurl,
|
||||
license, and copyright. This can be used to create custom RecentChanges.
|
||||
* meta: To support the pagespec functions, metadata about pages has to be
|
||||
retained as pagestate.
|
||||
* Fix encoding bug when pagestate values contained spaces.
|
||||
|
||||
-- Joey Hess <joeyh@debian.org> Fri, 11 Jan 2008 15:09:37 -0500
|
||||
|
||||
|
|
|
@ -33,10 +33,13 @@ functions:
|
|||
was created
|
||||
* "`created_before(page)`" - match only pages created before the given page
|
||||
was created
|
||||
* "`glob(foo)`" - match pages that match the given glob `foo`. Just writing
|
||||
* "`glob(someglob)`" - match pages that match the given glob. Just writing
|
||||
the glob by itself is actually a shorthand for this function.
|
||||
* "`internal(foo)`" - like `glob()`, but matches even internal-use
|
||||
* "`internal(glob)`" - like `glob()`, but matches even internal-use
|
||||
pages that globs do not usually match.
|
||||
* "`title(glob)`", "`author(glob)`", "`authorurl(glob)`",
|
||||
"`license(glob)`", "`copyright(glob)`" - match pages that have the given
|
||||
metadata, matching the specified glob.
|
||||
|
||||
For example, to match all pages in a blog that link to the page about music
|
||||
and were written in 2005:
|
||||
|
|
|
@ -10,3 +10,17 @@ plugin, but you can use it elsewhere too if you like. It's used like this:
|
|||
|
||||
\[[inline pages="internal(recentchanges/change_*)"
|
||||
template=recentchanges show=0]]
|
||||
|
||||
Here's an example of how to show only changes to "bugs/*".
|
||||
This matches against the title of the change, which includes a list of
|
||||
modified pages.
|
||||
|
||||
\[[inline pages="internal(recentchanges/change_*) and title(*bugs/*)"
|
||||
template=recentchanges show=0]]
|
||||
|
||||
Here's an example of how to show only changes that Joey didn't make.
|
||||
(Joey commits sometimes as user `joey`, and sometimes via openid.)
|
||||
|
||||
\[[inline pages="internal(recentchanges/change_*) and
|
||||
!author(joey) and !author(http://joey.kitenet.net*)"
|
||||
template=recentchanges show=0]]
|
||||
|
|
|
@ -533,18 +533,16 @@ rendered to.
|
|||
|
||||
## Internal use pages
|
||||
|
||||
Sometimes it's useful to put pages in the wiki without having them be
|
||||
rendered to individual html files. Such internal use pages are collected
|
||||
together to form the RecentChanges page, for example.
|
||||
Sometimes it's useful to put pages in the wiki without the overhead of
|
||||
having them be rendered to individual html files. Such internal use pages
|
||||
are collected together to form the RecentChanges page, for example.
|
||||
|
||||
To make an internal use page, register a filename extension that starts
|
||||
with "_". Internal use pages cannot be edited with the web interface, are
|
||||
not scanned for wikilinks (though wikilinks and preprocessor directives can
|
||||
appear on them, this is rarely a good idea and should be done with caution),
|
||||
and are not matched by regular PageSpecs glob patterns, but instead only by a
|
||||
special `internal()` [[ikiwiki/PageSpec]].
|
||||
|
||||
Ikiwiki is optimised to handle lots of internal use pages, very quickly.
|
||||
with "_". Internal use pages cannot be edited with the web interface,
|
||||
generally shouldn't contain wikilinks or preprocessor directives (use
|
||||
either on them with extreme caution), and are not matched by regular
|
||||
PageSpecs glob patterns, but instead only by a special `internal()`
|
||||
[[ikiwiki/PageSpec]].
|
||||
|
||||
## RCS plugins
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ use IkiWiki::Setup::Standard {
|
|||
syslog => 0,
|
||||
userdir => "users",
|
||||
usedirs => 0,
|
||||
rcs => "git",
|
||||
rss => 1,
|
||||
url => "http://ikiwiki.info/",
|
||||
add_plugins => [qw{goodstuff version haiku polygen fortune}],
|
||||
disable_plugins => [qw{recentchanges}],
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2008-01-29 15:46-0500\n"
|
||||
"POT-Creation-Date: 2008-01-29 17:15-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -47,8 +47,8 @@ msgstr ""
|
|||
|
||||
#: ../IkiWiki/CGI.pm:382 ../IkiWiki/Plugin/brokenlinks.pm:24
|
||||
#: ../IkiWiki/Plugin/inline.pm:241 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:100
|
||||
#: ../IkiWiki/Render.pm:180
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:101
|
||||
#: ../IkiWiki/Render.pm:181
|
||||
msgid "discussion"
|
||||
msgstr ""
|
||||
|
||||
|
@ -218,7 +218,7 @@ msgstr ""
|
|||
msgid "nonexistant template %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:249 ../IkiWiki/Render.pm:104
|
||||
#: ../IkiWiki/Plugin/inline.pm:249 ../IkiWiki/Render.pm:105
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
|
@ -240,15 +240,15 @@ msgstr ""
|
|||
msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/meta.pm:124
|
||||
#: ../IkiWiki/Plugin/meta.pm:118
|
||||
msgid "stylesheet not found"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/meta.pm:148
|
||||
#: ../IkiWiki/Plugin/meta.pm:142
|
||||
msgid "redir page not found"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/meta.pm:161
|
||||
#: ../IkiWiki/Plugin/meta.pm:155
|
||||
msgid "redir cycle is not allowed"
|
||||
msgstr ""
|
||||
|
||||
|
@ -503,47 +503,47 @@ msgstr ""
|
|||
msgid "getctime not implemented"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:280 ../IkiWiki/Render.pm:301
|
||||
#: ../IkiWiki/Render.pm:281 ../IkiWiki/Render.pm:302
|
||||
#, perl-format
|
||||
msgid "skipping bad filename %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:350
|
||||
#: ../IkiWiki/Render.pm:351
|
||||
#, perl-format
|
||||
msgid "removing old page %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:389
|
||||
#: ../IkiWiki/Render.pm:391
|
||||
#, perl-format
|
||||
msgid "scanning %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:394
|
||||
#: ../IkiWiki/Render.pm:396
|
||||
#, perl-format
|
||||
msgid "rendering %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:415
|
||||
#: ../IkiWiki/Render.pm:417
|
||||
#, perl-format
|
||||
msgid "rendering %s, which links to %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:436
|
||||
#: ../IkiWiki/Render.pm:438
|
||||
#, perl-format
|
||||
msgid "rendering %s, which depends on %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:475
|
||||
#: ../IkiWiki/Render.pm:477
|
||||
#, perl-format
|
||||
msgid "rendering %s, to update its backlinks"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:487
|
||||
#: ../IkiWiki/Render.pm:489
|
||||
#, perl-format
|
||||
msgid "removing %s, no longer rendered by %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Render.pm:513
|
||||
#: ../IkiWiki/Render.pm:515
|
||||
#, perl-format
|
||||
msgid "ikiwiki: cannot render %s"
|
||||
msgstr ""
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<TMPL_IF AUTHORURL>
|
||||
[[meta authorurl="""<TMPL_VAR AUTHORURL>"""]]
|
||||
</TMPL_IF>
|
||||
[[meta title="""update of <TMPL_VAR WIKINAME>'s <TMPL_LOOP NAME="PAGES"> <TMPL_VAR PAGE></TMPL_LOOP>"""]]
|
||||
[[meta title="""update of <TMPL_VAR WIKINAME>'s<TMPL_LOOP NAME="PAGES"> <TMPL_VAR PAGE></TMPL_LOOP>"""]]
|
||||
<div class="metadata">
|
||||
<span class="desc"><br />Changed pages:</span>
|
||||
<span class="pagelinks">
|
||||
|
|
Loading…
Reference in New Issue