=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