aboutsummaryrefslogtreecommitdiffstats
path: root/old
diff options
context:
space:
mode:
authoredenc <edenc@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2007-12-17 18:45:59 +0000
committeredenc <edenc@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2007-12-17 18:45:59 +0000
commit7ff308905da567a0ac9fbebf63a04ede5696cded (patch)
tree9f3459ea447365f447d9b7ad22f4edbeaca45c79 /old
parent1f9daa1e4b71e08c2c3eae0e0c4cb8fde983dd2d (diff)
downloadreaction-7ff308905da567a0ac9fbebf63a04ede5696cded.tar.gz
reaction-7ff308905da567a0ac9fbebf63a04ede5696cded.zip
moved docs to /old
Diffstat (limited to 'old')
-rw-r--r--old/Manual.pod47
-rw-r--r--old/Manual/Cookbook.pod74
-rw-r--r--old/Manual/Example.pod304
-rw-r--r--old/Manual/FAQ.pod101
-rw-r--r--old/Manual/Internals.pod270
-rw-r--r--old/Manual/Intro.pod62
6 files changed, 858 insertions, 0 deletions
diff --git a/old/Manual.pod b/old/Manual.pod
new file mode 100644
index 0000000..ab366cc
--- /dev/null
+++ b/old/Manual.pod
@@ -0,0 +1,47 @@
+=head1 NAME
+
+Reaction::Manual - The Index of The Manual
+
+=head1 DESCRIPTON
+
+Reaction is basically an extended MVC framework built upon L<Catalyst>.
+
+=head1 SECTIONS
+
+=head2 L<Reaction::Manual::Intro>
+
+=head2 L<Reaction::Manual::Example>
+
+=head2 L<Reaction::Manual::Cookbook>
+
+=head2 L<Reaction::Manual::Internals>
+
+=head2 L<Reaction::Manual::FAQ>
+
+=head1 SEE ALSO
+
+=over
+
+=item * L<Catalyst::Manual>
+
+=item * L<DBIx::Class::Manual>
+
+=item * L<Moose>
+
+=item * L<Template::Toolkit>
+
+=back
+
+=head1 SUPPORT
+
+IRC: Join #reaction on irc.perl.org
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/old/Manual/Cookbook.pod b/old/Manual/Cookbook.pod
new file mode 100644
index 0000000..e04c6ee
--- /dev/null
+++ b/old/Manual/Cookbook.pod
@@ -0,0 +1,74 @@
+=head1 NAME
+
+Reaction::Manual::Cookbook - Miscellaneous recipes
+
+=head1 RECIPES
+
+These should include some hopefully useful tips and tricks!
+
+=head2 Display
+
+These would typically go in your /root directory along with your other
+templates.
+
+=head3 Alternating listview row styles with CSS
+
+Filename: listview
+
+ [%
+
+ PROCESS base/listview;
+
+ row_block = 'listview_row_fancy';
+
+ BLOCK listview_row_fancy;
+
+ IF loop.count % 2 == 1;
+ attrs.class = 'dark';
+ ELSE;
+ attrs.class = 'light';
+ END;
+
+ INCLUDE listview_row;
+
+ END;
+
+ %]
+
+=head3 Displaying heading on action forms
+
+Filename: form_base
+
+ [%
+
+ PROCESS base/form_base;
+
+ main_block = 'form_base_control_fancy';
+
+ BLOCK form_base_control_fancy;
+
+ action_class = self.action.meta.name.split('::').pop;
+ '<h3>'; action_class.split('(?=[A-Z])').join(' '); '</h3>';
+ INCLUDE form_base_control;
+
+ END;
+
+ %]
+
+=head2 Controllers
+
+Things
+
+=head2 Models
+
+Stuff
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/old/Manual/Example.pod b/old/Manual/Example.pod
new file mode 100644
index 0000000..02a55fe
--- /dev/null
+++ b/old/Manual/Example.pod
@@ -0,0 +1,304 @@
+=head1 NAME
+
+Reaction::Manual::Example - Simple Reaction example
+
+=head1 DESCRIPTION
+
+This tutorial will guide you through the process of setting up and testing a
+very basic CRUD application based on the database from
+L<DBIx::Class::Manual::Example>.
+
+You need at least a fairly basic understanding of L<DBIx::Class::Schema> for
+this example to have value for you.
+
+=head2 Installation
+
+Install L<DBIx::Class> via CPAN.
+
+Install Reaction from http://code2.0beta.co.uk/reaction/svn via SVN or SVK.
+
+Set up the database as mentioned in L<DBIx::Class::Manual::Example>. Don't do
+any of the DBIx::Class related stuff, only the SQLite database.
+
+=head2 Create the application
+
+ catalyst.pl Test::Reaction
+ cd Test-Reaction
+ script/test_reaction_create.pl Model Test::Reaction DBIC::Schema Test::Reaction::DB
+
+Also, remember to include Catalyst::Plugin::I18N in your plugin list, like
+this:
+
+ use Catalyst qw/-Debug ConfigLoader Static::Simple I18N/;
+
+=head2 Set up DBIx::Class::Schema
+
+In addition to the normal DBIC stuff, you need to moosify your DBIC classes.
+
+Change directory back from db to the directory app:
+
+ cd lib/Test/Reaction
+ mkdir DB
+
+Then, create the following DBIx::Class::Schema classes:
+
+DB.pm:
+
+ package Test::Reaction::DB;
+
+ use base 'DBIx::Class::Schema';
+
+ __PACKAGE__->load_classes;
+
+ 1;
+
+DB/Artist.pm:
+
+ package Test::Reaction::DB::Artist;
+
+ use base 'DBIx::Class';
+ use Reaction::Class;
+
+ has 'artistid' => ( isa => 'Int', is => 'ro', required => 1 );
+ has 'name' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 );
+
+ sub display_name {
+ my $self = shift;
+ return $self->name;
+ }
+
+ __PACKAGE__->load_components(qw/PK::Auto Core/);
+ __PACKAGE__->table('artist');
+ __PACKAGE__->add_columns(qw/ artistid name /);
+ __PACKAGE__->set_primary_key('artistid');
+ __PACKAGE__->has_many( 'cds' => 'Test::Reaction::DB::Cd' );
+
+ 1;
+
+DB/Cd.pm:
+
+ package Test::Reaction::DB::Cd;
+
+ use base 'DBIx::Class';
+ use Reaction::Class;
+
+ has 'cdid' => ( isa => 'Int', is => 'ro', required => 1 );
+ has 'artist' =>
+ ( isa => 'Test::Reaction::DB::Artist', is => 'rw', required => 1 );
+ has 'title' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 );
+
+ sub display_name {
+ my $self = shift;
+ return $self->title;
+ }
+
+ __PACKAGE__->load_components(qw/PK::Auto Core/);
+ __PACKAGE__->table('cd');
+ __PACKAGE__->add_columns(qw/ cdid artist title/);
+ __PACKAGE__->set_primary_key('cdid');
+ __PACKAGE__->belongs_to( 'artist' => 'Test::Reaction::DB::Artist' );
+ __PACKAGE__->has_many( 'tracks' => 'Test::Reaction::DB::Track' );
+
+ 1;
+
+DB/Track.pm:
+
+ package Test::Reaction::DB::Track;
+
+ use base 'DBIx::Class';
+ use Reaction::Class;
+
+ has 'trackid' => ( isa => 'Int', is => 'ro', required => 1 );
+ has 'cd' => ( isa => 'Test::Reaction::DB::Cd', is => 'rw', required => 1 );
+ has 'title' => ( isa => 'NonEmptySimpleStr', is => 'rw', required => 1 );
+
+ __PACKAGE__->load_components(qw/PK::Auto Core/);
+ __PACKAGE__->table('track');
+ __PACKAGE__->add_columns(qw/ trackid cd title/);
+ __PACKAGE__->set_primary_key('trackid');
+ __PACKAGE__->belongs_to( 'cd' => 'Test::Reaction::DB::Cd' );
+
+ 1;
+
+=head3 Reaction attributes
+
+See L<Reaction::Types::Core>
+
+=head3 The rest
+
+Reaction will use I<sub display_name> for displaying when there is a 1:Many or
+Many:Many relation. It will return a suitable text representation.
+
+=head2 Models
+
+=head3 Create Test::Reaction::Model::Action
+
+Still in lib/Test/Reaction, create
+
+Model/Action.pm:
+
+ package Test::Reaction::Model::Action;
+
+ use Reaction::Class;
+
+ use Test::Reaction::DB;
+
+ use aliased 'Reaction::InterfaceModel::Action::DBIC::ActionReflector';
+
+ my $r = ActionReflector->new;
+
+ $r->reflect_actions_for( 'Test::Reaction::DB::Artist' => __PACKAGE__ );
+ $r->reflect_actions_for( 'Test::Reaction::DB::Cd' => __PACKAGE__ );
+ $r->reflect_actions_for( 'Test::Reaction::DB::Track' => __PACKAGE__ );
+
+ 1;
+
+=head2 Controllers
+
+Reaction controllers inherit from Reaction::UI::CRUDController, like this:
+
+Controller/Artist.pm
+
+ package Test::Reaction::Controller::Artist;
+
+ use strict;
+ use warnings;
+ use base 'Reaction::UI::CRUDController';
+ use Reaction::Class;
+
+ __PACKAGE__->config(
+ model_base => 'Test::Reaction',
+ model_name => 'Artist',
+ action => { base => { Chained => '/base', PathPart => 'artist' } }
+ );
+
+ 1;
+
+Controller/Cd.pm
+
+ package Test::Reaction::Controller::Cd;
+
+ use strict;
+ use warnings;
+ use base 'Reaction::UI::CRUDController';
+ use Reaction::Class;
+
+ __PACKAGE__->config(
+ model_base => 'Test::Reaction',
+ model_name => 'Cd',
+ action => { base => { Chained => '/base', PathPart => 'cd' } }
+ );
+
+ 1;
+
+Controller/Track.pm
+
+ package Test::Reaction::Controller::Track;
+
+ use strict;
+ use warnings;
+ use base 'Reaction::UI::CRUDController';
+ use Reaction::Class;
+
+ __PACKAGE__->config(
+ model_base => 'Test::Reaction',
+ model_name => 'Track',
+ action => { base => { Chained => '/base', PathPart => 'track' } }
+ );
+
+ 1;
+
+Finally, change Controller/Root.pm to
+
+ package Test::Reaction::Controller::Root;
+
+ use strict;
+ use warnings;
+ use base 'Reaction::UI::RootController';
+ use Reaction::Class;
+
+ use aliased 'Reaction::UI::ViewPort';
+ use aliased 'Reaction::UI::ViewPort::ListView';
+ use aliased 'Reaction::UI::ViewPort::ActionForm';
+
+ __PACKAGE__->config->{namespace} = '';
+
+ sub base :Chained('/') :PathPart('') :CaptureArgs(0) {
+ my ($self, $c) = @_;
+
+ $self->push_viewport(ViewPort, layout => 'xhtml');
+ }
+
+ sub root :Chained('base') :PathPart('') :Args(0) {
+ my ($self, $c) = @_;
+
+ $self->push_viewport(ViewPort, layout => 'index');
+ }
+
+ 1;
+
+=head2 View
+
+View/XHTML.pm looks like this
+
+ package Test::Reaction::View::XHTML;
+
+ use Reaction::Class;
+
+ extends 'Reaction::UI::Renderer::XHTML';
+
+ 1;
+
+This is all the perly stuff. Now return to the base Test-Reaction directory and
+create root/index:
+
+ [%
+
+ main_block = 'index';
+
+ BLOCK index;
+
+ %]<p><a href="[% ctx.uri_for('/artist') %]">artist</a></p>
+ <p><a href="[% ctx.uri_for('/cd') %]">cd</a></p>
+ <p><a href="[% ctx.uri_for('/track') %]">track</a></p>[%
+
+ END;
+
+ %]
+
+=head2 Running
+
+Now all that remains is to tell catalyst about the root and the model. Let
+test_reaction.yml look like this:
+
+ ---
+ name: Test::Reaction
+ Controller::Root:
+ view_name: 'XHTML'
+ window_title: 'Reaction Test App'
+ Model::Test::Reaction:
+ schema_class: 'Test::Reaction::DB'
+ connect_info:
+ - 'dbi:SQLite:dbname=database/example.db'
+
+The finals step for this example is to link to Reaction's templates:
+
+ ln -s <path to reaction install directory>/root/base/ root/base
+
+At last you're now ready to run the server
+
+ script/test_reaction_server.pl
+
+=head1 Notes
+
+=head1 TODO
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/old/Manual/FAQ.pod b/old/Manual/FAQ.pod
new file mode 100644
index 0000000..96f20fd
--- /dev/null
+++ b/old/Manual/FAQ.pod
@@ -0,0 +1,101 @@
+=head1 NAME
+
+Reaction::Manual::FAQ
+
+=head2 INTRODUCTION
+
+=head3 What is Reaction?
+
+Reaction is an MVCish framework that is designed with two goals in mind:
+"don't repeat yourself" and "components rule."
+
+=head3 How is it different from other MVC frameworks?
+
+Reaction is more flexible and abstract. Web development is only a specialized
+set of what Reaction is designed to provide - the inner classes are general
+enough to be used in many different environments and for solving non-web
+problems.
+
+It is planned to go a lot further than just the web - we want to develop GUIs
+and CLIs as easily and painlessly as possible, using Reaction. How about
+writing your web application and instantly getting a CLI to go with it? That's
+only part of the flexibility we have in mind.
+
+=head3 How is it different from Catalyst?
+
+Catalyst is MVC-based whereas Reaction splits the Model into 2 parts: The
+"Domain Model" and the "Interface Model." Web development is only a sample of
+what Reaction can do - but it already comes bundled with the basic components
+that you would have to program in Catalyst. At the moment, Reaction runs on
+Catalyst for web development.
+
+=head3 What's a Domain?
+
+A domain is the field where an abstraction makes sense. For example, to build
+a web site a programmer may come up with an abstraction of a User, Products,
+User roles, etc. These concepts are just one particular implementation of all
+the possible abstractions for that web site -- the set of all these possible
+abstractions make up the Domain.
+
+=head3 What's a Domain Model?
+
+A Domain Model is an actual computational model of an abstraction. In most
+cases these models are business-based, as in the set of objects that make up
+the representation for a particular domain, such as Users, Products, User
+Roles, etc.
+
+=head3 What's an Interface Model?
+
+A well defined model for the common operations involved in a particular mode
+of interaction with the domain. In other words, it's a layer around the Domain
+Model that provides interaction with it. One example would be an authorization
+procedure for different views of the same data, based on user's credentials.
+
+=head3 I'm lost! What does "Model" mean?
+
+The term "model" can mean two things: "model as in Computer Model" and "Model
+as in MVC". For this document, the former will be written as just "Model"
+whereas the latter will be referred to as "Model as in MVC."
+
+=head3 Haven't I seen these definitions elsewhere?
+Yes, similar terms have been used in Java-land and Smalltalk-ville. Note that
+for the sake of simplicity we are not giving rigorous (and more complex)
+definitions.
+
+=head3 What's a View?
+
+=head3 What's a Viewport?
+
+ListView and ActionForm are subclasses of ViewPort.
+
+=head3 What's a Focus Stack?
+
+=head3 What are Tangents?
+
+=head3 Can I have a pony?
+
+=head2 USING REACTION
+
+=head3 Where do I put my HTML?
+
+Packages involved
+ ComponentUI
+ ComponentUI::Controller::Bar
+ ComponentUI::Controller::Baz
+ ComponentUI::Controller::Foo
+ ComponentUI::Controller::Root
+ ComponentUI::Model::TestDB
+ ComponentUI::Model::Action
+ ComponentUI::View::XHTML
+
+CRUD
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/old/Manual/Internals.pod b/old/Manual/Internals.pod
new file mode 100644
index 0000000..720608c
--- /dev/null
+++ b/old/Manual/Internals.pod
@@ -0,0 +1,270 @@
+=head1 NAME
+
+Reaction::Manual::Internals
+
+=head2 Hacking on Reaction
+
+=head3 What is a component?
+
+=head3 What component types are there?
+
+=head3 How do I create a new component?
+
+=head3 How does it work with a database?
+
+=head3 What about Moose?
+
+L<Moose>
+
+=head3 Type system
+
+=head3 What Perl modules should I be familiar with, in order to hack on Reaction's
+internals?
+
+=over
+
+=item L<Moose>
+
+A complete modern object system for Perl 5.
+
+=item L<aliased>
+
+Use shorter package names, i.e., "X::Y::Z" as "Z".
+
+=item L<Catalyst>
+
+The MVC application framework Reaction uses.
+
+=over
+
+=item * L<Catalyst::Controller::BindLex>
+
+=item * L<Catalyst::Model::DBIC::Schema>
+
+=item * L<Catalyst::Plugin::ConfigLoader>
+
+=item * L<Catalyst::Plugin::I18N>
+
+=item * L<Catalyst::Plugin::Static::Simple>
+
+=item * L<Catalyst::View::TT>
+
+=back
+
+=item TT
+
+Template Toolkit
+
+=item L<Config::General>
+
+Generic config file module.
+
+=item L<DBIx::Class>
+
+Object/Relational mapper.
+
+=item L<DateTime>
+
+=item L<DateTime::Format::MySQL>
+
+=item L<Digest::MD5>
+
+=item L<Email::MIME>
+
+=item L<Email::MIME::Creator>
+
+=item L<Email::Send>
+
+=item L<Email::Valid>
+
+=item L<SQL::Translator>
+
+=item L<Test::Class>
+
+=item L<Test::Memory::Cycle>
+
+=item L<Time::ParseDate>
+
+=back
+
+=head3 Packages involved
+
+=over
+
+=item L<Reaction::Class>
+
+Utility class, sets up to export a few methods that return parameters for use
+within Moose's C<has> (as new parameters) in other packages. It also C<use>s
+Moose itself.
+
+The methods it injects are:
+
+=over
+
+=item set_or_lazy_build($field_name)
+
+The attribute is required, if not provided beforehand the build_${name} method
+will be called on the object when the attribute's getter is first called. If
+the method does not exist, or returns undef, an error will be thrown.
+
+=item set_or_lazy_fail()
+
+The attribute is required, if not provided beforehand the 'lazy' parameter of
+Moose will make it fail.
+
+=item trigger_adopt()
+
+Calls adopt_${type} after the attribute value is set to $type.
+
+=item register_inc_entry()
+
+Will mark the calling package as already included, using %INC.
+
+=back
+
+=item Reaction::InterfaceModel::Action
+
+=item Reaction::InterfaceModel::Action::DBIC::ResultSet::Create;
+
+=item Reaction::InterfaceModel::Action::DBIC::ActionReflector;
+
+A method "adaptor" that creates the needed objects to support CRUD DBIC
+actions. In the future the code could be moved to a class higher in the
+hierarchy and only contain the operations to adapt.
+
+Sample run:
+
+Reaction::InterfaceModel::Action::DBIC::ActionReflector->reflect_actions_for(
+Reaction::InterfaceModel::Action::DBIC::ActionReflector=HASH(0x93cb2f0)
+RTest::TestDB::Foo
+ComponentUI::Model::Action
+)
+
+Generates and evaluates:
+
+package ComponentUI::Model::Action::DeleteFoo;
+use Reaction::Class;
+extends 'Reaction::InterfaceModel::Action::DBIC::Result::Delete';
+package ComponentUI::Model::Action::UpdateFoo;
+use Reaction::Class;
+extends 'Reaction::InterfaceModel::Action::DBIC::Result::Update';
+has 'baz_list' => (isa => 'ArrayRef', is => 'rw', set_or_lazy_fail('baz_list'), default => sub { [] }, valid_values => sub {
+$_[0]->target_model
+->result_source
+->related_source('links_to_baz_list')
+->related_source('baz')
+->resultset;
+});
+has 'last_name' => (isa => 'NonEmptySimpleStr', is => 'rw', set_or_lazy_fail('last_name'));
+has 'first_name' => (isa => 'NonEmptySimpleStr', is => 'rw', set_or_lazy_fail('first_name'));
+package ComponentUI::Model::Action::CreateFoo;
+use Reaction::Class;
+extends 'Reaction::InterfaceModel::Action::DBIC::ResultSet::Create';
+has 'baz_list' => (isa => 'ArrayRef', is => 'rw', set_or_lazy_fail('baz_list'), default => sub { [] }, valid_values => sub {
+$_[0]->target_model
+->result_source
+->related_source('links_to_baz_list')
+->related_source('baz')
+->resultset;
+});
+has 'last_name' => (isa => 'NonEmptySimpleStr', is => 'rw', set_or_lazy_fail('last_name'));
+has 'first_name' => (isa => 'NonEmptySimpleStr', is => 'rw', set_or_lazy_fail('first_name'));
+
+=item Reaction::InterfaceModel::Action::DBIC::Result::Delete
+
+=item Reaction::InterfaceModel::Action::DBIC::Result::Update
+
+=item Reaction::InterfaceModel::Action::DBIC::User::ResetPassword
+
+=item Reaction::InterfaceModel::Action::DBIC::User::Role::SetPassword
+
+=item Reaction::InterfaceModel::Action::DBIC::User::ChangePassword
+
+=item Reaction::InterfaceModel::Action::User::ResetPassword
+
+=item Reaction::InterfaceModel::Action::User::ChangePassword
+
+=item Reaction::InterfaceModel::Action::User::SetPassword
+
+=item Reaction::Meta::InterfaceModel::Action::ParameterAttribute
+
+=item Reaction::Meta::InterfaceModel::Action::Class
+
+=item Reaction::Types::Email
+
+=item Reaction::Types::Core
+
+=item Reaction::Types::DateTime
+
+=item Reaction::Types::File
+
+=item Reaction::Types::DBIC
+
+=item Reaction::UI::ViewPort::ListView
+
+=item Reaction::UI::ViewPort::Field::Text
+
+=item Reaction::UI::ViewPort::Field::ChooseMany
+
+=item Reaction::UI::ViewPort::Field::String
+
+=item Reaction::UI::ViewPort::Field::Number
+
+=item Reaction::UI::ViewPort::Field::HiddenArray
+
+=item Reaction::UI::ViewPort::Field::DateTime
+
+=item Reaction::UI::ViewPort::Field::File
+
+=item Reaction::UI::ViewPort::Field::ChooseOne
+
+=item Reaction::UI::ViewPort::Field::Password
+
+=item Reaction::UI::ViewPort::ActionForm
+
+=item Reaction::UI::ViewPort::Field
+
+=item Reaction::UI::FocusStack
+
+=item Reaction::UI::RootController
+
+=item Reaction::UI::Window
+
+=item Reaction::UI::Renderer::XHTML
+
+=item Reaction::UI::ViewPort
+
+=item Reaction::UI::CRUDController
+
+=item Reaction::UI::Controller
+
+=back
+
+=head3 Remarks about POD
+
+Don't use C<=over N>. POD assumes that the indent level is 4 if you leave
+it out. Most POD renderers ignore your indent level anyway.
+
+=head2 UNSORTED
+
+Packages involved
+
+t/lib/Rtest/TestDB*: TestDB DBIC declarations.
+t/lib/RTest/TestDB.pm: does DBIC populate for t/.
+t/lib/RTest/UI/ XXX
+
+Reaction::Test::WithDB;
+Reaction::Test;
+Reaction::Test::Mock::Context;
+Reaction::Test::Mock::Request;
+Reaction::Test::Mock::Response;
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/old/Manual/Intro.pod b/old/Manual/Intro.pod
new file mode 100644
index 0000000..73d3846
--- /dev/null
+++ b/old/Manual/Intro.pod
@@ -0,0 +1,62 @@
+=head1 NAME
+
+Reaction::Manual::Intro - Introduction to Reaction
+
+=head1 INTRODUCTION
+
+Reaction is basically an extended MVC:
+
+=over
+
+=item Domain Model
+
+DBIC schema, etc.
+
+=item Interface Model
+
+Model::DBIC::Schema and Action classes.
+
+=item Controller
+
+Mediation and navigation.
+
+=item ViewPort
+
+View logic and event handling encapsulation.
+
+=item Renderer
+
+View:: classes, handed viewports.
+
+=back
+
+=head1 THE REACTION WAY
+
+The idea is you separate your domain model, which encapsulates the domain
+itself from your interface model, which is a model of how a particular app or
+class of apps interact with that domain and provides objects/methods to
+encapsulate the common operations it does.
+
+=head2 Basic usage
+
+XXX TODO
+
+=head1 SEE ALSO
+
+=over
+
+=item * L<Reaction::Manual::Cookbook>
+
+=item * L<Reaction::Manual::FAQ>
+
+=back
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut