3 use vars qw(@ISA @EXPORT_OK);
6 @EXPORT_OK = qw(generate_article generate_all generate_button
8 use Constants qw($CONTENTBASE $GENERATE_BUTTON $SHOPID $AUTO_GENERATE);
10 use BSE::WebUtil qw(refresh_to_admin);
12 # returns non-zero if the Regenerate button should work
14 if ($GENERATE_BUTTON) {
15 if (my $ref = ref $GENERATE_BUTTON) {
17 return $GENERATE_BUTTON->();
20 # assumed to be an object
21 return $GENERATE_BUTTON->want_button();
31 # regenerate an individual article
33 my ($articles, $article, $cfg) = @_;
35 $cfg ||= BSE::Cfg->new;
36 my $genname = $article->{generator};
39 my $gen = $genname->new(articles=>$articles, cfg=>$cfg, top=>$article);
41 my $outname = $article->{link};
42 $outname =~ s!/\w*$!!;
43 $outname =~ s{^\w+://[\w.-]+(?::\d+)?}{};
44 $outname = $CONTENTBASE . $outname;
46 my $content = $gen->generate($article, $articles);
47 my $tempname = $outname . ".work";
49 open OUT, "> $tempname" or die "Cannot create $tempname: $!";
50 print OUT $content or die "Cannot write content to $outname: $!";
51 close OUT or die "Cannot close $outname: $!";
53 rename($tempname, $outname)
54 or die "Cannot rename $tempname to $outname: $!";
57 sub generate_article {
58 my ($articles, $article, $cfg) = @_;
61 generate_low($articles, $article, $cfg)
62 if $article->{link} && $article->{template};
64 if ($article->{parentid} != -1) {
65 $article = $articles->getByPkey($article->{parentid});
73 # generates search.tmpl from search_base.tmpl
75 my ($articles, $cfg) = @_;
77 $cfg or confess "Call generate search with a config object";
79 # build a dummy article
80 use Constants qw($SEARCH_TITLE $SEARCH_TITLE_IMAGE $CGI_URI);
81 my %article = map { $_, '' } Article->columns;
82 @article{qw(id parentid title titleImage displayOrder link level listed)} =
83 (-1, -1, $SEARCH_TITLE, $SEARCH_TITLE_IMAGE, 0, $CGI_URI."/search.pl", 0, 1);
85 require 'Generate/Article.pm';
86 my $gen = Generate::Article->new(cfg=>$cfg, top => \%article);
89 %acts = $gen->baseActs($articles, \%acts, \%article);
90 my $content = BSE::Template->get_page('search_base', $cfg, \%acts);
91 my $tmpldir = $cfg->entryVar('paths', 'templates');
92 my $outname = "$tmpldir/search.tmpl.work";
93 my $finalname = "$tmpldir/search.tmpl";
94 open OUT, "> $outname"
95 or die "Cannot open $outname for write: $!";
97 or die "Cannot write to $outname: $!";
99 or die "Cannot close $outname: $!";
100 rename $outname, $finalname
101 or die "Cannot rename $outname to $finalname: $!";
108 'cart', 'checkout', 'checkoutfinal', 'checkoutcard', 'checkoutconfirm',
110 require 'Generate/Article.pm';
111 my $shop = $articles->getByPkey($SHOPID);
112 my $cfg = BSE::Cfg->new;
113 my $gen = Generate::Article->new(cfg=>$cfg, top=>$shop);
114 for my $name (@pages) {
116 %acts = $gen->baseActs($articles, \%acts, $shop);
117 # different url behaviour - point the user at the http version
118 # of the site if the url contains no scheme
119 my $oldurl = $acts{url};
122 my $value = $oldurl->(@_);
123 unless ($value =~ /^\w+:/) {
124 # put in the base site url
125 $value = $cfg->entryErr('site', 'url').$value;
129 my $content = BSE::Template->get_page("${name}_base", $cfg, \%acts);
130 my $tmpldir = $cfg->entryVar('paths', 'templates');
131 my $outname = "$tmpldir/$name.tmpl.work";
132 my $finalname = "$tmpldir/$name.tmpl";
133 open OUT, "> $outname"
134 or die "Cannot open $outname for write: $!";
136 or die "Cannot write to $outname: $!";
138 or die "Cannot close $outname: $!";
140 rename $outname, $finalname
141 or die "Cannot rename $outname to $finalname: $!";
145 sub generate_extras {
146 my ($articles, $cfg, $callback) = @_;
149 $cfg ||= BSE::Cfg->new;
150 my $template_dir = $cfg->entryVar('paths', 'templates');
152 open EXTRAS, "$template_dir/extras.txt"
158 if (/^(\S+)\s+(\S+)/) {
159 push(@extras, [ $1, $2 ]);
164 require BSE::Template;
165 my $gen = Generate->new(cfg=>$cfg);
166 for my $row (@extras) {
167 my ($in, $out) = @$row;
168 $callback->("$in to $out") if $callback;
170 %acts = $gen->baseActs($articles, \%acts);
171 my $oldurl = $acts{url};
174 my $value = $oldurl->(@_);
175 unless ($value =~ /^\w+:/) {
176 # put in the base site url
177 $value = $cfg->entryErr('site', 'url').$value;
181 my $content = BSE::Template->get_page($in, $cfg, \%acts);
182 my $outname = $CONTENTBASE . $out . ".work";
183 my $finalname = $CONTENTBASE . $out;
184 open OUT, "> $outname"
185 or die "Cannot open $outname for write: $!";
187 or die "Cannot write content to $outname: $!";
189 or die "Cannot close $outname: $!";
191 rename $outname, $finalname
192 or die "Cannot rename $outname to $finalname: $!";
196 my %entries = $cfg->entries('pregenerate');
198 require 'Generate/Article.pm';
199 for my $out (keys %entries) {
200 my ($presets, $input) = split ',', $entries{$out}, 2;
201 $callback->("$input to $out with $presets") if $callback;
202 my %article = map { $_, '' } Article->columns;
203 $article{displayOrder} = 1;
205 $article{parentid} = -1;
206 $article{link} = $cfg->entryErr('site', 'url');
207 for my $field (Article->columns) {
208 if ($cfg->entry("$presets settings", $field)) {
209 $article{$field} = $cfg->entryVar("$presets settings", $field);
213 my $gen = Generate::Article->new(cfg=>$cfg, top=>\%article);
214 %acts = $gen->baseActs($articles, \%acts, \%article);
215 my $oldurl = $acts{url};
218 my $value = $oldurl->(@_);
219 unless ($value =~ /^\w+:/) {
220 # put in the base site url
221 $value = $cfg->entryErr('site', 'url').$value;
225 my $content = BSE::Template->get_page($input, $cfg, \%acts);
226 my $outname = $template_dir .'/'.$out.'.work';
227 my $finalname = $template_dir . '/'. $out;
228 open OUT, "> $outname"
229 or die "Cannot open $outname for write: $!";
231 or die "Cannot write content to $outname: $!";
233 or die "Cannot close $outname: $!";
235 rename $outname, $finalname
236 or die "Cannot rename $outname to $finalname: $!";
242 my ($articles, $cfg, $callback) = @_;
244 my @articleids = $articles->allids;
246 $callback->("Generating articles (".scalar(@articleids)." to do)")
250 Squirrel::Table->caching(1);
252 for my $articleid (@articleids) {
253 my $article = $articles->getByPkey($articleid);
255 if ($article->{link} && $article->{template}) {
256 #$callback->("Article $articleid");
257 generate_low($articles, $article, $cfg);
259 my $newpc = $index / @articleids * 100;
261 if ($callback && $newpc >= $pc + 1 || abs($newpc-100) < 0.01) {
262 $callback->(sprintf("%5d: %.1f%% done - elapsed: %.1f", $articleid, $newpc, $now - $allstart)) if $callback;
267 $callback->("Generating search base") if $callback;
268 generate_search($articles, $cfg);
270 $callback->("Generating shop base pages") if $callback;
271 generate_shop($articles);
273 $callback->("Generating extra pages") if $callback;
274 generate_extras($articles, $cfg, $callback);
276 $callback->("Total of ".(time()-$allstart)." seconds") if $callback;
279 =item regen_and_refresh($articles, $article, $generate, $refreshto, $cfg, $progress)
281 An error checking wrapper around the page regeneration code.
283 In some cases IIS appears to lock the static pages, which was causing
284 various problems. Here we catch the error and let the user know what
287 If $article is set to undef then everything is regenerated.
289 $cfg should be an initialized BSE::Cfg object
291 $progress should be either missing, undef or a code reference.
293 $generate is typically 1 or $AUTO_GENERATE
295 Returns 1 if the regeneration was performed successfully.
299 sub regen_and_refresh {
300 my ($articles, $article, $generate, $refreshto, $cfg, $progress) = @_;
305 if ($article eq 'extras') {
306 $progress->("Generating search base") if $progress;
307 generate_search($articles, $cfg);
309 $progress->("Generating shop base pages") if $progress ;
310 generate_shop($articles);
312 $progress->("Generating extra pages") if $progress;
313 generate_extras($articles, $cfg, $progress);
316 generate_article($articles, $article, $cfg);
320 generate_all($articles, $cfg, $progress);
329 require 'BSE/Util/Tags.pm';
330 require 'BSE/Template.pm';
334 BSE::Util::Tags->basic(\%acts, undef, $cfg),
335 ifArticle => sub { $article },
339 return CGI::escapeHTML($article->{$_[0]});
345 error => sub { CGI::escapeHTML($error) },
347 BSE::Template->show_page('admin/regenerror', $cfg, \%acts);
355 refresh_to_admin($cfg, $refreshto);