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