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 | |
aeb875d9 |
41 | =bac |
42 | |
43 | =head1 THE BIG PICTURE |
44 | |
45 | .=========. |
46 | | Request | |
47 | '=========' |
48 | | |
49 | | |
50 | v |
51 | .--------------------. .============================. |
52 | | Web Application | | Interface Model | |
53 | | Action Dispatching |<--| Object, Collection, Action | |
54 | '--------------------' '============================' |
55 | | ^ |
56 | v | |
57 | .====================. .-------------------. |
58 | | ViewPort | | Domain Model | |
59 | | Plain, Collection, | | Business Logic, | |
60 | | Object, Action | | Persistence Layer | |
61 | '====================' '-------------------' |
62 | | |
63 | v |
64 | .====================. |
65 | | FocusStack | |
66 | | Contains ViewPorts | |
67 | '====================' |
68 | | |
69 | v |
70 | .-----------. .===================. |
71 | | View | | RenderingContext | |
72 | | HTML, PDF |---->| Template Toolkit |----. |
73 | '-----------' '===================' | |
74 | | ^ | |
75 | v | | |
76 | .======================. | | |
77 | | LayoutSet / ViewPort | | | |
78 | | Layouts: widget, foo | | | |
79 | '======================' | | |
80 | | | | |
81 | v | | |
82 | .========================. | | |
83 | | Widget / LayoutSet | | | |
84 | | Fragments: widget, foo |---------' v |
85 | '========================' .==========. |
86 | | Response | |
87 | '==========' |
ebc3b5e2 |
88 | |
63bb30b4 |
89 | =head1 APPLICATION |
90 | |
91 | A Reaction application is really a L<Catalyst> application under the hood. Reaction |
92 | uses reflection to build more flexible and re-usable Catalyst components. |
93 | |
94 | The main application module (usually called C<MyApp> or C<MyApp.pm> in documentation) |
95 | looks exactly like a typical Catalyst application module. Reaction's modular architecture |
96 | allows it therefor to be integrated into other Catalyst applications, or to integrate |
97 | other Catalyst extensions and components itself. |
98 | |
99 | =head1 CONTROLLERS |
100 | |
101 | Usually in Catalyst applications the controller's actions will take their arguments, |
102 | maybe modify them or clean them up. After that they are processed by the model and then |
103 | stashed away to be later used by the view. |
104 | |
105 | Reactions approach is a bit different. The cleanup and validation of values, and the |
106 | involvement of the model are abstracted into a L<Reaction::InterfaceModel::Action> |
107 | subclass. Examples for such actions would be C<Create>, C<Update> or C<Delete> in a |
108 | CRUD situation. |
109 | |
110 | Controllers that use Reaction have to inherit from L<Reaction::UI::Controller> or a |
111 | subclass of it. Some other useful controller base classes are: |
112 | |
113 | =over |
114 | |
115 | =item * |
116 | |
117 | L<Reaction::UI::Controller::Root> should be the base for the root controller to |
118 | every chain of Reaction actions. It will provide a C<base> action you can chain |
119 | to which will make sure the L<window viewport|/VIEWPORTS> and |
120 | L<focus stack|/FOCUS STACK> are set up. |
121 | |
122 | =item * |
123 | |
124 | L<Reaction::UI::Controller::Collection> to ease the creation of components that act |
125 | on collections as their model (database results for example). It provides actions |
126 | to list and view the collection items. |
127 | |
128 | =item * |
129 | |
130 | L<Reaction::UI::Controller::Collection::CRUD> is a subclass of the above and provides |
131 | additional C<create>, C<update>, C<delete> and C<delete_all> actions. |
132 | |
133 | =back |
134 | |
135 | =head1 VIEWPORTS |
136 | |
137 | Viewports represent the components that render your page when combined. |
138 | |
139 | The C<begin> action in L<Reaction::Controller::Root> creates a new L<Reaction::UI::Window> |
140 | object and stores it as C<window> in the stash. The L<focus stack|/FOCUSSTACKS> of that |
141 | window object is used as the base focus stack for the request. |
142 | |
143 | You can add a new inner viewport to the focus stack with the C<push_viewport> method |
144 | available on your controller: |
145 | |
146 | $controller->push_viewport($viewport_class, %viewport_args); |
147 | |
148 | This will add a new instance of C<$viewport_class> to the current focus stack using |
149 | C<%viewport_args> as arguments. For more information on the usage and other options |
150 | (for example the C<next_action> option, which redirects afterwards) see |
151 | L<Reaction::UI::FocusStack> and L<Reaction::UI::ViewPort>. |
152 | |
153 | You can use the L<Reaction::UI::ViewPort::Action> viewport to build viewports |
154 | that perform typical form actions like OK, Apply and Close. |
155 | |
156 | =head1 FOCUSSTACKS |
157 | |
158 | Viewports are pushed onto the current focus stack. The C<end> action in |
159 | L<Reaction::Controller::Root> will C<flush> the L<Reaction::UI::Window> |
160 | object stored as C<window> in the stash. |
161 | |
162 | =head1 DOMAIN MODELS |
163 | |
164 | The domain models should be completely decoupled from the application and it's business |
165 | logic. Normally, you need to decide whether to put your business logic in your controller |
166 | or in your model. Reaction solves this problem by using L<interface models|/INTERFACE MODELS> |
167 | as a separation between the two. |
168 | |
169 | If you want your domain model to be reflectable (L<DBIx::Class> for example) you will have |
170 | to use L<Moose> to add attribute metadata to those classes. |
171 | |
172 | =head1 INTERFACE MODELS |
173 | |
174 | The interface models contain your business logic. That is, the application specific logic |
175 | representing the model your application will use. |
176 | |
177 | An interface model consists of action classes subclassing L<Reaction::InterfaceModel::Action>. |
178 | These instances will have both the request context and the target model available and can do |
179 | their work in a C<do_apply> method. |
180 | |
181 | To allow your own models to be tied in to reflective controllers like |
182 | L<Reaction::Controller::Collection>, you can subclass L<Reaction::InterfaceModel::Object>. |
183 | That will provide you with a way to let the viewports introspect the actions that your |
184 | interface model defines for this model. |
185 | |
186 | An example of this would be: |
187 | |
188 | - MyApp::Controller::Foo is a Reaction::Controller::Collection::CRUD |
189 | for MyApp::Model::Foo |
190 | - The model_name config setting is 'Model::Foo' |
191 | - User calls action MyApp::Controller::Foo->delete_old |
192 | - The 'delete_old' controller action will call |
193 | $self->basic_model_action($c, \%vp_args) |
194 | - The 'target' option in %vp_args will be asked for an action that |
195 | corresponds with the 'delete_old' controller action |
196 | - An instance of MyApp::Model::Foo::Action::DeleteOld is |
197 | returned |
198 | - This is passed as 'model' to a new instance of |
199 | Reaction::UI::ViewPort::Action which is then pushed |
200 | onto the focus stack. |
201 | |
202 | Form processing as provided by L<Reaction::UI::ViewPort::Action> is a very good |
203 | example of Reaction's usefulness; Instead of creating a new dialog for every |
204 | form using myriads of helper functions, you provide a controller baseclass |
205 | rendering the dialog by introspecting an interface model object with fields and |
206 | actions. |
207 | |
208 | Then you just need to create a new controller and interface model for your new |
209 | dialog and it just works. |
210 | |
211 | If your model is a L<DBIx::Class::Schema> and contains L<Moose> metadata, you |
212 | can let L<Reaction::InterfaceModel::Reflector::DBIC> set up your interface |
213 | model objects and actions. |
214 | |
215 | =head1 SKINS, LAYOUTS AND WIDGETS |
216 | |
217 | When you push a viewport onto the focus stack like this: |
218 | |
219 | $controller->push_viewport('Reaction::UI::ViewPort::SiteLayout'); |
220 | |
221 | Reaction will look for a layout file named |
222 | C<$search_path/skin/$skin_name/layout/site_layout.tt>. If it can't find it, |
223 | it will also look in the base skin and search paths. |
224 | |
225 | You can also provide a specific layout: |
226 | |
227 | $controller->push_viewport( |
228 | 'Reaction::UI::ViewPort::SiteLayout', |
229 | layout => 'my_site_layout', |
230 | ); |
231 | |
232 | A new instance of L<Reaction::UI::LayoutSet> will be created using the layout |
233 | file. It is then used to determine the class of widget to create. The widget |
234 | contains the Perl code counterpart of the templating part in the layout file. |
235 | |
236 | The widget is either determined by the C<=widget> template directive in the |
237 | layout file or by the L<Reaction::UI::Skin> object created to represent the |
238 | skin. |
239 | |
240 | The details of skins or layouts are documented in L<Reaction::Manual::Templates>. |
241 | |
242 | =head1 SEE ALSO |
243 | |
244 | =over |
245 | |
246 | =item * L<Reaction::Manual> |
247 | |
248 | =item * L<Reaction::Manual::Intro> |
249 | |
250 | =back |
251 | |
252 | =head1 AUTHORS |
253 | |
254 | See L<Reaction::Class> for authors. |
255 | |
256 | =head1 LICENSE |
257 | |
258 | See L<Reaction::Class> for the license. |
259 | |
260 | =cut |