[Catalyst-commits] r12426 - in
trunk/examples/CatalystAdvent/root/2009: . pen
zts at dev.catalyst.perl.org
zts at dev.catalyst.perl.org
Fri Dec 18 00:03:00 GMT 2009
Author: zts
Date: 2009-12-18 00:03:00 +0000 (Fri, 18 Dec 2009)
New Revision: 12426
Added:
trunk/examples/CatalystAdvent/root/2009/18.pod
Removed:
trunk/examples/CatalystAdvent/root/2009/pen/gitalist.pod
Log:
Publish day 18 (gitalist).
Copied: trunk/examples/CatalystAdvent/root/2009/18.pod (from rev 12425, trunk/examples/CatalystAdvent/root/2009/pen/gitalist.pod)
===================================================================
--- trunk/examples/CatalystAdvent/root/2009/18.pod (rev 0)
+++ trunk/examples/CatalystAdvent/root/2009/18.pod 2009-12-18 00:03:00 UTC (rev 12426)
@@ -0,0 +1,118 @@
+=head1 Keeping Your Model Reusable
+
+=head2 Introduction
+
+Catalyst's MVC (Model/View/Controller) structure gently guides us to
+separate the code handling the various aspects of our application, without
+insisting that we do the right thing.
+
+Good advice, and an oft-heard refrain, is to avoid creating fat controllers.
+What makes a controller fat? The inclusion of code concerned with doing
+the work your application is built to do. If you were building an app to
+translate text from one language to another, the code performing the
+translation logic should be neatly wrapped up in a model, not stuck in
+the controller.
+
+This approach improves your life in a variety of ways. The resulting code
+is easier to understand, easier to debug, and easier to test. Taken one
+step further, it also makes it trivial to re-use. Let's see how this can
+work by looking at the example of Gitalist.
+
+=head2 Gitalist
+
+Gitalist began as a project to implement gitweb (the Git web viewer) as a
+Catalyst application. While the main aim was to produce a web application,
+we knew that we'd want to be able to write other, non-web tools that had
+access to the same functionality.
+
+With this in mind, we needed our Catalyst model (C<Gitalist::Model::GitRepos>)
+to serve as a thin layer of glue connecting our plain model (C<Gitalist::Git>)
+into the application. Fortunately, this is incredibly easy.
+
+=head2 The Plain Model
+
+First, we implement the plain model. In Gitalist, we needed to represent
+both an individual git repository (a Project), and the directory containing
+a collection of Projects (a Repo; though we don't like this class name, and
+it changes in the next release).
+
+A simplified version of the Repo class looks like this:
+
+ use MooseX::Declare;
+
+ class Gitalist::Git::Repo {
+ has path => ( isa => Dir, required => 1 );
+ has projects => ( isa => ArrayRef['Gitalist::Git::Project'],
+ required => 1,
+ lazy_build => 1 );
+
+ method _build_projects {
+ # return an array of each git repository found.
+ }
+
+ method get_project ($project_name) {
+ my $project_path = $self->path->subdir($project_name);
+ return Gitalist::Git::Project->new( $project_path );
+ }
+ }
+
+While the actual code is more complex, there's no trace of Catalyst in
+sight - exactly as it should be! This class can readily be used in
+other applications, and is very easy to test.
+
+=head2 The Catalyst Model
+
+If all our actual logic is contained in the plain model, it follows that
+our Catalyst model will contain none. Sure enough, we do the minimum
+amount of work required to create an instance of C<Gitalist::Git::Repo>.
+
+ package Gitalist::Model::GitRepos;
+ use Moose;
+
+ extends 'Catalyst::Model';
+ with 'Catalyst::Component::InstancePerContext';
+
+ use Gitalist::Git::Repo;
+
+ has repo_dir => ( isa => Str, is => 'ro', lazy_build => 1 );
+ sub _build_repo_dir {
+ # code to determine the value of repo_dir
+ }
+
+ sub build_per_context_instance {
+ my ($self, $app) = @_;
+
+ Gitalist::Git::Repo->new(repo_dir => $self->repo_dir);
+ }
+
+We used L<Catalist::Component::InstancePerContext> which will run
+C<build_per_context_instance> for each new request. This suits Gitalist,
+but for other uses it may be preferable for your model to persist between
+requests - in that case, L<Catalyst::Model::Adaptor> is what you'll need.
+
+=head2 The Controller
+
+With the model in place, the controller is straightforward. If we've done
+everything right, we shouldn't even notice that our model exists outside
+Catalyst. An action like this will do just what you expect:
+
+ sub project : Chained('base') CaptureArgs(1) {
+ my($self, $c, $project_name) = @_;
+
+ my $project = $c->model->('GitRepos')->get_project($project_name);
+ $c->detach('/error_404') unless $project;
+
+ $c->stash( Project => $project );
+ }
+
+=head2 Further Reading
+
+Both L<Catalyst::Component::InstancePerContext> and
+L<Catalyst::Model::Factory::PerRequest> can be used to build a new
+model instance for each request.
+
+For a persistent instance, instead look at L<Catalyst::Model::Adapter>.
+
+=head1 AUTHOR
+
+Zac Stevens <zts at cryptocracy.com>
Deleted: trunk/examples/CatalystAdvent/root/2009/pen/gitalist.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2009/pen/gitalist.pod 2009-12-17 23:52:50 UTC (rev 12425)
+++ trunk/examples/CatalystAdvent/root/2009/pen/gitalist.pod 2009-12-18 00:03:00 UTC (rev 12426)
@@ -1,118 +0,0 @@
-=head1 Keeping Your Model Reusable
-
-=head2 Introduction
-
-Catalyst's MVC (Model/View/Controller) structure gently guides us to
-separate the code handling the various aspects of our application, without
-insisting that we do the right thing.
-
-Good advice, and an oft-heard refrain, is to avoid creating fat controllers.
-What makes a controller fat? The inclusion of code concerned with doing
-the work your application is built to do. If you were building an app to
-translate text from one language to another, the code performing the
-translation logic should be neatly wrapped up in a model, not stuck in
-the controller.
-
-This approach improves your life in a variety of ways. The resulting code
-is easier to understand, easier to debug, and easier to test. Taken one
-step further, it also makes it trivial to re-use. Let's see how this can
-work by looking at the example of Gitalist.
-
-=head2 Gitalist
-
-Gitalist began as a project to implement gitweb (the Git web viewer) as a
-Catalyst application. While the main aim was to produce a web application,
-we knew that we'd want to be able to write other, non-web tools that had
-access to the same functionality.
-
-With this in mind, we needed our Catalyst model (C<Gitalist::Model::GitRepos>)
-to serve as a thin layer of glue connecting our plain model (C<Gitalist::Git>)
-into the application. Fortunately, this is incredibly easy.
-
-=head2 The Plain Model
-
-First, we implement the plain model. In Gitalist, we needed to represent
-both an individual git repository (a Project), and the directory containing
-a collection of Projects (a Repo; though we don't like this class name, and
-it changes in the next release).
-
-A simplified version of the Repo class looks like this:
-
- use MooseX::Declare;
-
- class Gitalist::Git::Repo {
- has path => ( isa => Dir, required => 1 );
- has projects => ( isa => ArrayRef['Gitalist::Git::Project'],
- required => 1,
- lazy_build => 1 );
-
- method _build_projects {
- # return an array of each git repository found.
- }
-
- method get_project ($project_name) {
- my $project_path = $self->path->subdir($project_name);
- return Gitalist::Git::Project->new( $project_path );
- }
- }
-
-While the actual code is more complex, there's no trace of Catalyst in
-sight - exactly as it should be! This class can readily be used in
-other applications, and is very easy to test.
-
-=head2 The Catalyst Model
-
-If all our actual logic is contained in the plain model, it follows that
-our Catalyst model will contain none. Sure enough, we do the minimum
-amount of work required to create an instance of C<Gitalist::Git::Repo>.
-
- package Gitalist::Model::GitRepos;
- use Moose;
-
- extends 'Catalyst::Model';
- with 'Catalyst::Component::InstancePerContext';
-
- use Gitalist::Git::Repo;
-
- has repo_dir => ( isa => Str, is => 'ro', lazy_build => 1 );
- sub _build_repo_dir {
- # code to determine the value of repo_dir
- }
-
- sub build_per_context_instance {
- my ($self, $app) = @_;
-
- Gitalist::Git::Repo->new(repo_dir => $self->repo_dir);
- }
-
-We used L<Catalist::Component::InstancePerContext> which will run
-C<build_per_context_instance> for each new request. This suits Gitalist,
-but for other uses it may be preferable for your model to persist between
-requests - in that case, L<Catalyst::Model::Adaptor> is what you'll need.
-
-=head2 The Controller
-
-With the model in place, the controller is straightforward. If we've done
-everything right, we shouldn't even notice that our model exists outside
-Catalyst. An action like this will do just what you expect:
-
- sub project : Chained('base') CaptureArgs(1) {
- my($self, $c, $project_name) = @_;
-
- my $project = $c->model->('GitRepos')->get_project($project_name);
- $c->detach('/error_404') unless $project;
-
- $c->stash( Project => $project );
- }
-
-=head2 Further Reading
-
-Both L<Catalyst::Component::InstancePerContext> and
-L<Catalyst::Model::Factory::PerRequest> can be used to build a new
-model instance for each request.
-
-For a persistent instance, instead look at L<Catalyst::Model::Adapter>.
-
-=head1 AUTHOR
-
-Zac Stevens <zts at cryptocracy.com>
More information about the Catalyst-commits
mailing list