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");
19 # ... and transient as somewhere to put our internal pages
20 IkiWiki
::loadplugin
("transient");
29 recentchangespage
=> {
31 example
=> "recentchanges",
32 description
=> "name of the recentchanges page",
39 description
=> "number of changes to track",
46 $config{recentchangespage
}='recentchanges' unless defined $config{recentchangespage
};
47 $config{recentchangesnum
}=100 unless defined $config{recentchangesnum
};
54 foreach my $change (IkiWiki
::rcs_recentchanges
($config{recentchangesnum
})) {
55 $seen{store
($change, $config{recentchangespage
})}=1;
58 # delete old and excess changes
59 foreach my $page (keys %pagesources) {
60 if ($pagesources{$page} =~ /\._change$/ && ! $seen{$page}) {
61 unlink($IkiWiki::Plugin
::transient
::transientdir
.'/'.$pagesources{$page}) || unlink($config{srcdir
}.'/'.$pagesources{$page});
67 my ($q, $session) = @_;
68 my $do = $q->param('do');
69 my $rev = $q->param('rev');
71 return unless $do eq 'revert' && $rev;
73 my @changes=$IkiWiki::hooks
{rcs
}{rcs_preprevert
}{call
}->($rev);
74 IkiWiki
::check_canchange
(
80 eval q{use CGI::FormBuilder};
82 my $form = CGI
::FormBuilder
->new(
89 action
=> IkiWiki
::cgiurl
(),
91 template
=> { template
('revert.tmpl') },
92 fields
=> [qw{revertmessage
do sid rev
}],
94 my $buttons=["Revert", "Cancel"];
96 $form->field(name
=> "revertmessage", type
=> "text", size
=> 80);
97 $form->field(name
=> "sid", type
=> "hidden", value
=> $session->id,
99 $form->field(name
=> "do", type
=> "hidden", value
=> "revert",
102 IkiWiki
::decode_form_utf8
($form);
104 if ($form->submitted eq 'Revert' && $form->validate) {
105 IkiWiki
::checksessionexpiry
($q, $session, $q->param('sid'));
106 my $message=sprintf(gettext
("This reverts commit %s"), $rev);
107 if (defined $form->field('revertmessage') &&
108 length $form->field('revertmessage')) {
109 $message=$form->field('revertmessage')."\n\n".$message;
111 my $r = $IkiWiki::hooks
{rcs
}{rcs_revert
}{call
}->($rev);
112 error
$r if defined $r;
113 IkiWiki
::disable_commit_hook
();
114 IkiWiki
::rcs_commit_staged
(
118 IkiWiki
::enable_commit_hook
();
120 require IkiWiki
::Render
;
122 IkiWiki
::saveindex
();
124 elsif ($form->submitted ne 'Cancel') {
125 $form->title(sprintf(gettext
("confirm reversion of %s"), $rev));
126 $form->tmpl_param(diff
=> encode_entities
(scalar IkiWiki
::rcs_diff
($rev, 200)));
127 $form->field(name
=> "rev", type
=> "hidden", value
=> $rev, force
=> 1);
128 IkiWiki
::showform
($form, $buttons, $session, $q);
132 IkiWiki
::redirect
($q, urlto
($config{recentchangespage
}));
136 # Enable the recentchanges link.
137 sub pagetemplate
(@
) {
139 my $template=$params{template
};
140 my $page=$params{page
};
142 if (defined $config{recentchangespage
} && $config{rcs
} &&
143 $template->query(name
=> "recentchangesurl") &&
144 $page ne $config{recentchangespage
}) {
145 $template->param(recentchangesurl
=> urlto
($config{recentchangespage
}, $page));
146 $template->param(have_actions
=> 1);
150 # Pages with extension _change have plain html markup, pass through.
153 return $params{content
};
159 my $page="$config{recentchangespage}/change_".titlepage
($change->{rev
});
161 # Optimisation to avoid re-writing pages. Assumes commits never
162 # change (or that any changes are not important).
163 return $page if exists $pagesources{$page} && ! $config{rebuild
};
165 # Limit pages to first 10, and add links to the changed pages.
166 my $is_excess = exists $change->{pages
}[10];
167 delete @
{$change->{pages
}}[10 .. @
{$change->{pages
}}] if $is_excess;
170 if (length $config{cgiurl
}) {
171 $_->{link} = "<a href=\"".
176 "\" rel=\"nofollow\">".
177 pagetitle
($_->{page
}).
181 $_->{link} = pagetitle
($_->{page
});
185 } @
{$change->{pages
}}
187 push @
{$change->{pages
}}, { link => '...' } if $is_excess;
189 if (length $config{cgiurl
} &&
190 exists $IkiWiki::hooks
{rcs
}{rcs_preprevert
} &&
191 exists $IkiWiki::hooks
{rcs
}{rcs_revert
}) {
192 $change->{reverturl
} = IkiWiki
::cgiurl
(
194 rev
=> $change->{rev
}
198 $change->{author
}=$change->{user
};
199 my $oiduser=eval { IkiWiki
::openiduser
($change->{user
}) };
200 if (defined $oiduser) {
201 $change->{authorurl
}=$change->{user
};
202 $change->{user
}=defined $change->{nickname
} ?
$change->{nickname
} : $oiduser;
204 elsif (length $config{cgiurl
}) {
205 $change->{authorurl
} = IkiWiki
::cgiurl
(
207 page
=> IkiWiki
::userpage
($change->{author
}),
211 if (ref $change->{message
}) {
212 foreach my $field (@
{$change->{message
}}) {
213 if (exists $field->{line
}) {
215 $field->{line
} = encode_entities
($field->{line
});
216 # escape links and preprocessor stuff
217 $field->{line
} = encode_entities
($field->{line
}, '\[\]');
222 # Fill out a template with the change info.
223 my $template=template
("change.tmpl", blind_cache
=> 1);
226 commitdate
=> displaytime
($change->{when}, "%X %x"),
227 wikiname
=> $config{wikiname
},
230 $template->param(permalink
=> urlto
($config{recentchangespage
})."#change-".titlepage
($change->{rev
}))
231 if exists $config{url
};
233 IkiWiki
::run_hooks
(pagetemplate
=> sub {
234 shift->(page
=> $page, destpage
=> $page,
235 template
=> $template, rev
=> $change->{rev
});
238 my $file=$page."._change";
239 writefile
($file, $IkiWiki::Plugin
::transient
::transientdir
, $template->output);
240 utime $change->{when}, $change->{when}, $IkiWiki::Plugin
::transient
::transientdir
.'/'.$file;