Skip to content

Commit dae0f48

Browse files
author
joey
committed
* Work on firming up the plugin interface:
- Plugins should not need to load IkiWiki::Render to get commonly used functions, so moved some functions from there to IkiWiki. - Picked out the set of functions and variables that most plugins use, documented them, and made IkiWiki export them by default, like a proper perl module should. - Use the other functions at your own risk. - This is not quite complete, I still have to decide whether to export some other things. * Changed all plugins included in ikiwiki to not use "IkiWiki::" when referring to stuff now exported by the IkiWiki module. * Anyone with a third-party ikiwiki plugin is strongly enrouraged to make like changes to it and avoid use of non-exported symboles from "IkiWiki::". * Link debian/changelog and debian/news to NEWS and CHANGELOG. * Support hyperestradier version 1.4.2, which adds a new required phraseform setting.
1 parent d92142d commit dae0f48

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+630
-489
lines changed

CHANGELOG

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
debian/changelog

IkiWiki.pm

+142-9
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@ use Encode;
77
use HTML::Entities;
88
use open qw{:utf8 :std};
99

10+
use vars qw{%config %links %oldlinks %oldpagemtime %pagectime %pagecase
11+
%renderedfiles %pagesources %depends %hooks %forcerebuild};
12+
13+
use Exporter q{import};
14+
our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
15+
bestlink htmllink readfile writefile pagetype srcfile pagename
16+
%config %links %renderedfiles %pagesources);
17+
1018
# Optimisation.
1119
use Memoize;
1220
memoize("abs2rel");
1321
memoize("pagespec_translate");
1422

15-
use vars qw{%config %links %oldlinks %oldpagemtime %pagectime %pagecase
16-
%renderedfiles %pagesources %depends %hooks %forcerebuild};
17-
1823
my $installdir=''; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE
1924

2025
sub defaultconfig () { #{{{
@@ -254,11 +259,6 @@ sub writefile ($$$;$) { #{{{
254259
} #}}}
255260

256261
sub bestlink ($$) { #{{{
257-
# Given a page and the text of a link on the page, determine which
258-
# existing page that link best points to. Prefers pages under a
259-
# subdirectory with the same name as the source page, failing that
260-
# goes down the directory tree to the base looking for matching
261-
# pages.
262262
my $page=shift;
263263
my $link=shift;
264264

@@ -329,6 +329,16 @@ sub abs2rel ($$) { #{{{
329329
return $ret;
330330
} #}}}
331331

332+
sub displaytime ($) { #{{{
333+
my $time=shift;
334+
335+
eval q{use POSIX};
336+
# strftime doesn't know about encodings, so make sure
337+
# its output is properly treated as utf8
338+
return decode_utf8(POSIX::strftime(
339+
$config{timeformat}, localtime($time)));
340+
} #}}}
341+
332342
sub htmllink ($$$;$$$) { #{{{
333343
my $lpage=shift; # the page doing the linking
334344
my $page=shift; # the page that will contain the link (different for inline)
@@ -370,6 +380,117 @@ sub htmllink ($$$;$$$) { #{{{
370380
return "<a href=\"$bestlink\">$linktext</a>";
371381
} #}}}
372382

383+
sub htmlize ($$$) { #{{{
384+
my $page=shift;
385+
my $type=shift;
386+
my $content=shift;
387+
388+
if (exists $hooks{htmlize}{$type}) {
389+
$content=$hooks{htmlize}{$type}{call}->(
390+
page => $page,
391+
content => $content,
392+
);
393+
}
394+
else {
395+
error("htmlization of $type not supported");
396+
}
397+
398+
run_hooks(sanitize => sub {
399+
$content=shift->(
400+
page => $page,
401+
content => $content,
402+
);
403+
});
404+
405+
return $content;
406+
} #}}}
407+
408+
sub linkify ($$$) { #{{{
409+
my $lpage=shift; # the page containing the links
410+
my $page=shift; # the page the link will end up on (different for inline)
411+
my $content=shift;
412+
413+
$content =~ s{(\\?)$config{wiki_link_regexp}}{
414+
$2 ? ( $1 ? "[[$2|$3]]" : htmllink($lpage, $page, titlepage($3), 0, 0, pagetitle($2)))
415+
: ( $1 ? "[[$3]]" : htmllink($lpage, $page, titlepage($3)))
416+
}eg;
417+
418+
return $content;
419+
} #}}}
420+
421+
my %preprocessing;
422+
sub preprocess ($$$) { #{{{
423+
my $page=shift; # the page the data comes from
424+
my $destpage=shift; # the page the data will appear in (different for inline)
425+
my $content=shift;
426+
427+
my $handle=sub {
428+
my $escape=shift;
429+
my $command=shift;
430+
my $params=shift;
431+
if (length $escape) {
432+
return "[[$command $params]]";
433+
}
434+
elsif (exists $hooks{preprocess}{$command}) {
435+
# Note: preserve order of params, some plugins may
436+
# consider it significant.
437+
my @params;
438+
while ($params =~ /(?:(\w+)=)?(?:"""(.*?)"""|"([^"]+)"|(\S+))(?:\s+|$)/sg) {
439+
my $key=$1;
440+
my $val;
441+
if (defined $2) {
442+
$val=$2;
443+
$val=~s/\r\n/\n/mg;
444+
$val=~s/^\n+//g;
445+
$val=~s/\n+$//g;
446+
}
447+
elsif (defined $3) {
448+
$val=$3;
449+
}
450+
elsif (defined $4) {
451+
$val=$4;
452+
}
453+
454+
if (defined $key) {
455+
push @params, $key, $val;
456+
}
457+
else {
458+
push @params, $val, '';
459+
}
460+
}
461+
if ($preprocessing{$page}++ > 3) {
462+
# Avoid loops of preprocessed pages preprocessing
463+
# other pages that preprocess them, etc.
464+
return "[[$command preprocessing loop detected on $page at depth $preprocessing{$page}]]";
465+
}
466+
my $ret=$hooks{preprocess}{$command}{call}->(
467+
@params,
468+
page => $page,
469+
destpage => $destpage,
470+
);
471+
$preprocessing{$page}--;
472+
return $ret;
473+
}
474+
else {
475+
return "[[$command $params]]";
476+
}
477+
};
478+
479+
$content =~ s{(\\?)\[\[(\w+)\s+((?:(?:\w+=)?(?:""".*?"""|"[^"]+"|[^\s\]]+)\s*)*)\]\]}{$handle->($1, $2, $3)}seg;
480+
return $content;
481+
} #}}}
482+
483+
sub filter ($$) {
484+
my $page=shift;
485+
my $content=shift;
486+
487+
run_hooks(filter => sub {
488+
$content=shift->(page => $page, content => $content);
489+
});
490+
491+
return $content;
492+
}
493+
373494
sub indexlink () { #{{{
374495
return "<a href=\"$config{url}\">$config{wikiname}</a>";
375496
} #}}}
@@ -478,7 +599,7 @@ sub misctemplate ($$) { #{{{
478599
indexlink => indexlink(),
479600
wikiname => $config{wikiname},
480601
pagebody => $pagebody,
481-
baseurl => baseurl(),
602+
baseurl => baseurl(),
482603
);
483604
return $template->output;
484605
}#}}}
@@ -594,6 +715,18 @@ sub pagespec_translate ($) { #{{{
594715
return $code;
595716
} #}}}
596717

718+
sub add_depends ($$) { #{{{
719+
my $page=shift;
720+
my $pagespec=shift;
721+
722+
if (! exists $depends{$page}) {
723+
$depends{$page}=$pagespec;
724+
}
725+
else {
726+
$depends{$page}=pagespec_merge($depends{$page}, $pagespec);
727+
}
728+
} # }}}
729+
597730
sub pagespec_match ($$) { #{{{
598731
my $page=shift;
599732
my $spec=shift;

IkiWiki/CGI.pm

-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ sub cgi_editpage ($$) { #{{{
431431
return;
432432
}
433433
elsif ($form->submitted eq "Preview") {
434-
require IkiWiki::Render;
435434
my $content=$form->field('editcontent');
436435
my $comments=$form->field('comments');
437436
$form->field(name => "editcontent",

IkiWiki/Plugin/aggregate.pm

+27-33
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,24 @@ my %feeds;
1414
my %guids;
1515

1616
sub import { #{{{
17-
IkiWiki::hook(type => "getopt", id => "aggregate",
18-
call => \&getopt);
19-
IkiWiki::hook(type => "checkconfig", id => "aggregate",
20-
call => \&checkconfig);
21-
IkiWiki::hook(type => "filter", id => "aggregate",
22-
call => \&filter);
23-
IkiWiki::hook(type => "preprocess", id => "aggregate",
24-
call => \&preprocess);
25-
IkiWiki::hook(type => "delete", id => "aggregate",
26-
call => \&delete);
27-
IkiWiki::hook(type => "savestate", id => "aggregate",
28-
call => \&savestate);
17+
hook(type => "getopt", id => "aggregate", call => \&getopt);
18+
hook(type => "checkconfig", id => "aggregate", call => \&checkconfig);
19+
hook(type => "filter", id => "aggregate", call => \&filter);
20+
hook(type => "preprocess", id => "aggregate", call => \&preprocess);
21+
hook(type => "delete", id => "aggregate", call => \&delete);
22+
hook(type => "savestate", id => "aggregate", call => \&savestate);
2923
} # }}}
3024

3125
sub getopt () { #{{{
3226
eval q{use Getopt::Long};
3327
Getopt::Long::Configure('pass_through');
34-
GetOptions("aggregate" => \$IkiWiki::config{aggregate});
28+
GetOptions("aggregate" => \$config{aggregate});
3529
} #}}}
3630

3731
sub checkconfig () { #{{{
3832
IkiWiki::lockwiki();
3933
loadstate();
40-
if ($IkiWiki::config{aggregate}) {
34+
if ($config{aggregate}) {
4135
IkiWiki::loadindex();
4236
aggregate();
4337
savestate();
@@ -78,7 +72,7 @@ sub preprocess (@) { #{{{
7872
$feed->{url}=$params{url};
7973
my $dir=exists $params{dir} ? $params{dir} : $params{page}."/".IkiWiki::titlepage($params{name});
8074
$dir=~s/^\/+//;
81-
($dir)=$dir=~/$IkiWiki::config{wiki_file_regexp}/;
75+
($dir)=$dir=~/$config{wiki_file_regexp}/;
8276
$feed->{dir}=$dir;
8377
$feed->{feedurl}=defined $params{feedurl} ? $params{feedurl} : "";
8478
$feed->{updateinterval}=defined $params{updateinterval} ? $params{updateinterval} * 60 : 15 * 60;
@@ -109,15 +103,15 @@ sub delete (@) { #{{{
109103

110104
# Remove feed data for removed pages.
111105
foreach my $file (@files) {
112-
my $page=IkiWiki::pagename($file);
106+
my $page=pagename($file);
113107
remove_feeds($page);
114108
}
115109
} #}}}
116110

117111
sub loadstate () { #{{{
118-
if (-e "$IkiWiki::config{wikistatedir}/aggregate") {
119-
open (IN, "$IkiWiki::config{wikistatedir}/aggregate" ||
120-
die "$IkiWiki::config{wikistatedir}/aggregate: $!");
112+
if (-e "$config{wikistatedir}/aggregate") {
113+
open (IN, "$config{wikistatedir}/aggregate" ||
114+
die "$config{wikistatedir}/aggregate: $!");
121115
while (<IN>) {
122116
$_=IkiWiki::possibly_foolish_untaint($_);
123117
chomp;
@@ -151,8 +145,8 @@ sub loadstate () { #{{{
151145
sub savestate () { #{{{
152146
eval q{use HTML::Entities};
153147
die $@ if $@;
154-
open (OUT, ">$IkiWiki::config{wikistatedir}/aggregate" ||
155-
die "$IkiWiki::config{wikistatedir}/aggregate: $!");
148+
open (OUT, ">$config{wikistatedir}/aggregate" ||
149+
die "$config{wikistatedir}/aggregate: $!");
156150
foreach my $data (values %feeds, values %guids) {
157151
if ($data->{remove}) {
158152
if ($data->{name}) {
@@ -193,32 +187,32 @@ sub aggregate () { #{{{
193187
die $@ if $@;
194188

195189
foreach my $feed (values %feeds) {
196-
next unless $IkiWiki::config{rebuild} ||
190+
next unless $config{rebuild} ||
197191
time - $feed->{lastupdate} >= $feed->{updateinterval};
198192
$feed->{lastupdate}=time;
199193
$feed->{newposts}=0;
200194
$IkiWiki::forcerebuild{$feed->{sourcepage}}=1;
201195

202-
IkiWiki::debug("checking feed ".$feed->{name}." ...");
196+
debug("checking feed ".$feed->{name}." ...");
203197

204198
if (! length $feed->{feedurl}) {
205199
my @urls=XML::Feed->find_feeds($feed->{url});
206200
if (! @urls) {
207201
$feed->{message}="could not find feed at ".$feed->{feedurl};
208-
IkiWiki::debug($feed->{message});
202+
debug($feed->{message});
209203
next;
210204
}
211205
$feed->{feedurl}=pop @urls;
212206
}
213207
my $f=eval{XML::Feed->parse(URI->new($feed->{feedurl}))};
214208
if ($@) {
215209
$feed->{message}="feed crashed XML::Feed! $@";
216-
IkiWiki::debug($feed->{message});
210+
debug($feed->{message});
217211
next;
218212
}
219213
if (! $f) {
220214
$feed->{message}=XML::Feed->errstr;
221-
IkiWiki::debug($feed->{message});
215+
debug($feed->{message});
222216
next;
223217
}
224218

@@ -234,7 +228,7 @@ sub aggregate () { #{{{
234228
}
235229

236230
$feed->{message}="processed ok at ".
237-
IkiWiki::displaytime($feed->{lastupdate});
231+
displaytime($feed->{lastupdate});
238232
}
239233

240234
# TODO: expiry
@@ -264,7 +258,7 @@ sub add_page (@) { #{{{
264258
# directory name or trigger ".." disallowing code.
265259
$page=~s!([/.])!"__".ord($1)."__"!eg;
266260
$page=$feed->{dir}."/".$page;
267-
($page)=$page=~/$IkiWiki::config{wiki_file_regexp}/;
261+
($page)=$page=~/$config{wiki_file_regexp}/;
268262
if (! defined $page || ! length $page) {
269263
$page=$feed->{dir}."/item";
270264
}
@@ -274,7 +268,7 @@ sub add_page (@) { #{{{
274268
$c++
275269
}
276270
$guid->{page}=$page;
277-
IkiWiki::debug("creating new page $page");
271+
debug("creating new page $page");
278272
}
279273
$guid->{feed}=$feed->{name};
280274

@@ -284,11 +278,11 @@ sub add_page (@) { #{{{
284278
eval q{use Digest::MD5 'md5_hex'};
285279
require Encode;
286280
my $digest=md5_hex(Encode::encode_utf8($params{content}));
287-
return unless ! exists $guid->{md5} || $guid->{md5} ne $digest || $IkiWiki::config{rebuild};
281+
return unless ! exists $guid->{md5} || $guid->{md5} ne $digest || $config{rebuild};
288282
$guid->{md5}=$digest;
289283

290284
# Create the page.
291-
my $template=IkiWiki::template("aggregatepost.tmpl", blind_cache => 1);
285+
my $template=template("aggregatepost.tmpl", blind_cache => 1);
292286
$template->param(title => $params{title})
293287
if defined $params{title} && length($params{title});
294288
$template->param(content => htmlescape(htmlabs($params{content}, $feed->{feedurl})));
@@ -299,7 +293,7 @@ sub add_page (@) { #{{{
299293
if (ref $feed->{tags}) {
300294
$template->param(tags => [map { tag => $_ }, @{$feed->{tags}}]);
301295
}
302-
IkiWiki::writefile(IkiWiki::htmlpage($guid->{page}), $IkiWiki::config{srcdir},
296+
writefile(htmlpage($guid->{page}), $config{srcdir},
303297
$template->output);
304298

305299
# Set the mtime, this lets the build process get the right creation
@@ -374,7 +368,7 @@ sub remove_feeds () { #{{{
374368
sub pagefile ($) { #{{{
375369
my $page=shift;
376370

377-
return "$IkiWiki::config{srcdir}/".IkiWiki::htmlpage($page);
371+
return "$config{srcdir}/".htmlpage($page);
378372
} #}}}
379373

380374
1

0 commit comments

Comments
 (0)