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