creating documentation branch
[catagits/Reaction.git] / lib / Reaction / UI / Controller.pm
CommitLineData
7adfd53f 1package Reaction::UI::Controller;
2
d0736579 3use base qw(Catalyst::Controller Reaction::Object);
1810d302 4
7adfd53f 5use Reaction::Class;
747a1feb 6use Scalar::Util 'weaken';
db80cb74 7use namespace::clean -except => [ qw(meta) ];
7adfd53f 8
d0736579 9has context => (is => 'ro', isa => 'Object', weak_ref => 1);
10with 'Catalyst::Component::InstancePerContext';
11
12sub build_per_context_instance {
13 my ($self, $c, @args) = @_;
14 my $newself = $self->new($self->_application, {%$self, context => $c, @args});
15 return $newself;
16}
17
7adfd53f 18sub push_viewport {
19 my $self = shift;
1810d302 20 my $c = $self->context;
21 my $focus_stack = $c->stash->{focus_stack};
7adfd53f 22 my ($class, @proto_args) = @_;
23 my %args;
7adfd53f 24 if (my $vp_attr = $c->stack->[-1]->attributes->{ViewPort}) {
25 if (ref($vp_attr) eq 'ARRAY') {
26 $vp_attr = $vp_attr->[0];
27 }
28 if (ref($vp_attr) eq 'HASH') {
29 if (my $conf_class = delete $vp_attr->{class}) {
30 $class = $conf_class;
31 }
504e2c44 32 %args = %{ $self->merge_config_hashes($vp_attr, {@proto_args}) };
7adfd53f 33 } else {
34 $class = $vp_attr;
35 %args = @proto_args;
36 }
37 } else {
38 %args = @proto_args;
39 }
40
41 $args{ctx} = $c;
42
43 if (exists $args{next_action} && !ref($args{next_action})) {
44 $args{next_action} = [ $self, 'redirect_to', $args{next_action} ];
45 }
46 $focus_stack->push_viewport($class, %args);
47}
48
49sub pop_viewport {
1810d302 50 return shift->context->stash->{focus_stack}->pop_viewport;
7adfd53f 51}
52
53sub pop_viewports_to {
54 my ($self, $vp) = @_;
1810d302 55 return $self->context->stash->{focus_stack}->pop_viewports_to($vp);
7adfd53f 56}
57
58sub redirect_to {
59 my ($self, $c, $to, $cap, $args, $attrs) = @_;
60
61 #the confess calls could be changed later to $c->log ?
62 my $action;
9cf5bc0b 63 my $reftype = ref($to);
64 if( $reftype eq '' ){
65 $action = $self->action_for($to);
66 confess("Failed to locate action ${to} in " . blessed($self)) unless $action;
67 } elsif($reftype eq 'ARRAY' && @$to == 2){ #is that overkill / too strict?
68 $action = $c->controller($to->[0])->action_for($to->[1]);
69 confess("Failed to locate action $to->[1] in $to->[0]" ) unless $action;
70 } elsif( blessed $to && $to->isa('Catalyst::Action') ){
71 $action = $to;
7adfd53f 72 } else{
9cf5bc0b 73 confess("Failed to locate action from ${to}");
7adfd53f 74 }
75
76 $cap ||= $c->req->captures;
77 $args ||= $c->req->args;
78 $attrs ||= {};
79 my $uri = $c->uri_for($action, $cap, @$args, $attrs);
80 $c->res->redirect($uri);
81}
82
747a1feb 83sub make_context_closure {
84 my($self, $closure) = @_;
85 my $ctx = $self->context;
db80cb74 86 weaken($ctx);
747a1feb 87 return sub { $closure->($ctx, @_) };
88}
89
7adfd53f 901;
f2756356 91
92__END__;
93
94=head1 NAME
95
bd1aa0c2 96Reaction::UI::Controller
f2756356 97
98=head1 DESCRIPTION
99
100Base Reaction Controller class. Inherits from:
101
102=over 4
103
104=item L<Catalyst::Controller>
105=item L<Catalyst::Component::ACCEPT_CONTEXT>
106=item L<Reaction::Object>
107
108=back
109
110=head1 METHODS
111
112=head2 push_viewport $vp_class, %args
113
f1cd5548 114Creates a new instance of the L<Reaction::UI::ViewPort> class
115($vp_class) using the rest of the arguments given (%args). Defaults of
116the action can be overridden by using the C<ViewPort> key in the
117controller configuration. For example to override the default number
118of items in a CRUD list action:
119
120__PACKAGE__->config(
121 action => {
122 list => { ViewPort => { per_page => 50 } },
123 }
124 );
125
126The ViewPort is added to the L<Reaction::UI::Window>'s FocusStack in
127the stash, and also returned to the calling code.
128
129Related items:
130
131=over
132
133=item L<Reaction::UI::Controller::Root>
134=item L<Reaction::UI::Window>
135
136=back
f2756356 137
138TODO: explain how next_action as a scalar gets converted to the redirect arrayref thing
139
140=head2 pop_viewport
141
142=head2 pop_viewport_to $vp
143
f1cd5548 144Call L<Reaction::UI::FocusStack/pop_viewport> or
145L<Reaction::UI::FocusStack/pop_viewport_to> on
146the C<< $c->stash->{focus_stack} >>.
f2756356 147
148=head2 redirect_to $c, $to, $captures, $args, $attrs
149
f1cd5548 150Construct a URI and redirect to it.
151
152$to can be:
153
154=over
f2756356 155
f1cd5548 156=item The name of an action in the current controller.
f2756356 157
f1cd5548 158=item A L<Catalyst::Action> instance.
159
160=item An arrayref of controller name and the name of an action in that
161controller.
162
163=back
f2756356 164
f1cd5548 165$captures and $args default to the current requests $captures and
166$args if not supplied.
f2756356 167
168=head1 AUTHORS
169
170See L<Reaction::Class> for authors.
171
172=head1 LICENSE
173
174See L<Reaction::Class> for the license.
175
176=cut