work in progress, listview still broken
[catagits/Reaction.git] / lib / Reaction / UI / Controller / Collection.pm
1 package Reaction::UI::Controller::Collection;
2
3 use strict;
4 use warnings;
5 use base 'Reaction::UI::Controller';
6 use Reaction::Class;
7
8 use aliased 'Reaction::UI::ViewPort::ListView';
9 use aliased 'Reaction::UI::ViewPort::Object';
10
11 has 'model_name'      => (isa => 'Str', is => 'rw', required => 1);
12 has 'collection_name' => (isa => 'Str', is => 'rw', required => 1);
13
14 has action_viewport_map  => (isa => 'HashRef', is => 'rw', lazy_build => 1);
15 has action_viewport_args => (isa => 'HashRef', is => 'rw', lazy_build => 1);
16
17 sub _build_action_viewport_map {
18   return {
19           list => ListView,
20           view => Object,
21          };
22 }
23
24 sub _build_action_viewport_args {
25   return { };
26 }
27
28 sub base :Action :CaptureArgs(0) {
29   my ($self, $c) = @_;
30 }
31
32 #XXX candidate for futre optimization, should cache reader?
33 sub get_collection {
34   my ($self, $c) = @_;
35   my $model = $c->model( $self->model_name );
36   my $attr  = $model->meta->find_attribute_by_name( $self->collection_name );
37   my $reader = $attr->get_read_method;
38   return $model->$reader;
39 }
40
41 sub list :Chained('base') :PathPart('') :Args(0) {
42   my ($self, $c) = @_;
43   $c->forward(basic_page => [{ collection => $self->get_collection($c) }]);
44 }
45
46 sub object :Chained('base') :PathPart('id') :CaptureArgs(1) {
47   my ($self, $c, $key) = @_;
48   my $object :Stashed = $self->get_collection($c)->find($key);
49   confess "Object? what object?" unless $object; # should be a 404.
50 }
51
52 sub view :Chained('object') :Args(0) {
53   my ($self, $c) = @_;
54   my $object :Stashed;
55   $c->forward(basic_page => [{model => $object}]);
56 }
57
58 sub basic_page : Private {
59   my ($self, $c, $vp_args) = @_;
60   my $action_name = $c->stack->[-2]->name;
61   return $self->push_viewport
62     (
63      $self->action_viewport_map->{$action_name},
64      %{ $vp_args || {} },
65      %{ $self->action_viewport_args->{$action_name} || {} },
66     );
67 }
68
69 1;