blib/lib/Bigtop/Backend/CGI/Gantry.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 57 | 229 | 24.8 |
branch | 0 | 56 | 0.0 |
condition | 0 | 25 | 0.0 |
subroutine | 19 | 31 | 61.2 |
pod | 5 | 5 | 100.0 |
total | 81 | 346 | 23.4 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Bigtop::Backend::CGI::Gantry; | ||||||
2 | |||||||
3 | 1 | 1 | 1899 | use strict; | |||
1 | 2 | ||||||
1 | 38 | ||||||
4 | |||||||
5 | 1 | 1 | 4 | use Bigtop; | |||
1 | 3 | ||||||
1 | 21 | ||||||
6 | 1 | 1 | 594 | use Bigtop::Backend::CGI; | |||
1 | 3 | ||||||
1 | 29 | ||||||
7 | 1 | 1 | 7 | use Inline; | |||
1 | 3 | ||||||
1 | 7 | ||||||
8 | |||||||
9 | sub what_do_you_make { | ||||||
10 | return [ | ||||||
11 | 0 | 0 | 1 | [ 'app.cgi' => 'CGI or FastCGI dispatching script' ], | |||
12 | [ 'app.server' => 'Stand alone Gantry::Server [optional]' ], | ||||||
13 | ]; | ||||||
14 | } | ||||||
15 | |||||||
16 | sub backend_block_keywords { | ||||||
17 | return [ | ||||||
18 | 0 | 0 | 1 | { keyword => 'no_gen', | |||
19 | label => 'No Gen', | ||||||
20 | descr => 'Skip everything for this backend', | ||||||
21 | type => 'boolean' }, | ||||||
22 | |||||||
23 | { keyword => 'fast_cgi', | ||||||
24 | label => 'FastCGI', | ||||||
25 | descr => 'Make the script for use with FastCGI', | ||||||
26 | type => 'boolean' }, | ||||||
27 | |||||||
28 | { keyword => 'gantry_conf', | ||||||
29 | label => 'Use Gantry::Conf', | ||||||
30 | descr => 'check here if you use the Conf Gantry backend', | ||||||
31 | type => 'boolean', }, | ||||||
32 | |||||||
33 | { keyword => 'with_server', | ||||||
34 | label => 'Build Server', | ||||||
35 | descr => 'Turns on stand alone Gantry::Server generation', | ||||||
36 | type => 'boolean' }, | ||||||
37 | |||||||
38 | { keyword => 'server_port', | ||||||
39 | label => 'Server Port', | ||||||
40 | descr => 'Specifies the port for stand alone server ' | ||||||
41 | . '[ignored unless Build Server is checked]', | ||||||
42 | type => 'text' }, | ||||||
43 | |||||||
44 | { keyword => 'gen_root', | ||||||
45 | label => 'Generate Root Path', | ||||||
46 | descr => q!used to make a default root on request, ! | ||||||
47 | . q!now you get defaults by defaul!, | ||||||
48 | type => 'deprecated' }, | ||||||
49 | |||||||
50 | { keyword => 'flex_db', | ||||||
51 | label => 'Database Flexibility', | ||||||
52 | descr => 'Adds command line args to stand alone server to ' | ||||||
53 | . 'allow easy DBD switching', | ||||||
54 | type => 'boolean', | ||||||
55 | default => 'false', }, | ||||||
56 | |||||||
57 | { keyword => 'template', | ||||||
58 | label => 'Alternate Template', | ||||||
59 | descr => 'A custom TT template.', | ||||||
60 | type => 'text' }, | ||||||
61 | |||||||
62 | ]; | ||||||
63 | } | ||||||
64 | |||||||
65 | sub gen_CGI { | ||||||
66 | 0 | 0 | 1 | my $class = shift; | |||
67 | 0 | my $base_dir = shift; | |||||
68 | 0 | my $tree = shift; | |||||
69 | |||||||
70 | 0 | my $configs = $tree->get_app_configs(); | |||||
71 | 0 | 0 | my $fast_cgi = $tree->get_config->{CGI}{fast_cgi} || 0; | ||||
72 | 0 | 0 | my $gantry_conf = $tree->get_config->{CGI}{gantry_conf} || 0; | ||||
73 | |||||||
74 | 0 | my %cgi_conf_types; | |||||
75 | |||||||
76 | 0 | CGI_ONLY_CHECK: | |||||
77 | 0 | foreach my $conf_type ( keys %{ $configs } ) { | |||||
78 | 0 | 0 | $cgi_conf_types{ $conf_type } = 1 if ( $conf_type =~ /^CGI|CGI$/i ); | ||||
79 | } | ||||||
80 | |||||||
81 | 0 | my $there_is_a_cgi = keys %cgi_conf_types; | |||||
82 | |||||||
83 | 0 | CONF_TYPE: | |||||
84 | 0 | foreach my $conf_type ( keys %{ $configs } ) { | |||||
85 | 0 | my $content = $class->output_cgi( | |||||
86 | { | ||||||
87 | tree => $tree, | ||||||
88 | configs => $configs, | ||||||
89 | conf_type => $conf_type, | ||||||
90 | fast_cgi => $fast_cgi, | ||||||
91 | base_dir => $base_dir, | ||||||
92 | } | ||||||
93 | ); | ||||||
94 | |||||||
95 | 0 | my $write_cgi = 1; | |||||
96 | 0 | 0 | my $file_type = ( $conf_type eq 'base' ) ? '' : "$conf_type."; | ||||
97 | 0 | my $server_type = $file_type; | |||||
98 | |||||||
99 | 0 | 0 | if ( $there_is_a_cgi ) { | ||||
100 | 0 | $file_type = $conf_type; | |||||
101 | 0 | 0 | $write_cgi = 0 if ( $file_type !~ s/^CGI|CGI$// ); | ||||
102 | } | ||||||
103 | |||||||
104 | 0 | my $cgi_file = File::Spec->catfile( | |||||
105 | $base_dir, "app.${file_type}cgi" | ||||||
106 | ); | ||||||
107 | |||||||
108 | 0 | 0 | Bigtop::write_file( $cgi_file, $content->{ cgi } ) if $write_cgi; | ||||
109 | |||||||
110 | 0 | chmod 0755, $cgi_file; | |||||
111 | |||||||
112 | 0 | 0 | if ( $tree->get_config->{CGI}{with_server} ) { | ||||
113 | 0 | 0 | 0 | next CONF_TYPE if ( $gantry_conf and $conf_type ne 'base' ); | |||
114 | |||||||
115 | 0 | my $server_file = File::Spec->catfile( | |||||
116 | $base_dir, | ||||||
117 | "app.${server_type}server" | ||||||
118 | ); | ||||||
119 | |||||||
120 | 0 | Bigtop::write_file( $server_file, $content->{ server } ); | |||||
121 | |||||||
122 | 0 | chmod 0755, $server_file; | |||||
123 | } | ||||||
124 | } | ||||||
125 | } | ||||||
126 | |||||||
127 | our $template_is_setup = 0; | ||||||
128 | our $default_template_text = <<'EO_TT_BLOCKS'; | ||||||
129 | [% BLOCK cgi_script %] | ||||||
130 | #![% perl_path +%] | ||||||
131 | use strict; | ||||||
132 | |||||||
133 | [% literal %] | ||||||
134 | |||||||
135 | use CGI::Carp qw( fatalsToBrowser ); | ||||||
136 | |||||||
137 | use [% app_name %] qw{ | ||||||
138 | -Engine=CGI | ||||||
139 | -TemplateEngine=[% template_engine +%] | ||||||
140 | [% IF plugins %] -PluginNamespace=[% app_name +%] | ||||||
141 | [% plugins +%] | ||||||
142 | [% END %] | ||||||
143 | }; | ||||||
144 | |||||||
145 | use Gantry::Engine::CGI; | ||||||
146 | |||||||
147 | my $cgi = Gantry::Engine::CGI->new( { | ||||||
148 | [% config %] | ||||||
149 | [% locs %] | ||||||
150 | } ); | ||||||
151 | |||||||
152 | $cgi->dispatch(); | ||||||
153 | |||||||
154 | if ( $cgi->{config}{debug} ) { | ||||||
155 | foreach ( sort { $a cmp $b } keys %ENV ) { | ||||||
156 | print "$_ $ENV{$_} \n"; |
||||||
157 | } | ||||||
158 | } | ||||||
159 | [% END %][%# end of block cgi_script %] | ||||||
160 | |||||||
161 | [% BLOCK stand_alone_server %] | ||||||
162 | #![% perl_path +%] | ||||||
163 | use strict; | ||||||
164 | |||||||
165 | [% literal %] | ||||||
166 | |||||||
167 | use lib qw( lib ); | ||||||
168 | |||||||
169 | use [% app_name %] qw{ | ||||||
170 | -Engine=CGI | ||||||
171 | -TemplateEngine=[% template_engine +%] | ||||||
172 | Static | ||||||
173 | [% IF plugins %] -PluginNamespace=[% app_name +%] | ||||||
174 | [% plugins +%] | ||||||
175 | [% END %] | ||||||
176 | }; | ||||||
177 | |||||||
178 | [% IF flex_db %] | ||||||
179 | use Getopt::Long; | ||||||
180 | [% END %] | ||||||
181 | use Gantry::Server; | ||||||
182 | use Gantry::Engine::CGI; | ||||||
183 | |||||||
184 | [% IF flex_db %] | ||||||
185 | use Gantry::Conf; | ||||||
186 | |||||||
187 | my $dbd; | ||||||
188 | my $dbuser; | ||||||
189 | my $dbpass; | ||||||
190 | my $dbname; | ||||||
191 | |||||||
192 | my $conf_instance = '[% instance %]'; | ||||||
193 | my $conf_type; | ||||||
194 | my $conf_file = 'docs/app.gantry.conf'; | ||||||
195 | |||||||
196 | GetOptions( | ||||||
197 | 'dbd|d=s' => \$dbd, | ||||||
198 | 'dbuser|u=s' => \$dbuser, | ||||||
199 | 'dbpass|p=s' => \$dbpass, | ||||||
200 | 'dbname|n=s' => \$dbname, | ||||||
201 | 'instance|i=s' => \$conf_instance, | ||||||
202 | 'type|t=s' => \$conf_type, | ||||||
203 | 'file|f=s' => \$conf_file, | ||||||
204 | 'help|h' => \&usage, | ||||||
205 | ); | ||||||
206 | |||||||
207 | if ( $conf_type and $conf_type ne 'base' ) { | ||||||
208 | $conf_instance = "[% instance %]_$conf_type"; | ||||||
209 | } | ||||||
210 | |||||||
211 | my $config = Gantry::Conf->retrieve( | ||||||
212 | { | ||||||
213 | instance => $conf_instance, | ||||||
214 | config_file => $conf_file, | ||||||
215 | } | ||||||
216 | ); | ||||||
217 | |||||||
218 | if ( $dbd or $dbname ) { | ||||||
219 | $dbd ||= 'SQLite'; | ||||||
220 | $config->{ dbconn } = "dbi:$dbd:dbname=$dbname"; | ||||||
221 | } | ||||||
222 | |||||||
223 | $config->{ dbuser } = $dbuser if $dbuser; | ||||||
224 | $config->{ dbpass } = $dbpass if $dbpass; | ||||||
225 | |||||||
226 | my $cgi = Gantry::Engine::CGI->new( { | ||||||
227 | config => $config, | ||||||
228 | [% locs %] | ||||||
229 | } ); | ||||||
230 | [% ELSE %] | ||||||
231 | |||||||
232 | my $cgi = Gantry::Engine::CGI->new( { | ||||||
233 | [% config %] | ||||||
234 | [% locs %] | ||||||
235 | } ); | ||||||
236 | [% END %] | ||||||
237 | |||||||
238 | my $port = shift || [% port || 8080 %]; | ||||||
239 | |||||||
240 | my $server = Gantry::Server->new( $port ); | ||||||
241 | $server->set_engine_object( $cgi ); | ||||||
242 | |||||||
243 | print STDERR "Available urls:\n"; | ||||||
244 | foreach my $url ( sort keys %{ $cgi->{ locations } } ) { | ||||||
245 | print STDERR " http://localhost:${port}$url\n"; | ||||||
246 | } | ||||||
247 | print STDERR "\n"; | ||||||
248 | |||||||
249 | $server->run(); | ||||||
250 | |||||||
251 | [% IF flex_db %] | ||||||
252 | sub usage { | ||||||
253 | print << 'EO_HELP'; | ||||||
254 | usage: app.server [options] [port] | ||||||
255 | port defaults to [% port || 8080 +%] | ||||||
256 | |||||||
257 | options: | ||||||
258 | -h --help prints this message and quits | ||||||
259 | -i --instance name of a Gantry::Conf instance | ||||||
260 | defaults to [% instance +%] | ||||||
261 | -t --type type of one Bigtop config block | ||||||
262 | defaults to the unnamed block | ||||||
263 | -f --file master Gantry::Conf file | ||||||
264 | defaults to docs/app.gantry.conf | ||||||
265 | |||||||
266 | options which override Gantry::Conf values: | ||||||
267 | -d --dbd DBD module name (e.g. Pg, mysql, etc) | ||||||
268 | -n --dbname name of database | ||||||
269 | -u --dbuser database user name | ||||||
270 | -p --dbpass dbuser's database password | ||||||
271 | |||||||
272 | Note that -i and -t are incompatible. The former fully specifies an | ||||||
273 | instance name for Gantry::Conf. The later specifies the config type | ||||||
274 | suffix of an instance name. If you use both, -t takes precedence. | ||||||
275 | |||||||
276 | -d defaults to SQLite. | ||||||
277 | |||||||
278 | EO_HELP | ||||||
279 | |||||||
280 | exit 0; | ||||||
281 | } | ||||||
282 | |||||||
283 | =head1 NAME | ||||||
284 | |||||||
285 | app.server - A generated server for the [% app_name %] app | ||||||
286 | |||||||
287 | =head1 SYNOPSIS | ||||||
288 | |||||||
289 | usage: app.server [options] [port] | ||||||
290 | |||||||
291 | port defaults to 8080 | ||||||
292 | |||||||
293 | =head1 DESCRIPTION | ||||||
294 | |||||||
295 | This is a Gantry::Server based stand alone server for the [% app_name +%] | ||||||
296 | app. It was built to use the [% instance %] Gantry::Conf instance in the | ||||||
297 | docs directory. | ||||||
298 | |||||||
299 | To override the database connection information in your conf file, | ||||||
300 | see L |
||||||
301 | |||||||
302 | To change instances or master conf files, use these | ||||||
303 | flags (they all require values): | ||||||
304 | |||||||
305 | =over 4 | ||||||
306 | |||||||
307 | =item --instance (or -i) | ||||||
308 | |||||||
309 | (Incompatible with --type) | ||||||
310 | |||||||
311 | The full name of your conf instance, defaults to [% instance %]. | ||||||
312 | |||||||
313 | =item --type (or -t) | ||||||
314 | |||||||
315 | (Incompatible with --instance) | ||||||
316 | |||||||
317 | Use this if you use named config blocks in your Bigtop file. Use the | ||||||
318 | name of the config block as the value for --type. This will build the | ||||||
319 | corresponding instance name as [% instance %]_TYPE, where TYPE is the value | ||||||
320 | of this flag. | ||||||
321 | |||||||
322 | If you don't neither --instance nor --type, the instance you get will | ||||||
323 | be [% instance %]. | ||||||
324 | |||||||
325 | =item --file (or -f) | ||||||
326 | |||||||
327 | The name of your master Gantry::Conf file, defaults to docs/app.gantry.conf. | ||||||
328 | |||||||
329 | =back | ||||||
330 | |||||||
331 | =head1 Changing Databases without Changing Conf | ||||||
332 | |||||||
333 | You may use the following flags to control database connections. If you | ||||||
334 | supply these flags, they will take precedence over your Gantry::Conf instance. | ||||||
335 | All of them require values. | ||||||
336 | |||||||
337 | =over 4 | ||||||
338 | |||||||
339 | =item --dbd (or -d) | ||||||
340 | |||||||
341 | The name of your DBD module (like SQLite, Pg, or mysql). If you use | ||||||
342 | dbname, this defaults to SQLite. | ||||||
343 | |||||||
344 | =item --dbname (or -n) | ||||||
345 | |||||||
346 | The name of your database. | ||||||
347 | |||||||
348 | =item --dbuser (or -u) | ||||||
349 | |||||||
350 | Your database user name. | ||||||
351 | |||||||
352 | =item --dbpass (or -p) | ||||||
353 | |||||||
354 | Your database password. | ||||||
355 | |||||||
356 | =back | ||||||
357 | |||||||
358 | =cut | ||||||
359 | [% END %][%# end of if flex_db %] | ||||||
360 | [% END %][%# end of stand_alone_server %] | ||||||
361 | |||||||
362 | [% BLOCK fast_cgi_script %] | ||||||
363 | #![% perl_path +%] | ||||||
364 | use strict; | ||||||
365 | |||||||
366 | use FCGI; | ||||||
367 | use CGI::Carp qw( fatalsToBrowser ); | ||||||
368 | |||||||
369 | use [% app_name %] qw{ | ||||||
370 | -Engine=CGI | ||||||
371 | -TemplateEngine=[% template_engine +%] | ||||||
372 | [% IF plugins %] -PluginNamespace=[% app_name +%] | ||||||
373 | [% plugins +%] | ||||||
374 | [% END %] | ||||||
375 | }; | ||||||
376 | |||||||
377 | use Gantry::Engine::CGI; | ||||||
378 | |||||||
379 | my $cgi = Gantry::Engine::CGI->new( { | ||||||
380 | [% config %] | ||||||
381 | [% locs %] | ||||||
382 | } ); | ||||||
383 | |||||||
384 | my $request = FCGI::Request(); | ||||||
385 | |||||||
386 | while ( $request->Accept() >= 0 ) { | ||||||
387 | |||||||
388 | $cgi->dispatch(); | ||||||
389 | |||||||
390 | if ( $cgi->{config}{debug} ) { | ||||||
391 | foreach ( sort { $a cmp $b } keys %ENV ) { | ||||||
392 | print "$_ $ENV{$_} \n"; |
||||||
393 | } | ||||||
394 | } | ||||||
395 | } | ||||||
396 | [% END %][%# end of block fast_cgi_script %] | ||||||
397 | |||||||
398 | [% BLOCK application_loc %] | ||||||
399 | locations => { | ||||||
400 | '[% location %]' => '[% name %]', | ||||||
401 | [% body %] | ||||||
402 | }, | ||||||
403 | [% END %][%# end of block application_loc %] | ||||||
404 | |||||||
405 | [% BLOCK application_config %] | ||||||
406 | config => { | ||||||
407 | [% body +%] | ||||||
408 | }, | ||||||
409 | [% END %][%# end of block application_config %] | ||||||
410 | |||||||
411 | [% BLOCK controller_block_loc %] | ||||||
412 | [% IF rel_loc %] | ||||||
413 | '[% app_location %]/[% rel_loc %]' => '[% full_name %]', | ||||||
414 | [% ELSE %] | ||||||
415 | '[% abs_loc %]' => '[% full_name %]', | ||||||
416 | [% END %][%# end of if rel_loc %] | ||||||
417 | [% END %] | ||||||
418 | |||||||
419 | [% BLOCK config_body %] | ||||||
420 | [% FOREACH config IN configs %] | ||||||
421 | [% IF config.value.match( '^\d+$' ) %] | ||||||
422 | [% config.name %] => [% config.value %], | ||||||
423 | [% ELSE %] | ||||||
424 | [% config.name %] => '[% config.value %]', | ||||||
425 | [% END %][%# end of if %] | ||||||
426 | [% END %][%# end of foreach %] | ||||||
427 | [% END %][%# end of block config %] | ||||||
428 | |||||||
429 | EO_TT_BLOCKS | ||||||
430 | |||||||
431 | sub setup_template { | ||||||
432 | 0 | 0 | 1 | my $class = shift; | |||
433 | 0 | 0 | my $template_text = shift || $default_template_text; | ||||
434 | |||||||
435 | 0 | 0 | return if ( $template_is_setup ); | ||||
436 | |||||||
437 | 0 | Inline->bind( | |||||
438 | TT => $template_text, | ||||||
439 | POST_CHOMP => 1, | ||||||
440 | TRIM_LEADING_SPACE => 0, | ||||||
441 | TRIM_TRAILING_SPACE => 0, | ||||||
442 | ); | ||||||
443 | |||||||
444 | 0 | $template_is_setup = 1; | |||||
445 | } | ||||||
446 | |||||||
447 | sub output_cgi { | ||||||
448 | 0 | 0 | 1 | my $class = shift; | |||
449 | 0 | my $opts = shift; | |||||
450 | 0 | my $tree = $opts->{ tree }; | |||||
451 | 0 | my $fast_cgi = $opts->{ fast_cgi }; | |||||
452 | 0 | my $conf_type = $opts->{ conf_type }; | |||||
453 | 0 | my $configs = $opts->{ configs }; | |||||
454 | |||||||
455 | # first find the base location | ||||||
456 | 0 | my $location_output = $tree->walk_postorder( 'output_location' ); | |||||
457 | 0 | 0 | my $location = $location_output->[0] || ''; # default to host root | ||||
458 | |||||||
459 | 0 | $location =~ s{/+$}{}; | |||||
460 | |||||||
461 | # now build the config and locations hashes | ||||||
462 | 0 | my $config; | |||||
463 | my $stand_alone_config; | ||||||
464 | 0 | my $locations = $tree->walk_postorder( 'output_cgi_locations', $location ); | |||||
465 | 0 | my $literals = $tree->walk_postorder( 'output_literal' ); | |||||
466 | 0 | my $app_name = $tree->get_appname(); | |||||
467 | |||||||
468 | 0 | my $literal = join "\n", @{ $literals }; | |||||
0 | |||||||
469 | |||||||
470 | 0 | my $backend_block = $tree->get_config->{CGI}; | |||||
471 | |||||||
472 | 0 | my $gconf = $backend_block->{ gantry_conf }; | |||||
473 | 0 | my $instance; | |||||
474 | my $conffile; | ||||||
475 | |||||||
476 | 0 | 0 | if ( $gconf ) { | ||||
477 | 0 | my $gantry_conf_block = $tree->get_config->{ Conf }; | |||||
478 | 0 | $instance = $gantry_conf_block->{ instance }; | |||||
479 | 0 | $conffile = $gantry_conf_block->{ conffile }; | |||||
480 | } | ||||||
481 | |||||||
482 | 0 | 0 | $instance ||= $backend_block->{ instance }; | ||||
483 | 0 | 0 | $conffile ||= $backend_block->{ conffile }; | ||||
484 | |||||||
485 | 0 | 0 | if ( $instance ) { | ||||
486 | 0 | 0 | $instance .= "_$conf_type" unless $conf_type eq 'base'; | ||||
487 | 0 | my $conffile_text = ''; | |||||
488 | 0 | 0 | if ( $conffile ) { | ||||
489 | 0 | $conffile_text = ' ' x 8 | |||||
490 | . "GantryConfFile => '$conffile',"; | ||||||
491 | } | ||||||
492 | $config = | ||||||
493 | 0 | " config => { | |||||
494 | GantryConfInstance => '$instance', | ||||||
495 | $conffile_text | ||||||
496 | }, | ||||||
497 | "; | ||||||
498 | 0 | 0 | if ( $backend_block->{ flex_db } ) { | ||||
499 | 0 | $stand_alone_config = | |||||
500 | ' config => { | ||||||
501 | GantryConfInstance => $conf_instance, | ||||||
502 | GantryConfFile => $conf_file, | ||||||
503 | },' . "\n"; | ||||||
504 | } | ||||||
505 | else { | ||||||
506 | 0 | $stand_alone_config = $config; | |||||
507 | } | ||||||
508 | } | ||||||
509 | else { | ||||||
510 | my $config_output = $tree->walk_postorder( | ||||||
511 | 'output_config', | ||||||
512 | { | ||||||
513 | backend_block => $backend_block, | ||||||
514 | conf_type => $conf_type, | ||||||
515 | configs => $configs, | ||||||
516 | base_dir => $opts->{ base_dir }, | ||||||
517 | } | ||||||
518 | 0 | ); | |||||
519 | |||||||
520 | 0 | my %configs = @{ $config_output }; | |||||
0 | |||||||
521 | |||||||
522 | 0 | $config = $configs{ cgi_config }; | |||||
523 | 0 | $stand_alone_config = $configs{ stand_along_config }; | |||||
524 | } | ||||||
525 | |||||||
526 | 0 | 0 | 0 | if ( $backend_block->{ flex_db } and not $instance ) { | |||
527 | 0 | die "Use of flex_db now requires Conf Gantry backend and " | |||||
528 | . "gantry_conf statement.\n"; | ||||||
529 | } | ||||||
530 | |||||||
531 | 0 | my $port; | |||||
532 | 0 | 0 | $port = $backend_block->{server_port} | ||||
533 | if ( defined $backend_block->{server_port} ); | ||||||
534 | |||||||
535 | 0 | my $cgi_output; | |||||
536 | 0 | my $perl_path = $^X; | |||||
537 | |||||||
538 | 0 | 0 | if ( $fast_cgi ) { | ||||
539 | 0 | $cgi_output = Bigtop::Backend::CGI::Gantry::fast_cgi_script( | |||||
540 | { | ||||||
541 | config => $config, | ||||||
542 | 0 | locs => join( '', @{ $locations } ), | |||||
543 | app_name => $app_name, | ||||||
544 | literal => $literal, | ||||||
545 | 0 | %{ $tree->get_config() }, # Go Fish! (think template_engine) | |||||
546 | perl_path => $perl_path, | ||||||
547 | } | ||||||
548 | ); | ||||||
549 | } | ||||||
550 | else { | ||||||
551 | 0 | $cgi_output = Bigtop::Backend::CGI::Gantry::cgi_script( | |||||
552 | { | ||||||
553 | config => $config, | ||||||
554 | 0 | locs => join( '', @{ $locations } ), | |||||
555 | app_name => $app_name, | ||||||
556 | literal => $literal, | ||||||
557 | 0 | %{ $tree->get_config() }, # Go Fish! (think template_engine) | |||||
558 | perl_path => $perl_path, | ||||||
559 | } | ||||||
560 | ); | ||||||
561 | } | ||||||
562 | |||||||
563 | 0 | my $server_output = Bigtop::Backend::CGI::Gantry::stand_alone_server( | |||||
564 | { | ||||||
565 | config => $stand_alone_config, | ||||||
566 | locs => join( '', @{ $locations } ), | ||||||
567 | app_name => $app_name, | ||||||
568 | literal => $literal, | ||||||
569 | port => $port, | ||||||
570 | flex_db => $backend_block->{ flex_db }, | ||||||
571 | 0 | %{ $tree->get_config() }, # Go Fish! (think template_engine) | |||||
0 | |||||||
572 | perl_path => $perl_path, | ||||||
573 | instance => $instance, | ||||||
574 | } | ||||||
575 | ); | ||||||
576 | |||||||
577 | 0 | return { cgi => $cgi_output, server => $server_output }; | |||||
578 | } | ||||||
579 | |||||||
580 | package # application | ||||||
581 | application; | ||||||
582 | 1 | 1 | 2165 | use strict; use warnings; | |||
1 | 1 | 2 | |||||
1 | 30 | ||||||
1 | 7 | ||||||
1 | 2 | ||||||
1 | 25 | ||||||
583 | |||||||
584 | 1 | 1 | 5 | use Cwd; | |||
1 | 2 | ||||||
1 | 599 | ||||||
585 | |||||||
586 | sub output_config { | ||||||
587 | 0 | 0 | my $self = shift; | ||||
588 | 0 | my $child_output = shift; | |||||
589 | 0 | my $data = shift; | |||||
590 | 0 | my $backend_block = $data->{ backend_block }; | |||||
591 | |||||||
592 | # see if there is already a root variable | ||||||
593 | 0 | my $gen_root = 1; | |||||
594 | 0 | CONFIG_VAR: | |||||
595 | 0 | foreach my $var ( @{ $child_output } ) { | |||||
596 | 0 | $var =~ /^\s+(\S+)/; | |||||
597 | 0 | my $var_name = $1; | |||||
598 | 0 | 0 | if ( $var_name eq 'root' ) { | ||||
599 | 0 | $gen_root = 0; | |||||
600 | 0 | last CONFIG_VAR; | |||||
601 | } | ||||||
602 | } | ||||||
603 | |||||||
604 | # if no root, make one no questions asked | ||||||
605 | 0 | 0 | if ( $gen_root ) { | ||||
606 | 0 | my $templates = File::Spec->catdir( qw( html templates ) ); | |||||
607 | |||||||
608 | 0 | 0 | if ( $data->{ conf_type } =~ /^CGI|CGI$/ ) { | ||||
609 | 0 | my $cwd = getcwd(); | |||||
610 | 0 | my $html = File::Spec->catdir( $cwd, $data->{ base_dir }, 'html' ); | |||||
611 | 0 | $templates = File::Spec->catdir( $html, 'templates' ); | |||||
612 | |||||||
613 | 0 | push @{ $child_output }, " root => '$html:$templates',"; | |||||
0 | |||||||
614 | } | ||||||
615 | else { | ||||||
616 | 0 | push @{ $child_output }, " root => 'html:$templates',"; | |||||
0 | |||||||
617 | } | ||||||
618 | } | ||||||
619 | |||||||
620 | 0 | my $output = Bigtop::Backend::CGI::Gantry::application_config( | |||||
621 | { | ||||||
622 | 0 | body => join "\n", @{ $child_output }, | |||||
623 | } | ||||||
624 | ); | ||||||
625 | |||||||
626 | 0 | my @stand_alone_output = @{ $child_output }; | |||||
0 | |||||||
627 | 0 | 0 | if ( $backend_block->{ flex_db } ) { | ||||
628 | 0 | @stand_alone_output = grep ! | |||||
629 | /^\s*GantryConfInstance|^\s*GantryConfFile|/, | ||||||
630 | 0 | @{ $child_output }; | |||||
631 | 0 | unshift @stand_alone_output, | |||||
632 | ' ' x 8 . q!GantryConfInstance => $conf_instance,!, | ||||||
633 | ' ' x 8 . q!GantryConfFile => $conf_file,!; | ||||||
634 | } | ||||||
635 | |||||||
636 | 0 | my $extra_output = Bigtop::Backend::CGI::Gantry::application_config( | |||||
637 | { | ||||||
638 | body => join "\n", @stand_alone_output, | ||||||
639 | } | ||||||
640 | ); | ||||||
641 | |||||||
642 | 0 | return [ cgi_config => $output, stand_along_config => $extra_output ]; | |||||
643 | } | ||||||
644 | |||||||
645 | sub output_cgi_locations { | ||||||
646 | 0 | 0 | my $self = shift; | ||||
647 | 0 | my $child_output = shift; | |||||
648 | 0 | 0 | my $location = shift || '/'; | ||||
649 | |||||||
650 | 0 | my $output = Bigtop::Backend::CGI::Gantry::application_loc( | |||||
651 | { | ||||||
652 | location => $location, | ||||||
653 | name => $self->get_name(), | ||||||
654 | 0 | body => join '', @{ $child_output }, | |||||
655 | } | ||||||
656 | ); | ||||||
657 | |||||||
658 | 0 | return [ $output ]; | |||||
659 | } | ||||||
660 | |||||||
661 | package # app_statement | ||||||
662 | app_statement; | ||||||
663 | 1 | 1 | 6 | use strict; use warnings; | |||
1 | 1 | 3 | |||||
1 | 34 | ||||||
1 | 5 | ||||||
1 | 2 | ||||||
1 | 41 | ||||||
664 | |||||||
665 | package # app_config_block | ||||||
666 | app_config_block; | ||||||
667 | 1 | 1 | 6 | use strict; use warnings; | |||
1 | 1 | 1 | |||||
1 | 24 | ||||||
1 | 4 | ||||||
1 | 2 | ||||||
1 | 282 | ||||||
668 | |||||||
669 | sub output_config { | ||||||
670 | 0 | 0 | my $self = shift; | ||||
671 | 0 | my $child_output = shift; | |||||
672 | 0 | my $data = shift; | |||||
673 | 0 | my $conf_type = $data->{ conf_type }; | |||||
674 | 0 | my $configs = $data->{ configs }; | |||||
675 | |||||||
676 | 0 | 0 | return unless $child_output; | ||||
677 | |||||||
678 | 0 | 0 | my $my_type = $self->{__TYPE__} || 'base'; | ||||
679 | |||||||
680 | 0 | 0 | return unless $my_type eq $conf_type; | ||||
681 | |||||||
682 | 0 | 0 | if ( $my_type ne 'base' ) { | ||||
683 | |||||||
684 | 0 | my %config_set_for; | |||||
685 | |||||||
686 | # see what conf was in the named block | ||||||
687 | 0 | foreach my $conf_item ( @{ $child_output } ) { | |||||
0 | |||||||
688 | 0 | my $var = $conf_item->{ name }; | |||||
689 | |||||||
690 | 0 | $config_set_for{ $var }++; | |||||
691 | } | ||||||
692 | |||||||
693 | # fill in omitted keys from the base block | ||||||
694 | BASE_KEY: | ||||||
695 | 0 | foreach my $base_key ( keys %{ $configs->{ base } } ) { | |||||
0 | |||||||
696 | 0 | 0 | next BASE_KEY if $config_set_for{ $base_key }; | ||||
697 | |||||||
698 | 0 | push @{ $child_output }, { | |||||
699 | name => $base_key, | ||||||
700 | 0 | value => $configs->{ base }{ $base_key } | |||||
701 | }; | ||||||
702 | } | ||||||
703 | } | ||||||
704 | |||||||
705 | 0 | my $output = Bigtop::Backend::CGI::Gantry::config_body( | |||||
706 | { | ||||||
707 | configs => $child_output, | ||||||
708 | } | ||||||
709 | ); | ||||||
710 | |||||||
711 | 0 | my @output = split /\n/, $output; | |||||
712 | |||||||
713 | 0 | return \@output; | |||||
714 | } | ||||||
715 | |||||||
716 | package # app_config_statement | ||||||
717 | app_config_statement; | ||||||
718 | 1 | 1 | 6 | use strict; use warnings; | |||
1 | 1 | 3 | |||||
1 | 56 | ||||||
1 | 6 | ||||||
1 | 2 | ||||||
1 | 79 | ||||||
719 | |||||||
720 | sub output_config { | ||||||
721 | 0 | 0 | my $self = shift; | ||||
722 | |||||||
723 | 0 | my $output_vals = $self->{__ARGS__}->get_args(); | |||||
724 | |||||||
725 | 0 | return [ { name => $self->{__KEYWORD__}, value => $output_vals } ]; | |||||
726 | } | ||||||
727 | |||||||
728 | package # controller_block | ||||||
729 | controller_block; | ||||||
730 | 1 | 1 | 5 | use strict; use warnings; | |||
1 | 1 | 1 | |||||
1 | 20 | ||||||
1 | 5 | ||||||
1 | 2 | ||||||
1 | 153 | ||||||
731 | |||||||
732 | sub output_cgi_locations { | ||||||
733 | 0 | 0 | my $self = shift; | ||||
734 | 0 | my $child_output = shift; | |||||
735 | 0 | my $location = shift; | |||||
736 | |||||||
737 | 0 | 0 | return if $self->is_base_controller(); | ||||
738 | |||||||
739 | 0 | my %child_loc = @{ $child_output }; | |||||
0 | |||||||
740 | |||||||
741 | 0 | 0 | if ( keys %child_loc != 1 ) { | ||||
742 | 0 | die "Error: controller '" . $self->get_name() | |||||
743 | . "' must have one location or rel_location statement.\n"; | ||||||
744 | } | ||||||
745 | |||||||
746 | 0 | my $app = $self->{__PARENT__}{__PARENT__}{__PARENT__}; | |||||
747 | 0 | my $full_name = $app->get_name() . '::' . $self->get_name(); | |||||
748 | |||||||
749 | 0 | my $output = Bigtop::Backend::CGI::Gantry::controller_block_loc( | |||||
750 | { | ||||||
751 | full_name => $full_name, | ||||||
752 | rel_loc => $child_loc{rel_location}, | ||||||
753 | abs_loc => $child_loc{location}, | ||||||
754 | app_location => $location, | ||||||
755 | } | ||||||
756 | ); | ||||||
757 | |||||||
758 | 0 | return [ $output ]; | |||||
759 | } | ||||||
760 | |||||||
761 | # controller_statement | ||||||
762 | |||||||
763 | package # controller_statement | ||||||
764 | controller_statement; | ||||||
765 | 1 | 1 | 4 | use strict; use warnings; | |||
1 | 1 | 1 | |||||
1 | 21 | ||||||
1 | 4 | ||||||
1 | 2 | ||||||
1 | 97 | ||||||
766 | |||||||
767 | sub output_cgi_locations { | ||||||
768 | 0 | 0 | my $self = shift; | ||||
769 | |||||||
770 | 0 | 0 | if ( $self->{__KEYWORD__} eq 'rel_location' ) { | ||||
0 | |||||||
771 | 0 | return [ rel_location => $self->{__ARGS__}->get_first_arg() ]; | |||||
772 | } | ||||||
773 | elsif ( $self->{__KEYWORD__} eq 'location' ) { | ||||||
774 | 0 | return [ location => $self->{__ARGS__}->get_first_arg() ]; | |||||
775 | } | ||||||
776 | else { | ||||||
777 | 0 | return; | |||||
778 | } | ||||||
779 | |||||||
780 | } | ||||||
781 | |||||||
782 | package # literal_block | ||||||
783 | literal_block; | ||||||
784 | 1 | 1 | 5 | use strict; use warnings; | |||
1 | 1 | 1 | |||||
1 | 23 | ||||||
1 | 5 | ||||||
1 | 1 | ||||||
1 | 66 | ||||||
785 | |||||||
786 | sub output_literal { | ||||||
787 | 0 | 0 | my $self = shift; | ||||
788 | |||||||
789 | 0 | return $self->make_output( 'PerlTop' ); | |||||
790 | } | ||||||
791 | |||||||
792 | 1; | ||||||
793 | |||||||
794 | =head1 NAME | ||||||
795 | |||||||
796 | Bigtop::CGI::Backend::Gantry - CGI dispatch script generator for the Gantry framework | ||||||
797 | |||||||
798 | =head1 SYNOPSIS | ||||||
799 | |||||||
800 | If your bigtop file includes: | ||||||
801 | |||||||
802 | config { | ||||||
803 | CGI Gantry { | ||||||
804 | # optional statements: | ||||||
805 | # to get a stand alone server: | ||||||
806 | with_server 1; | ||||||
807 | # to use FastCGI instead of regular CGI: | ||||||
808 | fast_cgi 1; | ||||||
809 | } | ||||||
810 | } | ||||||
811 | |||||||
812 | and there are controllers in your app section, this module will generate | ||||||
813 | app.cgi when you type: | ||||||
814 | |||||||
815 | bigtop app.bigtop CGI | ||||||
816 | |||||||
817 | or | ||||||
818 | |||||||
819 | bigtop app.bigtop all | ||||||
820 | |||||||
821 | You can then directly point your httpd.conf directly to the generated | ||||||
822 | app.cgi. | ||||||
823 | |||||||
824 | =head1 DESCRIPTION | ||||||
825 | |||||||
826 | This is a Bigtop backend which generates cgi dispatching scripts for Gantry | ||||||
827 | supported apps. | ||||||
828 | |||||||
829 | =head1 KEYWORDS | ||||||
830 | |||||||
831 | This module does not register any keywords. See Bigtop::CGI | ||||||
832 | for a list of allowed keywords (think app and controller level 'location' | ||||||
833 | and controller level 'rel_location' statements). | ||||||
834 | |||||||
835 | =head1 METHODS | ||||||
836 | |||||||
837 | To keep podcoverage tests happy. | ||||||
838 | |||||||
839 | =over 4 | ||||||
840 | |||||||
841 | =item backend_block_keywords | ||||||
842 | |||||||
843 | Tells tentmaker that I understand these config section backend block keywords: | ||||||
844 | |||||||
845 | no_gen | ||||||
846 | fast_cgi | ||||||
847 | with_server | ||||||
848 | server_port | ||||||
849 | flex_db | ||||||
850 | gantry_conf | ||||||
851 | template | ||||||
852 | |||||||
853 | instance | ||||||
854 | conffile | ||||||
855 | |||||||
856 | Note that instance and conffile are now deprecated in favor of setting | ||||||
857 | gantry_conf to true, which draws the values from the Conf Gantry backend. | ||||||
858 | You may still use them if you like, but that may change in the future. | ||||||
859 | |||||||
860 | =item what_do_you_make | ||||||
861 | |||||||
862 | Tells tentmaker what this module makes. Summary: app.server and app.cgi. | ||||||
863 | |||||||
864 | =item gen_CGI | ||||||
865 | |||||||
866 | Called by Bigtop::Parser to get me to do my thing. | ||||||
867 | |||||||
868 | =item output_cgi | ||||||
869 | |||||||
870 | What I call on the various AST packages to do my thing. | ||||||
871 | |||||||
872 | =item setup_template | ||||||
873 | |||||||
874 | Called by Bigtop::Parser so the user can substitute an alternate template | ||||||
875 | for the hard coded one here. | ||||||
876 | |||||||
877 | =back | ||||||
878 | |||||||
879 | =head1 AUTHOR | ||||||
880 | |||||||
881 | Phil Crow |
||||||
882 | |||||||
883 | =head1 COPYRIGHT and LICENSE | ||||||
884 | |||||||
885 | Copyright (C) 2005 by Phil Crow | ||||||
886 | |||||||
887 | This library is free software; you can redistribute it and/or modify | ||||||
888 | it under the same terms as Perl itself, either Perl version 5.8.6 or, | ||||||
889 | at your option, any later version of Perl 5 you may have available. | ||||||
890 | |||||||
891 | =cut |