added cookbook example for localtime.
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Cookbook.pod
1 =head1 NAME
2
3 Catalyst::Manual::Cookbook - Cooking with Catalyst
4
5 =head1 DESCRIPTION
6
7 Yummy code like your mum used to bake!
8
9 =head1 RECIPES
10
11 =head2 Force debug screen
12
13 You can force Catalyst to display the debug screen at the end of the request by
14 placing a die() call in the _end action.
15
16     __PACKAGE__->action(
17         '!end' => sub {
18             my ( $self, $c ) = @_;
19             die "testing";
20         }
21     );
22
23 =head2 Disable statistics
24
25 Just add this line to your application class if you don't want those nifty
26 statistics in your debug messages.
27
28     sub Catalyst::Log::info { }
29
30 =head2 Scaffolding
31
32 Scaffolding is very simple with Catalyst.
33 Just use Catalyst::Model::CDBI::CRUD as baseclass.
34
35     # lib/MyApp/Model/CDBI.pm
36     package MyApp::Model::CDBI;
37
38     use strict;
39     use base 'Catalyst::Model::CDBI::CRUD';
40
41     __PACKAGE__->config(
42         dsn           => 'dbi:SQLite:/tmp/myapp.db',
43         relationships => 1
44     );
45
46     1;
47
48     # lib/MyApp.pm
49     package MyApp;
50
51     use Catalyst 'FormValidator';
52
53     __PACKAGE__->config(
54         name => 'My Application',
55         root => '/home/joeuser/myapp/root'
56     );
57
58     __PACKAGE__->action(
59         'table' => sub {
60             my ( $self, $c ) = @_;
61             $c->form( optional => [ MyApp::Model::CDBI::Table->columns ] );
62             $c->forward('MyApp::Model::CDBI::Table');
63         }
64     );
65
66     1;
67
68 Modify the $c->form() parameters to match your needs, and don't forget to copy
69 the templates. ;)
70
71 =head2 Serving static files and CSS as text/css
72
73 If you want to serve static content (like images, txt or CSS) via Catalyst,
74 then all you need is the plugin Catalyst::Plugin::Static as well as a small
75 regex to set the MIME type for CSS to text/css.
76
77     # lib/MyApp.pm
78     package MyApp;
79
80     use strict;
81     use Catalyst qw/-Debug Static/;
82     
83     __PACKAGE__->action(
84
85         '!default' => sub {
86             my ( $self, $c ) = @_;
87             $c->serve_static;
88         },
89             
90         '/^.*\.css$/' => sub {
91             my ( $self, $c ) = @_;
92             $c->serve_static('text/css');
93         },
94     );
95
96 =head2 Uploads with Catalyst
97
98 To implement uploads in Catalyst you need to have a HTML form similiar to
99 this:
100
101     <form action="/upload" method="post" enctype="multipart/form-data">
102       <input type="hidden" name="form_submit" value="yes">
103       <input type="file" name="my_file">
104       <input type="submit" value="Send">
105     </form>
106
107 It's very important not to forget enctype="multipart/form-data" in form, 
108 if it's not there, uploads just don't work.
109
110 Catalyst Controller module 'upload' action:
111
112     MyApp->action(
113     
114         'upload' => sub {
115             my ($self, $c) = @_;
116             if ($c->req->parameters->{form_submit} eq 'yes') {
117                 my $filename = $c->req->parameters->{my_file};
118                 if ($filename) {
119                     my $fh = $c->req->uploads->{$filename}->{fh};
120                     open(NEW_FILE, ">/tmp/$filename") or die
121                         "Can't open file for writing: $!";
122                     while ($fh->read(my $buf, 32768)) {
123                         print NEW_FILE $buf;
124                     }
125                     close(NEW_FILE);
126                 }
127             }
128             $c->stash->{template} = 'upload_form.tt';
129             $c->forward('MyApp::V::View');
130         },
131     );
132
133 If you want to upload bigger files than 1MB, then just add to your Controller 
134 module:
135
136     $CGI::Simple::POST_MAX = 1048576000;
137
138
139 =head2 Easily working with datetime objects.
140
141 If you store datetime data in your tables, you can easily expand this column to
142 a L<Time::Piece> object which lets you call useful methods like ymd, mon and 
143 datetime on it.
144
145 In order to set it up, add something like the following to your CDBI Model Class,
146 if you are storing dates as ISO timestamps:
147
148      __PACKAGE__->has_a(
149          mycolumn => 'Time::Piece',
150          inflate => sub { Time::Piece->strptime( shift, "%FT%H:%M:%S" ) },
151          deflate => 'datetime'
152      );
153
154 or if you prefer to store dates in unix epoch time you can do something like this:
155
156      __PACKAGE__->has_a(
157          mycolumn => 'Time::Piece',
158          inflate => sub { Time::Piece->strptime( shift, "%s" ) },
159          deflate => 'epoch'
160      );
161
162 If you want to use another format in the database, you can change the strptime call 
163 to fit your format, and use strftime to return it with your custom format to the 
164 database during deflate. See the L<Time::Piece> and L<Class::DBI> docs for more info.
165
166 =head1 AUTHOR
167
168 Sebastian Riedel, C<sri@oook.de>
169
170 =head1 COPYRIGHT
171
172 This program is free software, you can redistribute it and/or modify it under
173 the same terms as Perl itself.