2 package IkiWiki
::Plugin
::recentchanges
;
11 hook
(type
=> "getsetup", id
=> "recentchanges", call
=> \
&getsetup
);
12 hook
(type
=> "checkconfig", id
=> "recentchanges", call
=> \
&checkconfig
);
13 hook
(type
=> "refresh", id
=> "recentchanges", call
=> \
&refresh
);
14 hook
(type
=> "pagetemplate", id
=> "recentchanges", call
=> \
&pagetemplate
);
15 hook
(type
=> "htmlize", id
=> "_change", call
=> \
&htmlize
);
16 hook
(type
=> "sessioncgi", id
=> "recentchanges", call
=> \
&sessioncgi
);
17 # Load goto to fix up links from recentchanges
18 IkiWiki
::loadplugin
("goto");
27 recentchangespage
=> {
29 example
=> "recentchanges",
30 description
=> "name of the recentchanges page",
37 description
=> "number of changes to track",
44 $config{recentchangespage
}='recentchanges' unless defined $config{recentchangespage
};
45 $config{recentchangesnum
}=100 unless defined $config{recentchangesnum
};
52 foreach my $change (IkiWiki
::rcs_recentchanges
($config{recentchangesnum
})) {
53 $seen{store
($change, $config{recentchangespage
})}=1;
56 # delete old and excess changes
57 foreach my $page (keys %pagesources) {
58 if ($pagesources{$page} =~ /\._change$/ && ! $seen{$page}) {
59 unlink($config{srcdir
}.'/'.$pagesources{$page});
65 my ($q, $session) = @_;
66 my $do = $q->param('do');
67 my $rev = $q->param('rev');
69 return unless $do eq 'revert' && $rev;
71 my @changes=$IkiWiki::hooks
{rcs
}{rcs_preprevert
}{call
}->($rev);
72 IkiWiki
::check_canchange
(
78 eval q{use CGI::FormBuilder};
80 my $form = CGI
::FormBuilder
->new(
87 action
=> IkiWiki
::cgiurl
(),
89 template
=> { template
('revert.tmpl') },
90 fields
=> [qw{revertmessage
do sid rev
}],
92 my $buttons=["Revert", "Cancel"];
94 $form->field(name
=> "revertmessage", type
=> "text", size
=> 80);
95 $form->field(name
=> "sid", type
=> "hidden", value
=> $session->id,
97 $form->field(name
=> "do", type
=> "hidden", value
=> "revert",
100 IkiWiki
::decode_form_utf8
($form);
102 if ($form->submitted eq 'Revert' && $form->validate) {
103 IkiWiki
::checksessionexpiry
($q, $session, $q->param('sid'));
104 my $message=sprintf(gettext
("This reverts commit %s"), $rev);
105 if (defined $form->field('revertmessage') &&
106 length $form->field('revertmessage')) {
107 $message=$form->field('revertmessage')."\n\n".$message;
109 my $r = $IkiWiki::hooks
{rcs
}{rcs_revert
}{call
}->($rev);
110 error
$r if defined $r;
111 IkiWiki
::disable_commit_hook
();
112 IkiWiki
::rcs_commit_staged
(
116 IkiWiki
::enable_commit_hook
();
118 require IkiWiki
::Render
;
120 IkiWiki
::saveindex
();
122 elsif ($form->submitted ne 'Cancel') {
123 $form->title(sprintf(gettext
("confirm reversion of %s"), $rev));
124 $form->tmpl_param(diff
=> encode_entities
(scalar IkiWiki
::rcs_diff
($rev, 200)));
125 $form->field(name
=> "rev", type
=> "hidden", value
=> $rev, force
=> 1);
126 IkiWiki
::showform
($form, $buttons, $session, $q);
130 IkiWiki
::redirect
($q, urlto
($config{recentchangespage
}));
134 # Enable the recentchanges link.
135 sub pagetemplate
(@
) {
137 my $template=$params{template
};
138 my $page=$params{page
};
140 if (defined $config{recentchangespage
} && $config{rcs
} &&
141 $template->query(name
=> "recentchangesurl") &&
142 $page ne $config{recentchangespage
}) {
143 $template->param(recentchangesurl
=> urlto
($config{recentchangespage
}, $page));
144 $template->param(have_actions
=> 1);
148 # Pages with extension _change have plain html markup, pass through.
151 return $params{content
};
157 my $page="$config{recentchangespage}/change_".titlepage
($change->{rev
});
159 # Optimisation to avoid re-writing pages. Assumes commits never
160 # change (or that any changes are not important).
161 return $page if exists $pagesources{$page} && ! $config{rebuild
};
163 # Limit pages to first 10, and add links to the changed pages.
164 my $is_excess = exists $change->{pages
}[10];
165 delete @
{$change->{pages
}}[10 .. @
{$change->{pages
}}] if $is_excess;
168 if (length $config{cgiurl
}) {
169 $_->{link} = "<a href=\"".
174 "\" rel=\"nofollow\">".
175 pagetitle
($_->{page
}).
179 $_->{link} = pagetitle
($_->{page
});
183 } @
{$change->{pages
}}
185 push @
{$change->{pages
}}, { link => '...' } if $is_excess;
187 if (length $config{cgiurl
} &&
188 exists $IkiWiki::hooks
{rcs
}{rcs_preprevert
} &&
189 exists $IkiWiki::hooks
{rcs
}{rcs_revert
}) {
190 $change->{reverturl
} = IkiWiki
::cgiurl
(
192 rev
=> $change->{rev
}
196 $change->{author
}=$change->{user
};
197 my $oiduser=eval { IkiWiki
::openiduser
($change->{user
}) };
198 if (defined $oiduser) {
199 $change->{authorurl
}=$change->{user
};
200 $change->{user
}=defined $change->{nickname
} ?
$change->{nickname
} : $oiduser;
202 elsif (length $config{cgiurl
}) {
203 $change->{authorurl
} = IkiWiki
::cgiurl
(
205 page
=> IkiWiki
::userpage
($change->{author
}),
209 if (ref $change->{message
}) {
210 foreach my $field (@
{$change->{message
}}) {
211 if (exists $field->{line
}) {
213 $field->{line
} = encode_entities
($field->{line
});
214 # escape links and preprocessor stuff
215 $field->{line
} = encode_entities
($field->{line
}, '\[\]');
220 # Fill out a template with the change info.
221 my $template=template
("change.tmpl", blind_cache
=> 1);
224 commitdate
=> displaytime
($change->{when}, "%X %x"),
225 wikiname
=> $config{wikiname
},
228 $template->param(permalink
=> urlto
($config{recentchangespage
})."#change-".titlepage
($change->{rev
}))
229 if exists $config{url
};
231 IkiWiki
::run_hooks
(pagetemplate
=> sub {
232 shift->(page
=> $page, destpage
=> $page,
233 template
=> $template, rev
=> $change->{rev
});
236 my $file=$page."._change";
237 writefile
($file, $config{srcdir
}, $template->output);
238 utime $change->{when}, $change->{when}, "$config{srcdir}/$file";