[Catalyst-commits] r8832 - trunk/examples/CatalystAdvent/root/2008/pen

matthewt at dev.catalyst.perl.org matthewt at dev.catalyst.perl.org
Thu Dec 11 23:58:38 GMT 2008


Author: matthewt
Date: 2008-12-11 23:58:37 +0000 (Thu, 11 Dec 2008)
New Revision: 8832

Added:
   trunk/examples/CatalystAdvent/root/2008/pen/11.pod
Log:
11.pod

Added: trunk/examples/CatalystAdvent/root/2008/pen/11.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2008/pen/11.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2008/pen/11.pod	2008-12-11 23:58:37 UTC (rev 8832)
@@ -0,0 +1,131 @@
+=head1 Doing rails-style routes with Catalyst
+
+People often ask about using rails-style routes, and why Catalyst doesn't
+"support" them. Well, actually, it does - through the magic of config.
+
+=head1 Routes via the config file
+
+The key is this: action attributes are actually just defaults - when you do
+
+  sub foo :Local {
+
+that makes the default attribute hash for foo { Local => [ '' ] }. Well,
+it doesn't, because Local is parsed - what you actually get for
+
+  package MyApp::Controller::Name;
+
+  sub foo :Local {
+
+is { Path => [ 'name/foo' ] }. Now, this can be overriden from the config
+file by doing something like:
+
+  <Controller Name>
+    <action foo>
+      Path somewhere/else
+    </action>
+  </Controller>
+
+Which is perhaps a little bit verbose, but then you only use config for
+per-deployment stuff, right? Right?
+
+=head1 Routes via code, and controller reuse
+
+So doing it from MyApp.pm is maybe a bit cleaner -
+
+  __PACKAGE__->config(
+    Controller => {
+      Name => {
+        actions => {
+          foo => { Path => 'somewhere/else' }
+        }
+      }
+    }
+  );
+
+alhtough this is still quite verbose, of course. Generally, this approach is
+only ever used to allow URL localisations - for example if you sell a white
+label app to a foreign client you can change the URL parts to their language;
+I'm aware of people having done this in production.
+
+Of course, the other thing you can do is to use this to make reusable
+controllers -
+
+  package MyApp::ControllerBase::List;
+
+  sub list :Args(0) {
+    my ($self, $c) = @_;
+    my $rs = $c->stash->{rs}->page($c->req->query_params->{page}||1);
+    $c->stash(
+      pager => $rs->pager,
+      results => [ $rs->all ]
+    );
+  }
+
+  package MyApp::Controller::Thingies;
+
+  use base qw(MyApp::ControllerBase::List);
+
+  __PACKAGE__->config(
+    actions => {
+      list => { Chained => 'load_thingies' }
+    }
+  );
+
+  sub load_thingies :Chained('/') :CaptureArgs(0) :PathPart('thingies') {
+    my ($self, $c) = @_:
+    $c->stash(
+      rs => $c->model('DB::Thingy')
+    );
+  }
+
+and now Thingies->list will be chained off Thingies->load_thingies.
+
+=head1 Syntactic sugar
+
+But we were talking about routes, weren't we? Though I would observe that
+controllers' self-contained-ness is what makes this sort of subclass-to-reuse
+stuff possible; the rails guys say "re-use in the large is overrated", we
+say "well, actually, it's bloody hard, but if you're careful ...". Anyway.
+
+Let's see if we can't make routes a bit prettier.
+
+  {
+
+    my %config;
+
+    sub routes (&) {
+      my $cr = $_[0];
+      %config = ();
+      $cr->();
+      __PACKAGE__->config(\%config);
+    }
+
+    sub route {
+      my ($path, $to) = @_;
+      my ($controller, $action) = split(/->/, $to);
+      $config{"Controller::$controller"}{actions}{$action}{Path} = [ $path ];
+    }
+
+    sub to { @_ }
+  }
+  use namespace::clean; # this will get rid of the subs on EOF
+
+  routes {
+    route 'some/path' to 'Name->foo';
+  };
+
+and the end result will be (provided we've marked foo as an action via
+
+  sub foo :Action {
+
+) that /some/path will dispatch to that method on MyApp::Controller::Name.
+
+Of course, I still think that Catalyst's self-contained controller approach
+is better, but if you really want routes, please consider the code above as
+under the same license as perl and send CatalystX::Routes to the CPAN :)
+
+-- mst
+
+=head1 AUTHOR
+
+Matt S Trout C<< <mst at shadowcat.co.uk> >> ( http://www.shadowcat.co.uk/ )




More information about the Catalyst-commits mailing list