nuked SiteLayout->http_header, should need of it since we have arg and %_
[catagits/Reaction.git] / lib / Reaction / Manual / Intro.pod
CommitLineData
df2804f5 1=head1 NAME
2
3Reaction::Manual::Intro - Introduction to Reaction
4
5=head1 INTRODUCTION
6
7Reaction is basically an extended MVC:
8
9=over
10
11=item Domain Model
12
13DBIx::Class::Schema, MyApp::Foo, MyApp::Bar, etc.
14
15=item Interface Model
16
17InterfaceModel::DBIC::Schema, InterfaceModel::Action,
18MyApp::InterfaceModel::Foo classes.
19
20=item Controller
21
22Mediation and navigation.
23
24=item ViewPort
25
26Event handling encapsulation.
27
28=item Widget
29
30View logic.
31
32=item Renderer
33
34MyApp::View:: classes, renders viewports.
35
36=back
37
38=head1 THE REACTION WAY
39
40The idea is you separate your domain model, which encapsulates the domain
41itself from your interface model, which is a model of how a particular app or
42class of apps interact with that domain and provides objects/methods to
43encapsulate the common operations it does.
44
45=head2 Domain Models vs Interface Models
46
47Domain models are expected to drive the application business logic and data.
48All domain models that need to be effectively displayed somehow at the user
49interface (a table, for instance) must interact with an interface model.
50These should provide the common methods needed in order to carry out
51user-generated events.
52
53=head1 SETTING UP A REACTION APPLICATION
54
55Reaction applications are set up just like Catalyst:
56
57 $ catalyst.pl MyApp
58 # output ommited
59 $ cd MyApp
60
61=head2 Models
62
63Reaction provides a reflector component which automagically
64maps a L<DBIx::Class::Schema> into a set of Interface Models which can be used
65by Reaction to build the interface components. If you're not familiar with
66L<DBIx::Class> or don't have a schema handy, now is a good time to go through
67L<DBIx::Class::Manual::Intro> to get a schema set up.
68
888532d3 69It is important that your Result-objects implement the meta-protocol of Moose
70One way to achive that is to do the following:
71
72 package MyApp::Schema::Result::Bar;
73 use base 'DBIx::Class';
74 use Moose;
75
159fd246 76 has 'name' => (isa => 'Str', required => 1, rw => 1);
888532d3 77
78 use namespace::clean -except => [ 'meta' ];
79
80 __PACKAGE__->load_components(qw(Core));
81 __PACKAGE__->table('bar');
82 __PACKAGE__->add_columns(
83 name => {
84 data_type => 'varchar',
85 size => 255,
86 is_nullable => 0,
87 }
88 );
89 __PACKAGE__->primary_key('name');
90 1;
91
92Once you have your schema set up like that, you can create the InferfaceModel:
93
df2804f5 94 package MyApp::InterfaceModel::DBIC;
95
96 use base 'Reaction::InterfaceModel::Object';
97 use Reaction::InterfaceModel::Reflector::DBIC;
98
99 my $reflector = Reaction::InterfaceModel::Reflector::DBIC->new;
100
101 $reflector->reflect_schema(
102 model_class => __PACKAGE__,
103 schema_class => 'MyApp::Schema',
104 sources => [qw/Foo Baz/],
105 );
106
107 1;
108
888532d3 109Then you create a MyApp::Model that uses this InferfaceModel:
110
111 package Myapp::Model::IM;
112
888532d3 113 use Reaction::Class;
114
2b14a136 115 extends 'Catalyst::Model::Reaction::InterfaceModel::DBIC';
888532d3 116
117 1;
118
df2804f5 119=head2 Controllers
120
888532d3 121=head3 Root controller
122
df2804f5 123Your Reaction application must have a Root controller which inherits from
124C<Reaction::UI::Controller::Root>.
125
126 package MyApp::Controller::Root;
127
128 use warnings;
129 use strict;
130 use base qw/Reaction::UI::Controller::Root/;
131
132 __PACKAGE__->config(
133 view_name => 'Site',
134 window_title => 'My Reaction App',
135 namespace => ''
136 );
137
5a333e30 138 sub base : Chained('/') PathPart('') CaptureArgs(0) {
139 # do some setup for every request
140 # also provides a chain root for other controllers to use
141 }
142
df2804f5 143 1;
144
888532d3 145=head3 Individual controllers
146
147For each Collection(table?) in your DB, you need to create a controller
148
149 package MyApp::Controller::Foo;
150
151 use base 'Reaction::UI::Controller::Collection::CRUD';
152 use Reaction::Class;
153
154 __PACKAGE__->config(
155 model_name => 'IM', # This corresponds to the name of the MyApp::Model you created earlier
156 collection_name => 'Foo', # Name of one of the sources in your InterfaceModel
5a333e30 157 action => {
158 base => { Chained => '/base', # chain to the base action in the root controller
159 PathPart => 'foo' },
160 },
888532d3 161 );
162
163 1;
164
df2804f5 165XX TODO
166
167=head2 View
168
888532d3 169One of the views in your application should look something like this:
170
171 package MyApp::View::TT;
172
173 use Reaction::Class;
174
2b14a136 175 extends 'Reaction::UI::View::TT';
888532d3 176
177 1;
178
179 __END__;
180
181
df2804f5 182XX TODO
183
184=head1 SEE ALSO
185
186=over
187
188=item * L<Reaction::Manual::Cookbook>
189
190=item * L<Reaction::Manual::FAQ>
191
192=back
193
194=head1 AUTHORS
195
196See L<Reaction::Class> for authors.
197
198=head1 LICENSE
199
200See L<Reaction::Class> for the license.
201
202=cut