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