]> sipb.mit.edu Git - ikiwiki.git/blob - IkiWiki/Plugin/goto.pm
avoid redir loop when going to an internal page that has no permalink
[ikiwiki.git] / IkiWiki / Plugin / goto.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::goto;
3
4 use warnings;
5 use strict;
6 use IkiWiki 3.00;
7
8 sub import {
9         hook(type => "cgi", id => 'goto',  call => \&cgi);
10 }
11
12 sub getsetup () {
13         return
14                 plugin => {
15                         safe => 1,
16                         rebuild => 0,
17                         section => "web",
18                 }
19 }
20
21 # cgi_goto(CGI, [page])
22 # Redirect to a specified page, or display "not found". If not specified,
23 # the page param from the CGI object is used.
24 sub cgi_goto ($;$) {
25         my $q = shift;
26         my $page = shift;
27
28         if (!defined $page) {
29                 $page = IkiWiki::decode_utf8($q->param("page"));
30
31                 if (!defined $page) {
32                         error("missing page parameter");
33                 }
34         }
35
36         # It's possible that $page is not a valid page name;
37         # if so attempt to turn it into one.
38         if ($page !~ /$config{wiki_file_regexp}/) {
39                 $page=titlepage($page);
40         }
41
42         IkiWiki::loadindex();
43
44         my $link;
45         if (! IkiWiki::isinternal($page)) {
46                 $link = bestlink("", $page);
47         }
48         elsif (defined $pagestate{$page}{meta}{permalink}) {
49                 # Can only redirect to an internal page if it has a
50                 # permalink.
51                 IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
52         }
53
54         if (! length $link) {
55                 IkiWiki::cgi_custom_failure(
56                         $q,
57                         "404 Not Found",
58                         IkiWiki::misctemplate(gettext("missing page"),
59                                 "<p>".
60                                 sprintf(gettext("The page %s does not exist."),
61                                         htmllink("", "", $page)).
62                                 "</p>")
63                 )
64         }
65         else {
66                 IkiWiki::redirect($q, urlto($link, undef, 1));
67         }
68
69         exit;
70 }
71
72 sub cgi ($) {
73         my $cgi=shift;
74         my $do = $cgi->param('do');
75
76         if (defined $do && ($do eq 'goto' || $do eq 'commenter' ||
77                                $do eq 'recentchanges_link')) {
78                 # goto is the preferred name for this; recentchanges_link and
79                 # commenter are for compatibility with any saved URLs
80                 cgi_goto($cgi);
81         }
82 }
83
84 1;