Commit | Line | Data |
89b70ba7 |
1 | package Reaction::UI::Controller::Collection; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | use base 'Reaction::UI::Controller'; |
6 | use Reaction::Class; |
7 | |
8cc0103d |
8 | use aliased 'Reaction::UI::ViewPort::Collection::Grid'; |
c8fbb8ad |
9 | use aliased 'Reaction::UI::ViewPort::Object'; |
89b70ba7 |
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 { |
8cc0103d |
19 | list => Grid, |
c8fbb8ad |
20 | view => Object, |
89b70ba7 |
21 | }; |
22 | } |
23 | |
24 | sub _build_action_viewport_args { |
25 | return { }; |
26 | } |
27 | |
89b70ba7 |
28 | #XXX candidate for futre optimization, should cache reader? |
29 | sub get_collection { |
30 | my ($self, $c) = @_; |
31 | my $model = $c->model( $self->model_name ); |
0ccdac9b |
32 | my $collection = $self->collection_name; |
33 | if( my $meth = $model->can( $collection ) ){ |
34 | return $model->$meth; |
35 | } elsif ( my $attr = $model->meta->find_attribute_by_name($collection) ) { |
36 | my $reader = $attr->get_read_method; |
37 | return $model->$reader; |
38 | } |
39 | confess "Failed to find collection $collection"; |
89b70ba7 |
40 | } |
41 | |
b3832dbc |
42 | sub base :Action :CaptureArgs(0) { |
89b70ba7 |
43 | my ($self, $c) = @_; |
89b70ba7 |
44 | } |
45 | |
46 | sub object :Chained('base') :PathPart('id') :CaptureArgs(1) { |
47 | my ($self, $c, $key) = @_; |
1810d302 |
48 | my $object = $self->get_collection($c)->find($key); |
cb92a3a3 |
49 | $c->detach("/error_404") unless $object; |
1810d302 |
50 | $c->stash(object => $object); |
89b70ba7 |
51 | } |
52 | |
b3832dbc |
53 | sub list :Chained('base') :PathPart('') :Args(0) { |
54 | my ($self, $c) = @_; |
b68d6a35 |
55 | $self->basic_page($c, { collection => $self->get_collection($c) }); |
b3832dbc |
56 | } |
57 | |
89b70ba7 |
58 | sub view :Chained('object') :Args(0) { |
59 | my ($self, $c) = @_; |
b68d6a35 |
60 | $self->basic_page($c, { model => $c->stash->{object} }); |
89b70ba7 |
61 | } |
62 | |
aee256be |
63 | sub basic_page { |
89b70ba7 |
64 | my ($self, $c, $vp_args) = @_; |
aee256be |
65 | my $action_name = $c->stack->[-1]->name; |
380db949 |
66 | my $vp = $self->action_viewport_map->{$action_name}, |
67 | my $args = $self->merge_config_hashes |
89b70ba7 |
68 | ( |
380db949 |
69 | $vp_args || {}, |
70 | $self->action_viewport_args->{$action_name} || {} , |
89b70ba7 |
71 | ); |
380db949 |
72 | return $self->push_viewport($vp, %$args); |
89b70ba7 |
73 | } |
74 | |
75 | 1; |
b3832dbc |
76 | |
77 | |
78 | __END__; |
79 | |
80 | =head1 NAME |
81 | |
7d3fe0d2 |
82 | Reaction::UI::Controller |
b3832dbc |
83 | |
84 | =head1 DESCRIPTION |
85 | |
86 | Controller class used to make displaying collections easier. |
87 | Inherits from L<Reaction::UI::Controller>. |
88 | |
89 | =head1 ATTRIBUTES |
90 | |
91 | =head2 model_name |
92 | |
0ccdac9b |
93 | The name of the model this controller will use as it's data source. Should be a |
7d3fe0d2 |
94 | name that can be passed to C<$C-E<gt>model> |
b3832dbc |
95 | |
96 | =head2 collection_name |
97 | |
0ccdac9b |
98 | The name of the collection whithin the model that this Controller will be |
7d3fe0d2 |
99 | utilizing. |
b3832dbc |
100 | |
101 | =head2 action_viewport_map |
102 | |
103 | =over 4 |
104 | |
105 | =item B<_build_action_viewport_map> - Provided builder method, see METHODS |
106 | |
107 | =item B<has_action_viewport_map> - Auto generated predicate |
108 | |
109 | =item B<clear_action_viewport_map>- Auto generated clearer method |
110 | |
111 | =back |
112 | |
0ccdac9b |
113 | Read-write lazy building hashref. The keys should match action names in the |
114 | Controller and the value should be the ViewPort class that this action should |
7d3fe0d2 |
115 | use. See method C<basic_page> for more info. |
b3832dbc |
116 | |
de5b3fab |
117 | =head2 action_viewport_args |
b3832dbc |
118 | |
0ccdac9b |
119 | Read-write lazy building hashref. Additional ViewPort arguments for the action |
7d3fe0d2 |
120 | named as the key in the controller. See method C<basic_page> for more info. |
b3832dbc |
121 | |
122 | =over 4 |
123 | |
124 | =item B<_build_action_viewport_args> - Provided builder method, see METHODS |
125 | |
126 | =item B<has_action_viewport_args> - Auto generated predicate |
127 | |
128 | =item B<clear_action_viewport_args>- Auto generated clearer method |
129 | |
130 | =back |
131 | |
132 | =head1 METHODS |
133 | |
134 | =head2 get_collection $c |
135 | |
136 | Returns an instance of the collection this controller uses. |
137 | |
138 | =head2 _build_action_viewport_map |
139 | |
140 | Provided builder for C<action_viewport_map>. Returns a hash with two items: |
141 | |
142 | list => 'Reaction::UI::ViewPort::ListView', |
143 | view => 'Reaction::UI::ViewPort::Object', |
144 | |
145 | =head2 _build_action_viewport_args |
146 | |
147 | Returns an empty hashref. |
148 | |
7d3fe0d2 |
149 | =head2 basic_page $c, \%vp_args |
150 | |
151 | Accepts two arguments, context, and a hashref of viewport arguments. It will |
152 | automatically determine the action name using the catalyst stack and call |
0ccdac9b |
153 | C<push_viewport> with the ViewPort class name contained in the |
7d3fe0d2 |
154 | C<action_viewport_map> with a set of options determined by merging C<$vp_args> |
155 | and the arguments contained in C<action_viewport_args>, if any. |
156 | |
b3832dbc |
157 | =head1 ACTIONS |
158 | |
159 | =head2 base |
160 | |
161 | Chain link, no-op. |
162 | |
163 | =head2 list |
164 | |
7d3fe0d2 |
165 | Chain link, chained to C<base>. C<list> fetches the collection for the model |
166 | and calls C<basic_page> with a single argument, C<collection>. |
b3832dbc |
167 | |
7d3fe0d2 |
168 | The default ViewPort for this action is C<Reaction::UI::ViewPort::ListView> and |
169 | can be changed by altering the C<action_viewport_map> attribute hash. |
b3832dbc |
170 | |
171 | =head2 object |
172 | |
0ccdac9b |
173 | Chain link, chained to C<base>, captures one argument, 'id'. Attempts to find |
7d3fe0d2 |
174 | a single object by searching for a member of the current collection which has a |
175 | Primary Key or Unique constraint matching that argument. If the object is found |
176 | it is stored in the stash under the C<object> key. |
b3832dbc |
177 | |
178 | =head2 view |
179 | |
7d3fe0d2 |
180 | Chain link, chained to C<object>. Calls C<basic page> with one argument, |
181 | C<model>, which contains an instance of the object fetched by the C<object> |
182 | action link. |
b3832dbc |
183 | |
0ccdac9b |
184 | The default ViewPort for this action is C<Reaction::UI::ViewPort::Object> and |
7d3fe0d2 |
185 | can be changed by altering the C<action_viewport_map> attribute hash. |
b3832dbc |
186 | |
de5b3fab |
187 | =head1 SEE ALSO |
b3832dbc |
188 | |
7d3fe0d2 |
189 | L<Reaction::UI::Controller> |
b3832dbc |
190 | |
191 | =head1 AUTHORS |
192 | |
193 | See L<Reaction::Class> for authors. |
194 | |
195 | =head1 LICENSE |
196 | |
197 | See L<Reaction::Class> for the license. |
198 | |
199 | =cut |