Reaction::Manual::Overview(3)

NAME
Reaction::Manual::Overview - Orientation in Reaction

DESCRIPTION
This document aims at describing the modular parts of Reaction and explain how they are tied together.

WHAT IS REACTION
Reaction is a Catalyst extension providing you with:

•   Model mutations abstracted into Action objects.

•   Reflection to generate interface models using the Action objects from a DBIx::Class schema.

•   An abstract UI expression system based on view, skin, rendering context, widget and layout set.

•   Stylable via skins. Parts of the skins can be extended and flexibly from large down to very small parts.

•   Full separation of interface rendering structure and templating, making re-usable extensions even easier.

THE BIG PICTURE
          .=========.
          | Request |
          '========='
               |
               |
               v
    .--------------------.   .============================.
    |  Web Application   |   |      Interface Model       |
    | Action Dispatching |<--| Object, Collection, Action |
    '--------------------'   '============================'
               |                            ^
               v                            |
    .====================.        .-------------------.
    |      ViewPort      |        |   Domain Model    |
    | Plain, Collection, |        |  Business Logic,  |
    |   Object, Action   |        | Persistence Layer |
    '===================='        '-------------------'
               |
               v
    .====================.
    |     FocusStack     |
    | Contains ViewPorts |
    '===================='
               |
               v
         .-----------.     .===================.
         |   View    |     | RenderingContext  |
         | HTML, PDF |---->| Template Toolkit  |----.
         '-----------'     '==================='    |
               |                     ^              |
               v                     |              |
   .======================.          |              |
   | LayoutSet / ViewPort |          |              |
   | Layouts: widget, foo |          |              |
   '======================'          |              |
               |                     |              |
               v                     |              |
  .========================.         |              |
  |   Widget / LayoutSet   |         |              |
  | Fragments: widget, foo |---------'              v
  '========================'                  .==========.
                                              | Response |
                                              '=========='

APPLICATION
A Reaction application is really a Catalyst application under the hood. Reaction uses reflection to build more flexible and re-usable Catalyst components.

The main application module (usually called "MyApp" or "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.

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 Reaction::InterfaceModel::Action subclass. Examples for such actions would be "Create", "Update" or "Delete" in a CRUD situation.

Controllers that use Reaction have to inherit from Reaction::UI::Controller or a subclass of it. Some other useful controller base classes are:

•   Reaction::UI::Controller::Root should be the base for the root controller to every chain of Reaction actions. It will provide a "base" action you can chain to which will make sure the window viewport and focus stack are set up.

•   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.

•   Reaction::UI::Controller::Collection::CRUD is a subclass of the above and provides additional "create", "update", "delete" and "delete_all" actions.

VIEWPORTS
Viewports represent the components that render your page when combined.

The "begin" action in Reaction::Controller::Root creates a new Reaction::UI::Window object and stores it as "window" in the stash. The focus stack 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 "push_viewport" method available on your controller:

  $controller->push_viewport($viewport_class, %viewport_args);

This will add a new instance of $viewport_class to the current focus stack using %viewport_args as arguments. For more information on the usage and other options (for example the "next_action" option, which redirects afterwards) see Reaction::UI::FocusStack and Reaction::UI::ViewPort.

You can use the Reaction::UI::ViewPort::Action viewport to build viewports that perform typical form actions like OK, Apply and Close.

FOCUSSTACKS
Viewports are pushed onto the current focus stack. The "end" action in Reaction::Controller::Root will "flush" the Reaction::UI::Window object stored as "window" in the stash.

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 interface models as a separation between the two.

If you want your domain model to be reflectable (DBIx::Class for example) you will have to use Moose to add attribute metadata to those classes.

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 Reaction::InterfaceModel::Action. These instances will have both the request context and the target model available and can do their work in a "do_apply" method.

To allow your own models to be tied in to reflective controllers like Reaction::Controller::Collection, you can subclass 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 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 DBIx::Class::Schema and contains Moose metadata, you can let Reaction::InterfaceModel::Reflector::DBIC set up your interface model objects and actions.

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 "$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 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 "=widget" template directive in the layout file or by the Reaction::UI::Skin object created to represent the skin.

The details of skins or layouts are documented in Reaction::Manual::Templates.

SEE ALSO

•   Reaction::Manual

•   Reaction::Manual::Intro

AUTHORS
See Reaction::Class for authors.

LICENSE
See Reaction::Class for the license.

POD ERRORS
Hey! The above document had some coding errors, which are explained below:

Around line 41:
    Unknown directive: =bac

Around line 43:
    You forgot a '=back' before '=head1'