Commit | Line | Data |
63bb30b4 |
1 | =head1 NAME |
2 | |
3 | Reaction::Manual::Overview - Orientation in Reaction |
4 | |
5 | =head1 DESCRIPTION |
6 | |
7 | This document aims at describing the modular parts of L<Reaction> and explain |
8 | how they are tied together. |
9 | |
ebc3b5e2 |
10 | =head1 WHAT IS REACTION |
11 | |
12 | Reaction is a L<Catalyst> extension providing you with: |
13 | |
14 | =over 4 |
15 | |
16 | =item * |
17 | |
18 | Model mutations abstracted into Action objects. |
19 | |
20 | =item * |
21 | |
22 | Reflection to generate interface models using the Action objects from a L<DBIx::Class> |
23 | schema. |
24 | |
25 | =item * |
26 | |
27 | An abstract UI expression system based on L<view|Reaction::UI::View::TT>, |
28 | L<skin|Reaction::UI::Skin>, L<rendering context|Reaction::UI::RenderingContext>, |
29 | L<widget|Reaction::UI::Widget> and L<layout set|Reaction::UI::LayoutSet>. |
30 | |
31 | =item * |
32 | |
33 | Stylable via skins. Parts of the skins can be extended and flexibly from large |
34 | down to very small parts. |
35 | |
36 | =item * |
37 | |
38 | Full separation of interface rendering structure and templating, making re-usable |
39 | extensions even easier. |
40 | |
41 | =back |
42 | |
63bb30b4 |
43 | =head1 APPLICATION |
44 | |
45 | A Reaction application is really a L<Catalyst> application under the hood. Reaction |
46 | uses reflection to build more flexible and re-usable Catalyst components. |
47 | |
48 | The main application module (usually called C<MyApp> or C<MyApp.pm> in documentation) |
49 | looks exactly like a typical Catalyst application module. Reaction's modular architecture |
50 | allows it therefor to be integrated into other Catalyst applications, or to integrate |
51 | other Catalyst extensions and components itself. |
52 | |
53 | =head1 CONTROLLERS |
54 | |
55 | Usually in Catalyst applications the controller's actions will take their arguments, |
56 | maybe modify them or clean them up. After that they are processed by the model and then |
57 | stashed away to be later used by the view. |
58 | |
59 | Reactions approach is a bit different. The cleanup and validation of values, and the |
60 | involvement of the model are abstracted into a L<Reaction::InterfaceModel::Action> |
61 | subclass. Examples for such actions would be C<Create>, C<Update> or C<Delete> in a |
62 | CRUD situation. |
63 | |
64 | Controllers that use Reaction have to inherit from L<Reaction::UI::Controller> or a |
65 | subclass of it. Some other useful controller base classes are: |
66 | |
67 | =over |
68 | |
69 | =item * |
70 | |
71 | L<Reaction::UI::Controller::Root> should be the base for the root controller to |
72 | every chain of Reaction actions. It will provide a C<base> action you can chain |
73 | to which will make sure the L<window viewport|/VIEWPORTS> and |
74 | L<focus stack|/FOCUS STACK> are set up. |
75 | |
76 | =item * |
77 | |
78 | L<Reaction::UI::Controller::Collection> to ease the creation of components that act |
79 | on collections as their model (database results for example). It provides actions |
80 | to list and view the collection items. |
81 | |
82 | =item * |
83 | |
84 | L<Reaction::UI::Controller::Collection::CRUD> is a subclass of the above and provides |
85 | additional C<create>, C<update>, C<delete> and C<delete_all> actions. |
86 | |
87 | =back |
88 | |
89 | =head1 VIEWPORTS |
90 | |
91 | Viewports represent the components that render your page when combined. |
92 | |
93 | The C<begin> action in L<Reaction::Controller::Root> creates a new L<Reaction::UI::Window> |
94 | object and stores it as C<window> in the stash. The L<focus stack|/FOCUSSTACKS> of that |
95 | window object is used as the base focus stack for the request. |
96 | |
97 | You can add a new inner viewport to the focus stack with the C<push_viewport> method |
98 | available on your controller: |
99 | |
100 | $controller->push_viewport($viewport_class, %viewport_args); |
101 | |
102 | This will add a new instance of C<$viewport_class> to the current focus stack using |
103 | C<%viewport_args> as arguments. For more information on the usage and other options |
104 | (for example the C<next_action> option, which redirects afterwards) see |
105 | L<Reaction::UI::FocusStack> and L<Reaction::UI::ViewPort>. |
106 | |
107 | You can use the L<Reaction::UI::ViewPort::Action> viewport to build viewports |
108 | that perform typical form actions like OK, Apply and Close. |
109 | |
110 | =head1 FOCUSSTACKS |
111 | |
112 | Viewports are pushed onto the current focus stack. The C<end> action in |
113 | L<Reaction::Controller::Root> will C<flush> the L<Reaction::UI::Window> |
114 | object stored as C<window> in the stash. |
115 | |
116 | =head1 DOMAIN MODELS |
117 | |
118 | The domain models should be completely decoupled from the application and it's business |
119 | logic. Normally, you need to decide whether to put your business logic in your controller |
120 | or in your model. Reaction solves this problem by using L<interface models|/INTERFACE MODELS> |
121 | as a separation between the two. |
122 | |
123 | If you want your domain model to be reflectable (L<DBIx::Class> for example) you will have |
124 | to use L<Moose> to add attribute metadata to those classes. |
125 | |
126 | =head1 INTERFACE MODELS |
127 | |
128 | The interface models contain your business logic. That is, the application specific logic |
129 | representing the model your application will use. |
130 | |
131 | An interface model consists of action classes subclassing L<Reaction::InterfaceModel::Action>. |
132 | These instances will have both the request context and the target model available and can do |
133 | their work in a C<do_apply> method. |
134 | |
135 | To allow your own models to be tied in to reflective controllers like |
136 | L<Reaction::Controller::Collection>, you can subclass L<Reaction::InterfaceModel::Object>. |
137 | That will provide you with a way to let the viewports introspect the actions that your |
138 | interface model defines for this model. |
139 | |
140 | An example of this would be: |
141 | |
142 | - MyApp::Controller::Foo is a Reaction::Controller::Collection::CRUD |
143 | for MyApp::Model::Foo |
144 | - The model_name config setting is 'Model::Foo' |
145 | - User calls action MyApp::Controller::Foo->delete_old |
146 | - The 'delete_old' controller action will call |
147 | $self->basic_model_action($c, \%vp_args) |
148 | - The 'target' option in %vp_args will be asked for an action that |
149 | corresponds with the 'delete_old' controller action |
150 | - An instance of MyApp::Model::Foo::Action::DeleteOld is |
151 | returned |
152 | - This is passed as 'model' to a new instance of |
153 | Reaction::UI::ViewPort::Action which is then pushed |
154 | onto the focus stack. |
155 | |
156 | Form processing as provided by L<Reaction::UI::ViewPort::Action> is a very good |
157 | example of Reaction's usefulness; Instead of creating a new dialog for every |
158 | form using myriads of helper functions, you provide a controller baseclass |
159 | rendering the dialog by introspecting an interface model object with fields and |
160 | actions. |
161 | |
162 | Then you just need to create a new controller and interface model for your new |
163 | dialog and it just works. |
164 | |
165 | If your model is a L<DBIx::Class::Schema> and contains L<Moose> metadata, you |
166 | can let L<Reaction::InterfaceModel::Reflector::DBIC> set up your interface |
167 | model objects and actions. |
168 | |
169 | =head1 SKINS, LAYOUTS AND WIDGETS |
170 | |
171 | When you push a viewport onto the focus stack like this: |
172 | |
173 | $controller->push_viewport('Reaction::UI::ViewPort::SiteLayout'); |
174 | |
175 | Reaction will look for a layout file named |
176 | C<$search_path/skin/$skin_name/layout/site_layout.tt>. If it can't find it, |
177 | it will also look in the base skin and search paths. |
178 | |
179 | You can also provide a specific layout: |
180 | |
181 | $controller->push_viewport( |
182 | 'Reaction::UI::ViewPort::SiteLayout', |
183 | layout => 'my_site_layout', |
184 | ); |
185 | |
186 | A new instance of L<Reaction::UI::LayoutSet> will be created using the layout |
187 | file. It is then used to determine the class of widget to create. The widget |
188 | contains the Perl code counterpart of the templating part in the layout file. |
189 | |
190 | The widget is either determined by the C<=widget> template directive in the |
191 | layout file or by the L<Reaction::UI::Skin> object created to represent the |
192 | skin. |
193 | |
194 | The details of skins or layouts are documented in L<Reaction::Manual::Templates>. |
195 | |
196 | =head1 SEE ALSO |
197 | |
198 | =over |
199 | |
200 | =item * L<Reaction::Manual> |
201 | |
202 | =item * L<Reaction::Manual::Intro> |
203 | |
204 | =back |
205 | |
206 | =head1 AUTHORS |
207 | |
208 | See L<Reaction::Class> for authors. |
209 | |
210 | =head1 LICENSE |
211 | |
212 | See L<Reaction::Class> for the license. |
213 | |
214 | =cut |