There is nothing to change in the application class file.
+As you work through this tutorial you'll be creating several new files in
+various directories. You can save some time by creating the directories now,
+like this:
+
+ mkdir -p share/skin/myapp/layout lib/MyApp/View/Site/Widget lib/MyApp/Schema lib/MyApp/InterfaceModel
+
=head1 THE VIEW
Since we are not just rendering templates with Reaction, but layouts and widgets,
package MyApp::View::Site;
use Reaction::Class;
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
extends 'Reaction::UI::View::TT';
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.
+L<namespace::autoclean>.
In its simplest version, our view just needs to do a C<extends 'Reaction::UI::View::TT'>
to make a new subclass of it.
use aliased 'Reaction::UI::ViewPort';
use aliased 'Reaction::UI::ViewPort::SiteLayout';
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
__PACKAGE__->config(
view_name => 'Site',
$self->push_viewport(SiteLayout,
title => 'MyApp Test Title',
static_base_uri => join('', $ctx->uri_for('/static')),
+ meta_info => {
+ http_header => {
+ 'Content-Type' => 'text/html;charset=utf-8',
+ },
+ },
);
}
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 effects of L<strict>, L<warnings>, L<parent>, L<aliased> and L<namespace::autoclean>
+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
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.
+we could call C<[% call_next %]> to include the layout fragment from the extended layout.
The layout representing the root action is called C<share/skin/myapp/layout/root.tt>:
package MyApp::View::Site::Widget::Root;
use Reaction::UI::WidgetClass;
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
__PACKAGE__->meta->make_immutable;
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:
+The first thing we will need is a schema class in C<lib/MyApp/Schema.pm>:
package MyApp::Schema;
use strict;
$
The result class for this table combines the usual style of L<DBIx::Class> with L<Moose> meta
-data additions:
+data additions in C<lib/MyApp/Schema/Foo.pm>:
package MyApp::Schema::Foo;
use Moose;
use MooseX::Types::Moose qw( Int );
use Reaction::Types::Core qw( NonEmptySimpleStr );
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
extends 'DBIx::Class';
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>):
+model actions for our schema (C<Create>, C<Update>, C<Delete>, C<DeleteAll>) in
+C<lib/MyApp/InterfaceModel/DBIC.pm>:
package MyApp::InterfaceModel::DBIC;
use Reaction::Class;
use Reaction::InterfaceModel::Reflector::DBIC;
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
my $reflector = Reaction::InterfaceModel::Reflector::DBIC->new;
package MyApp::Model::DBIC;
use Reaction::Class;
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
extends 'Catalyst::Model::Reaction::InterfaceModel::DBIC';
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
+model and the C<db_dsn>. If you're using a different kind of database then you
+may neeb to add config for C<db_user>, C<db_password>, and C<db_params>.
+All these get passed to the schema's connect() method.
+
+Of course, since this is Catalyst, all 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:
+data, it isn't very hard (at least not for us) to build a basic (but extendable)
+CRUD controller in C<lib/MyApp/Controller/Foo.pm>:
package MyApp::Controller::Foo;
use strict;
use parent 'Reaction::UI::Controller::Collection::CRUD';
use Reaction::Class;
- use namespace::clean -except => 'meta';
+ use namespace::autoclean;
__PACKAGE__->config(
model_name => 'DBIC',
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
+the collection in the specified interface model. For us, this would be C<Foo>, to match 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