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