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