From 7ff308905da567a0ac9fbebf63a04ede5696cded Mon Sep 17 00:00:00 2001 From: edenc Date: Mon, 17 Dec 2007 18:45:59 +0000 Subject: moved docs to /old --- lib/Reaction/Manual.pod | 47 ------ lib/Reaction/Manual/Cookbook.pod | 74 ---------- lib/Reaction/Manual/Example.pod | 304 -------------------------------------- lib/Reaction/Manual/FAQ.pod | 101 ------------- lib/Reaction/Manual/Internals.pod | 270 --------------------------------- lib/Reaction/Manual/Intro.pod | 62 -------- old/Manual.pod | 47 ++++++ old/Manual/Cookbook.pod | 74 ++++++++++ old/Manual/Example.pod | 304 ++++++++++++++++++++++++++++++++++++++ old/Manual/FAQ.pod | 101 +++++++++++++ old/Manual/Internals.pod | 270 +++++++++++++++++++++++++++++++++ old/Manual/Intro.pod | 62 ++++++++ 12 files changed, 858 insertions(+), 858 deletions(-) delete mode 100644 lib/Reaction/Manual.pod delete mode 100644 lib/Reaction/Manual/Cookbook.pod delete mode 100644 lib/Reaction/Manual/Example.pod delete mode 100644 lib/Reaction/Manual/FAQ.pod delete mode 100644 lib/Reaction/Manual/Internals.pod delete mode 100644 lib/Reaction/Manual/Intro.pod create mode 100644 old/Manual.pod create mode 100644 old/Manual/Cookbook.pod create mode 100644 old/Manual/Example.pod create mode 100644 old/Manual/FAQ.pod create mode 100644 old/Manual/Internals.pod create mode 100644 old/Manual/Intro.pod diff --git a/lib/Reaction/Manual.pod b/lib/Reaction/Manual.pod deleted file mode 100644 index ab366cc..0000000 --- a/lib/Reaction/Manual.pod +++ /dev/null @@ -1,47 +0,0 @@ -=head1 NAME - -Reaction::Manual - The Index of The Manual - -=head1 DESCRIPTON - -Reaction is basically an extended MVC framework built upon L. - -=head1 SECTIONS - -=head2 L - -=head2 L - -=head2 L - -=head2 L - -=head2 L - -=head1 SEE ALSO - -=over - -=item * L - -=item * L - -=item * L - -=item * L - -=back - -=head1 SUPPORT - -IRC: Join #reaction on irc.perl.org - -=head1 AUTHORS - -See L for authors for authors. - -=head1 LICENSE - -See L for the license. - -=cut diff --git a/lib/Reaction/Manual/Cookbook.pod b/lib/Reaction/Manual/Cookbook.pod deleted file mode 100644 index e04c6ee..0000000 --- a/lib/Reaction/Manual/Cookbook.pod +++ /dev/null @@ -1,74 +0,0 @@ -=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; - '

'; action_class.split('(?=[A-Z])').join(' '); '

'; - INCLUDE form_base_control; - - END; - - %] - -=head2 Controllers - -Things - -=head2 Models - -Stuff - -=head1 AUTHORS - -See L for authors. - -=head1 LICENSE - -See L for the license. - -=cut diff --git a/lib/Reaction/Manual/Example.pod b/lib/Reaction/Manual/Example.pod deleted file mode 100644 index 02a55fe..0000000 --- a/lib/Reaction/Manual/Example.pod +++ /dev/null @@ -1,304 +0,0 @@ -=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. - -You need at least a fairly basic understanding of L for -this example to have value for you. - -=head2 Installation - -Install L via CPAN. - -Install Reaction from http://code2.0beta.co.uk/reaction/svn via SVN or SVK. - -Set up the database as mentioned in L. 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 - -=head3 The rest - -Reaction will use I 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; - - %]

artist

-

cd

-

track

[% - - 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 /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 for authors. - -=head1 LICENSE - -See L for the license. - -=cut diff --git a/lib/Reaction/Manual/FAQ.pod b/lib/Reaction/Manual/FAQ.pod deleted file mode 100644 index 96f20fd..0000000 --- a/lib/Reaction/Manual/FAQ.pod +++ /dev/null @@ -1,101 +0,0 @@ -=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 for authors. - -=head1 LICENSE - -See L for the license. - -=cut diff --git a/lib/Reaction/Manual/Internals.pod b/lib/Reaction/Manual/Internals.pod deleted file mode 100644 index 720608c..0000000 --- a/lib/Reaction/Manual/Internals.pod +++ /dev/null @@ -1,270 +0,0 @@ -=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 - -=head3 Type system - -=head3 What Perl modules should I be familiar with, in order to hack on Reaction's -internals? - -=over - -=item L - -A complete modern object system for Perl 5. - -=item L - -Use shorter package names, i.e., "X::Y::Z" as "Z". - -=item L - -The MVC application framework Reaction uses. - -=over - -=item * L - -=item * L - -=item * L - -=item * L - -=item * L - -=item * L - -=back - -=item TT - -Template Toolkit - -=item L - -Generic config file module. - -=item L - -Object/Relational mapper. - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=item L - -=back - -=head3 Packages involved - -=over - -=item L - -Utility class, sets up to export a few methods that return parameters for use -within Moose's C (as new parameters) in other packages. It also Cs -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 for authors. - -=head1 LICENSE - -See L for the license. - -=cut diff --git a/lib/Reaction/Manual/Intro.pod b/lib/Reaction/Manual/Intro.pod deleted file mode 100644 index 73d3846..0000000 --- a/lib/Reaction/Manual/Intro.pod +++ /dev/null @@ -1,62 +0,0 @@ -=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 - -=item * L - -=back - -=head1 AUTHORS - -See L for authors. - -=head1 LICENSE - -See L for the license. - -=cut 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. + +=head1 SECTIONS + +=head2 L + +=head2 L + +=head2 L + +=head2 L + +=head2 L + +=head1 SEE ALSO + +=over + +=item * L + +=item * L + +=item * L + +=item * L + +=back + +=head1 SUPPORT + +IRC: Join #reaction on irc.perl.org + +=head1 AUTHORS + +See L for authors for authors. + +=head1 LICENSE + +See L 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; + '

'; action_class.split('(?=[A-Z])').join(' '); '

'; + INCLUDE form_base_control; + + END; + + %] + +=head2 Controllers + +Things + +=head2 Models + +Stuff + +=head1 AUTHORS + +See L for authors. + +=head1 LICENSE + +See L 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. + +You need at least a fairly basic understanding of L for +this example to have value for you. + +=head2 Installation + +Install L via CPAN. + +Install Reaction from http://code2.0beta.co.uk/reaction/svn via SVN or SVK. + +Set up the database as mentioned in L. 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 + +=head3 The rest + +Reaction will use I 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; + + %]

artist

+

cd

+

track

[% + + 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 /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 for authors. + +=head1 LICENSE + +See L 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 for authors. + +=head1 LICENSE + +See L 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 + +=head3 Type system + +=head3 What Perl modules should I be familiar with, in order to hack on Reaction's +internals? + +=over + +=item L + +A complete modern object system for Perl 5. + +=item L + +Use shorter package names, i.e., "X::Y::Z" as "Z". + +=item L + +The MVC application framework Reaction uses. + +=over + +=item * L + +=item * L + +=item * L + +=item * L + +=item * L + +=item * L + +=back + +=item TT + +Template Toolkit + +=item L + +Generic config file module. + +=item L + +Object/Relational mapper. + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=item L + +=back + +=head3 Packages involved + +=over + +=item L + +Utility class, sets up to export a few methods that return parameters for use +within Moose's C (as new parameters) in other packages. It also Cs +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 for authors. + +=head1 LICENSE + +See L 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 + +=item * L + +=back + +=head1 AUTHORS + +See L for authors. + +=head1 LICENSE + +See L for the license. + +=cut -- cgit v1.2.3-54-g00ecf