IM has no customized functionality, it can simply delegate all work to the DM. When
you need to add custom business logic, you can add or replace functionality as needed.
-The DM/IM split is sometimes referred to as a FacadeModel - see L<http://www.twinforces.com/tf/docs/MFCV.html>, for example.
+The DM/IM split is sometimes referred to as a FacadeModel - see
+L<http://www.twinforces.com/tf/docs/MFCV.html>, for example.
=head1 WHAT YOU'LL NEED TO KNOW
=head1 NEXT STEPS
+The L<Reaction::Manual::Overview> document tries to tie the parts of reaction
+together to form a big picture.
+
If you'd like an example, see L<Reaction::Manual::Example>.
-If you're ready to dive in and start learning step by step, see L<Reaction::Manual::Tutorial>.
+If you're ready to dive in and start learning step by step, see
+L<Reaction::Manual::Tutorial>.
-As you encounter unfamiliar terms, or want to see how a particular term is used in the context of the Reaction project, refer to the L<Reaction::Manual::Glossary>.
+As you encounter unfamiliar terms, or want to see how a particular term is used in the
+context of the Reaction project, refer to the L<Reaction::Manual::Glossary>.
=head1 SEE ALSO
--- /dev/null
+=head1 NAME
+
+Reaction::Manual::Overview - Orientation in Reaction
+
+=head1 DESCRIPTION
+
+This document aims at describing the modular parts of L<Reaction> and explain
+how they are tied together.
+
+=head1 APPLICATION
+
+A Reaction application is really a L<Catalyst> application under the hood. Reaction
+uses reflection to build more flexible and re-usable Catalyst components.
+
+The main application module (usually called C<MyApp> or C<MyApp.pm> in documentation)
+looks exactly like a typical Catalyst application module. Reaction's modular architecture
+allows it therefor to be integrated into other Catalyst applications, or to integrate
+other Catalyst extensions and components itself.
+
+=head1 CONTROLLERS
+
+Usually in Catalyst applications the controller's actions will take their arguments,
+maybe modify them or clean them up. After that they are processed by the model and then
+stashed away to be later used by the view.
+
+Reactions approach is a bit different. The cleanup and validation of values, and the
+involvement of the model are abstracted into a L<Reaction::InterfaceModel::Action>
+subclass. Examples for such actions would be C<Create>, C<Update> or C<Delete> in a
+CRUD situation.
+
+Controllers that use Reaction have to inherit from L<Reaction::UI::Controller> or a
+subclass of it. Some other useful controller base classes are:
+
+=over
+
+=item *
+
+L<Reaction::UI::Controller::Root> should be the base for the root controller to
+every chain of Reaction actions. It will provide a C<base> action you can chain
+to which will make sure the L<window viewport|/VIEWPORTS> and
+L<focus stack|/FOCUS STACK> are set up.
+
+=item *
+
+L<Reaction::UI::Controller::Collection> to ease the creation of components that act
+on collections as their model (database results for example). It provides actions
+to list and view the collection items.
+
+=item *
+
+L<Reaction::UI::Controller::Collection::CRUD> is a subclass of the above and provides
+additional C<create>, C<update>, C<delete> and C<delete_all> actions.
+
+=back
+
+=head1 VIEWPORTS
+
+Viewports represent the components that render your page when combined.
+
+The C<begin> action in L<Reaction::Controller::Root> creates a new L<Reaction::UI::Window>
+object and stores it as C<window> in the stash. The L<focus stack|/FOCUSSTACKS> of that
+window object is used as the base focus stack for the request.
+
+You can add a new inner viewport to the focus stack with the C<push_viewport> method
+available on your controller:
+
+ $controller->push_viewport($viewport_class, %viewport_args);
+
+This will add a new instance of C<$viewport_class> to the current focus stack using
+C<%viewport_args> as arguments. For more information on the usage and other options
+(for example the C<next_action> option, which redirects afterwards) see
+L<Reaction::UI::FocusStack> and L<Reaction::UI::ViewPort>.
+
+You can use the L<Reaction::UI::ViewPort::Action> viewport to build viewports
+that perform typical form actions like OK, Apply and Close.
+
+=head1 FOCUSSTACKS
+
+Viewports are pushed onto the current focus stack. The C<end> action in
+L<Reaction::Controller::Root> will C<flush> the L<Reaction::UI::Window>
+object stored as C<window> in the stash.
+
+=head1 DOMAIN MODELS
+
+The domain models should be completely decoupled from the application and it's business
+logic. Normally, you need to decide whether to put your business logic in your controller
+or in your model. Reaction solves this problem by using L<interface models|/INTERFACE MODELS>
+as a separation between the two.
+
+If you want your domain model to be reflectable (L<DBIx::Class> for example) you will have
+to use L<Moose> to add attribute metadata to those classes.
+
+=head1 INTERFACE MODELS
+
+The interface models contain your business logic. That is, the application specific logic
+representing the model your application will use.
+
+An interface model consists of action classes subclassing L<Reaction::InterfaceModel::Action>.
+These instances will have both the request context and the target model available and can do
+their work in a C<do_apply> method.
+
+To allow your own models to be tied in to reflective controllers like
+L<Reaction::Controller::Collection>, you can subclass L<Reaction::InterfaceModel::Object>.
+That will provide you with a way to let the viewports introspect the actions that your
+interface model defines for this model.
+
+An example of this would be:
+
+ - MyApp::Controller::Foo is a Reaction::Controller::Collection::CRUD
+ for MyApp::Model::Foo
+ - The model_name config setting is 'Model::Foo'
+ - User calls action MyApp::Controller::Foo->delete_old
+ - The 'delete_old' controller action will call
+ $self->basic_model_action($c, \%vp_args)
+ - The 'target' option in %vp_args will be asked for an action that
+ corresponds with the 'delete_old' controller action
+ - An instance of MyApp::Model::Foo::Action::DeleteOld is
+ returned
+ - This is passed as 'model' to a new instance of
+ Reaction::UI::ViewPort::Action which is then pushed
+ onto the focus stack.
+
+Form processing as provided by L<Reaction::UI::ViewPort::Action> is a very good
+example of Reaction's usefulness; Instead of creating a new dialog for every
+form using myriads of helper functions, you provide a controller baseclass
+rendering the dialog by introspecting an interface model object with fields and
+actions.
+
+Then you just need to create a new controller and interface model for your new
+dialog and it just works.
+
+If your model is a L<DBIx::Class::Schema> and contains L<Moose> metadata, you
+can let L<Reaction::InterfaceModel::Reflector::DBIC> set up your interface
+model objects and actions.
+
+=head1 SKINS, LAYOUTS AND WIDGETS
+
+When you push a viewport onto the focus stack like this:
+
+ $controller->push_viewport('Reaction::UI::ViewPort::SiteLayout');
+
+Reaction will look for a layout file named
+C<$search_path/skin/$skin_name/layout/site_layout.tt>. If it can't find it,
+it will also look in the base skin and search paths.
+
+You can also provide a specific layout:
+
+ $controller->push_viewport(
+ 'Reaction::UI::ViewPort::SiteLayout',
+ layout => 'my_site_layout',
+ );
+
+A new instance of L<Reaction::UI::LayoutSet> will be created using the layout
+file. It is then used to determine the class of widget to create. The widget
+contains the Perl code counterpart of the templating part in the layout file.
+
+The widget is either determined by the C<=widget> template directive in the
+layout file or by the L<Reaction::UI::Skin> object created to represent the
+skin.
+
+The details of skins or layouts are documented in L<Reaction::Manual::Templates>.
+
+=head1 SEE ALSO
+
+=over
+
+=item * L<Reaction::Manual>
+
+=item * L<Reaction::Manual::Intro>
+
+=back
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
--- /dev/null
+=head1 NAME
+
+Reaction::Manual::Tutorial.pod - Step by Step Tutorial
+
+=head1 DESCRIPTION
+
+This document aims at giving simple step-by-step leading to an example application
+using the common functionality provided by L<Reaction>.
+
+=head1 CREATING A NEW APPLICATION
+
+At first we have to create a new application. For this we use the C<catalyst.pl>
+script as we would for any other Catalyst application:
+
+ $ catalyst.pl MyApp
+ [lots "created ..." messages]
+
+There is nothing to change in the application class file.
+
+=head1 THE VIEW
+
+Since we are not just rendering templates with Reaction, but layouts and widgets,
+a simple TT view won't suffice. We need to create our own C<lib/MyApp/View/Site.pm>:
+
+ package MyApp::View::Site;
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Reaction::UI::View::TT';
+
+ __PACKAGE__->meta->make_immutable;
+
+ 1;
+
+The C<use Reaction::Class> line will import L<Moose>, L<strict> and L<warnings> into
+our file and might perform some Reaction specific setups.
+
+We make sure that we don't provide imported functions as methods at runtime by using
+L<namespace::clean>. But we need to C<-except> the C<meta> method that was exported
+by Moose.
+
+In its simplest version, our view just needs to do a C<extends 'Reaction::UI::View::TT'>
+to make a new subclass of it.
+
+We chose to call C<make_immutable> on the class' meta class instance to have it inline
+methods for runtime speed improvements.
+
+=head1 THE ROOT CONTROLLER
+
+As usual in Catalyst, our root controller (at C<lib/MyApp/Controller/Root.pm> represents
+the root namespace for our application. For this purpose, it should look like this:
+
+ package MyApp::Controller::Root;
+ use strict;
+ use warnings;
+ use parent 'Reaction::UI::Controller::Root';
+
+ use aliased 'Reaction::UI::ViewPort';
+ use aliased 'Reaction::UI::ViewPort::SiteLayout';
+
+ use namespace::clean -except => 'meta';
+
+ __PACKAGE__->config(
+ view_name => 'Site',
+ window_title => 'MyApp Window',
+ namespace => '',
+ );
+
+ sub base: Chained('/') PathPart('') CaptureArgs(0) {
+ my ($self, $ctx) = @_;
+ $self->push_viewport(SiteLayout,
+ title => 'MyApp Test Title',
+ static_base_uri => join('', $ctx->uri_for('/static')),
+ );
+ }
+
+ sub root: Chained('base') PathPart('') Args(0) {
+ my ($self, $ctx) = @_;
+ $self->push_viewport(ViewPort, layout => 'root');
+ }
+
+ 1;
+
+The effects of L<strict>, L<warnings>, L<parent>, L<aliased> and L<namespace::clean> should
+be clear by now. Let's take a look at the configuration.
+
+The C<view_name> determines which view to use. We set it to C<Site>, which is our only view
+by now. Be careful to set C<view_name> and not C<view>, which would fail telling you it
+expected an object.
+
+The C<window_title> is the title given to the L<Reaction::UI::Window> instance that will be
+stored in C<$ctx-E<gt>stash-E<gt>{window}> by the C<begin> action provided by
+L<Reaction::UI::Controller::Root>.
+
+The C<namespace> setting anchors the root controller at C</>.
+
+The C<base> action here acts as a general point all other actions can chain off of. It
+pushes the L<Reaction::UI::ViewPort::SiteLayout> viewport onto the
+L<focus stack|Reaction::UI::FocusStack>. As arguments we see a C<title> that will be used
+as page title later. The C<static_base_uri> is used for static links like CSS and JavaScript
+files. Since we didn't specify a layout C<site_layout> will be used.
+
+We also defined a C<root> action serving as application index. It chains off the C<base>
+action. It is only pushing the root viewport L<Reaction::UI::ViewPort> on the focus stack,
+but this time we specified a layout named C<root>.
+
+Reaction will try to find our layout files in C<share/skin/$skin_name/layout/*>, so the next
+thing to do is to create a new skin and the layout files.
+
+=head1 A NEW SKIN
+
+If your version of Catalyst still creates a C<root> instead of a C<share> directory, you
+might want to rename it. This is regarded as a best practice and follows the conventions
+of this tutorial and other Reaction documentation.
+
+First we need to create a directory for our new skin:
+
+ $ mkdir -p share/skin/myapp/layout
+
+Next we need to configure our new skin. This is done in the C<share/skin/myapp/skin.conf>
+file. At the moment, all it should contain is
+
+ extends /Reaction/default
+
+Note that this C<extends> specification contains the distribution name of the
+library or application of which to use the templates as base. You can also give it
+a relative name like
+
+ extends foo
+
+and it would try to extend a skin named C<foo> in your own application's C<share/skin>
+directory.
+
+Now we create C<share/skin/defaults.conf> to allow settings that concern all skins of
+the application. It should contain only this:
+
+ widget_search_path MyApp::View::Site::Widget
+ widget_search_path Reaction::UI::Widget
+
+This will tell Reaction to look in C<Reaction::UI::Widget::*> and
+C<MyApp::View::Site::Widget::*> for widget classes. That means that our layout named
+C<root> will check for C<MyApp::View::Site::Widget::Root> first and then look if
+C<Reaction::UI::Widget> exists.
+
+We want the first line to be able to create our own widgets and the second line to
+have Reaction find its own widgets.
+
+Now we need to tell Reaction what skin it should use. We do this by adding this section
+to our C<myapp.conf>:
+
+ <View Site>
+ skin_name myapp
+ </View>
+
+The value should be the name of the target directory under C<share/skin/>.
+
+=head1 LAYOUTS
+
+We will need two layout files to begin with. One controlling the site layout and one
+for the root action.
+
+The first will be created as C<share/skin/myapp/layout/site_layout.tt>:
+
+ =extends NEXT
+
+ =for layout body
+
+ <h1>Welcome to MyApp</h1>
+
+ <div id="content">
+ [% inner %]
+ </div>
+
+ =cut
+
+The C<=extends> directive specifies that this layout file is an extension of another
+layout file. The C<NEXT> value here tells Reaction that this extends the C<site_layout>
+layout in the base skin, which we have defined as C</Reaction/default>. That means, you
+can take a look at the layout we are extending at C<share/skin/default/layout/site_layout.tt>
+in the L<Reaction> distribution.
+
+The C<=for layout> directives allows us to set a layout fragment. We define a C<body> fragment
+containing the common C<body> for all pages using this site layout. The C<[% inner %]> is
+where the deeper parts of the stack will be included, in the case of our C<root> action that
+would be the C<Reaction::UI::ViewPort> with the C<root> layout.
+
+If we wanted to override a specific fragment, we could do just that. And inside that fragment
+we could call C<[% next_call %]> to include the layout fragment from the extended layout.
+
+The layout representing the root action is called C<share/skin/myapp/layout/root.tt>:
+
+ =for layout widget
+
+ <p>Hello, World!</p>
+
+ =cut
+
+This one is rather simple. The C<=for layout widget> directive is special in that the
+C<widget> fragment will always be where the rendering starts. In fact, our C<site_layout>
+layout too contains a C<widget> fragment, you just don't see it because you inherited it from
+your base skin (or your base skin's base skin, for that matter) instead of defining it yourself.
+
+=head1 A SIMPLE WIDGET
+
+If we wanted to use a different kind of widget than that assumed automatically by Reaction, we
+could add a
+
+ =widget ClassName
+
+directive at the top of the layout file. But for now, we will instead create our own
+widget at C<lib/MyApp/View/Site/Widget/Root.pm>:
+
+ package MyApp::View::Site::Widget::Root;
+ use Reaction::UI::WidgetClass;
+
+ use namespace::clean -except => 'meta';
+
+ __PACKAGE__->meta->make_immutable;
+
+ 1;
+
+This adds no new functionality at the moment. It just uses C<Reaction::UI::WidgetClass> to ease
+and automate the setup of a new widget class. The widget can provide functionality and fragments
+to the layout. In a way, it can be seen as the Perl code backend to the layout file.
+
+You can now start your C<script/myapp_server.pl> and visit
+
+ http://localhost:3000/
+
+to view your "Hello, World" page.
+
+=head1 ADDING A SCHEMA
+
+The next part of the tutorial will be about adding data storage to our application. While most
+L<Catalyst> web applications today (or at least they should) abstract their database schema
+with L<DBIx::Class::Schema> into a separate module separated from the webapplication, Reaction
+takes this one step further by introducing so called interface models. The interface model
+defines the layer between your application and your domain model (in this case, the L<DBIx::Class>
+schema).
+
+The first thing we will need is a schema class:
+
+ package MyApp::Schema;
+ use strict;
+ use warnings;
+
+ use parent 'DBIx::Class::Schema';
+
+ __PACKAGE__->load_classes;
+
+ 1;
+
+The schema class itself is built like a typical L<DBIx::Class::Schema>. The difference in class
+definition starts at the result classes. For the example's sake, let's make a SQLite database
+called C<example.sqlite>:
+
+ $ cat > example.sqlite.sql
+ CREATE TABLE foo (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ first_name VARCHAR NOT NULL,
+ last_name VARCHAR NOT NULL
+ );
+ <Ctrl-D>
+
+ $ sqlite3 example.sqlite < example.sqlite.sql
+ $
+
+The result class for this table combines the usual style of L<DBIx::Class> with L<Moose> meta
+data additions:
+
+ package MyApp::Schema::Foo;
+ use Moose;
+ use MooseX::Types::Moose qw( Int );
+ use Reaction::Types::Core qw( NonEmptySimpleStr );
+
+ use namespace::clean -except => 'meta';
+
+ extends 'DBIx::Class';
+
+ has id =>
+ (is => 'ro', isa => Int, required => 1);
+
+ has first_name =>
+ (is => 'rw', isa => NonEmptySimpleStr, required => 1);
+
+ has last_name =>
+ (is => 'rw', isa => NonEmptySimpleStr, required => 1);
+
+ __PACKAGE__->load_components(qw( IntrospectableM2M Core ));
+ __PACKAGE__->table('foo');
+
+ __PACKAGE__->add_columns(
+ id => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ first_name => { data_type => 'varchar' },
+ last_name => { data_type => 'varchar' },
+ );
+
+ __PACKAGE__->set_primary_key('id');
+
+ 1;
+
+The L<MooseX::Types::Moose> and L<Reaction::Types::Core> modules export L<Moose> type
+constraints (See also L<MooseX::Types> and L<Moose::Util::TypeConstraints>). Note that
+we are using L<Moose/extends> here instead of L<base> or L<parent> to extend
+L<DBIx::Class>.
+
+Next we see our columns in form of Moose attribute definitions. The C<is>, C<isa> and
+C<required> attribute parameters will all be used for introspection and interface
+building later. The C<required> is rather straight-forward. The C<is> will decide whether
+this attribute (or column) can be edited (C<ro> means that it can't, C<rw> means it can).
+The C<isa> attribute will be used for validation and rendering of input fields.
+
+The imported C<NonEmptySimpleStr> for example gives us a simple single-line input box,
+while a C<Str> from L<MooseX::Types::Moose> would give us a textbox.
+
+Following that, we have the usual L<DBIx::Class> result class definitions. The only thing
+different might be the new L<DBIx::Class::IntrospectableM2M> which will allow us to
+inspect many-to-many relations later on.
+
+=head1 CREATING AN INTERFACE MODEL
+
+The interface model should be separated from the application and the schema, since it
+will tie both together. In this case, we will use a reflector to set up the usual interface
+model actions for our schema (C<Create>, C<Update>, C<Delete>, C<DeleteAll>):
+
+ package MyApp::InterfaceModel::DBIC;
+
+ # keep this on top
+ use parent 'Reaction::InterfaceModel::Object';
+
+ use Reaction::Class;
+ use Reaction::InterfaceModel::Reflector::DBIC;
+
+ use namespace::clean -except => 'meta';
+
+ my $reflector = Reaction::InterfaceModel::Reflector::DBIC->new;
+
+ $reflector->reflect_schema(
+ model_class => __PACKAGE__,
+ schema_class => 'MyApp::Schema',
+ );
+
+ __PACKAGE__->meta->make_immutable;
+
+ 1;
+
+The L<parent> import must happen before the L<Reaction::Class> one in this case. Other
+than that, the only thing we do here is create a new L<Reaction::InterfaceModel::Reflector::DBIC>
+and call C<reflect_schema> to build our C<MyApp::InterfaceModel::DBIC::*> namespace out of our
+C<MyApp::Schema>.
+
+=head1 TIEING THE INTERFACE MODEL TO THE APPLICATION
+
+Next on the list is the integration of our new interface model into our application. For
+this we create a simple catalyst model in C<lib/MyApp/Model/DBIC.pm>:
+
+ package MyApp::Model::DBIC;
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Catalyst::Model::Reaction::InterfaceModel::DBIC';
+
+ __PACKAGE__->meta->make_immutable;
+
+ __PACKAGE__->config(
+ im_class => 'MyApp::InterfaceModel::DBIC',
+ db_dsn => 'dbi:SQLite:example.sqlite',
+ );
+
+ 1;
+
+This model L<extends|Moose> the L<Catalyst::Model::Reaction::InterfaceModel::DBIC> base class
+shipped with Reaction. It's configuration must contain the C<im_class> naming our interface
+model and the C<db_dsn>. Of course, since this is Catalyst, this can also easily be specified
+via your application config file under the C<Model::DBIC> key.
+
+=head1 BUILDING A SIMPLE CRUD CONTROLLER
+
+Now, since we have defined our interface model as well as our domain model including meta
+data, it isn't very hard (at least not for us) to build a basic (but extendable) CRUD controller:
+
+ package MyApp::Controller::Foo;
+ use strict;
+ use warnings;
+
+ use parent 'Reaction::UI::Controller::Collection::CRUD';
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ __PACKAGE__->config(
+ model_name => 'DBIC',
+ collection_name => 'Foo',
+ actions => {
+ base => { Chained => '/base', PathPart => 'foo' },
+ },
+ );
+
+ 1;
+
+This controller subclasses L<Reaction::UI::Controller::Collection::CRUD>, which is itself a
+subclass of L<Reaction::UI::Controller::Collection>, a class to ease the creation of controllers
+who act on collections of things.
+
+As you can see, for the simplest case we don't need any code; we simply configure our controller.
+
+The C<model_name> is the name of our interface model sans the C<MyApp::Model::> prefix. This means
+this entry points to C<MyApp::Model::DBIC> in this case. The C<collection_name> is the name of
+the collection in the specified interface model. For us, this would be C<Foo>, like the result
+class we created above and want to manage.
+
+The C<actions> part of the configuration is not Reaction, but rather Catalyst specific. This
+configures the actions inherited from L<Reaction::UI::Controller::Collection::CRUD>. For it to
+work, we only need to tell the C<base> action where to chain off from, and what C<PathPart>
+to use. We chain it to the C<base> action in our root controller. The C<foo> path part is rather
+obvious.
+
+Now you can restart your application and visit
+
+ http://localhost:3000/foo
+
+and you have a complete CRUD interface for C<Foo> with listing, viewing, creating, updating
+and deleting capabilities.
+
+=head1 SEE ALSO
+
+=over
+
+=item * L<Reaction::Manual>
+
+=item * L<Reaction::Manual::Intro>
+
+=item * L<Reaction::Manual::Overview>
+
+=item * L<Reaction::Manual::Templates>
+
+=item * L<Reaction::Manual::RenderPage>
+
+=item * L<Reaction::UI::View::TT>
+
+=item * L<Reaction::UI::Controller::Root>
+
+=item * L<Reaction::UI::WidgetClass>
+
+=back
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
=head1 NAME
-Reaction::UI::Controller
+Reaction::UI::Controller - Reaction Base Controller Class
+
+=head1 SYNOPSIS
+
+ package MyApp::Controller::Foo;
+ use strict;
+ use warnings;
+ use parent 'Reaction::UI::Controller';
+
+ use aliased 'Reaction::UI::ViewPort';
+
+ sub foo: Chained('/base') Args(0) {
+ my ($self, $ctx) = @_;
+
+ $ctx->push_viewport(ViewPort,
+ layout => 'foo',
+ );
+ }
+
+ 1;
=head1 DESCRIPTION
=head1 NAME
-Reaction::UI::ViewPort::Action
+Reaction::UI::ViewPort::Action - Provide user with a form with OK, Apply and Close.
=head1 SYNOPSIS
+ $controller->push_viewport('Reaction::UI::ViewPort::Action',
+ model => $interface_model_action,
+ field_order => [qw( firstname lastname )],
+ excluded_fields => [qw( password )],
+ );
+
=head1 DESCRIPTION
This subclass of L<Reaction::UI::ViewPort::Object::Mutable> is used for
=head1 ATTRIBUTES
+=head2 message
+
+=head2 model
+
+Inherited from L<Reaction::UI::ViewPort::Object::Mutable>. Must be a
+L<Reaction::InterfaceModel::Action>.
+
+Also handles C<error_message> and C<has_error_message> methods.
+
=head2 method
post / get
=head2 can_apply
+Returns true if no field C<needs_sync> and the L</model> C<can_apply>.
+
=head2 do_apply
+Delegates to C<do_apply> on the L</model>, which is a
+L<Reaction::InterfaceModel::Action>.
+
=head2 sync_action_from_fields
+Firstly calls C<sync_to_action> on every L<Reaction::UI::ViewPort::Field::Mutable>
+in L<fields|Reaction::UI::ViewPort::Object/fields>. Then it calls C<sync_all> on
+the L<Reaction::InterfaceModel::Action> in L</model>. Next it will call
+C<sync_from_action> on every field to repopulate them from the L</model>.
+
+=head1 SUBCLASSING
+
+ package MyApp::UI::ViewPort::Action;
+ use Reaction::Class;
+ use MooseX::Types::Moose qw( Int );
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Reaction::UI::ViewPort::Action';
+
+ has render_timestamp => (
+ is => 'ro',
+ isa => Int,
+ default => sub { time },
+ required => 1,
+ );
+
+ has '+field_order' => (default => sub {[qw( firstname lastname )]});
+
+ 1;
+
=head1 SEE ALSO
L<Reaction::UI::ViewPort>
=head1 NAME
-Reaction::UI::ViewPort::Action::Role::Apply
+Reaction::UI::ViewPort::Action::Role::Apply - Integrate an Apply event into the ViewPort
+
+=head1 SYNOPSIS
+
+ package MyApp::UI::ViewPort::SomeAction;
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Reaction::UI::ViewPort::Object::Mutable';
+ with 'Reaction::UI::ViewPort::Action::Role::Apply';
+
+ ...
+ 1;
+
+=head1 DESCRIPTION
+
+This role integrates an C<apply> event into the consuming viewport that will call the
+required L</do_apply> role.
+
+=head1 REQUIRED METHODS
+
+=head2 do_apply
+
+Will be called when an L</apply> event comes in.
=head1 ATTRIBUTES
=head2 apply_label
-Default: 'apply'
+Defaults to 'apply', returned by L</_build_apply_label>.
=head2 on_apply_callback
-CodeRef.
+CodeRef. Will be called after L</apply> if L</can_apply> and L</do_apply> return
+true. See L</apply> for argument details.
=head1 METHODS
=head2 can_apply
+Returns true by default. Determines if L</do_apply> can be called.
+
=head2 apply
Calls a user-supplied C<do_apply> and if it is successful runs the
C<on_apply_callback> passing C<$self> and the result of C<do_apply> as args.
+=head1 INTERNAL METHODS
+
+=head2 _build_apply_label
+
+Defaults to C<apply>.
+
=head1 SEE ALSO
L<Reaction::UI::ViewPort::Action::Role::Close>
=head1 NAME
-Reaction::UI::ViewPort::Action::Role::Close
+Reaction::UI::ViewPort::Action::Role::Close - Integrate Close and Apply events into ViewPort
+
+=head1 SYNOPSIS
+
+ package MyApp::UI::ViewPort::SomeAction;
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Reaction::UI::ViewPort::Object::Mutable';
+ with 'Reaction::UI::ViewPort::Action::Role::Close';
+
+ ...
+ 1;
+
+=head1 DESCRIPTION
+
+This role integrates a C<close> event and inherits an
+L<apply|Reaction::UI::ViewPort::Action::Role::Close/apply>
+event into the consuming viewport.
=head1 ATTRIBUTES
=head2 close_label
-Default: C<close_label_close>
+Defaults to returned string value of L</_build_close_label> (C<close>).
=head2 close_label_close
-Default: 'close'
+Defaults to returned string value of L</_build_close_label_close> (C<close>).
=head2 close_label_cancel
-This label is only shown when C<changed> is true.
+This label is only shown when C<changed> is true. It is initialised
+with the returned string value of L</_build_close_label_cancel>.
Default: 'cancel'
=head2 on_close_callback
-CodeRef.
+CodeRef. If set will be called on L</close>.
=head1 METHODS
=head2 close
+Calls L</on_close_callback> if one is set.
+
=head2 can_close
+Returns true.
+
+=head2 apply
+
+Extends L<Reaction::UI::ViewPort::Action::Role::Apply/apply> and sets
+the L</close_label> to L</close_label_cancel> if the original call to
+C<apply> was not successfull.
+
+Returns the result of the original C<apply> call.
+
+=head2 accept_events
+
+Extends L<Reaction::UI::ViewPort::Action::Role::Apply/accept_events>
+with the C<close> event if an L</on_close_callback> was provided.
+
=head1 SEE ALSO
L<Reaction::UI::ViewPort::Action::Role::Apply>
=head1 NAME
-Reaction::UI::ViewPort::Action::Role::Close
+Reaction::UI::ViewPort::Action::Role::OK - Integrate OK, Apply and Close events
+
+=head1 SYNOPSIS
+
+ package MyApp::UI::ViewPort::SomeAction;
+ use Reaction::Class;
+
+ use namespace::clean -except => 'meta';
+
+ extends 'Reaction::UI::ViewPort::Object::Mutable';
+ with 'Reaction::UI::ViewPort::Action::Role::OK';
+
+ ...
+ 1;
+
+=head1 DESCRIPTION
+
+This role integrates an C<ok> event and inherits a
+L<close|Reaction::UI::ViewPort::Action::Role::Close/close>
+and an L<apply|Reaction::UI::ViewPort::Action::Role::Apply/apply>
+event into the consuming viewport.
=head1 ATTRIBUTES
=head2 ok_label
-Default: 'ok'
+Defaults to C<ok>. String is built by L</_build_ok_label>.
=head1 METHODS
Calls C<apply>, and then C<close> if successful.
+=head2 accept_events
+
+Extends L<Reaction::UI::ViewPort::Action::Role::Close/accept_events> with the
+event C<ok> if an L<on_close_callback|Reaction::UI::ViewPort::Action::Role::Close/on_close_callback>
+was provided.
+
+=head1 INTERNAL METHODS
+
+=head2 _build_ok_label
+
+Returns the string representing the label for the OK action. Defaults to C<ok>.
+
=head1 SEE ALSO
L<Reaction::UI::ViewPort::Action::Role::Apply>
=head1 NAME
-Reaction::UI::ViewPort::Object
+Reaction::UI::ViewPort::Object - Display an InterfaceModel::Object
+
+=head1 SYNOPSIS
+
+ use aliased 'Reaction::UI::ViewPort::Object';
+
+ ...
+ $controller->push_viewport(Object,
+ model => $person_interface_model_object,
+ fields_order => [qw( firstname lastname )],
+ excluded_fields => [qw( password )],
+ );
=head1 DESCRIPTION
+Takes a L<Reaction::InterfaceModel::Object> class and displays the
+configured fields.
+
=head1 ATTRIBUTES
=head2 model
+Required L<Reaction::InterfaceModel::Object>.
+
=head2 fields
+Initialised via L</_build_fields>
+
=head2 field_args
+Hash reference keyed by field names. Values are hash references containing
+arguments to the field builder method of the attribute.
+
=head2 field_order
+Array reference of strings defining the order of all fields (including
+the ones that might be excluded).
+
=head2 builder_cache
+Hash reference containing resolved builder method names per field. Utilised
+by L</_build_fields>
+
=head2 excluded_fields
+Array reference of strings naming fields to exclude from the interface.
+
=head2 computed_field_order
+Array reference of strings Initialised by the L</_computed_field_order> method.
+Contains the fields to show in the correct order.
+
+=head2 containers
+
+Array reference populated by L</_build_containers>.
+
+=head2 container_layouts
+
+Array reference containing container layout specifications.
+
=head1 INTERNAL METHODS
These methods, although stable, are subject to change without notice. These are meant
=head2 BUILD
+Takes the value of the C<Field> constructor argument, if true, and sets it as
+the new L</field_args> hash reference.
+
=head2 get_builder_for
+Takes an attribute object as argument and returns a string containing
+the name of the method that builds the fields for this attribute.
+
+If the viewport implements it, C<_build_fields_for_name_${attr_name}> will be used.
+
+If that is not available, it will take the C<isa> information of the type constraint
+and see if it is a loaded class implementing C<meta>. If it is, every class in its
+C<class_precedence_list> will be taken and used to try to find a
+C<_build_fields_for_type_${mangled_class_name}> method on the viewport.
+
+"mangled" means here that every C<:*> will be replaced with C<_>. For example:
+C<Foo::Bar> would become C<Foo_Bar>.
+
+If the C<isa> information was not obtainable or no fitting method was found, it will
+try the type name in a method named C<_build_fields_for_type_${mangled_type_name}>.
+
+If could be found on this constraint, it will make the same attempts to find a
+method on its parent type constraint.
+
+This method will die if it can't locate a method to build a field for this
+attribute.
+
+=head2 _build_containers
+
+Uses L</container_layouts> to build a list of L<Reaction::UI::ViewPort::Field::Container>
+objects.
+
+=head2 _build_fields
+
+Takes the L</model>s C<parameter_attributes> to build fields via L</get_builder_for>.
+They will be ordered as specified in L</computed_field_order>.
+
+=head2 _build_computed_field_order
+
+Takes the names of the L</model>s C<parameter_attributes>' reader methods and assumes
+them as field names. Then it uses L</field_order> and L</excluded_fields> to calculate
+the order of all included fields and returns those names.
+
=head2 _build_simple_field
+ $self->_build_simple_field(
+ attribute => $attribute_object,
+ class => $field_class,
+ %field_attrs,
+ );
+
+Takes an attribute meta object, a field class (a L<Reaction::UI::ViewPort::Field> subclass)
+and an additional set of arguments to pass to the field constructor and returns the new
+field. Field classes themselves are L<Reaction::UI::ViewPort> subclasses.
+
=head2 _build_fields_for_type_Num
=head2 _build_fields_for_type_Int
=head2 _build_fields_for_type_Reaction_InterfaceModel_Collection
+=head1 FIELD TYPES
+
+L<Text|Reaction::UI::ViewPort::Field::Text>,
+L<Number|Reaction::UI::ViewPort::Field::Number>,
+L<Integer|Reaction::UI::ViewPort::Field::Integer>,
+L<Boolean|Reaction::UI::ViewPort::Field::Boolean>,
+L<String|Reaction::UI::ViewPort::Field::String>,
+L<DateTime|Reaction::UI::ViewPort::Field::DateTime>,
+L<RelatedObject|Reaction::UI::ViewPort::Field::RelatedObject>,
+L<Array|Reaction::UI::ViewPort::Field::Array>,
+L<Collection|Reaction::UI::ViewPort::Field::Collection>,
+L<File|Reaction::UI::ViewPort::Field::File>,
+L<Container|Reaction::UI::ViewPort::Field::Container>
+
=head1 AUTHORS
See L<Reaction::Class> for authors.
=head1 NAME
-Reaction::UI::ViewPort::Object::Mutable
+Reaction::UI::ViewPort::Object::Mutable - Allow the user to to perform an InterfaceModel Action
=head1 SYNOPSIS
+ use aliased 'Reaction::UI::ViewPort::Object::Mutable';
+
+ ...
+ $controller->push_viewport(Mutable,
+ model => $interface_model_action,
+ );
+
=head1 DESCRIPTION
This subclass of L<Reaction::UI::ViewPort::Object> is used for rendering a
=head1 METHODS
+=head2 is_modified
+
+Returns true if any of the L<fields|Reaction::UI::ViewPort::Object/fields> has been
+modified.
+
+=head1 INTERNAL METHODS
+
+The builder methods are resolved in the same way as described in L<Reaction::UI::ViewPort::Object>,
+but they create L<Reaction::UI::ViewPort::Field::Mutable> objects.
+
+=head2 Mutable Field Types
+
+L<Text|Reaction::UI::ViewPort::Field::Mutable::Text>,
+L<Array|Reaction::UI::ViewPort::Field::Mutable::Array>,
+L<String|Reaction::UI::ViewPort::Field::Mutable::String>,
+L<Number|Reaction::UI::ViewPort::Field::Mutable::Number>,
+L<Integer|Reaction::UI::ViewPort::Field::Mutable::Integer>,
+L<Boolean|Reaction::UI::ViewPort::Field::Mutable::Boolean>,
+L<Password|Reaction::UI::ViewPort::Field::Mutable::Password>,
+L<DateTime|Reaction::UI::ViewPort::Field::Mutable::DateTime>,
+L<ChooseOne|Reaction::UI::ViewPort::Field::Mutable::ChooseOne>,
+L<ChooseMany|Reaction::UI::ViewPort::Field::Mutable::ChooseMany>,
+L<Files|Reaction::UI::ViewPort::Field::Mutable::File>
+
=head2 _build_fields_for_type_Num
=head2 _build_fields_for_type_Int