return @ret;
}
+# URL to top of wiki as a path starting with /, valid from any wiki page or
+# the CGI; if that's not possible, an absolute URL. Either way, it ends with /
+my $local_url;
+# URL to CGI script, similar to $local_url
+my $local_cgiurl;
+
sub checkconfig () {
# locale stuff; avoid LC_ALL since it overrides everything
if (defined $ENV{LC_ALL}) {
if ($config{cgi} && ! length $config{url}) {
error(gettext("Must specify url to wiki with --url when using --cgi"));
}
-
+
+ if (defined $config{url} && length $config{url}) {
+ eval q{use URI};
+ my $baseurl = URI->new($config{url});
+
+ $local_url = $baseurl->path . "/";
+ $local_cgiurl = undef;
+
+ if (length $config{cgiurl}) {
+ my $cgiurl = URI->new($config{cgiurl});
+
+ $local_cgiurl = $cgiurl->path;
+
+ if ($cgiurl->scheme ne $baseurl->scheme or
+ $cgiurl->authority ne $baseurl->authority) {
+ # too far apart, fall back to absolute URLs
+ $local_url = "$config{url}/";
+ $local_cgiurl = $config{cgiurl};
+ }
+ }
+
+ $local_url =~ s{//$}{/};
+ }
+ else {
+ $local_cgiurl = $config{cgiurl};
+ }
+
$config{wikistatedir}="$config{srcdir}/.ikiwiki"
unless exists $config{wikistatedir} && defined $config{wikistatedir};
return (srcfile_stat(@_))[0];
}
-sub add_underlay ($) {
+sub add_literal_underlay ($) {
my $dir=shift;
- if ($dir !~ /^\//) {
- $dir="$config{underlaydirbase}/$dir";
- }
-
if (! grep { $_ eq $dir } @{$config{underlaydirs}}) {
unshift @{$config{underlaydirs}}, $dir;
}
+}
+
+sub add_underlay ($) {
+ my $dir = shift;
+
+ if ($dir !~ /^\//) {
+ $dir="$config{underlaydirbase}/$dir";
+ }
+ add_literal_underlay($dir);
+ # why does it return 1? we just don't know
return 1;
}
sub cgiurl (@) {
my %params=@_;
- my $cgiurl=$config{cgiurl};
+ my $cgiurl=$local_cgiurl;
+
if (exists $params{cgiurl}) {
$cgiurl=$params{cgiurl};
delete $params{cgiurl};
}
+
+ unless (%params) {
+ return $cgiurl;
+ }
+
return $cgiurl."?".
join("&", map $_."=".uri_escape_utf8($params{$_}), keys %params);
}
sub baseurl (;$) {
my $page=shift;
- return "$config{url}/" if ! defined $page;
+ return $local_url if ! defined $page;
$page=htmlpage($page);
$page=~s/[^\/]+$//;
return $page;
}
+sub urlabs ($$) {
+ my $url=shift;
+ my $urlbase=shift;
+
+ return $url unless defined $urlbase && length $urlbase;
+
+ eval q{use URI};
+ URI->new_abs($url, $urlbase)->as_string;
+}
+
sub abs2rel ($$) {
# Work around very innefficient behavior in File::Spec if abs2rel
# is passed two relative paths. It's much faster if paths are
return $url;
}
-sub urlto ($$;$) {
+sub urlto ($;$$) {
my $to=shift;
my $from=shift;
my $absolute=shift;
if (! length $to) {
- return beautify_urlpath(baseurl($from)."index.$config{htmlext}");
+ $to = 'index';
}
if (! $destsources{$to}) {
return $config{url}.beautify_urlpath("/".$to);
}
+ if (! defined $from) {
+ my $u = $local_url || '';
+ $u =~ s{/$}{};
+ return $u.beautify_urlpath("/".$to);
+ }
+
my $link = abs2rel($to, dirname(htmlpage($from)));
return beautify_urlpath($link);
},
loop_context_vars => 1,
die_on_bad_params => 0,
+ parent_global_vars => 1,
filename => $filename,
@_,
($untrusted ? (no_includes => 1) : ()),
template_depends(shift, undef, @_);
}
-sub misctemplate ($$;@) {
- my $title=shift;
- my $content=shift;
- my %params=@_;
-
- my $template=template("page.tmpl");
-
- my $page="";
- if (exists $params{page}) {
- $page=delete $params{page};
- }
- run_hooks(pagetemplate => sub {
- shift->(
- page => $page,
- destpage => $page,
- template => $template,
- );
- });
- templateactions($template, "");
-
- $template->param(
- dynamic => 1,
- title => $title,
- wikiname => $config{wikiname},
- content => $content,
- baseurl => baseurl(),
- html5 => $config{html5},
- %params,
- );
-
- return $template->output;
-}
-
sub templateactions ($$) {
my $template=shift;
my $page=shift;
$hooks{rcs}{rcs_recentchanges}{call}->(@_);
}
-sub rcs_diff ($) {
+sub rcs_diff ($;$) {
$hooks{rcs}{rcs_diff}{call}->(@_);
}
my $re=quotemeta(shift);
$re=~s/\\\*/.*/g;
$re=~s/\\\?/./g;
- return $re;
+ return qr/^$re$/i;
}
package IkiWiki::FailReason;
return $path;
}
+my %glob_cache;
+
sub match_glob ($$;@) {
my $page=shift;
my $glob=shift;
$glob=derel($glob, $params{location});
- my $regexp=IkiWiki::glob2re($glob);
- if ($page=~/^$regexp$/i) {
+ # Instead of converting the glob to a regex every time,
+ # cache the compiled regex to save time.
+ my $re=$glob_cache{$glob};
+ unless (defined $re) {
+ $glob_cache{$glob} = $re = IkiWiki::glob2re($glob);
+ }
+ if ($page =~ $re) {
if (! IkiWiki::isinternal($page) || $params{internal}) {
return IkiWiki::SuccessReason->new("$glob matches $page");
}
return IkiWiki::ErrorReason->new("no user specified");
}
- if (defined $params{user} && $params{user}=~/^$regexp$/i) {
+ if (defined $params{user} && $params{user}=~$regexp) {
return IkiWiki::SuccessReason->new("user is $user");
}
elsif (! defined $params{user}) {