[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