Search a list of potential template directories, including the project base.
[catagits/Catalyst-Devel.git] / lib / Catalyst / Helper.pm
CommitLineData
68ccb5e5 1package Catalyst::Helper;
957ccd4d 2use Moose;
68ccb5e5 3use Config;
4use File::Spec;
18b4b23e 5use File::Spec::Unix;
68ccb5e5 6use File::Path;
68ccb5e5 7use FindBin;
2415f774 8use IO::File;
9use POSIX 'strftime';
68ccb5e5 10use Template;
9ffb6b83 11use Catalyst::Devel;
68ccb5e5 12use Catalyst::Utils;
13use Catalyst::Exception;
afd739f1 14use Path::Class qw/dir file/;
15use File::ShareDir qw/dist_dir/;
957ccd4d 16use namespace::autoclean;
68ccb5e5 17
dcc30470 18with 'MooseX::Emulate::Class::Accessor::Fast';
19
efc787e1 20# Change Catalyst/Devel.pm also
2d8f9d3d 21our $VERSION = '1.23';
efc787e1 22
68ccb5e5 23my %cache;
24
25=head1 NAME
26
27Catalyst::Helper - Bootstrap a Catalyst application
28
29=head1 SYNOPSIS
30
fab70e0a 31 catalyst.pl <myappname>
68ccb5e5 32
33=cut
34
afd739f1 35sub get_sharedir_file {
36 my ($self, @filename) = @_;
d2985b95 37
38 my @try_dirs;
39 if (exists $self->{base}) {
40 push @try_dirs, $self->{base};
41 }
4c709311 42 if (exists $ENV{CATALYST_DEVEL_SHAREDIR}) {
d2985b95 43 push @try_dirs, $ENV{CATALYST_DEVEL_SHAREDIR}
4c709311 44 }
d2985b95 45 if (-d "inc/.author" && -f "lib/Catalyst/Helper.pm"
d7ebca0f 46 ) { # Can't use sharedir if we're in a checkout
47 # this feels horrible, better ideas?
d2985b95 48 push @try_dirs, 'share';
76b106bc 49 }
50 else {
d2985b95 51 push @try_dirs, dist_dir('Catalyst-Devel');
52 }
53
54 my $file;
55 foreach my $dist_dir (@try_dirs) {
56 $file = file( $dist_dir, @filename);
57 last if -r $file;
76b106bc 58 }
f8d3d4e0 59 Carp::confess("Cannot find $file") unless -r $file;
afd739f1 60 my $contents = $file->slurp;
61 return $contents;
62}
63
faae88e5 64# Do not touch this method, *EVER*, it is needed for back compat.
68ccb5e5 65sub get_file {
03082a71 66 my ( $self, $class, $file ) = @_;
67 unless ( $cache{$class} ) {
68 local $/;
69 $cache{$class} = eval "package $class; <DATA>";
70 }
71 my $data = $cache{$class};
0acedf59 72 Carp::confess("Could not get data from __DATA__ segment for $class")
73 unless $data;
03082a71 74 my @files = split /^__(.+)__\r?\n/m, $data;
75 shift @files;
76 while (@files) {
77 my ( $name, $content ) = splice @files, 0, 2;
78 return $content if $name eq $file;
79 }
80 return 0;
68ccb5e5 81}
b4b7c206 82
a73b3971 83
68ccb5e5 84sub mk_app {
fdb9d1d9 85 my ( $self, $name ) = @_;
68ccb5e5 86
87 # Needs to be here for PAR
88 require Catalyst;
89
fdb9d1d9 90 if ( $name =~ /[^\w:]/ || $name =~ /^\d/ || $name =~ /\b:\b|:{3,}/) {
91 warn "Error: Invalid application name.\n";
92 return 0;
93 }
94 $self->{name } = $name;
95 $self->{dir } = $name;
96 $self->{dir } =~ s/\:\:/-/g;
97 $self->{script } = dir( $self->{dir}, 'script' );
98 $self->{appprefix } = Catalyst::Utils::appprefix($name);
99 $self->{appenv } = Catalyst::Utils::class2env($name);
675fef06 100 $self->{startperl } = -r '/usr/bin/env'
101 ? '#!/usr/bin/env perl'
9bc8b354 102 : "#!$Config{perlpath} -w";
2ad36447 103 $self->{scriptgen } = $Catalyst::Devel::CATALYST_SCRIPT_GEN;
902763f2 104 $self->{catalyst_version} = $Catalyst::VERSION;
fdb9d1d9 105 $self->{author } = $self->{author} = $ENV{'AUTHOR'}
106 || eval { @{ [ getpwuid($<) ] }[6] }
107 || 'Catalyst developer';
68ccb5e5 108
109 my $gen_scripts = ( $self->{makefile} ) ? 0 : 1;
110 my $gen_makefile = ( $self->{scripts} ) ? 0 : 1;
111 my $gen_app = ( $self->{scripts} || $self->{makefile} ) ? 0 : 1;
112
113 if ($gen_app) {
420ad692 114 for ( qw/ _mk_dirs _mk_config _mk_appclass _mk_rootclass _mk_readme
115 _mk_changes _mk_apptest _mk_images _mk_favicon/ ) {
116
fdb9d1d9 117 $self->$_;
420ad692 118 }
68ccb5e5 119 }
120 if ($gen_makefile) {
121 $self->_mk_makefile;
122 }
123 if ($gen_scripts) {
420ad692 124 for ( qw/ _mk_cgi _mk_fastcgi _mk_server
28d172c6 125 _mk_test _mk_create _mk_information
126 / ) {
fdb9d1d9 127 $self->$_;
28d172c6 128 }
68ccb5e5 129 }
fdb9d1d9 130 return $self->{dir};
68ccb5e5 131}
132
23f9f145 133## not much of this can really be changed, mk_compclass must be left for
134## backcompat
68ccb5e5 135sub mk_component {
136 my $self = shift;
137 my $app = shift;
138 $self->{app} = $app;
fdb9d1d9 139 $self->{author} = $self->{author} = $ENV{'AUTHOR'}
140 || eval { @{ [ getpwuid($<) ] }[6] }
141 || 'A clever guy';
142 $self->{base} ||= dir( $FindBin::Bin, '..' );
68ccb5e5 143 unless ( $_[0] =~ /^(?:model|view|controller)$/i ) {
144 my $helper = shift;
145 my @args = @_;
146 my $class = "Catalyst::Helper::$helper";
147 eval "require $class";
148
149 if ($@) {
150 Catalyst::Exception->throw(
151 message => qq/Couldn't load helper "$class", "$@"/ );
152 }
153
154 if ( $class->can('mk_stuff') ) {
155 return 1 unless $class->mk_stuff( $self, @args );
156 }
157 }
158 else {
159 my $type = shift;
160 my $name = shift || "Missing name for model/view/controller";
161 my $helper = shift;
162 my @args = @_;
fab70e0a 163 return 0 if $name =~ /[^\w\:]/;
68ccb5e5 164 $type = lc $type;
165 $self->{long_type} = ucfirst $type;
166 $type = 'M' if $type =~ /model/i;
167 $type = 'V' if $type =~ /view/i;
168 $type = 'C' if $type =~ /controller/i;
068587bd 169 my $appdir = dir( split /\:\:/, $app );
68ccb5e5 170 my $test_path =
068587bd 171 dir( $self->{base}, 'lib', $appdir, 'C' );
68ccb5e5 172 $type = $self->{long_type} unless -d $test_path;
173 $self->{type} = $type;
174 $self->{name} = $name;
175 $self->{class} = "$app\::$type\::$name";
176
177 # Class
178 my $path =
068587bd 179 dir( $self->{base}, 'lib', $appdir, $type );
68ccb5e5 180 my $file = $name;
181 if ( $name =~ /\:/ ) {
182 my @path = split /\:\:/, $name;
183 $file = pop @path;
068587bd 184 $path = dir( $path, @path );
68ccb5e5 185 }
186 $self->mk_dir($path);
068587bd 187 $file = file( $path, "$file.pm" );
68ccb5e5 188 $self->{file} = $file;
189
190 # Test
068587bd 191 $self->{test_dir} = dir( $self->{base}, 't' );
68ccb5e5 192 $self->{test} = $self->next_test;
193
194 # Helper
195 if ($helper) {
196 my $comp = $self->{long_type};
197 my $class = "Catalyst::Helper::$comp\::$helper";
198 eval "require $class";
199
200 if ($@) {
201 Catalyst::Exception->throw(
202 message => qq/Couldn't load helper "$class", "$@"/ );
203 }
204
205 if ( $class->can('mk_compclass') ) {
206 return 1 unless $class->mk_compclass( $self, @args );
207 }
20755aa7 208 else {
209 return 1 unless $self->_mk_compclass
210 }
68ccb5e5 211
212 if ( $class->can('mk_comptest') ) {
213 $class->mk_comptest( $self, @args );
214 }
20755aa7 215 else {
216 $self->_mk_comptest
217 }
68ccb5e5 218 }
219
220 # Fallback
221 else {
222 return 1 unless $self->_mk_compclass;
223 $self->_mk_comptest;
224 }
225 }
226 return 1;
227}
228
68ccb5e5 229sub mk_dir {
230 my ( $self, $dir ) = @_;
231 if ( -d $dir ) {
232 print qq/ exists "$dir"\n/;
233 return 0;
234 }
235 if ( mkpath [$dir] ) {
236 print qq/created "$dir"\n/;
237 return 1;
238 }
239
240 Catalyst::Exception->throw( message => qq/Couldn't create "$dir", "$!"/ );
241}
242
68ccb5e5 243sub mk_file {
244 my ( $self, $file, $content ) = @_;
06f62452 245 if ( -e $file && -s _ ) {
68ccb5e5 246 print qq/ exists "$file"\n/;
247 return 0
248 unless ( $self->{'.newfiles'}
249 || $self->{scripts}
250 || $self->{makefile} );
251 if ( $self->{'.newfiles'} ) {
252 if ( my $f = IO::File->new("< $file") ) {
253 my $oldcontent = join( '', (<$f>) );
254 return 0 if $content eq $oldcontent;
255 }
256 $file .= '.new';
257 }
258 }
620dd287 259
68ccb5e5 260 if ( my $f = IO::File->new("> $file") ) {
261 binmode $f;
262 print $f $content;
263 print qq/created "$file"\n/;
264 return 1;
265 }
266
267 Catalyst::Exception->throw( message => qq/Couldn't create "$file", "$!"/ );
268}
269
68ccb5e5 270sub next_test {
271 my ( $self, $tname ) = @_;
272 if ($tname) { $tname = "$tname.t" }
273 else {
274 my $name = $self->{name};
275 my $prefix = $name;
276 $prefix =~ s/::/-/g;
277 $prefix = $prefix;
278 $tname = $prefix . '.t';
279 $self->{prefix} = $prefix;
280 $prefix = lc $prefix;
281 $prefix =~ s/-/\//g;
282 $self->{uri} = "/$prefix";
283 }
284 my $dir = $self->{test_dir};
285 my $type = lc $self->{type};
286 $self->mk_dir($dir);
068587bd 287 return file( $dir, "$type\_$tname" );
68ccb5e5 288}
289
faae88e5 290# Do not touch this method, *EVER*, it is needed for back compat.
7025ed89 291## addendum: we had to split this method so we could have backwards
19fecc42 292## compatability. otherwise, we'd have no way to pass stuff from __DATA__
faae88e5 293
68ccb5e5 294sub render_file {
295 my ( $self, $file, $path, $vars ) = @_;
7025ed89 296 my $template = $self->get_file( ( caller(0) )[0], $file );
06f62452 297 $self->render_file_contents($template, $path, $vars);
7025ed89 298}
299
300sub render_sharedir_file {
301 my ( $self, $file, $path, $vars ) = @_;
302 my $template = $self->get_sharedir_file( $file );
f8d3d4e0 303 die("Cannot get template from $file for $self\n") unless $template;
e97273a4 304 $self->render_file_contents($template, $path, $vars);
7025ed89 305}
306
307sub render_file_contents {
308 my ( $self, $template, $path, $vars ) = @_;
68ccb5e5 309 $vars ||= {};
310 my $t = Template->new;
68ccb5e5 311 return 0 unless $template;
312 my $output;
313 $t->process( \$template, { %{$self}, %$vars }, \$output )
314 || Catalyst::Exception->throw(
7025ed89 315 message => qq/Couldn't process "$template", / . $t->error() );
68ccb5e5 316 $self->mk_file( $path, $output );
317}
318
45d74601 319sub _mk_information {
320 my $self = shift;
321 print qq/Change to application directory and Run "perl Makefile.PL" to make sure your install is complete\n/;
322}
323
68ccb5e5 324sub _mk_dirs {
325 my $self = shift;
fdb9d1d9 326 $self->mk_dir( $self->{dir} );
327 $self->mk_dir( $self->{script} );
328 $self->{lib} = dir( $self->{dir}, 'lib' );
329 $self->mk_dir( $self->{lib} );
330 $self->{root} = dir( $self->{dir}, 'root' );
331 $self->mk_dir( $self->{root} );
332 $self->{static} = dir( $self->{root}, 'static' );
333 $self->mk_dir( $self->{static} );
334 $self->{images} = dir( $self->{static}, 'images' );
335 $self->mk_dir( $self->{images} );
336 $self->{t} = dir( $self->{dir}, 't' );
337 $self->mk_dir( $self->{t} );
338
339 $self->{class} = dir( split( /\:\:/, $self->{name} ) );
340 $self->{mod} = dir( $self->{lib}, $self->{class} );
341 $self->mk_dir( $self->{mod} );
342
343 if ( $self->{short} ) {
344 $self->{m} = dir( $self->{mod}, 'M' );
345 $self->mk_dir( $self->{m} );
346 $self->{v} = dir( $self->{mod}, 'V' );
347 $self->mk_dir( $self->{v} );
348 $self->{c} = dir( $self->{mod}, 'C' );
349 $self->mk_dir( $self->{c} );
350 }
351 else {
352 $self->{m} = dir( $self->{mod}, 'Model' );
353 $self->mk_dir( $self->{m} );
354 $self->{v} = dir( $self->{mod}, 'View' );
355 $self->mk_dir( $self->{v} );
356 $self->{c} = dir( $self->{mod}, 'Controller' );
357 $self->mk_dir( $self->{c} );
ec62787d 358 }
fdb9d1d9 359 my $name = $self->{name};
360 $self->{rootname} =
361 $self->{short} ? "$name\::C::Root" : "$name\::Controller::Root";
362 $self->{base} = dir( $self->{dir} )->absolute;
68ccb5e5 363}
364
365sub _mk_appclass {
366 my $self = shift;
fdb9d1d9 367 my $mod = $self->{mod};
068587bd 368 $self->render_sharedir_file( file('lib', 'MyApp.pm.tt'), "$mod.pm" );
68ccb5e5 369}
370
371sub _mk_rootclass {
372 my $self = shift;
068587bd 373 $self->render_sharedir_file( file('lib', 'MyApp', 'Controller', 'Root.pm.tt'),
fdb9d1d9 374 file( $self->{c}, "Root.pm" ) );
68ccb5e5 375}
376
377sub _mk_makefile {
378 my $self = shift;
068587bd 379 $self->{path} = dir( 'lib', split( '::', $self->{name} ) );
68ccb5e5 380 $self->{path} .= '.pm';
fdb9d1d9 381 my $dir = $self->{dir};
382 $self->render_sharedir_file( 'Makefile.PL.tt', file($dir, "Makefile.PL") );
68ccb5e5 383
384 if ( $self->{makefile} ) {
385
386 # deprecate the old Build.PL file when regenerating Makefile.PL
387 $self->_deprecate_file(
fdb9d1d9 388 file( $self->{dir}, 'Build.PL' ) );
68ccb5e5 389 }
390}
391
392sub _mk_config {
393 my $self = shift;
fdb9d1d9 394 my $dir = $self->{dir};
395 my $appprefix = $self->{appprefix};
d5ff5c0f 396 $self->render_sharedir_file( 'myapp.conf.tt',
fdb9d1d9 397 file( $dir, "$appprefix.conf" ) );
68ccb5e5 398}
399
400sub _mk_readme {
401 my $self = shift;
fdb9d1d9 402 my $dir = $self->{dir};
403 $self->render_sharedir_file( 'README.tt', file($dir, "README") );
68ccb5e5 404}
405
406sub _mk_changes {
407 my $self = shift;
fdb9d1d9 408 my $dir = $self->{dir};
5b1ec88b 409 my $time = strftime('%Y-%m-%d %H:%M:%S', localtime time);
fdb9d1d9 410 $self->render_sharedir_file( 'Changes.tt', file($dir, "Changes"), { time => $time } );
68ccb5e5 411}
412
413sub _mk_apptest {
414 my $self = shift;
415 my $t = $self->{t};
068587bd 416 $self->render_sharedir_file( file('t', '01app.t.tt'), file($t, "01app.t") );
417 $self->render_sharedir_file( file('t', '02pod.t.tt'), file($t, "02pod.t") );
418 $self->render_sharedir_file( file('t', '03podcoverage.t.tt'), file($t, "03podcoverage.t") );
68ccb5e5 419}
420
421sub _mk_cgi {
422 my $self = shift;
fdb9d1d9 423 my $script = $self->{script};
424 my $appprefix = $self->{appprefix};
425 $self->render_sharedir_file( file('script', 'myapp_cgi.pl.tt'), file($script,"$appprefix\_cgi.pl") );
426 chmod 0700, file($script,"$appprefix\_cgi.pl");
68ccb5e5 427}
428
429sub _mk_fastcgi {
430 my $self = shift;
fdb9d1d9 431 my $script = $self->{script};
432 my $appprefix = $self->{appprefix};
433 $self->render_sharedir_file( file('script', 'myapp_fastcgi.pl.tt'), file($script, "$appprefix\_fastcgi.pl") );
434 chmod 0700, file($script, "$appprefix\_fastcgi.pl");
68ccb5e5 435}
436
437sub _mk_server {
438 my $self = shift;
fdb9d1d9 439 my $script = $self->{script};
440 my $appprefix = $self->{appprefix};
441 $self->render_sharedir_file( file('script', 'myapp_server.pl.tt'), file($script, "$appprefix\_server.pl") );
442 chmod 0700, file($script, "$appprefix\_server.pl");
68ccb5e5 443}
444
445sub _mk_test {
446 my $self = shift;
fdb9d1d9 447 my $script = $self->{script};
448 my $appprefix = $self->{appprefix};
449 $self->render_sharedir_file( file('script', 'myapp_test.pl.tt'), file($script, "$appprefix\_test.pl") );
450 chmod 0700, file($script, "$appprefix\_test.pl");
68ccb5e5 451}
452
453sub _mk_create {
454 my $self = shift;
fdb9d1d9 455 my $script = $self->{script};
456 my $appprefix = $self->{appprefix};
457 $self->render_sharedir_file( file('script', 'myapp_create.pl.tt'), file($script, "$appprefix\_create.pl") );
458 chmod 0700, file($script, "$appprefix\_create.pl");
68ccb5e5 459}
460
461sub _mk_compclass {
462 my $self = shift;
463 my $file = $self->{file};
068587bd 464 return $self->render_sharedir_file( file('lib', 'Helper', 'compclass.pm.tt'), $file );
68ccb5e5 465}
466
467sub _mk_comptest {
468 my $self = shift;
469 my $test = $self->{test};
068587bd 470 $self->render_sharedir_file( file('t', 'comptest.tt'), $test ); ## wtf do i rename this to?
68ccb5e5 471}
472
473sub _mk_images {
474 my $self = shift;
475 my $images = $self->{images};
476 my @images =
477 qw/catalyst_logo btn_120x50_built btn_120x50_built_shadow
478 btn_120x50_powered btn_120x50_powered_shadow btn_88x31_built
479 btn_88x31_built_shadow btn_88x31_powered btn_88x31_powered_shadow/;
480 for my $name (@images) {
3f2f19ec 481 my $image = $self->get_sharedir_file("root", "static", "images", "$name.png.bin");
068587bd 482 $self->mk_file( file( $images, "$name.png" ), $image );
68ccb5e5 483 }
484}
485
486sub _mk_favicon {
487 my $self = shift;
488 my $root = $self->{root};
f023d4a1 489 my $favicon = $self->get_sharedir_file( 'root', 'favicon.ico.bin' );
068587bd 490 my $dest = dir( $root, "favicon.ico" );
afd739f1 491 $self->mk_file( $dest, $favicon );
68ccb5e5 492
493}
494
495sub _deprecate_file {
496 my ( $self, $file ) = @_;
497 if ( -e $file ) {
28d172c6 498 my ($f, $oldcontent);
499 if ( $f = IO::File->new("< $file") ) {
68ccb5e5 500 $oldcontent = join( '', (<$f>) );
501 }
502 my $newfile = $file . '.deprecated';
28d172c6 503 if ( $f = IO::File->new("> $newfile") ) {
68ccb5e5 504 binmode $f;
505 print $f $oldcontent;
506 print qq/created "$newfile"\n/;
507 unlink $file;
508 print qq/removed "$file"\n/;
509 return 1;
510 }
511 Catalyst::Exception->throw(
512 message => qq/Couldn't create "$file", "$!"/ );
513 }
514}
515
fab70e0a 516=head1 DESCRIPTION
517
518This module is used by B<catalyst.pl> to create a set of scripts for a
519new catalyst application. The scripts each contain documentation and
520will output help on how to use them if called incorrectly or in some
521cases, with no arguments.
522
523It also provides some useful methods for a Helper module to call when
524creating a component. See L</METHODS>.
525
526=head1 SCRIPTS
527
528=head2 _create.pl
529
530Used to create new components for a catalyst application at the
531development stage.
532
533=head2 _server.pl
534
535The catalyst test server, starts an HTTPD which outputs debugging to
536the terminal.
537
538=head2 _test.pl
539
540A script for running tests from the command-line.
541
542=head2 _cgi.pl
543
544Run your application as a CGI.
545
546=head2 _fastcgi.pl
547
548Run the application as a fastcgi app. Either by hand, or call this
549from FastCgiServer in your http server config.
550
68ccb5e5 551=head1 HELPERS
552
fab70e0a 553The L</_create.pl> script creates application components using Helper
554modules. The Catalyst team provides a good number of Helper modules
555for you to use. You can also add your own.
556
68ccb5e5 557Helpers are classes that provide two methods.
558
559 * mk_compclass - creates the Component class
560 * mk_comptest - creates the Component test
561
fab70e0a 562So when you call C<scripts/myapp_create.pl view MyView TT>, create
563will try to execute Catalyst::Helper::View::TT->mk_compclass and
68ccb5e5 564Catalyst::Helper::View::TT->mk_comptest.
565
c4c50c2d 566See L<Catalyst::Helper::View::TT> and
567L<Catalyst::Helper::Model::DBIC::Schema> for examples.
68ccb5e5 568
569All helper classes should be under one of the following namespaces.
570
571 Catalyst::Helper::Model::
572 Catalyst::Helper::View::
573 Catalyst::Helper::Controller::
574
675fef06 575=head2 COMMON HELPERS
bc8d7994 576
577=over
578
579=item *
580
581L<Catalyst::Helper::Model::DBIC::Schema> - DBIx::Class models
582
583=item *
584
585L<Catalyst::Helper::View::TT> - Template Toolkit view
586
587=item *
588
589L<Catalyst::Helper::Model::LDAP>
590
591=item *
592
593L<Catalyst::Helper::Model::Adaptor> - wrap any class into a Catalyst model
594
595=back
596
597=head3 NOTE
598
acde1869 599The helpers will read author name from /etc/passwd by default.
600To override, please export the AUTHOR variable.
bc8d7994 601
602=head1 METHODS
603
fab70e0a 604=head2 mk_compclass
605
606This method in your Helper module is called with C<$helper>
607which is a L<Catalyst::Helper> object, and whichever other arguments
608the user added to the command-line. You can use the $helper to call methods
609described below.
610
611If the Helper module does not contain a C<mk_compclass> method, it
612will fall back to calling L</render_file>, with an argument of
613C<compclass>.
614
615=head2 mk_comptest
616
617This method in your Helper module is called with C<$helper>
618which is a L<Catalyst::Helper> object, and whichever other arguments
619the user added to the command-line. You can use the $helper to call methods
620described below.
621
622If the Helper module does not contain a C<mk_compclass> method, it
623will fall back to calling L</render_file>, with an argument of
624C<comptest>.
625
626=head2 mk_stuff
627
628This method is called if the user does not supply any of the usual
629component types C<view>, C<controller>, C<model>. It is passed the
630C<$helper> object (an instance of L<Catalyst::Helper>), and any other
631arguments the user typed.
632
633There is no fallback for this method.
634
bc8d7994 635=head1 INTERNAL METHODS
fab70e0a 636
637These are the methods that the Helper classes can call on the
638<$helper> object passed to them.
639
28eb1300 640=head2 render_file ($file, $path, $vars)
fab70e0a 641
28eb1300 642Render and create a file from a template in DATA using Template
643Toolkit. $file is the relevent chunk of the __DATA__ section, $path is
644the path to the file and $vars is the hashref as expected by
645L<Template Toolkit|Template>.
fab70e0a 646
28eb1300 647=head2 get_file ($class, $file)
fab70e0a 648
649Fetch file contents from the DATA section. This is used internally by
28eb1300 650L</render_file>. $class is the name of the class to get the DATA
651section from. __PACKAGE__ or ( caller(0) )[0] might be sensible
652values for this.
fab70e0a 653
654=head2 mk_app
655
656Create the main application skeleton. This is called by L<catalyst.pl>.
657
28eb1300 658=head2 mk_component ($app)
fab70e0a 659
660This method is called by L<create.pl> to make new components
661for your application.
662
608f6b92 663=head2 mk_dir ($path)
fab70e0a 664
665Surprisingly, this function makes a directory.
666
28eb1300 667=head2 mk_file ($file, $content)
fab70e0a 668
669Writes content to a file. Called by L</render_file>.
670
28eb1300 671=head2 next_test ($test_name)
fab70e0a 672
673Calculates the name of the next numbered test file and returns it.
28eb1300 674Don't give the number or the .t suffix for the test name.
fab70e0a 675
c6dbb300 676=cut
677
678=head2 get_sharedir_file
679
680Method for getting a file out of share/
681
682=cut
683
684=head2 render_file_contents
685
686Process a L<Template::Toolkit> template.
687
688=cut
689
690=head2 render_sharedir_file
691
692Render a template/image file from our share directory
693
694=cut
695
68ccb5e5 696=head1 NOTE
697
698The helpers will read author name from /etc/passwd by default.
699To override, please export the AUTHOR variable.
700
701=head1 SEE ALSO
702
703L<Catalyst::Manual>, L<Catalyst::Test>, L<Catalyst::Request>,
704L<Catalyst::Response>, L<Catalyst>
705
f64c718c 706=head1 AUTHORS
68ccb5e5 707
f64c718c 708Catalyst Contributors, see Catalyst.pm
68ccb5e5 709
710=head1 LICENSE
711
7cd3b67e 712This library is free software. You can redistribute it and/or modify
68ccb5e5 713it under the same terms as Perl itself.
714
715=cut
716
7171;
68ccb5e5 718